#include "compiler/LiveInfo.h" #include "compiler/BitVectors.h" #include "compiler/Coloring.h" #include "compiler/CompilerTools.h" #include "compiler/PCode.h" #include "compiler/Registers.h" #include "compiler/objects.h" #include "compiler/types.h" #include "compiler/CParser.h" LiveInfo *liveinfo; static void allocateliveinfo(void) { UInt32 regs; LiveInfo *info; int i; regs = used_virtual_registers[coloring_class]; liveinfo = oalloc(sizeof(LiveInfo) * pcblockcount); for (i = 0, info = liveinfo; i < pcblockcount; i++, info++) { bitvectorinitialize(info->vec0 = oalloc(4 * ((regs + 31) >> 5)), regs, 0); bitvectorinitialize(info->vec4 = oalloc(4 * ((regs + 31) >> 5)), regs, 0); bitvectorinitialize(info->vec8 = oalloc(4 * ((regs + 31) >> 5)), regs, 0); bitvectorinitialize(info->vecC = oalloc(4 * ((regs + 31) >> 5)), regs, 0); } } static void computelocalusedef(void) { LiveInfo *info; PCodeBlock *block; PCode *instr; UInt32 *vec0; UInt32 *vec4; PCodeArg *op; int i; for (block = pcbasicblocks; block; block = block->nextBlock) { info = &liveinfo[block->blockIndex]; vec0 = info->vec0; vec4 = info->vec4; for (instr = block->firstPCode; instr; instr = instr->nextPCode) { op = instr->args; i = instr->argCount; while (i--) { if ( op->kind == PCOp_REGISTER && (char) op->arg == coloring_class && (op->data.reg.effect & EffectRead) && !bitvectorgetbit(op->data.reg.reg, vec4) ) bitvectorsetbit(op->data.reg.reg, vec0); op++; } op = instr->args; i = instr->argCount; while (i--) { if ( op->kind == PCOp_REGISTER && (char) op->arg == coloring_class && (op->data.reg.effect & EffectWrite) && !bitvectorgetbit(op->data.reg.reg, vec0) ) bitvectorsetbit(op->data.reg.reg, vec4); op++; } } } } static void computeglobalinout(void) { UInt32 regs; LiveInfo *info; UInt32 *vec0; UInt32 *vec4; UInt32 *vec8; UInt32 *vecC; int bitvecsize; int blockIndex; int i; int flag; PCodeBlock *block; PCLink *link; UInt32 val; regs = used_virtual_registers[coloring_class]; bitvecsize = (regs + 31) >> 5; flag = 1; while (flag) { flag = 0; blockIndex = pcblockcount; while (blockIndex) { if ((block = depthfirstordering[--blockIndex])) { info = &liveinfo[block->blockIndex]; if ((link = block->successors)) { vecC = info->vecC; bitvectorcopy(vecC, liveinfo[link->block->blockIndex].vec8, regs); for (link = link->nextLink; link; link = link->nextLink) bitvectorunion(vecC, liveinfo[link->block->blockIndex].vec8, regs); } vecC = info->vecC; vec8 = info->vec8; vec0 = info->vec0; vec4 = info->vec4; for (i = 0; i < bitvecsize; i++) { val = *vec0 | (*vecC & ~*vec4); if (val != *vec8) { *vec8 = val; flag = 1; } vec8++; vecC++; vec0++; vec4++; } } } } } void computelivevariables(Object *proc) { Type *returnType; returnType = TYPE_FUNC(proc->type)->functype; computedepthfirstordering(); allocateliveinfo(); computelocalusedef(); if (coloring_class == RegClass_GPR && TYPE_FITS_IN_REGISTER(returnType)) { bitvectorsetbit(3, liveinfo[epilogue->blockIndex].vec0); if (TYPE_IS_8BYTES(returnType)) bitvectorsetbit(4, liveinfo[pclastblock->blockIndex].vec0); } else if (coloring_class == RegClass_FPR && IS_TYPE_FLOAT(returnType)) { bitvectorsetbit(1, liveinfo[epilogue->blockIndex].vec0); } else if (coloring_class == RegClass_VR && IS_TYPE_VECTOR(returnType)) { bitvectorsetbit(2, liveinfo[epilogue->blockIndex].vec0); } computeglobalinout(); } int dead(PCode *instr, char rclass, UInt32 *vec) { int i; PCodeArg *op; if (instr->flags & (fPCodeFlag1 | fPCodeFlag4 | fPCodeFlag8 | fIsVolatile | fSideEffects)) return 0; if (instr->block->flags & (fPCBlockFlag1 | fPCBlockFlag2)) return 0; op = instr->args; i = instr->argCount; while (i--) { if ( op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectWrite) && (rclass != (char) op->arg || bitvectorgetbit(op->data.reg.reg, vec)) ) return 0; op++; } return copts.optimizationlevel > 0; }