/* 构造表达式的值,并将其添加到 t,src1,src2三个变量的uses 中 */ void DefineTemp (Symbol t, int op, Symbol src1, Symbol src2) { ValueDef def; CALLOC(def); def->dst = t; def->op = op; def->src1 = src1; def->src2 = src2; def->ownBB = CurrentBB; /* 赋值和函数调用 */ if (op == MOV || op == CALL) { /* 将值添加到变量t 中 */ def->link = AsVar(t)->def; AsVar(t)->def = def; return; } /* 如果src1 和src2是变量则将值添加进去 */ if (src1->kind == SK_Variable) { TrackValueUse (src1, def); } if (src2 && src2->kind == SK_Variable) { TrackValueUse (src2, def); } AsVar(t)->def = def; }
static char* GetAccessName(Symbol p) { if (p->aname != NULL) return p->aname; switch (p->kind) { case SK_Constant: p->aname = FormatName("$%s", p->name); break; case SK_String: case SK_Label: p->aname = FormatName(".%s", p->name); break; case SK_Variable: case SK_Temp: if (p->level == 0) { p->aname = p->name; } else if (p->sclass == TK_STATIC) { p->aname = FormatName("%s.%d", p->name, TempNum++); } else { p->aname = FormatName("%d(%%ebp)", AsVar(p)->offset); } break; case SK_Function: p->aname = p->name; break; case SK_Offset: { Symbol base = p->link; int n = AsVar(p)->offset; if (base->level == 0 || base->sclass == TK_STATIC) { p->aname = FormatName("%s%s%d", GetAccessName(base), n >= 0 ? "+" : "", n); } else { n += AsVar(base)->offset; p->aname = FormatName("%d(%%ebp)", n); } } break; default: assert(0); } return p->aname; }
void DefineTemp(Symbol t, int op, Symbol src1, Symbol src2) { ValueDef def; ALLOC(def); def->dst = t; def->op = op; def->src1 = src1; def->src2 = src2; def->ownBB = CurrentBB; if (op == MOV || op == CALL) { def->link = AsVar(t)->def; AsVar(t)->def = def; return; } if (src1->kind == SK_Variable) { TrackValueUse(src1, def); } if (src2 && src2->kind == SK_Variable) { TrackValueUse(src2, def); } AsVar(t)->def = def; }
/* 将值def, 添加到符号p 中 */ static void TrackValueUse (Symbol p, ValueDef def) { ValueUse use; CALLOC(use); use->def = def; use->next = AsVar(p)->uses; AsVar(p)->uses = use; }
Symbol Deref(Type ty, Symbol addr) { Symbol tmp; if (addr->kind == SK_Temp && AsVar(addr)->def->op == ADDR) { return AsVar(addr)->def->src1; } tmp = CreateTemp(ty); GenerateAssign(ty, tmp, DEREF, addr, NULL); return tmp; }
Symbol AddressOf(Symbol p) { if (p->kind == SK_Temp && AsVar(p)->def->op == DEREF) { return AsVar(p)->def->src1; } p->addressed = 1; if (p->kind == SK_Variable) { TrackValueChange(p); } return TryAddValue(T(POINTER), ADDR, p, NULL); }
Symbol TryAddValue(Type ty, int op, Symbol src1, Symbol src2) { int h = ((unsigned)src1 + (unsigned)src2 + op) & 15; ValueDef def = FSYM->valNumTable[h]; Symbol t; if (op != ADDR && (src1->addressed || (src2 && src2->addressed))) goto new_temp; while (def) { if (def->op == op && (def->src1 == src1 && def->src2 == src2)) break; def = def->link; } if (def && def->ownBB == CurrentBB && def->dst != NULL) return def->dst; new_temp: t = CreateTemp(ty); GenerateAssign(ty, t, op, src1, src2); def = AsVar(t)->def; def->link = FSYM->valNumTable[h]; FSYM->valNumTable[h] = def; return t; }
/* 翻译一个复合语句 */ static void TranslateCompoundStatement (AstStatement stmt) { AstCompoundStatement compStmt = AsComp (stmt); AstNode p; Vector ilocals = compStmt->ilocals; Symbol v; int i; /* 翻译局部变量 */ for (i = 0; i < LEN (ilocals); ++i) { InitData initd; Type ty; Symbol dst, src; int size; v = GET_ITEM (ilocals, i); initd = AsVar(v)->idata; size = 0; while (initd != NULL) { if (initd->offset != size) { dst = CreateOffset (T(UCHAR), v, size); GenerateClear (dst, initd->offset - size); } ty = initd->expr->ty; if (initd->expr->op == OP_STR) { String str = initd->expr->val.p; src = AddString (ArrayOf (str->len + 1, ty->bty), str); } else { src = TranslateExpression (initd->expr); } dst = CreateOffset (ty, v, initd->offset); /* 赋值 */ GenerateMove (ty, dst, src); size = initd->offset + ty->size; initd = initd->next; } if (size < v->ty->size) { dst = CreateOffset (T(UCHAR), v, size); GenerateClear (dst, v->ty->size - size); } } for (p = compStmt->stmts; p; p = p->next) { TranslateStatement ((AstStatement)p); } }
/* 操作为非取地址时,目标值置空 */ static void TrackValueChange (Symbol p) { ValueUse use = AsVar(p)->uses; for ( ; use; use = use->next) { /* 操作为非取地址时,目标值置空 */ if (use->def->op != ADDR) use->def->dst = NULL; } }
static void TrackValueChange(Symbol p) { ValueUse use = AsVar(p)->uses; while (use) { if (use->def->op != ADDR) use->def->dst = NULL; use = use->next; } }
/* 创建偏移符号 */ Symbol CreateOffset (Type ty, Symbol base, int coff) { VariableSymbol p; if (0 == coff) return base; CALLOC (p); if (SK_Offset == base->kind) { coff += AsVar(base)->offset; base = base->link; } p->addressed = 1; p->kind = SK_Offset; p->ty = ty; p->link = base; p->offset = coff; p->name = FormatName ("%s[%d]", base->name, coff); base->ref++; return (Symbol)p; }
/* 尝试添加操作的值 * 在函数符号表中查找该操作, * 如果找到复合条件的则返回目标符号, * 否则创建值并添加到符号表中 */ Symbol TryAddValue (Type ty, int op, Symbol src1, Symbol src2) { int h = ((unsigned long long)src1 + (unsigned long long)src2 + op) & 15; ValueDef def; Symbol t; /* 非地址符号 */ if (op != ADDR && (src1->addressed || (src2 && src2->addressed))) goto new_temp; /* 在函数的符号表中查找此操作的值 */ for (def = FSYM->valNumTable[h]; def; def = def->link) { if (def->op == op && (def->src1 == src1 && def->src2 == src2)) break; } /* 如果查找到该值,并属于当前基本块,并且有目标符号,则直接返回, * 否则创建中间变量 */ if (def && def->ownBB == CurrentBB && def->dst != NULL) return def->dst; /* 创建新临时变量 */ new_temp: /* 创建临时变量添加到函数符号表中 */ t = CreateTemp (ty); /* 构造一个三地址码,并添加到当前块中 */ GenerateAssign (ty, t, op, src1, src2); /* t->def 是在GenerateAssign 中构造的值 */ def = AsVar(t)->def; /* 添加值到符号表中 */ def->link = FSYM->valNumTable[h]; FSYM->valNumTable[h] = def; return t; }
/** * Perform algebraic simplification and strenth reduction */ Symbol Simplify(Type ty, int opcode, Symbol src1, Symbol src2) { VariableSymbol t; Symbol p1, p2; int c1, c2; if (IsRealType(ty)) goto add_value; if (src2 == NULL || (src2->kind != SK_Constant && opcode != SUB)) goto add_value; switch (opcode) { case ADD: // a + 0 = a if (src2->val.i[0] == 0) return src1; // a + c1 + c2 = a + (c1 + c2) // a - c1 + c2 = a + (-c1 + c2) p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } if (c1 != 0) { src1 = p1; src2 = IntConstant(c1 + src2->val.i[0]); } break; case SUB: // a - 0 = a if (src2->kind == SK_Constant && src2->val.i[0] == 0) return src1; // put source operand into v + c format (v maybe NULL, c maybe 0) p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src1->kind == SK_Constant) { p1 = NULL; c1 = src1->val.i[0]; } p2 = src2; c2 = 0; if (src2->kind == SK_Temp) { t = AsVar(src2); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p2 = t->def->src1; c2 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src2->kind == SK_Constant) { p2 = NULL; c2 = src2->val.i[0]; } if (p1 == p2) { // (a + c1) - (a + c2) = c1 - c2 return IntConstant(c1 - c2); } else if (p1 == NULL) { // c1 - (a + c2) = (c1 - c2) - a src1 = IntConstant(c1 - c2); src2 = p2; } else if (p2 == NULL) { // (a + c1) - c2 = a + (c1 - c2) src1 = p1; opcode = ADD; src2 = IntConstant(c1 - c2); } break; case MUL: case DIV: // a * 1 = a; a / 1 = a; if (src2->val.i[0] == 1) return src1; // a * 2 power of n = a >> n c1 = Power2(src2->val.i[0]); if (c1 != 0) { src2 = IntConstant(c1); opcode = opcode == MUL ? LSH : RSH; } break; case MOD: // a % 1 = 0 if (src2->val.i[0] == 1) return IntConstant(0); // a % 2 power of n = a & (2 power of n - 1) c1 = Power2(src2->val.i[0]); if (c1 != 0) { src2 = IntConstant(src2->val.i[0] - 1); opcode = BAND; } break; case LSH: case RSH: // a >> 0 = a << 0 = a if (src2->val.i[0] == 0) return src1; break; case BOR: // a | 0 = a; a | -1 = -1 if (src2->val.i[0] == 0) return src1; if (src2->val.i[0] == -1) return src2; break; case BXOR: // a ^ 0 = a if (src2->val.i[0] == 0) return src1; break; case BAND: // a & 0 = 0, a & -1 = a if (src2->val.i[0] == 0) return IntConstant(0); if (src2->val.i[0] == -1) return src1; break; default: break; } add_value: return TryAddValue(ty, opcode, src1, src2); }
static void PeepHole(BBlock bb) { IRInst inst = bb->insth.next; IRInst ninst; while (inst != &bb->insth) { ninst = inst->next; if ((inst->opcode == CALL || (inst->opcode >= EXTI1 && inst->opcode <= CVTF8U4)) && ninst->opcode == MOV && inst->opds[0] == ninst->opds[1]) { inst->opds[0]->ref -= 2; inst->opds[0] = ninst->opds[0]; inst->next = ninst->next; ninst->next->prev = inst; bb->ninst--; if (ninst->opds[0]->kind == SK_Temp) DefineTemp(ninst->opds[0], inst->opcode, (Symbol)inst, NULL); } else if ((inst->opcode == MOV || inst->opcode == IMOV) && inst->opds[1]->kind == SK_Temp) { ValueDef def = AsVar(inst->opds[1])->def; IRInst p; if (def->op == MOV) { while (def != NULL) { p = (IRInst)def->src1; p->opds[0]->ref--; inst->opds[0]->ref++; p->opds[0] = inst->opds[0]; p->opcode = inst->opcode; def = def->link; } inst->opds[0]->ref--; inst->opds[1]->ref--; inst->prev->next = inst->next; inst->next->prev = inst->prev; } } else if ((inst->opcode == ADD || inst->opcode == SUB) && ninst->opcode == MOV && inst->opds[0] == ninst->opds[1] && inst->opds[1] == ninst->opds[0] && inst->opds[2]->kind == SK_Constant) { int tcode = TypeCode(inst->ty); if ((tcode == F4 && inst->opds[2]->val.f == 1.0f) || (tcode == F8 && inst->opds[2]->val.d == 1.0) || (inst->opds[2]->val.i[0] == 1)) { inst->opds[0]->ref -= 2; inst->opds[1]->ref--; inst->opds[2]->ref--; inst->opcode = inst->opcode == ADD ? INC : DEC; inst->opds[0] = inst->opds[1]; inst->opds[1] = inst->opds[2] = NULL; inst->next = ninst->next; ninst->next->prev = inst; } } inst = inst->next; } }
/* 算数优化 */ Symbol Simplify (Type ty, int opcode, Symbol src1, Symbol src2) { VariableSymbol t; Symbol p1, p2; int c1, c2; /* 浮点 */ if (IsRealType (ty)) goto add_value; if (src2 == NULL || (src2->kind != SK_Constant && opcode != SUB)) goto add_value; /* 以下是 加, 减, 乘, 除, 取余, 左移, 右移, 按位操作的优化 */ switch (opcode) { case ADD: { /* a + 0 = a */ if (src2->val.i[0] == 0) return src1; /* a + c1 + c2 = a + (c1 + c2) */ /* a - c1 + c2 = a + (-c1 + c2) */ p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } if (c1 != 0) { src1 = p1; /* 合并c1, c2 */ src2 = IntConstant (c1 + src2->val.i[0]); } }break; case SUB: { /* a - 0 = a */ if (src2->kind == SK_Constant && src2->val.i[0] == 0) return src1; // put source operand into v + c format (v maybe NULL, c maybe 0) p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src1->kind == SK_Constant) { p1 = NULL; c1 = src1->val.i[0]; } p2 = src2; c2 = 0; if (src2->kind == SK_Temp) { t = AsVar(src2); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p2 = t->def->src1; c2 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src2->kind == SK_Constant) { p2 = NULL; c2 = src2->val.i[0]; } if (p1 == p2) { /* (a + c1) - (a + c2) = c1 - c2 */ return IntConstant (c1 - c2); } else if (p1 == NULL) { /* c1 - (a + c2) = (c1 - c2) - a */ src1 = IntConstant (c1 - c2); src2 = p2; } else if (p2 == NULL) { /* (a + c1) - c2 = a + (c1 - c2) */ src1 = p1; opcode = ADD; src2 = IntConstant(c1 - c2); } }break; case MUL: case DIV: { /* a * 1 = a; a / 1 = a; */ if (src2->val.i[0] == 1) return src1; /* a * 2 power of n = a >> n */ c1 = Power2 (src2->val.i[0]); if (c1 != 0) { /* 转换乘除为位移操作 */ src2 = IntConstant (c1); opcode = opcode == MUL ? LSH : RSH; } }break; case MOD: { /* a % 1 = 0 */ if (src2->val.i[0] == 1) return IntConstant (0); /* a % 2 power of n = a & (2 power of n - 1) */ c1 = Power2 (src2->val.i[0]); if (c1 != 0) { src2 = IntConstant (src2->val.i[0] - 1); opcode = BAND; } }break; case LSH: case RSH: { /* a >> 0 = a << 0 = a */ if (src2->val.i[0] == 0) return src1; }break; case BOR: { /* a | 0 = a; a | -1 = -1 */ if (src2->val.i[0] == 0) return src1; if (src2->val.i[0] == -1) return src2; }break; case BXOR: { /* a ^ 0 = a */ if (src2->val.i[0] == 0) return src1; }break; case BAND: { /* a & 0 = 0, a & -1 = a */ if (src2->val.i[0] == 0) return IntConstant(0); if (src2->val.i[0] == -1) return src1; }break; default: break; } add_value: /* 构造值添加到符号表中,并返回 */ return TryAddValue (ty, opcode, src1, src2); }
/** * Get a symbol's name in assembly */ static char* GetAccessName(Symbol p) { if (p->aname != NULL) return p->aname; switch (p->kind) { case SK_Constant: if (p->name[0] == '0' && p->name[1] == 'x') p->aname = FormatName("0%sH", &p->name[2]); else p->aname = p->name; break; case SK_String: case SK_IRegister: case SK_Label: p->aname = p->name; break; case SK_Variable: case SK_Temp: if (p->level == 0) { p->aname = FormatName("_%s", p->name); } else if (p->sclass == TK_STATIC) { p->aname = FormatName("%s%d", p->name, TempNum++); } else { p->aname = FormatName("(%d)[ebp]", AsVar(p)->offset); } break; case SK_Function: p->aname = FormatName("_%s", p->name); break; case SK_Offset: { Symbol base = p->link; int n = AsVar(p)->offset; if (base->level == 0 || base->sclass == TK_STATIC) { p->aname = FormatName("%s%s%d", GetAccessName(base), n >= 0 ? "+" : "", n); } else { n += AsVar(base)->offset; p->aname = FormatName("(%d)[ebp]", n); } } break; default: assert(0); } return p->aname; }