MWCC/compiler_and_linker/unsorted/LiveVariables.c

158 lines
4.6 KiB
C

#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;
}