aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mips.c413
-rw-r--r--mips.h5
-rw-r--r--semantics.c4
-rw-r--r--ssa.c250
-rw-r--r--ssa.h2
5 files changed, 591 insertions, 83 deletions
diff --git a/mips.c b/mips.c
new file mode 100644
index 0000000..af3ded8
--- /dev/null
+++ b/mips.c
@@ -0,0 +1,413 @@
+#include <stdio.h>
+#include <assert.h>
+#include "ssa.h"
+#include "mips.h"
+
+int reg_v0 = 2;
+int reg_v1 = 3;
+
+void mips_prologue() {
+ CVList_t v;
+ CSList_t s;
+ printf(".data 0x10000000\n");
+ for (v = gvars; v; v = v->next)
+ {
+ CVar_t var = v->var;
+ printf("\t.align 2\n");
+ printf("_%s:\n", var->name);
+ var->start = -1;
+ printf("\t.space %d\n", calc_size(var->type));
+ }
+ for (s = cstrs; s; s = s->next)
+ {
+ printf("_str_%d:\n", s->id);
+ printf("\t.asciiz \"%s\"\n", s->str);
+ }
+ /* pre-calc done */
+ printf(".text\n");
+}
+
+void mips_load(int reg, COpr_t opr) {
+ CVar_t var = cinterv_repr(opr)->info.var;
+ CType_t type = var->type;
+ if (type->type == CSTRUCT ||
+ type->type == CUNION ||
+ type->type == CARR)
+ {
+ if (var->global)
+ printf("\tla $%d, _%s\n", reg, var->name);
+ else
+ printf("\taddi $%d, $sp, %d\n", reg, var->start);
+ }
+ else
+ {
+ const char *l = type->type == CCHAR ? "lb" : "lw";
+ if (var->global)
+ printf("\t%s $%d, _%s\n", l, reg, var->name);
+ else
+ printf("\t%s $%d, %d($sp)\t#%s\n", l, reg, var->start, var->name);
+ }
+}
+
+void mips_store(int reg, COpr_t opr) {
+ CVar_t var = cinterv_repr(opr)->info.var;
+ CType_t type = var->type;
+ const char *l = type->type == CCHAR ? "sb" : "sw";
+ /* TODO: struct */
+ if (var->global)
+ printf("\t%s $%d, _%s\n", l, reg, var->name);
+ else
+ printf("\t%s $%d, %d($sp)\t#%s\n", l, reg, var->start, var->name);
+}
+
+int mips_to_reg(COpr_t opr, int reg0) {
+ if (opr->kind == IMM)
+ {
+ printf("\tli $%d, %d\n", reg0, opr->info.imm);
+ return reg0;
+ }
+ else if (opr->kind == IMMS)
+ {
+ printf("\tla $%d, _str_%d\n", reg0, opr->info.cstr->id);
+ return reg0;
+ }
+ else if (opr->kind == IMMF)
+ {
+ printf("\tla $%d, %s\n", reg0, opr->info.str);
+ return reg0;
+ }
+ if (opr->reg != -1) return opr->reg;
+ mips_load(reg0, opr);
+ return reg0;
+}
+
+void mips_space_alloc() {
+ int local_size = func->rec.func.local_size;
+ int arg_size = 0;
+ int bret_size = 0;
+ int tmp_size = 0;
+ int offset = 0;
+ int prev = 0;
+ CBlock_t p;
+ COList_t d;
+ CVar_t v;
+ for (d = defs; d; d = d->next)
+ {
+ COpr_t opr = d->opr;
+ if (opr->kind == TMP && opr->par == opr)
+ {
+ int t = opr->info.var->type->type;
+ tmp_size += align_shift(tmp_size);
+ opr->info.var->start = tmp_size;
+ if (t == CSTRUCT || t == CUNION || t == CARR)
+ tmp_size += PTR_SIZE;
+ else if (t == CVOID)
+ tmp_size += INT_SIZE;
+ else
+ tmp_size += calc_size(opr->info.var->type);
+ }
+ }
+ for (p = entry; p; p = p->next)
+ {
+ CInst_t i, ih = p->insts;
+ for (i = ih->next; i != ih; i = i->next)
+ {
+ if (i->op == PUSH)
+ {
+ COpr_t arg = i->src1;
+ offset += align_shift(offset);
+ i->offset = offset;
+ if (arg->kind == IMM)
+ offset += INT_SIZE;
+ else if (arg->kind == IMMS)
+ offset += PTR_SIZE;
+ else if (arg->kind == IMMF)
+ offset += PTR_SIZE;
+ else
+ {
+ CType_t t = arg->info.var->type;
+ if (t->type == CARR)
+ offset += PTR_SIZE;
+ else
+ offset += calc_size(t);
+ }
+ }
+ else if (i->op == CALL)
+ {
+ CType_t rt = i->dest->info.var->type;
+ if (offset > arg_size)
+ arg_size = offset;
+ offset = 0;
+ if (rt->type == CSTRUCT || rt->type == CUNION)
+ {
+ bret_size += align_shift(bret_size);
+ i->bret = bret_size;
+ bret_size += calc_size(rt);
+ }
+ }
+ }
+ }
+ prev += arg_size;
+ prev += align_shift(prev);
+ /* adjust offset for local variables */
+ for (v = func->rec.func.local; v; v = v->next)
+ v->start += prev;
+ prev += local_size;
+ prev += align_shift(prev);
+ /* adjust offset for spilled temporaries */
+ for (d = defs; d; d = d->next)
+ {
+ COpr_t opr = d->opr;
+ if (opr->kind == TMP && opr->par == opr)
+ opr->info.var->start += prev;
+ }
+ prev += tmp_size;
+ prev += align_shift(prev);
+ for (p = entry; p; p = p->next)
+ {
+ CInst_t i, ih = p->insts;
+ for (i = ih->next; i != ih; i = i->next)
+ if (i->op == CALL)
+ i->bret += prev;
+ }
+ prev += bret_size;
+ prev += align_shift(prev);
+ prev += 4; /* return address */
+ for (v = func->rec.func.params; v; v = v->next)
+ v->start += prev; /* skip the whole frame to reach args */
+ func->rec.func.frame_size = prev;
+}
+
+void mips_func_begin() {
+ int fsize = func->rec.func.frame_size;
+ printf("\taddiu $sp, $sp, -%d\n", fsize);
+ printf("\tsw $31, %d($sp)\n", fsize - 4);
+}
+
+void mips_func_end() {
+ int fsize = func->rec.func.frame_size;
+ printf("_ret_%s:\n", func->name);
+ printf("\tlw $31, %d($sp)\n", fsize - 4);
+ printf("\taddiu $sp, $sp, %d\n", fsize);
+ printf("\tjr $31\n");
+}
+
+void mips_generate() {
+ CBlock_t p;
+ mips_space_alloc();
+ printf("%s:\n", func->name);
+ mips_func_begin();
+ for (p = entry; p; p = p->next)
+ {
+ if (p->ref) printf("_L%d:\n", p->id + gbbase);
+ CInst_t i, ih = p->insts;
+ const char *bop;
+ for (i = ih->next; i != ih; i = i->next)
+ {
+ int flag = 1, swap;
+ switch (i->op)
+ {
+ case LOAD:
+ if (i->dest->reg != -1)
+ mips_load(i->dest->reg, i->dest);
+ break;
+ case MOVE:
+ {
+ /* TODO: struct */
+ int rs = mips_to_reg(i->src1, reg_v0);
+ int rd = i->dest->reg;
+ if (rd != -1)
+ printf("\tmove $%d $%d\n", rd, rs);
+ else
+ rd = rs;
+ if (i->dest->reg == -1 || i->dest->kind == VAR)
+ mips_store(rd, i->dest);
+ }
+ break;
+ case BEQZ:
+ {
+ int rs = mips_to_reg(i->src1, reg_v0);
+ printf("\tbeqz $%d, _L%d\n", rs, i->dest->info.imm);
+ }
+ break;
+ case BNEZ:
+ {
+ int rs = mips_to_reg(i->src1, reg_v0);
+ printf("\tbnez $%d, _L%d\n", rs, i->dest->info.imm);
+ }
+ break;
+ case GOTO:
+ printf("\tj _L%d\n", i->dest->info.imm);
+ break;
+ case ARR:
+ {
+ int arr = mips_to_reg(i->src1, reg_v0);
+ int rd;
+ const char *l = i->dest->info.var->type->type == CCHAR ? "lb" : "lw";
+ if (i->src2->kind == IMM)
+ {
+ rd = i->dest->reg;
+ if (rd == -1) rd = reg_v1;
+ printf("\t%s $%d, %d($%d)\n", l, rd, i->src2->info.imm, arr);
+ }
+ else
+ {
+ int index = mips_to_reg(i->src2, reg_v1);
+ printf("\taddu $%d, $%d, $%d\n", index, arr, index);
+ rd = i->dest->reg;
+ if (rd == -1) rd = reg_v0;
+ printf("\t%s $%d, 0($%d)\n", l, rd, index);
+ }
+ if (i->dest->reg == -1 || i->dest->kind == VAR)
+ mips_store(rd, i->dest);
+ }
+ break;
+ case WARR:
+ {
+ int arr = mips_to_reg(i->dest, reg_v0);
+ const char *s = i->dest->info.var->type->type == CCHAR ? "sb" : "sw";
+ int rs;
+ if (i->src2->kind == IMM)
+ {
+ rs = mips_to_reg(i->src1, reg_v1);
+ printf("\t%s $%d, %d($%d)\n", s, rs, i->src2->info.imm, arr);
+ }
+ else
+ {
+ int index = mips_to_reg(i->src2, reg_v1);
+ printf("\taddu $%d, $%d, $%d\n", index, arr, index);
+ rs = mips_to_reg(i->src1, reg_v0);
+ printf("\t%s $%d, 0($%d)\n", s, rs, index);
+ }
+ }
+ break;
+ case PUSH:
+ {
+ int rs = mips_to_reg(i->src1, reg_v0);
+ /* TODO: push struct */
+ printf("\tsw $%d, %d($sp)\n", rs, i->offset);
+ }
+ break;
+ case CALL:
+ {
+ int rd = i->dest->reg;
+ if (i->src1->kind == IMMF)
+ printf("\tjal %s\n", i->src1->info.str);
+ else
+ printf("\tjalr $%d\n", mips_to_reg(i->src1, reg_v0));
+ if (rd != -1)
+ printf("\tmove $%d, $%d\n", rd, reg_v0);
+ else
+ rd = reg_v0;
+ if (i->dest->reg == -1 || i->dest->kind == VAR)
+ mips_store(reg_v0, i->dest);
+ }
+ break;
+ case RET:
+ {
+ if (i->src1->reg != -1)
+ printf("\tmove $%d, $%d\n", reg_v0, mips_to_reg(i->src1, reg_v1));
+ else
+ mips_to_reg(i->src1, reg_v0);
+ printf("\tj _ret_%s\n", func->name);
+ }
+ break;
+ case ADDR:
+ {
+ assert(i->src1->kind == VAR ||
+ i->src1->kind == IMMF);
+ int rd = i->dest->reg;
+ if (rd == -1) rd = reg_v0;
+ if (i->src1->kind == IMMF)
+ printf("\tla $%d, %s\n", rd, i->src1->info.str);
+ else
+ {
+ CVar_t var = i->src1->info.var;
+ if (var->global)
+ printf("\tla $%d, _%s\n", rd, var->name);
+ else
+ printf("\taddiu $%d, $sp, %d\n", rd, var->start);
+ if (i->dest->reg == -1 || i->dest->kind == VAR)
+ mips_store(rd, i->dest);
+ }
+ }
+ break;
+ default: flag = 0;
+ }
+ if (flag) continue;
+ flag = 1;
+ swap = 0;
+ switch (i->op)
+ {
+ case MUL: bop = "mul"; break;
+ case DIV: bop = "divu"; break;
+ case MOD: bop = "rem"; break;
+ case ADD: bop = "addu"; swap = 1; break;
+ case SUB: bop = "subu"; break;
+ case SHL: bop = "sllv"; break;
+ case SHR: bop = "srlv"; break;
+ case AND: bop = "and"; swap = 1; break;
+ case XOR: bop = "xor"; swap = 1; break;
+ case OR: bop = "or"; swap = 1; break;
+ case NOR: bop = "nor"; break;
+ case EQ: bop = "seq"; break;
+ case NE: bop = "sne"; break;
+ case LT: bop = "slt"; break;
+ case GT: bop = "sgt"; break;
+ case LE: bop = "sle"; break;
+ case GE: bop = "sge"; break;
+ default: flag = 0;
+ }
+ if (flag)
+ {
+ int rs, rt;
+ int rd = i->dest->reg;
+ if (rd == -1) rd = reg_v0;
+ if (swap)
+ {
+ COpr_t t;
+ if (i->src1->kind == IMM)
+ {
+ t = i->src1;
+ i->src1 = i->src2;
+ i->src2 = t;
+ }
+ if (i->src2->kind == IMM)
+ {
+ switch (i->op)
+ {
+ case ADD: bop = "addiu"; break;
+ case AND: bop = "andi"; break;
+ case XOR: bop = "xori"; break;
+ case OR: bop = "ori"; break;
+ default: ;
+ }
+ rs = mips_to_reg(i->src1, reg_v0);
+ printf("\t%s $%d, $%d, %d\n",
+ bop, rd, rs, i->src2->info.imm);
+ }
+ else swap = 0;
+ }
+ if (!swap)
+ {
+ rs = mips_to_reg(i->src1, reg_v0);
+ rt = mips_to_reg(i->src2, reg_v1);
+ printf("\t%s $%d, $%d, $%d\n", bop, rd, rs, rt);
+ }
+ if (i->dest->reg == -1 || i->dest->kind == VAR)
+ mips_store(rd, i->dest);
+ continue;
+ }
+ if (i->op == NEG)
+ {
+ int rs = mips_to_reg(i->src1, reg_v0);
+ int rd = i->dest->reg;
+ if (rd == -1) rd = reg_v0;
+ printf("\tnegu $%d, $%d\n", rd, rs);
+ if (i->dest->reg == -1 || i->dest->kind == VAR)
+ mips_store(rd, i->dest);
+ }
+ }
+ }
+ mips_func_end();
+}
diff --git a/mips.h b/mips.h
new file mode 100644
index 0000000..3a9db9b
--- /dev/null
+++ b/mips.h
@@ -0,0 +1,5 @@
+#ifndef MIPS_C
+#define MIPS_C
+void mips_prologue();
+void mips_generate();
+#endif
diff --git a/semantics.c b/semantics.c
index 014f7e5..e4a1cee 100644
--- a/semantics.c
+++ b/semantics.c
@@ -1312,7 +1312,11 @@ ExpType semantics_exp(CNode *p, CScope_t scope) {
res = exp_check_logical(op1, op2, p, '&');
break;
case OPT_SHL:
+ res = exp_check_bitwise(op1, op2, p, 'l');
+ break;
case OPT_SHR:
+ res = exp_check_bitwise(op1, op2, p, 'r');
+ break;
case '|':
case '^':
res = exp_check_bitwise(op1, op2, p, p->rec.subtype);
diff --git a/ssa.c b/ssa.c
index 21efd3c..ad8c158 100644
--- a/ssa.c
+++ b/ssa.c
@@ -22,6 +22,7 @@ CType_t func;
COpr_t copr_create() {
COpr_t opr = NEW(COpr);
opr->cval = NULL;
+ opr->dep = 0;
return opr;
}
@@ -108,13 +109,13 @@ void cfg_clear() {
for (p = cfg.head[i]; p; p = np)
{
np = p->next;
- free(p);
+ /* free(p); */
}
cfg.head[i] = NULL;
for (p = cfg.rhead[i]; p; p = np)
{
np = p->next;
- free(p);
+ /* free(p); */
}
cfg.rhead[i] = NULL;
}
@@ -128,7 +129,7 @@ void dtree_clear() {
for (p = dtree.head[i]; p; p = np)
{
np = p->next;
- free(p);
+ /* free(p); */
}
dtree.head[i] = NULL;
}
@@ -329,8 +330,8 @@ void ssa_generate() {
}
}
-COpr_t ssa_exp_(CNode *p, CBlock_t, CInst_t, CBlock_t);
-COpr_t ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
+COpr_t ssa_exp_(CNode *p, CBlock_t *, CInst_t, CBlock_t);
+COpr_t ssa_postfix(CNode *p, CBlock_t *cur, CInst_t lval, CBlock_t succ) {
CNode *post = p->chd->next;
CType_t rt = p->ext.type;
CInst_t base = cinst_create();
@@ -347,7 +348,7 @@ COpr_t ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
off->src2 = copr_create();
off->src2->kind = IMM;
off->src2->info.imm = calc_size(rt);
- cblock_append(cur, off);
+ cblock_append(*cur, off);
base->dest = copr_create();
base->dest->kind = TMP;
@@ -406,7 +407,7 @@ COpr_t ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
pi->src1 = ssa_exp_(arg, cur, lval, succ);
/* pi->next = ps;
ps = pi; */
- cblock_append(cur, pi);
+ cblock_append(*cur, pi);
}
/*
for (; ps; ps = t)
@@ -429,7 +430,7 @@ COpr_t ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
{
base->dest = tins->dest;
cblock_append(succ, base);
- free(tins);
+ /* free(tins); */
}
else
{
@@ -459,16 +460,16 @@ COpr_t ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
lval->op = WARR;
lval->dest = base->src1;
lval->src2 = base->src2;
- free(base);
+ /* free(base); */
return lval->dest;
}
- cblock_append(cur, base);
+ cblock_append(*cur, base);
return base->dest;
}
#define IS_PTR(tt) ((tt) == CPTR || (tt) == CARR)
-COpr_t ssa_exp(CNode *, CBlock_t, int);
-COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
+COpr_t ssa_exp(CNode *, CBlock_t *, int);
+COpr_t ssa_exp_(CNode *p, CBlock_t *cur, CInst_t lval, CBlock_t succ) {
COpr_t res;
CInst_t inst = cinst_create();
switch (p->type)
@@ -527,8 +528,9 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
ssa_exp_(p->chd, cur, inst, succ);
if (inst->op == MOVE)
{
- CInst_t last = cblock_getback(cur);
- if (last && last->dest == inst->src1)
+ CInst_t last = cblock_getback(*cur);
+ if (last && last->dest->kind == TMP
+ && last->dest == inst->src1)
{
free(last->dest);
last->dest = inst->dest;
@@ -537,21 +539,21 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
}
else
{
- cblock_append(cur, inst);
+ cblock_append(*cur, inst);
return inst->dest;
}
}
else
{
CInst_t tins = cinst_create();
- cblock_append(cur, inst);
+ cblock_append(*cur, inst);
tins->op = ARR;
tins->src1 = inst->dest; /* base */
tins->src2 = inst->src2; /* displacement */
tins->dest = copr_create();
tins->dest->kind = TMP;
tins->dest->info.var = ctmp_create(p->ext.type);
- cblock_append(cur, tins);
+ cblock_append(*cur, tins);
return tins->dest;
}
}
@@ -577,11 +579,90 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
inst->dest = copr_create();
inst->dest->kind = TMP;
inst->dest->info.var = ctmp_create(p->ext.type);
- cblock_append(cur, inst);
+ cblock_append(*cur, inst);
return inst->dest;
}
}
}
+ else if (op == OPT_AND)
+ {
+ CBlock_t else_h = cblock_create(1), else_t = else_h,
+ one_blk = cblock_create(1),
+ zero_blk = cblock_create(1),
+ next_blk = cblock_create(1);
+ COpr_t r0 = ssa_exp_(p->chd, cur, NULL, succ),
+ r1 = ssa_exp_(p->chd->next, &else_t, NULL, succ);
+ CInst_t b, a0, a1;
+ CPhi_t m = NEW(CPhi);
+ /* constant opt */
+ a0 = cinst_create();
+ a0->op = MOVE;
+ a0->dest = copr_create();
+ a0->dest->kind = TMP;
+ a0->dest->info.var = ctmp_create(p->ext.type); /* int */
+ a0->src1 = copr_create();
+ a0->src1->kind = IMM;
+ a0->src1->info.imm = 0;
+ cblock_append(zero_blk, a0);
+
+ a1 = cinst_create();
+ a1->op = MOVE;
+ a1->dest = copr_create();
+ a1->dest->kind = TMP;
+ a1->dest->info.var = ctmp_create(p->ext.type);
+ a1->src1 = copr_create();
+ a1->src1->kind = IMM;
+ a1->src1->info.imm = 1;
+ cblock_append(one_blk, a1);
+
+ m->dest = copr_create();
+ m->dest->kind = TMP;
+ m->dest->info.var = ctmp_create(p->ext.type);
+ m->oprs = (COpr_t *)malloc(sizeof(COpr_t) * 2);
+ m->oprs[0] = a0->dest;
+ m->oprs[1] = a1->dest;
+ cblock_pappend(next_blk, m);
+
+ b = cinst_create();
+ b->op = BEQZ;
+ b->src1 = r0;
+ b->dest = copr_create();
+ b->dest->kind = IMM;
+ b->dest->info.imm = zero_blk->id + gbbase;
+ cblock_append(*cur, b);
+
+ b = cinst_create();
+ b->op = BEQZ;
+ b->src1 = r1;
+ b->dest = copr_create();
+ b->dest->kind = IMM;
+ b->dest->info.imm = zero_blk->id + gbbase;
+ cblock_append(else_t, b);
+ zero_blk->ref = 1;
+
+ b = cinst_create();
+ b->op = GOTO;
+ b->dest = copr_create();
+ b->dest->kind = IMM;
+ b->dest->info.imm = next_blk->id + gbbase;
+ cblock_append(one_blk, b);
+ next_blk->ref = 1;
+
+ DBLINK(*cur, else_h);
+ DBLINK(else_t, one_blk);
+ DBLINK(one_blk, zero_blk);
+ DBLINK(zero_blk, next_blk);
+
+ cfg_add_edge(*cur, else_h);
+ cfg_add_edge(*cur, zero_blk);
+ cfg_add_edge(else_t, one_blk);
+ cfg_add_edge(else_t, zero_blk);
+ cfg_add_edge(one_blk, next_blk);
+ cfg_add_edge(zero_blk, next_blk);
+
+ *cur = next_blk;
+ return m->dest;
+ }
else if (op == '+' && IS_PTR(p->ext.type->type))
{
COpr_t lhs = ssa_exp_(p->chd, cur, lval, succ),
@@ -607,8 +688,8 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
inst->dest->info.var = ctmp_create(p->ext.type);
inst->src1 = lhs;
inst->src2 = index->dest;
- cblock_append(cur, index);
- cblock_append(cur, inst);
+ cblock_append(*cur, index);
+ cblock_append(*cur, inst);
return inst->dest;
}
else if (op == '-' && IS_PTR(p->chd->ext.type->type))
@@ -660,8 +741,8 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
inst->src1 = lhs;
inst->src2 = diff->dest;
}
- cblock_append(cur, diff);
- cblock_append(cur, inst);
+ cblock_append(*cur, diff);
+ cblock_append(*cur, inst);
return inst->dest;
}
else if (op == '&' && !p->chd->next)
@@ -680,7 +761,7 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
inst->dest = copr_create();
inst->dest->kind = TMP;
inst->dest->info.var = ctmp_create(p->ext.type);
- cblock_append(cur, inst);
+ cblock_append(*cur, inst);
return inst->dest;
}
else
@@ -718,7 +799,7 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
if (tins->op == MOVE)
{
inst->dest = tins->dest;
- cblock_append(cur, inst);
+ cblock_append(*cur, inst);
free(tins);
return inst->dest;
}
@@ -735,9 +816,9 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
tins2->dest = copr_create();
tins2->dest->kind = TMP;
tins2->dest->info.var = ctmp_create(p->ext.type);
- cblock_append(cur, inst);
- cblock_append(cur, tins);
- cblock_append(cur, tins2);
+ cblock_append(*cur, inst);
+ cblock_append(*cur, tins);
+ cblock_append(*cur, tins2);
return tins2->dest;
}
}
@@ -822,7 +903,7 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
inst->dest->kind = TMP;
inst->dest->info.var = ctmp_create(p->ext.type);
}
- cblock_append(cur, inst);
+ cblock_append(*cur, inst);
res = inst->dest;
}
}
@@ -832,7 +913,7 @@ COpr_t ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
return res;
}
-COpr_t ssa_exp(CNode *p, CBlock_t cur, int discard_last) {
+COpr_t ssa_exp(CNode *p, CBlock_t *cur, int discard_last) {
CBlock_t succ = cblock_create(0);
COpr_t res = ssa_exp_(p, cur, NULL, succ);
CInst_t last;
@@ -842,17 +923,17 @@ COpr_t ssa_exp(CNode *p, CBlock_t cur, int discard_last) {
{
t = head->next;
cblock_popfront(succ);
- cblock_append(cur, t);
+ cblock_append(*cur, t);
}
free(succ);
}
- last = cblock_getback(cur);
+ last = cblock_getback(*cur);
if (discard_last && last
&& last->dest->kind == TMP
&& last->op != CALL) /* temporary not used */
{
ctmp_destroy(last->dest->info.var);
- cblock_popback(cur);
+ cblock_popback(*cur);
free(last);
}
return res;
@@ -861,39 +942,37 @@ COpr_t ssa_exp(CNode *p, CBlock_t cur, int discard_last) {
CBlock_t ssa_stmt(CNode *, CBlock_t, CBlock_t);
CBlock_t ssa_while(CNode *p, CBlock_t cur) {
CNode *exp = p->chd;
- CBlock_t loop_blk = cblock_create(1), loop_t,
- cond_blk = cblock_create(1),
+ CBlock_t loop_h = cblock_create(1), loop_t,
+ cond_h= cblock_create(1), cond_t = cond_h,
next_blk = cblock_create(1);
CInst_t j_inst = cinst_create(),
if_inst = cinst_create();
- DBLINK(cond_blk, next_blk);
- loop_t = ssa_stmt(exp->next, loop_blk, next_blk);
-
- DBLINK(loop_t, cond_blk);
- cfg_add_edge(loop_t, cond_blk);
+ if_inst->op = BNEZ;
+ if_inst->src1 = ssa_exp(exp, &cond_t, 0);
+ if_inst->dest = copr_create();
+ if_inst->dest->kind = IMM;
+ if_inst->dest->info.imm = loop_h->id + gbbase;
+ loop_h->ref = 1;
+ cblock_append(cond_t, if_inst);
+ DBLINK(cond_t, next_blk);
+ loop_t = ssa_stmt(exp->next, loop_h, next_blk);
j_inst->op = GOTO;
j_inst->dest = copr_create();
j_inst->dest->kind = IMM;
- j_inst->dest->info.imm = cond_blk->id + gbbase;
- cond_blk->ref = 1;
+ j_inst->dest->info.imm = cond_h->id + gbbase;
+ cond_h->ref = 1;
cblock_append(cur, j_inst);
- if_inst->op = BNEZ;
- if_inst->src1 = ssa_exp(exp, cond_blk, 0);
- if_inst->dest = copr_create();
- if_inst->dest->kind = IMM;
- if_inst->dest->info.imm = loop_blk->id + gbbase;
- loop_blk->ref = 1;
- cblock_append(cond_blk, if_inst);
-
- cfg_add_edge(cur, cond_blk);
- cfg_add_edge(cond_blk, loop_blk);
- cfg_add_edge(cond_blk, next_blk);
+ cfg_add_edge(cur, cond_h);
+ cfg_add_edge(cond_t, loop_h);
+ cfg_add_edge(loop_t, cond_h);
+ cfg_add_edge(cond_t, next_blk);
- DBLINK(cur, loop_blk);
+ DBLINK(cur, loop_h);
+ DBLINK(loop_t, cond_h);
return next_blk;
}
@@ -902,41 +981,40 @@ CBlock_t ssa_for(CNode *p, CBlock_t cur) {
CNode *exp1 = p->chd,
*exp2 = exp1->next,
*exp3 = exp2->next;
- CBlock_t loop_blk = cblock_create(1), loop_t,
- cond_blk = cblock_create(1),
+ CBlock_t loop_h = cblock_create(1), loop_t,
+ cond_h = cblock_create(1), cond_t = cond_h,
next_blk = cblock_create(1);
CInst_t j_inst = cinst_create(),
if_inst = cinst_create();
- DBLINK(cond_blk, next_blk);
- loop_t = ssa_stmt(exp3->next, loop_blk, next_blk);
+ if_inst->op = BNEZ;
+ if_inst->src1 = ssa_exp(exp2, &cond_t, 0);
+ if_inst->dest = copr_create();
+ if_inst->dest->kind = IMM;
+ if_inst->dest->info.imm = loop_h->id + gbbase;
+ loop_h->ref = 1;
+ cblock_append(cond_t, if_inst);
- DBLINK(loop_t, cond_blk);
- cfg_add_edge(loop_t, cond_blk);
+ DBLINK(cond_t, next_blk);
+ loop_t = ssa_stmt(exp3->next, loop_h, next_blk);
- ssa_exp(exp1, cur, 1);
- ssa_exp(exp3, loop_t, 1);
+ ssa_exp(exp1, &cur, 1);
+ ssa_exp(exp3, &loop_t, 1);
j_inst->op = GOTO;
j_inst->dest = copr_create();
j_inst->dest->kind = IMM;
- j_inst->dest->info.imm = cond_blk->id + gbbase;
- cond_blk->ref = 1;
+ j_inst->dest->info.imm = cond_h->id + gbbase;
+ cond_h->ref = 1;
cblock_append(cur, j_inst);
- if_inst->op = BNEZ;
- if_inst->src1 = ssa_exp(exp2, cond_blk, 0);
- if_inst->dest = copr_create();
- if_inst->dest->kind = IMM;
- if_inst->dest->info.imm = loop_blk->id + gbbase;
- loop_blk->ref = 1;
- cblock_append(cond_blk, if_inst);
-
- cfg_add_edge(cur, cond_blk);
- cfg_add_edge(cond_blk, loop_blk);
- cfg_add_edge(cond_blk, next_blk);
+ cfg_add_edge(cur, cond_h);
+ cfg_add_edge(cond_t, loop_h);
+ cfg_add_edge(loop_t, cond_h);
+ cfg_add_edge(cond_t, next_blk);
- DBLINK(cur, loop_blk);
+ DBLINK(cur, loop_h);
+ DBLINK(loop_t, cond_h);
return next_blk;
}
@@ -947,7 +1025,7 @@ CBlock_t ssa_if(CNode *p, CBlock_t cur, CBlock_t loop_exit) {
CBlock_t then_blk, then_t, next_blk,
else_blk, else_t;
CInst_t if_inst = cinst_create();
- COpr_t rt = ssa_exp(p->chd, cur, 0);
+ COpr_t rt = ssa_exp(p->chd, &cur, 0);
if (rt->kind == IMM)
{
if (rt->info.imm)
@@ -1016,7 +1094,7 @@ CBlock_t ssa_ret(CNode *p, CBlock_t cur) {
CInst_t inst = cinst_create();
inst->op = RET;
if (p->chd->type != NOP)
- inst->src1 = ssa_exp(p->chd, cur, 0);
+ inst->src1 = ssa_exp(p->chd, &cur, 0);
cblock_append(cur, inst);
return cur;
}
@@ -1053,7 +1131,7 @@ CBlock_t ssa_stmt(CNode *p, CBlock_t cur, CBlock_t loop_exit) {
switch (p->rec.subtype)
{
case STMT_EXP:
- ssa_exp(p->chd, cur, 1);
+ ssa_exp(p->chd, &cur, 1);
break;
case STMT_COMP:
cur = ssa_comp(p, cur, loop_exit);
@@ -1199,8 +1277,8 @@ void calc_dominant_frontier() {
CBList_t p, np;
for (p = df[i]; p; p = np)
{
- free(p);
np = p->next;
+ free(p);
}
df[i] = NULL;
if (dfset[i]) cpset_destroy(dfset[i]);
@@ -1329,8 +1407,10 @@ void renaming_dfs(CBlock_t blk) {
for (t = 0; t < 2; t++)
{
COpr_t p = *(opr[t]);
- if (!(p && p->kind == VAR)) continue;
- /* free(p); */ /* memory leak */
+ if (!p) continue;
+ p->dep = 1;
+ if (p->kind != VAR) continue;
+ /* free(p); */ /* memory leak */
*(opr[t]) = p->info.var->stack->opr;
}
if (dest)
@@ -1370,7 +1450,11 @@ void renaming_dfs(CBlock_t blk) {
for (; pre->to != blk; pre = pre->next) j++;
ph = y->phis;
for (pi = ph->next; pi != ph; pi = pi->next)
- pi->oprs[j] = pi->dest->info.var->stack->opr;
+ {
+ if (pi->dest->kind == VAR)
+ pi->oprs[j] = pi->dest->info.var->stack->opr;
+ pi->oprs[j]->dep = 1;
+ }
}
for (e = dtree.head[blk->id]; e; e = e->next)
renaming_dfs(e->to);
@@ -1760,7 +1844,7 @@ void const_propagation() {
if (flag)
{
i->dest->cval = i->src1;
- if (i->dest->kind == TMP)
+ if (i->dest->kind == TMP && !i->dest->dep)
{
i->next->prev = i->prev;
i->prev->next = i->next;
diff --git a/ssa.h b/ssa.h
index d585c07..a170c80 100644
--- a/ssa.h
+++ b/ssa.h
@@ -31,6 +31,7 @@ struct COpr {
} info;
int sub;
+ int dep;
CInst_t def;
CRange_t range;
int reg; /* -1 for spilled */
@@ -134,6 +135,7 @@ typedef struct CInterv {
} CInterv;
void ssa_generate();
+COpr_t cinterv_repr(COpr_t opr);
extern int gbbase;
extern CBlock_t entry;
extern COList_t defs;