Index: src/IceTargetLoweringX8632.cpp |
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
index 6c3b6243c5dbfe20f5922e953c95abd8404da746..e7dab237bd6a1a314a7728a5d35f0ecd622fff8b 100644 |
--- a/src/IceTargetLoweringX8632.cpp |
+++ b/src/IceTargetLoweringX8632.cpp |
@@ -375,7 +375,7 @@ void TargetX8632::translateO2() { |
// associated cleanup, to make the dump cleaner and more useful. |
Func->dump("After initial x8632 codegen"); |
Func->getVMetadata()->init(VMK_All); |
- regAlloc(); |
+ regAlloc(RAK_Global); |
if (Func->hasError()) |
return; |
Func->dump("After linear scan regalloc"); |
@@ -429,6 +429,11 @@ void TargetX8632::translateOm1() { |
return; |
Func->dump("After initial x8632 codegen"); |
+ regAlloc(RAK_InfOnly); |
+ if (Func->hasError()) |
+ return; |
+ Func->dump("After regalloc of infinite-weight variables"); |
+ |
Func->genFrame(); |
if (Func->hasError()) |
return; |
@@ -4512,115 +4517,20 @@ Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { |
} |
void TargetX8632::postLower() { |
- if (Ctx->getOptLevel() != Opt_m1) { |
- // Find two-address non-SSA instructions where Dest==Src0, and set |
- // the DestNonKillable flag to keep liveness analysis consistent. |
- for (auto Inst = Context.begin(), E = Context.end(); Inst != E; ++Inst) { |
- if (Inst->isDeleted()) |
- continue; |
- if (Variable *Dest = Inst->getDest()) { |
- // TODO(stichnot): We may need to consider all source |
- // operands, not just the first one, if using 3-address |
- // instructions. |
- if (Inst->getSrcSize() > 0 && Inst->getSrc(0) == Dest) |
- Inst->setDestNonKillable(); |
- } |
- } |
+ if (Ctx->getOptLevel() == Opt_m1) |
return; |
- } |
- // TODO: Avoid recomputing WhiteList every instruction. |
- RegSetMask RegInclude = RegSet_All; |
- RegSetMask RegExclude = RegSet_StackPointer; |
- if (hasFramePointer()) |
- RegExclude |= RegSet_FramePointer; |
- llvm::SmallBitVector WhiteList = getRegisterSet(RegInclude, RegExclude); |
- // Make one pass to black-list pre-colored registers. TODO: If |
- // there was some prior register allocation pass that made register |
- // assignments, those registers need to be black-listed here as |
- // well. |
- llvm::DenseMap<const Variable *, const Inst *> LastUses; |
- // The first pass also keeps track of which instruction is the last |
- // use for each infinite-weight variable. After the last use, the |
- // variable is released to the free list. |
- for (auto Inst = Context.begin(), E = Context.end(); Inst != E; ++Inst) { |
- if (Inst->isDeleted()) |
- continue; |
- // Don't consider a FakeKill instruction, because (currently) it |
- // is only used to kill all scratch registers at a call site, and |
- // we don't want to black-list all scratch registers during the |
- // call lowering. This could become a problem since it relies on |
- // the lowering sequence not keeping any infinite-weight variables |
- // live across a call. TODO(stichnot): Consider replacing this |
- // whole postLower() implementation with a robust local register |
- // allocator, for example compute live ranges only for pre-colored |
- // and infinite-weight variables and run the existing linear-scan |
- // allocator. |
- assert(!llvm::isa<InstFakeKill>(Inst) || Inst->getSrcSize() == 0); |
- for (SizeT SrcNum = 0; SrcNum < Inst->getSrcSize(); ++SrcNum) { |
- Operand *Src = Inst->getSrc(SrcNum); |
- SizeT NumVars = Src->getNumVars(); |
- for (SizeT J = 0; J < NumVars; ++J) { |
- const Variable *Var = Src->getVar(J); |
- // Track last uses of all variables, regardless of whether |
- // they are pre-colored or infinite-weight. |
- LastUses[Var] = Inst; |
- if (!Var->hasReg()) |
- continue; |
- WhiteList[Var->getRegNum()] = false; |
- } |
- } |
- } |
- // The second pass colors infinite-weight variables. |
- llvm::SmallBitVector AvailableRegisters = WhiteList; |
- llvm::SmallBitVector FreedRegisters(WhiteList.size()); |
+ // Find two-address non-SSA instructions where Dest==Src0, and set |
+ // the DestNonKillable flag to keep liveness analysis consistent. |
for (auto Inst = Context.begin(), E = Context.end(); Inst != E; ++Inst) { |
- FreedRegisters.reset(); |
if (Inst->isDeleted()) |
continue; |
- // Iterate over all variables referenced in the instruction, |
- // including the Dest variable (if any). If the variable is |
- // marked as infinite-weight, find it a register. If this |
- // instruction is the last use of the variable in the lowered |
- // sequence, release the register to the free list after this |
- // instruction is completely processed. Note that the first pass |
- // ignores the Dest operand, under the assumption that a |
- // pre-colored Dest will appear as a source operand in some |
- // subsequent instruction in the lowered sequence. |
- Variable *Dest = Inst->getDest(); |
- SizeT NumSrcs = Inst->getSrcSize(); |
- if (Dest) |
- ++NumSrcs; |
- if (NumSrcs == 0) |
- continue; |
- OperandList Srcs(NumSrcs); |
- for (SizeT i = 0; i < Inst->getSrcSize(); ++i) |
- Srcs[i] = Inst->getSrc(i); |
- if (Dest) |
- Srcs[NumSrcs - 1] = Dest; |
- for (SizeT SrcNum = 0; SrcNum < NumSrcs; ++SrcNum) { |
- Operand *Src = Srcs[SrcNum]; |
- SizeT NumVars = Src->getNumVars(); |
- for (SizeT J = 0; J < NumVars; ++J) { |
- Variable *Var = Src->getVar(J); |
- if (!Var->hasReg() && Var->getWeight().isInf()) { |
- llvm::SmallBitVector AvailableTypedRegisters = |
- AvailableRegisters & getRegisterSetForType(Var->getType()); |
- assert(AvailableTypedRegisters.any()); |
- int32_t RegNum = AvailableTypedRegisters.find_first(); |
- Var->setRegNum(RegNum); |
- AvailableRegisters[RegNum] = false; |
- } |
- if (Var->hasReg()) { |
- int32_t RegNum = Var->getRegNum(); |
- assert(!AvailableRegisters[RegNum]); |
- if (LastUses[Var] == Inst) { |
- if (WhiteList[RegNum]) |
- FreedRegisters[RegNum] = true; |
- } |
- } |
- } |
+ if (Variable *Dest = Inst->getDest()) { |
+ // TODO(stichnot): We may need to consider all source |
+ // operands, not just the first one, if using 3-address |
+ // instructions. |
+ if (Inst->getSrcSize() > 0 && Inst->getSrc(0) == Dest) |
+ Inst->setDestNonKillable(); |
} |
- AvailableRegisters |= FreedRegisters; |
} |
} |