#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->use = oalloc(4 * ((regs + 31) >> 5)), regs, 0); bitvectorinitialize(info->def = oalloc(4 * ((regs + 31) >> 5)), regs, 0); bitvectorinitialize(info->in = oalloc(4 * ((regs + 31) >> 5)), regs, 0); bitvectorinitialize(info->out = oalloc(4 * ((regs + 31) >> 5)), regs, 0); } } static void computelocalusedef(void) { LiveInfo *info; PCodeBlock *block; PCode *instr; UInt32 *use; UInt32 *def; PCodeArg *op; int i; for (block = pcbasicblocks; block; block = block->nextBlock) { info = &liveinfo[block->blockIndex]; use = info->use; def = info->def; for (instr = block->firstPCode; instr; instr = instr->nextPCode) { op = instr->args; i = instr->argCount; while (i--) { if (PC_OP_IS_READ_ANY_REGISTER(op, coloring_class) && !bitvectorgetbit(op->data.reg.reg, def)) bitvectorsetbit(op->data.reg.reg, use); op++; } op = instr->args; i = instr->argCount; while (i--) { if (PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class) && !bitvectorgetbit(op->data.reg.reg, use)) bitvectorsetbit(op->data.reg.reg, def); op++; } } } } static void computeglobalinout(void) { UInt32 regs; LiveInfo *info; UInt32 *use; UInt32 *def; UInt32 *in; UInt32 *out; 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)) { out = info->out; bitvectorcopy(out, liveinfo[link->block->blockIndex].in, regs); for (link = link->nextLink; link; link = link->nextLink) bitvectorunion(out, liveinfo[link->block->blockIndex].in, regs); } out = info->out; in = info->in; use = info->use; def = info->def; for (i = 0; i < bitvecsize; i++) { val = *use | (*out & ~*def); if (val != *in) { *in = val; flag = 1; } in++; out++; use++; def++; } } } } } 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].use); if (TYPE_IS_8BYTES(returnType)) bitvectorsetbit(4, liveinfo[pclastblock->blockIndex].use); } else if (coloring_class == RegClass_FPR && IS_TYPE_FLOAT(returnType)) { bitvectorsetbit(1, liveinfo[epilogue->blockIndex].use); } else if (coloring_class == RegClass_VR && IS_TYPE_VECTOR(returnType)) { bitvectorsetbit(2, liveinfo[epilogue->blockIndex].use); } computeglobalinout(); } int dead(PCode *instr, RegClass rclass, UInt32 *vec) { int i; PCodeArg *op; if (instr->flags & (fIsBranch | fIsWrite | fIsCall | fIsVolatile | fSideEffects)) return 0; if (instr->block->flags & (fIsProlog | fIsEpilogue)) return 0; op = instr->args; i = instr->argCount; while (i--) { if ( op->kind == PCOp_REGISTER && (op->data.reg.effect & EffectWrite) && (rclass != op->arg || bitvectorgetbit(op->data.reg.reg, vec)) ) return 0; op++; } return copts.optimizationlevel > 0; }