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