Index: src/IceCfg.cpp |
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp |
index 0bd6b3675990f33973fbf5524149c3b625ab5bf6..a328d21fccf4202e449fe5a7620fa0dacbb78eab 100644 |
--- a/src/IceCfg.cpp |
+++ b/src/IceCfg.cpp |
@@ -26,7 +26,8 @@ namespace Ice { |
Cfg::Cfg(GlobalContext *Ctx) |
: Ctx(Ctx), FunctionName(""), ReturnType(IceType_void), |
IsInternalLinkage(false), HasError(false), FocusedTiming(false), |
- ErrorMessage(""), Entry(NULL), NextInstNumber(1), Live(nullptr), |
+ ErrorMessage(""), Entry(NULL), NextInstNumber(Inst::NumberInitial), |
+ Live(nullptr), |
Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)), |
VMetadata(new VariablesMetadata(this)), |
TargetAssembler( |
@@ -96,7 +97,7 @@ void Cfg::computePredecessors() { |
void Cfg::renumberInstructions() { |
TimerMarker T(TimerStack::TT_renumberInstructions, this); |
- NextInstNumber = 1; |
+ NextInstNumber = Inst::NumberInitial; |
for (CfgNode *Node : Nodes) |
Node->renumberInstructions(); |
} |
@@ -256,7 +257,6 @@ void Cfg::liveness(LivenessMode Mode) { |
llvm::BitVector NeedToProcess(Nodes.size(), true); |
while (NeedToProcess.any()) { |
// Iterate in reverse topological order to speed up convergence. |
- // TODO(stichnot): Use llvm::make_range with LLVM 3.5. |
for (auto I = Nodes.rbegin(), E = Nodes.rend(); I != E; ++I) { |
CfgNode *Node = *I; |
if (NeedToProcess[Node->getIndex()]) { |
@@ -276,38 +276,45 @@ void Cfg::liveness(LivenessMode Mode) { |
for (Variable *Var : Variables) |
Var->resetLiveRange(); |
} |
- // Collect timing for just the portion that constructs the live |
- // range intervals based on the end-of-live-range computation, for a |
- // finer breakdown of the cost. |
- TimerMarker T1(TimerStack::TT_liveRange, this); |
- // Make a final pass over instructions to delete dead instructions |
- // and build each Variable's live range. |
- for (CfgNode *Node : Nodes) |
- Node->livenessPostprocess(Mode, getLiveness()); |
- if (Mode == Liveness_Intervals) { |
- // Special treatment for live in-args. Their liveness needs to |
- // extend beyond the beginning of the function, otherwise an arg |
- // whose only use is in the first instruction will end up having |
- // the trivial live range [1,1) and will *not* interfere with |
- // other arguments. So if the first instruction of the method is |
- // "r=arg1+arg2", both args may be assigned the same register. |
- for (SizeT I = 0; I < Args.size(); ++I) { |
- Variable *Arg = Args[I]; |
- if (!Arg->getLiveRange().isEmpty()) { |
- // Add live range [-1,0) with weight 0. TODO: Here and below, |
- // use better symbolic constants along the lines of |
- // Inst::NumberDeleted and Inst::NumberSentinel instead of -1 |
- // and 0. |
- Arg->addLiveRange(-1, 0, 0); |
+ // Make a final pass over each node to delete dead instructions, |
+ // collect the first and last instruction numbers, and add live |
+ // range segments for that node. |
+ for (CfgNode *Node : Nodes) { |
+ InstNumberT FirstInstNum = Inst::NumberSentinel; |
+ InstNumberT LastInstNum = Inst::NumberSentinel; |
+ for (auto I = Node->getPhis().begin(), E = Node->getPhis().end(); I != E; |
+ ++I) { |
+ I->deleteIfDead(); |
+ if (Mode == Liveness_Intervals && !I->isDeleted()) { |
+ if (FirstInstNum == Inst::NumberSentinel) |
+ FirstInstNum = I->getNumber(); |
+ assert(I->getNumber() > LastInstNum); |
+ LastInstNum = I->getNumber(); |
} |
- // Do the same for i64 args that may have been lowered into i32 |
- // Lo and Hi components. |
- Variable *Lo = Arg->getLo(); |
- if (Lo && !Lo->getLiveRange().isEmpty()) |
- Lo->addLiveRange(-1, 0, 0); |
- Variable *Hi = Arg->getHi(); |
- if (Hi && !Hi->getLiveRange().isEmpty()) |
- Hi->addLiveRange(-1, 0, 0); |
+ } |
+ for (auto I = Node->getInsts().begin(), E = Node->getInsts().end(); I != E; |
+ ++I) { |
+ I->deleteIfDead(); |
+ if (Mode == Liveness_Intervals && !I->isDeleted()) { |
+ if (FirstInstNum == Inst::NumberSentinel) |
+ FirstInstNum = I->getNumber(); |
+ assert(I->getNumber() > LastInstNum); |
+ LastInstNum = I->getNumber(); |
+ } |
+ } |
+ if (Mode == Liveness_Intervals) { |
+ // Special treatment for live in-args. Their liveness needs to |
+ // extend beyond the beginning of the function, otherwise an arg |
+ // whose only use is in the first instruction will end up having |
+ // the trivial live range [2,2) and will *not* interfere with |
+ // other arguments. So if the first instruction of the method |
+ // is "r=arg1+arg2", both args may be assigned the same |
+ // register. This is accomplished by extending the entry |
+ // block's instruction range from [2,n) to [1,n) which will |
+ // transform the problematic [2,2) live ranges into [1,2). |
+ if (FirstInstNum == Inst::NumberInitial) |
+ FirstInstNum = Inst::NumberExtended; |
+ Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum); |
} |
} |
} |