Chromium Code Reviews| Index: src/IceCfgNode.cpp |
| diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp |
| index 60214c7e5fa1b3a72b695ebce74b05fc1e82e921..4fb336d03456b5ef778dfa9480cf7d5a0680c330 100644 |
| --- a/src/IceCfgNode.cpp |
| +++ b/src/IceCfgNode.cpp |
| @@ -736,10 +736,9 @@ void CfgNode::contractIfEmpty() { |
| // invalidate the iterator over this->InEdges). |
| if (OutEdges.front() != this) { |
| for (CfgNode *Pred : InEdges) { |
| - for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E; |
| - ++I) { |
| - if (*I == this) { |
| - *I = OutEdges.front(); |
| + for (CfgNode *&I : Pred->OutEdges) { |
| + if (I == this) { |
| + I = OutEdges.front(); |
| OutEdges.front()->InEdges.push_back(Pred); |
| } |
| } |
| @@ -748,23 +747,30 @@ void CfgNode::contractIfEmpty() { |
| I.repointEdges(this, OutEdges.front()); |
| } |
| } |
| + |
| + // Remove the in-edge to the successor to allow node reordering to make |
| + // better decisions. For example it's more helpful to place a node after |
| + // a reachable predecessor than an unreachable one (like the one we just |
| + // contracted). |
| + const auto SuccInEdgesBegin = OutEdges.front()->InEdges.begin(); |
| + const auto SuccInEdgesEnd = OutEdges.front()->InEdges.end(); |
| + OutEdges.front()->InEdges.erase( |
| + std::find(SuccInEdgesBegin, SuccInEdgesEnd, this)); |
| } |
| InEdges.clear(); |
| - // Don't bother removing the single out-edge, which would also |
| - // require finding the corresponding in-edge in the successor and |
| - // removing it. |
| } |
| void CfgNode::doBranchOpt(const CfgNode *NextNode) { |
| TargetLowering *Target = Func->getTarget(); |
| - // Check every instruction for a branch optimization opportunity. |
| - // It may be more efficient to iterate in reverse and stop after the |
| - // first opportunity, unless there is some target lowering where we |
| - // have the possibility of multiple such optimizations per block |
| - // (currently not the case for x86 lowering). |
| - for (Inst &I : Insts) { |
| + // Find the first opportunity for branch optimization (which will be the last |
| + // instruction in the block) and stop. This is sufficient unless there is some |
| + // target lowering where we have the possibility of multiple optimizations per |
| + // block. Take case with switch lowering as there are multiple unconditional |
|
jvoung (off chromium)
2015/07/23 00:01:23
What do you mean by "Take case with switch lowerin
ascull
2015/07/23 00:11:19
I mean 'take care'. Too much switching!
|
| + // branches and only the last can be deleted. |
| + for (Inst &I : reverse_range(Insts)) { |
| if (!I.isDeleted()) { |
| Target->doBranchOpt(&I, NextNode); |
| + return; |
| } |
| } |
| } |