mirror of https://git.wuffs.org/MWCC
158 lines
4.6 KiB
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;
|
||
|
}
|