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 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); }
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 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; }