Skip to content

Commit

Permalink
fix bugs in regalloc and liveness; simple optimize for static link; f…
Browse files Browse the repository at this point in the history
…inal version for handin
  • Loading branch information
hzqmwne committed Dec 25, 2017
1 parent 738bca1 commit ec53646
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 11 deletions.
12 changes: 10 additions & 2 deletions lab6/color.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <string.h>

#include "util.h"
#include "table.h"
#include "symbol.h"
#include "temp.h"
#include "tree.h"
Expand All @@ -11,7 +12,6 @@
#include "graph.h"
#include "liveness.h"
#include "color.h"
#include "table.h"


static G_table additionalNodeTable = NULL;
Expand Down Expand Up @@ -360,7 +360,8 @@ static void assignColors(Temp_tempList colors) {
/*
void printNodeList(G_nodeList nl, string s) {
printf("%s ", s);
for(G_nodeList il = nl; il; il = il->tail) {
G_nodeList il;
for(il = nl; il; il = il->tail) {
Live_additionalInfo info = Live_getAdditionalInfo(additionalNodeTable, il->head);
printf("%d:%d ", Temp_int(Live_gtemp(il->head)), info->degree);
}
Expand Down Expand Up @@ -442,8 +443,14 @@ struct COL_result COL_color(G_graph ig, Temp_map initial, Temp_tempList regs, Li
spills = Temp_TempList(Live_gtemp(nl->head), spills);
}
if(spills != NULL) {
TAB_table tempAlias = TAB_empty();
G_nodeList nl;
for(nl = coalescedNodes; nl; nl = nl->tail) {
TAB_enter(tempAlias, G_nodeInfo(nl->head), G_nodeInfo(getAlias(nl->head)));
}
ret.coloring = NULL;
ret.spills = spills;
ret.tempAlias = tempAlias;
}
else {
Temp_map coloring = Temp_empty();
Expand All @@ -455,6 +462,7 @@ struct COL_result COL_color(G_graph ig, Temp_map initial, Temp_tempList regs, Li
}
ret.coloring = coloring;
ret.spills = NULL;
ret.tempAlias = NULL;
}
ret.coalescedMoves = coalescedMoves;
return ret;
Expand Down
1 change: 1 addition & 0 deletions lab6/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct COL_result {
Temp_map coloring;
Temp_tempList spills;
Live_moveList coalescedMoves;
TAB_table tempAlias;
};
struct COL_result COL_color(G_graph ig, Temp_map initial, Temp_tempList regs, Live_moveList moves, bool **set, G_table table); // table is for additionalNodeInfo

Expand Down
6 changes: 4 additions & 2 deletions lab6/liveness.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,11 @@ struct Live_graph Live_liveness(G_graph flow) {
}
G_nodeList nl;
for(nl = flowNodes; nl; nl = nl->tail) {
Temp_tempList live = lookupLiveMap(liveMap, nl->head);
//Temp_tempList live = lookupLiveMap(liveMap, nl->head); // liveOut may not contain all temps !!!
AS_instr as = G_nodeInfo(nl->head);
Temp_tempList all = Temp_unionList(AS_src(as), AS_dst(as)); // AS_src and AS_dst must contain all temps
Temp_tempList tl;
for(tl = live; tl; tl = tl->tail) {
for(tl = all; tl; tl = tl->tail) {
if(getNodeByTemp(tl->head) == NULL) {
G_node newNode= G_Node(confilict, tl->head);
Live_additionalInfo p = calloc(1, sizeof(*p));
Expand Down
32 changes: 29 additions & 3 deletions lab6/regalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "table.h"
#include "symbol.h"
#include "temp.h"
#include "tree.h"
Expand All @@ -12,13 +13,37 @@
#include "liveness.h"
#include "color.h"
#include "regalloc.h"
#include "table.h"
#include "flowgraph.h"

static AS_instrList rewriteProgram(F_frame f, AS_instrList il, Temp_tempList spills) {
static AS_instrList rewriteProgram(F_frame f, AS_instrList il, Temp_tempList spills, TAB_table tempAlias) {
char as_buf[100];
il = AS_InstrList(NULL, il);
Temp_tempList tl;
AS_instrList now = il->tail;
AS_instrList prev = il;
while(now) {
AS_instr as = now->head;
for(tl = AS_src(as); tl; tl = tl->tail) {
Temp_temp t = TAB_look(tempAlias, tl->head);
if(t != NULL) {
tl->head = t;
}
}
for(tl = AS_dst(as); tl; tl = tl->tail) {
Temp_temp t = TAB_look(tempAlias, tl->head);
if(t != NULL) {
tl->head = t;
}
}
if(as->kind == I_MOVE && as->u.MOVE.src == as->u.MOVE.dst) {
prev->tail = now->tail;
now = now->tail;
}
else {
prev = now;
now = now->tail;
}
}
for(tl = spills; tl; tl = tl->tail) {
F_access newAcc = F_allocLocal(f, TRUE);
int offset = newAcc->u.offset;
Expand Down Expand Up @@ -92,11 +117,12 @@ struct RA_result RA_regAlloc(F_frame f, AS_instrList il) {
struct Live_graph liveness = Live_liveness(flow);
struct COL_result colResult = COL_color(liveness.graph, F_initial(), F_registers(), liveness.moves, liveness.adjSet, liveness.table);
if(colResult.spills != NULL) {
il = rewriteProgram(f, il, colResult.spills);
il = rewriteProgram(f, il, colResult.spills, colResult.tempAlias);
//AS_printInstrList(stdout, il, Temp_layerMap(F_tempMap, Temp_name()));
}
else {
il = deleteInstrs(il, colResult.coalescedMoves);
//AS_printInstrList(stdout, il, Temp_layerMap(F_tempMap, Temp_name()));
ret.coloring = colResult.coloring;
ret.il = il;
break;
Expand Down
16 changes: 16 additions & 0 deletions lab6/temp.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,22 @@ Temp_tempList Temp_removeOne(Temp_temp one, Temp_tempList list) {
return list;
}

Temp_tempList Temp_unionList(Temp_tempList first, Temp_tempList second) { // the two input list won't be modified
Temp_tempList result = NULL;
Temp_tempList tl;
for(tl = first; tl; tl = tl->tail) {
if(!Temp_inTempList(tl->head, result)) {
result = Temp_TempList(tl->head, result);
}
}
for(tl = second; tl; tl = tl->tail) {
if(!Temp_inTempList(tl->head, result)) {
result = Temp_TempList(tl->head, result);
}
}
return result;
}

Temp_labelList Temp_LabelList(Temp_label h, Temp_labelList t)
{Temp_labelList p = (Temp_labelList) checked_malloc(sizeof (*p));
p->head=h; p->tail=t;
Expand Down
3 changes: 2 additions & 1 deletion lab6/temp.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ typedef struct Temp_tempList_ *Temp_tempList;
struct Temp_tempList_ { Temp_temp head; Temp_tempList tail;};
Temp_tempList Temp_TempList(Temp_temp h, Temp_tempList t);
bool Temp_inTempList(Temp_temp t, Temp_tempList l);
Temp_tempList Temp_removeOne(Temp_temp one, Temp_tempList list);
Temp_tempList Temp_removeOne(Temp_temp one, Temp_tempList list); // the input list will be modified !!!
Temp_tempList Temp_unionList(Temp_tempList first, Temp_tempList second); // the two input list won't be modified

typedef S_symbol Temp_label;
Temp_label Temp_newlabel(void);
Expand Down
45 changes: 42 additions & 3 deletions lab6/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,54 @@ static struct Cx unCx(Tr_exp e) {
assert(0);
}

// /* >>>>>
struct staticLinkCache_ {
Tr_level current;
Tr_level declare;
T_exp r;
};
typedef struct staticLinkCache_ *staticLinkCache;

static TAB_table levelToStaticLinkTemp = NULL;

staticLinkCache StaticLinkCache(Tr_level current, Tr_level declare, T_exp r) {
staticLinkCache p = checked_malloc(sizeof(*p));
p->current = current;
p->declare = declare;
p->r = r;
return p;
}
// <<<<< */

static Tr_exp Tr_staticLink(Tr_level current, Tr_level declare) { // return value is FP(frame pointer) of each level
assert(current != NULL);
T_exp result = T_Temp(F_FP());
for(; current != declare; current = current->parent) {
assert(current != NULL);
F_access sl = F_formals(current->frame)->head; // must be inFrame(8) in x86
// /* >>>>>
if(current == declare) {
return Tr_Ex(result);
}
if(levelToStaticLinkTemp == NULL) {
levelToStaticLinkTemp = TAB_empty();
}
staticLinkCache cache = (staticLinkCache)TAB_look(levelToStaticLinkTemp, declare);
if(cache != NULL && cache->current == current && cache->declare == declare) {
return Tr_Ex(cache->r);
}
// <<<<< */
Tr_level now;
for(now = current; now != declare; now = now->parent) {
assert(now != NULL);
F_access sl = F_formals(now->frame)->head; // must be inFrame(8) in x86
assert(sl->kind == inFrame && sl->u.offset == 8);
result = F_exp(sl, result);
}
// /* >>>>>
Temp_temp t = Temp_newtemp();
Temp_temp t2 = Temp_newtemp();
result = T_Eseq(T_Seq(T_Move(T_Temp(t2), result), T_Move(T_Temp(t), T_Temp(t2))), T_Temp(t2));
staticLinkCache newCache = StaticLinkCache(current, declare, T_Temp(t));
TAB_enter(levelToStaticLinkTemp, declare, newCache);
// <<<<< */
return Tr_Ex(result);
}

Expand Down

0 comments on commit ec53646

Please sign in to comment.