/* 折半查找 */ static void TranslateSwitchBuckets (SwitchBucket *bucketArray, int left, int right, Symbol choice, BBlock currBB, BBlock defBB) { int mid, len, i; AstCaseStatement p; BBlock lhalfBB, rhalfBB; BBlock *dstBBs; Symbol index; if (left > right) return; mid = (left + right) / 2; lhalfBB = (left > mid - 1) ? defBB : CreateBBlock(); rhalfBB = (mid + 1 > right) ? defBB : CreateBBlock(); len = bucketArray[mid]->maxVal - bucketArray[mid]->minVal + 1; dstBBs = HeapAllocate (CurrentHeap, (len + 1)* sizeof(BBlock)); for (i = 0; i < len; ++i) dstBBs[i] = defBB; dstBBs[len] = NULL; for (p = bucketArray[mid]->cases; p; p = p->nextCase) { i = p->expr->val.i[0] - bucketArray[mid]->minVal; dstBBs[i] = p->respBB; } if (currBB != NULL) { StartBBlock (currBB); } GenerateBranch (choice->ty, lhalfBB, JL, choice, IntConstant (bucketArray[mid]->minVal)); StartBBlock (CreateBBlock()); GenerateBranch (choice->ty, rhalfBB, JG, choice, IntConstant (bucketArray[mid]->maxVal)); StartBBlock (CreateBBlock()); if (len != 1) { index = CreateTemp (choice->ty); GenerateAssign (choice->ty, index, SUB, choice, IntConstant (bucketArray[mid]->minVal)); GenerateIndirectJump (dstBBs, len, index); } else { GenerateJump (dstBBs[0]); } StartBBlock (CreateBBlock ()); /* 二分递归 */ TranslateSwitchBuckets (bucketArray, left, mid - 1, choice, lhalfBB, defBB); TranslateSwitchBuckets (bucketArray, mid + 1, right, choice, rhalfBB, defBB); }
void Compiler::EmitCall(IRInst inst) { ParameterList argslist = (ParameterList)SRC2; Symbol arg; int i, stksize = 0; for (i = argslist->npara - 1; i >= 0; i--) { arg = argslist->args[i]; PushArgument(arg); stksize += sizeof(int) * 1; } // call func PutASMCode(X86_CALL, inst->opds); // 如果参数不为0, 则返回时需要复原栈顶 if (stksize != 0) { Symbol p; p = IntConstant(stksize); PutASMCode(X86_REDUCEF, &p); } if (DST) DST->ref--; // 这里DST 不会 DST == NULL,因为根据要求为ID = call ID. //函数返回值放在EAX //AllocateReg(inst, 0); //if (DST->reg != Regs[EAX]) //{ // Move(DST, Regs[EAX]); //} DST->reg = Regs[EAX]; }
void Compiler::EmitPrologue(int varsize) { PutASMCode(PROLOGUE, NULL); if (varsize != 0) { Symbol sym = IntConstant(varsize*sizeof(int)); PutASMCode(EXPANDF, &sym); } }
/* * ClearInst -> Clear VarName, constant * */ void GenerateClear (Symbol dst, int size) { IRInst inst; CALLOC (inst); dst->ref++; inst->ty = T(UCHAR); inst->opcode = CLR; inst->opds[0] = dst; inst->opds[1] = IntConstant (size); inst->opds[1]->ref++; inst->opds[2] = NULL; AppendInst (inst); }
/** * 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); }
/* 算数优化 */ 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); }