void GenerateAssign(Type ty, Symbol dst, int opcode, Symbol src1, Symbol src2) { IRInst inst; ALLOC(inst); dst->ref++; src1->ref++; if (src2) src2->ref++; inst->ty = ty; inst->opcode = opcode; inst->opds[0] = dst; inst->opds[1] = src1; inst->opds[2] = src2; AppendInst(inst); DefineTemp(dst, opcode, src1, src2); }
void GenerateFunctionCall(Type ty, Symbol recv, Symbol faddr, Vector args) { ILArg p; IRInst inst; ALLOC(inst); if (recv) recv->ref++; faddr->ref++; FOR_EACH_ITEM(ILArg, p, args) p->sym->ref++; ENDFOR inst->ty = ty; inst->opcode = CALL; inst->opds[0] = recv; inst->opds[1] = faddr; inst->opds[2] = (Symbol)args; AppendInst(inst); if (recv != NULL) DefineTemp(recv, CALL, (Symbol)inst, NULL); }
/* 生成赋值指令 */ void GenerateMove (Type ty, Symbol dst, Symbol src) { IRInst inst; ALLOC(inst); dst->ref++; src->ref++; inst->ty = ty; inst->opcode = MOV; inst->opds[0] = dst; inst->opds[1] = src; inst->opds[2] = NULL; AppendInst (inst); if (dst->kind == SK_Variable) { TrackValueChange (dst); } else if (dst->kind == SK_Temp) { DefineTemp (dst, MOV, (Symbol)inst, NULL); } }
/* * AssignInst -> VarName = Expression | * -> VarName = Operand | * -> *VarName = Operand * */ void GenerateAssign (Type ty, Symbol dst, int opcode, Symbol src1, Symbol src2) { IRInst inst; CALLOC(inst); /* 符号被引用一次 */ dst->ref++; src1->ref++; if (src2) src2->ref++; /* 构造三地址码 */ inst->ty = ty; inst->opcode = opcode; inst->opds[0] = dst; inst->opds[1] = src1; inst->opds[2] = src2; /* 将三地址码添加到当前基本块中 */ AppendInst (inst); /* 构造表达式值,并添加到dst,src1,src2的uses中 */ DefineTemp (dst, 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; } }