Initial commit
This commit is contained in:
93
src/optims.c
Normal file
93
src/optims.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#include"optims.h"
|
||||
|
||||
#include<assert.h>
|
||||
|
||||
// Currently performs only copy propagation.
|
||||
// But CP is NECESSARY, otherwise it creates too many variables
|
||||
// that are unable to be coalesced by the regallocator
|
||||
|
||||
static void recalc_lifespan(VarTableEntry *vte) {
|
||||
assert(vte->kind == VARTABLEENTRY_VAR);
|
||||
|
||||
size_t start = 0xFFFFFFFF, end = 0;
|
||||
|
||||
UseDef *ud = vte->data.var.usedefFirst;
|
||||
while(ud) {
|
||||
if(ud->t < start) start = ud->t;
|
||||
|
||||
if(ud->t > end) end = ud->t;
|
||||
|
||||
ud = ud->next;
|
||||
}
|
||||
|
||||
vte->data.var.start = start;
|
||||
vte->data.var.end = end;
|
||||
}
|
||||
|
||||
void optim_chunk(ASTChunk *chu) {
|
||||
AST *s = chu->statementFirst, *sPrev = NULL;
|
||||
while(s) {
|
||||
if(s->nodeKind == AST_STMT_ASSIGN && s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_VAR) {
|
||||
VarTableEntry *dst = ((AST*) s->stmtAssign.what)->exprVar.thing;
|
||||
VarTableEntry *src = ((AST*) s->stmtAssign.to)->exprVar.thing;
|
||||
|
||||
if(dst->kind == VARTABLEENTRY_VAR && src->kind == VARTABLEENTRY_VAR) {
|
||||
// Find reaching source definition
|
||||
|
||||
UseDef *srcUD = src->data.var.usedefFirst;
|
||||
while(srcUD && srcUD->use != s->stmtAssign.to) {
|
||||
srcUD = srcUD->next;
|
||||
}
|
||||
|
||||
if(!srcUD) {
|
||||
goto copypropfail;
|
||||
}
|
||||
|
||||
// Find first use of this def
|
||||
|
||||
UseDef *dstUDPrev = NULL;
|
||||
UseDef *dstUD = dst->data.var.usedefFirst;
|
||||
while(dstUD->def != s) {
|
||||
dstUDPrev = dstUD;
|
||||
dstUD = dstUD->next;
|
||||
}
|
||||
|
||||
// Update all definitions
|
||||
|
||||
while(dstUD && dstUD->def == s) {
|
||||
((AST*) dstUD->use)->exprVar.thing = src;
|
||||
|
||||
UseDef *next = dstUD->next;
|
||||
|
||||
dstUD->def = srcUD->def;
|
||||
dstUD->next = srcUD->next;
|
||||
srcUD->next = dstUD;
|
||||
|
||||
dstUD = next;
|
||||
|
||||
if(dstUDPrev) {
|
||||
dstUDPrev->next = dstUD;
|
||||
} else {
|
||||
dst->data.var.usedefFirst = dstUD;
|
||||
}
|
||||
}
|
||||
|
||||
if(!dstUD) {
|
||||
// dst was never used again -> DELETE ASSIGNMENT COMPLETELY
|
||||
|
||||
if(sPrev) {
|
||||
sPrev->statement.next = s->statement.next;
|
||||
// TODO: free
|
||||
}
|
||||
}
|
||||
|
||||
recalc_lifespan(dst);
|
||||
recalc_lifespan(src);
|
||||
}
|
||||
}
|
||||
|
||||
copypropfail:
|
||||
sPrev = s;
|
||||
s = s->statement.next;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user