Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Unified Diff: src/IceCfg.cpp

Issue 802003003: Subzero: Clean up live range construction. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/IceCfgNode.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
}
}
« no previous file with comments | « no previous file | src/IceCfgNode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698