Skip to content

Commit

Permalink
escape analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
hzqmwne committed Dec 5, 2017
1 parent a40622e commit a44a6b1
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 3 deletions.
4 changes: 4 additions & 0 deletions lab6/env.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ E_enventry E_VarEntry(Tr_access access, Ty_ty ty)
{
E_enventry entry = checked_malloc(sizeof(*entry));

entry->kind = E_varEntry;
entry->u.var.access = access;
entry->u.var.ty = ty;
entry->readonly = 0;
return entry;
}

E_enventry E_ROVarEntry(Tr_access access, Ty_ty ty)
{
E_enventry entry = checked_malloc(sizeof(*entry));

entry->kind = E_varEntry;
entry->u.var.access = access;
entry->u.var.ty = ty;
entry->readonly = 1;
Expand All @@ -28,6 +31,7 @@ E_enventry E_FunEntry(Tr_level level, Temp_label label, Ty_tyList formals, Ty_ty
{
E_enventry entry = checked_malloc(sizeof(*entry));

entry->kind = E_funEntry;
entry->u.fun.level = level;
entry->u.fun.label = label;
entry->u.fun.formals = formals;
Expand Down
165 changes: 165 additions & 0 deletions lab6/escape.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,171 @@
#include "escape.h"
#include "table.h"

typedef struct Esc_escapeEntry_ *Esc_escapeEntry;
struct Esc_escapeEntry_ {
int depth;
bool *escape;
};
Esc_escapeEntry Esc_EscapeEntry(int depth, bool *escape) {
Esc_escapeEntry p = (Esc_escapeEntry)checked_malloc(sizeof(*p));
p->depth = depth;
p->escape = escape;
return p;
}

static void traverseExp(S_table env, int depth, A_exp e);
static void traverseDec(S_table env, int depth, A_dec d);
static void traverseVar(S_table env, int depth, A_var v);

static void traverseExp(S_table env, int depth, A_exp e) {
switch(e->kind) {
case A_varExp: {
traverseVar(env, depth, e->u.var);
break;
}
case A_nilExp: {
break;
}
case A_intExp: {
break;
}
case A_stringExp: {
break;
}
case A_callExp: {
for(A_expList el = e->u.call.args; el; el = el->tail) {
traverseExp(env, depth, el->head);
}
break;
}
case A_opExp: {
traverseExp(env, depth, e->u.op.left);
traverseExp(env, depth, e->u.op.right);
break;
}
case A_recordExp: {
for(A_efieldList fl = e->u.record.fields; fl; fl = fl->tail) {
traverseExp(env, depth, fl->head->exp);
}
break;
}
case A_seqExp: {
for(A_expList el = e->u.seq; el; el = el->tail) {
traverseExp(env, depth, el->head);
}
break;
}
case A_assignExp: {
traverseVar(env, depth, e->u.assign.var);
traverseExp(env, depth, e->u.assign.exp);
break;
}
case A_ifExp: {
traverseExp(env, depth, e->u.iff.test);
traverseExp(env, depth, e->u.iff.then);
if(e->u.iff.elsee != NULL) {
traverseExp(env, depth, e->u.iff.elsee);
}
break;
}
case A_whileExp: {
traverseExp(env, depth, e->u.whilee.test);
traverseExp(env, depth, e->u.whilee.body);
break;
}
case A_forExp: {
traverseExp(env, depth, e->u.forr.lo);
traverseExp(env, depth, e->u.forr.hi);
S_beginScope(env);
e->u.forr.escape = FALSE;
S_enter(env, e->u.forr.var, Esc_EscapeEntry(depth, &(e->u.forr.escape)));
traverseExp(env, depth, e->u.forr.body);
S_endScope(env);
break;
}
case A_breakExp: {
break;
}
case A_letExp: {
S_beginScope(env);
for(A_decList d = e->u.let.decs; d; d = d->tail) {
traverseDec(env, depth, d->head);
}
traverseExp(env, depth, e->u.let.body);
S_endScope(env);
break;
}
case A_arrayExp: {
traverseExp(env, depth, e->u.array.size);
traverseExp(env, depth, e->u.array.init);
break;
}
default: {
assert(0);
break;
}
}
}

static void traverseDec(S_table env, int depth, A_dec d) {
switch(d->kind) {
case A_functionDec: {
for(A_fundecList fl = d->u.function; fl; fl = fl->tail) {
A_fundec f = fl->head;
S_beginScope(env);
for(A_fieldList l = f->params; l; l = l->tail) {
l->head->escape = FALSE;
S_enter(env, l->head->name, Esc_EscapeEntry(depth + 1, &(l->head->escape)));
}
traverseExp(env, depth + 1, f->body);
S_endScope(env);
}
break;
}
case A_varDec: {
traverseExp(env, depth, d->u.var.init);
d->u.var.escape = FALSE;
S_enter(env, d->u.var.var, Esc_EscapeEntry(depth, &(d->u.var.escape)));
break;
}
case A_typeDec: {
break;
}
default: {
assert(0);
break;
}
}
}

static void traverseVar(S_table env, int depth, A_var v) {
switch(v->kind) {
case A_simpleVar: {
Esc_escapeEntry x = S_look(env, v->u.simple);
if(x) {
if(depth > x->depth) {
*(x->escape) = TRUE;
}
}
break;
}
case A_fieldVar: {
traverseVar(env, depth, v->u.field.var);
break;
}
case A_subscriptVar: {
traverseVar(env, depth, v->u.subscript.var);
traverseExp(env, depth, v->u.subscript.exp);
break;
}
default: {
assert(0);
}
}
}

void Esc_findEscape(A_exp exp) {
//your code here
S_table escapeEnv = S_empty();
traverseExp(escapeEnv, 1, exp);
}
2 changes: 1 addition & 1 deletion lab6/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ int main(int argc, string *argv)

//Lab 6: escape analysis
//If you have implemented escape analysis, uncomment this
//Esc_findEscape(absyn_root); /* set varDec's escape field */
Esc_findEscape(absyn_root); /* set varDec's escape field */

frags = SEM_transProg(absyn_root);
if (anyErrors) return 1; /* don't continue */
Expand Down
2 changes: 1 addition & 1 deletion lab6/semant.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ struct expty transExp(S_table venv, S_table tenv, A_exp a, Tr_level level, Temp_
return expTy(Tr_nop(), Ty_Void());
}
S_beginScope(venv);
Tr_access loopVar = Tr_allocLocal(level, FALSE); // don't allow fundec in for loop ???
Tr_access loopVar = Tr_allocLocal(level, a->u.forr.escape);
S_enter(venv, a->u.forr.var, E_ROVarEntry(loopVar, Ty_Int()));
struct expty eb = transExp(venv, tenv, a->u.forr.body, level, done);
if(eb.ty->kind != Ty_void) {
Expand Down
1 change: 0 additions & 1 deletion lab6/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,6 @@ Tr_exp Tr_whileExp(Tr_exp condp, Tr_exp bodyExp, Temp_label done) {
Tr_exp Tr_forExp(Tr_access loopVar, Tr_exp lo, Tr_exp hi, Tr_exp bodyExp, Temp_label done, Tr_level current) {
Temp_label start = Temp_newlabel();
Temp_label t = Temp_newlabel();
assert(loopVar->access->kind == inReg);
T_exp i = F_exp(loopVar->access, NULL);
F_access acc = F_allocLocal(current->frame, FALSE);
assert(acc->kind == inReg);
Expand Down

0 comments on commit a44a6b1

Please sign in to comment.