MWCC/PCode.c

287 lines
6.6 KiB
C

#include "CompilerTools.h"
#include "PCode.h"
// TODO RESOLVE ME
extern void initialize_aliases();
extern void *current_statement;
extern PCode *vformatpcode(short op, va_list args);
PCBlock *pcbasicblocks;
PCBlock *pclastblock;
void *prologue;
void *epilogue;
PCBlock **depthfirstordering;
int pcblockcount;
int pcloopweight;
static unsigned short pclabelcount;
void initpcode() {
pclastblock = 0;
pcbasicblocks = 0;
pcblockcount = 0;
pclabelcount = 0;
pcloopweight = 1;
initialize_aliases();
}
PCode *makepcode(short op, ...) {
PCode *pcode;
va_list list;
va_start(list, op);
pcode = vformatpcode(op, list);
// TODO
return pcode;
}
void emitpcode(short op, ...) {
PCode *pcode;
va_list list;
va_start(list, op);
pcode = vformatpcode(op, list);
// TODO
appendpcode(pclastblock, pcode);
}
PCode *copypcode(PCode *pcode) {
PCode *newpc;
int flag;
flag = 0;
// TODO
return newpc;
}
PCLabel *makepclabel() {
PCLabel *label;
label = (PCLabel *) lalloc(sizeof(PCLabel));
memclrw(label, sizeof(PCLabel));
label->index = pclabelcount++;
return label;
}
PCBlock *makepcblock() {
PCBlock *block;
block = (PCBlock *) lalloc(sizeof(PCBlock));
memclrw(block, sizeof(PCBlock));
block->loopWeight = pcloopweight;
block->blockIndex = pcblockcount++;
if (pclastblock) {
pclastblock->nextBlock = block;
block->prevBlock = pclastblock;
} else {
pcbasicblocks = block;
}
pclastblock = block;
return block;
}
void pclabel(PCBlock *block, PCLabel *label) {
PCLink *iter;
PCLink *next;
iter = (PCLink *) label->block;
while (iter) {
next = (PCLink *) iter->block;
iter->block = block;
iter = next;
}
label->block = block;
label->resolved = 1;
label->nextLabel = block->labels;
block->labels = label;
}
void pcbranch(PCBlock *block, PCLabel *label) {
PCLink *link;
link = (PCLink *) lalloc(sizeof(PCLink));
memclrw(link, sizeof(PCLink));
link->block = label->block;
if (!label->resolved)
label->block = (PCBlock *) link;
link->nextLink = block->successors;
block->successors = link;
}
void pccomputepredecessors() {
PCBlock *block;
PCLink *succ;
PCLink *pred;
for (block = pcbasicblocks; block; block = block->nextBlock) {
for (succ = block->successors; succ; succ = succ->nextLink) {
pred = (PCLink *) lalloc(sizeof(PCLink));
memclrw(pred, sizeof(PCLink));
pred->block = block;
pred->nextLink = succ->block->predecessors;
succ->block->predecessors = pred;
}
}
}
void deleteblock(PCBlock *block) {
block->prevBlock->nextBlock = block->nextBlock;
if (block->nextBlock)
block->nextBlock->prevBlock = block->prevBlock;
block->flags |= fPCBlockFlag20;
}
void deleteunreachableblocks() {
PCBlock *block;
computedepthfirstordering();
for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
if (!(block->flags & fPCBlockFlag4))
deleteblock(block);
}
}
void appendpcode(PCBlock *block, PCode *pcode) {
if (block->firstPCode) {
pcode->nextPCode = 0;
pcode->prevPCode = block->lastPCode;
block->lastPCode->nextPCode = pcode;
block->lastPCode = pcode;
} else {
block->lastPCode = pcode;
block->firstPCode = pcode;
pcode->prevPCode = 0;
pcode->nextPCode = 0;
}
pcode->block = block;
block->pcodeCount++;
}
void deletepcode(PCode *pcode) {
PCBlock *block;
block = pcode->block;
if (pcode->prevPCode)
pcode->prevPCode->nextPCode = pcode->nextPCode;
else
block->firstPCode = pcode->nextPCode;
if (pcode->nextPCode)
pcode->nextPCode->prevPCode = pcode->prevPCode;
else
block->lastPCode = pcode->prevPCode;
pcode->block = 0;
block->pcodeCount--;
block->flags &= ~fPCBlockFlag8;
}
void insertpcodebefore(PCode *anchor, PCode *newpcode) {
PCBlock *block;
block = anchor->block;
if (anchor->prevPCode)
anchor->prevPCode->nextPCode = newpcode;
else
block->firstPCode = newpcode;
newpcode->nextPCode = anchor;
newpcode->prevPCode = anchor->prevPCode;
anchor->prevPCode = newpcode;
newpcode->_1C = anchor->_1C;
newpcode->block = block;
block->pcodeCount++;
block->flags &= ~fPCBlockFlag8;
}
void insertpcodeafter(PCode *anchor, PCode *newpcode) {
PCBlock *block;
block = anchor->block;
if (anchor->nextPCode)
anchor->nextPCode->prevPCode = newpcode;
else
block->lastPCode = newpcode;
newpcode->prevPCode = anchor;
newpcode->nextPCode = anchor->nextPCode;
anchor->nextPCode = newpcode;
newpcode->_1C = anchor->_1C;
newpcode->block = block;
block->pcodeCount++;
block->flags &= ~fPCBlockFlag8;
}
void setpcodeflags(int flags) {
pclastblock->lastPCode->flags |= flags;
if (flags & fSideEffects)
pclastblock->lastPCode->flags &= ~(fIsCSE | fCommutative | fPCodeFlag10);
}
void clearpcodeflags(int flags) {
pclastblock->lastPCode->flags &= ~flags;
}
int pccomputeoffsets() {
int offset;
PCBlock *block;
offset = 0;
for (block = pcbasicblocks; block; block = block->nextBlock) {
block->codeOffset = offset;
offset += block->pcodeCount * 4;
}
return offset;
}
typedef struct _DFO {
PCBlock *block;
PCLink *link;
} DFO;
static int depthfirstorder;
void computedepthfirstordering() {
PCBlock *block;
PCLink *link;
DFO *dfo;
int index;
depthfirstordering = (PCBlock **) lalloc(sizeof(PCBlock *) * pcblockcount);
memclrw(depthfirstordering, sizeof(PCBlock *) * pcblockcount);
depthfirstorder = pcblockcount;
for (block = pcbasicblocks; block; block = block->nextBlock) {
block->flags &= ~fPCBlockFlag4;
}
dfo = (DFO *) oalloc(sizeof(DFO) * pcblockcount);
pcbasicblocks->flags |= fPCBlockFlag4;
dfo->block = pcbasicblocks;
dfo->link = pcbasicblocks->successors;
index = 1;
while (index) {
if ((link = dfo[index - 1].link)) {
dfo[index - 1].link = link->nextLink;
block = link->block;
if (!(block->flags & fPCBlockFlag4)) {
block->flags |= fPCBlockFlag4;
dfo[index].block = block;
dfo[index].link = block->successors;
index++;
}
} else {
depthfirstordering[--depthfirstorder] = dfo[--index].block;
}
}
while (depthfirstorder) {
depthfirstordering[--depthfirstorder] = 0;
}
}