MWCC/compiler_and_linker/unsorted/PCode.c

300 lines
7.4 KiB
C
Raw Normal View History

2022-11-07 03:06:21 +00:00
#include "compiler.h"
#include "compiler/CompilerTools.h"
#include "compiler/PCode.h"
#include "compiler/PCodeInfo.h"
2022-10-07 19:02:27 +00:00
2022-11-07 03:06:21 +00:00
PCodeBlock *pcbasicblocks;
PCodeBlock *pclastblock;
2022-10-07 19:02:27 +00:00
void *prologue;
void *epilogue;
2022-11-07 03:06:21 +00:00
PCodeBlock **depthfirstordering;
2022-10-07 19:02:27 +00:00
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);
2022-11-07 03:06:21 +00:00
pcode->sourceoffset = current_statement ? current_statement->sourceoffset : -1;
2022-10-07 19:02:27 +00:00
return pcode;
}
void emitpcode(short op, ...) {
PCode *pcode;
va_list list;
va_start(list, op);
pcode = vformatpcode(op, list);
2022-11-07 03:06:21 +00:00
pcode->sourceoffset = current_statement ? current_statement->sourceoffset : -1;
2022-10-07 19:02:27 +00:00
appendpcode(pclastblock, pcode);
}
PCode *copypcode(PCode *pcode) {
PCode *newpc;
2022-11-07 03:06:21 +00:00
int extra_arg;
int i;
extra_arg = 0;
if ((PCODE_FLAG_SET_F(pcode) & fPCodeFlag8000000) && !(PCODE_FLAG_SET_F(pcode) & fPCodeFlag20000000))
extra_arg = 1;
newpc = lalloc(sizeof(PCode) + sizeof(PCodeArg) * (pcode->argCount + extra_arg));
memclrw(newpc, sizeof(PCode) + sizeof(PCodeArg) * (pcode->argCount + extra_arg));
newpc->op = pcode->op;
newpc->flags = pcode->flags;
newpc->argCount = pcode->argCount;
newpc->_18 = pcode->_18;
for (i = 0; i < pcode->argCount; i++) {
newpc->args[i] = pcode->args[i];
}
2022-10-07 19:02:27 +00:00
2022-11-07 03:06:21 +00:00
if (extra_arg)
newpc->args[pcode->argCount].kind = PCOp_PLACEHOLDEROPERAND;
2022-10-07 19:02:27 +00:00
return newpc;
}
2022-11-07 03:06:21 +00:00
PCodeLabel *makepclabel() {
PCodeLabel *label;
2022-10-07 19:02:27 +00:00
2022-11-07 03:06:21 +00:00
label = (PCodeLabel *) lalloc(sizeof(PCodeLabel));
memclrw(label, sizeof(PCodeLabel));
2022-10-07 19:02:27 +00:00
label->index = pclabelcount++;
return label;
}
2022-11-07 03:06:21 +00:00
PCodeBlock *makepcblock() {
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
2022-11-07 03:06:21 +00:00
block = (PCodeBlock *) lalloc(sizeof(PCodeBlock));
memclrw(block, sizeof(PCodeBlock));
2022-10-07 19:02:27 +00:00
block->loopWeight = pcloopweight;
block->blockIndex = pcblockcount++;
if (pclastblock) {
pclastblock->nextBlock = block;
block->prevBlock = pclastblock;
} else {
pcbasicblocks = block;
}
pclastblock = block;
return block;
}
2022-11-07 03:06:21 +00:00
void pclabel(PCodeBlock *block, PCodeLabel *label) {
2022-10-07 19:02:27 +00:00
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;
}
2022-11-07 03:06:21 +00:00
void pcbranch(PCodeBlock *block, PCodeLabel *label) {
2022-10-07 19:02:27 +00:00
PCLink *link;
link = (PCLink *) lalloc(sizeof(PCLink));
memclrw(link, sizeof(PCLink));
link->block = label->block;
if (!label->resolved)
2022-11-07 03:06:21 +00:00
label->block = (PCodeBlock *) link;
2022-10-07 19:02:27 +00:00
link->nextLink = block->successors;
block->successors = link;
}
void pccomputepredecessors() {
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
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;
}
}
}
2022-11-07 03:06:21 +00:00
void deleteblock(PCodeBlock *block) {
2022-10-07 19:02:27 +00:00
block->prevBlock->nextBlock = block->nextBlock;
if (block->nextBlock)
block->nextBlock->prevBlock = block->prevBlock;
block->flags |= fPCBlockFlag20;
}
void deleteunreachableblocks() {
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
computedepthfirstordering();
for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
if (!(block->flags & fPCBlockFlag4))
deleteblock(block);
}
}
2022-11-07 03:06:21 +00:00
void appendpcode(PCodeBlock *block, PCode *pcode) {
2022-10-07 19:02:27 +00:00
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) {
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
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) {
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
block = anchor->block;
if (anchor->prevPCode)
anchor->prevPCode->nextPCode = newpcode;
else
block->firstPCode = newpcode;
newpcode->nextPCode = anchor;
newpcode->prevPCode = anchor->prevPCode;
anchor->prevPCode = newpcode;
2022-11-07 03:06:21 +00:00
newpcode->sourceoffset = anchor->sourceoffset;
2022-10-07 19:02:27 +00:00
newpcode->block = block;
block->pcodeCount++;
block->flags &= ~fPCBlockFlag8;
}
void insertpcodeafter(PCode *anchor, PCode *newpcode) {
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
block = anchor->block;
if (anchor->nextPCode)
anchor->nextPCode->prevPCode = newpcode;
else
block->lastPCode = newpcode;
newpcode->prevPCode = anchor;
newpcode->nextPCode = anchor->nextPCode;
anchor->nextPCode = newpcode;
2022-11-07 03:06:21 +00:00
newpcode->sourceoffset = anchor->sourceoffset;
2022-10-07 19:02:27 +00:00
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;
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
offset = 0;
for (block = pcbasicblocks; block; block = block->nextBlock) {
block->codeOffset = offset;
offset += block->pcodeCount * 4;
}
return offset;
}
typedef struct _DFO {
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
PCLink *link;
} DFO;
static int depthfirstorder;
void computedepthfirstordering() {
2022-11-07 03:06:21 +00:00
PCodeBlock *block;
2022-10-07 19:02:27 +00:00
PCLink *link;
DFO *dfo;
int index;
2022-11-07 03:06:21 +00:00
depthfirstordering = (PCodeBlock **) lalloc(sizeof(PCodeBlock *) * pcblockcount);
memclrw(depthfirstordering, sizeof(PCodeBlock *) * pcblockcount);
2022-10-07 19:02:27 +00:00
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;
}
}