From 2978a60a24a8e307721b4ac44f2b78decc8d6b8f Mon Sep 17 00:00:00 2001 From: Teddy Date: Fri, 2 May 2014 14:09:55 +0800 Subject: ... --- mips.c | 413 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mips.h | 5 + semantics.c | 4 + ssa.c | 250 ++++++++++++++++++++++++------------ ssa.h | 2 + 5 files changed, 591 insertions(+), 83 deletions(-) create mode 100644 mips.c create mode 100644 mips.h 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 +#include +#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; -- cgit v1.2.3