aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Scalar/StructurizeCFG.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/StructurizeCFG.cpp67
1 files changed, 61 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
index b3a445368537..f6525ad7de9b 100644
--- a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
@@ -18,10 +18,8 @@
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/Analysis/RegionPass.h"
-#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
-#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
@@ -33,7 +31,6 @@
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
-#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
@@ -41,7 +38,6 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils.h"
@@ -72,6 +68,11 @@ static cl::opt<bool>
cl::desc("Allow relaxed uniform region checks"),
cl::init(true));
+static cl::opt<unsigned>
+ ReorderNodeSize("structurizecfg-node-reorder-size",
+ cl::desc("Limit region size for reordering nodes"),
+ cl::init(100), cl::Hidden);
+
// Definition of the complex types used in this pass.
using BBValuePair = std::pair<BasicBlock *, Value *>;
@@ -266,6 +267,8 @@ class StructurizeCFG {
void orderNodes();
+ void reorderNodes();
+
void analyzeLoops(RegionNode *N);
Value *buildCondition(BranchInst *Term, unsigned Idx, bool Invert);
@@ -424,6 +427,57 @@ void StructurizeCFG::orderNodes() {
}
}
+/// Change the node ordering to decrease the range of live values, especially
+/// the values that capture the control flow path for branches. We do this
+/// by moving blocks with a single predecessor and successor to appear after
+/// predecessor. The motivation is to move some loop exit blocks into a loop.
+/// In cases where a loop has a large number of exit blocks, this reduces the
+/// amount of values needed across the loop boundary.
+void StructurizeCFG::reorderNodes() {
+ SmallVector<RegionNode *, 8> NewOrder;
+ DenseMap<BasicBlock *, unsigned> MoveTo;
+ BitVector Moved(Order.size());
+
+ // The benefits of reordering nodes occurs for large regions.
+ if (Order.size() <= ReorderNodeSize)
+ return;
+
+ // The algorithm works with two passes over Order. The first pass identifies
+ // the blocks to move and the position to move them to. The second pass
+ // creates the new order based upon this information. We move blocks with
+ // a single predecessor and successor. If there are multiple candidates then
+ // maintain the original order.
+ BBSet Seen;
+ for (int I = Order.size() - 1; I >= 0; --I) {
+ auto *BB = Order[I]->getEntry();
+ Seen.insert(BB);
+ auto *Pred = BB->getSinglePredecessor();
+ auto *Succ = BB->getSingleSuccessor();
+ // Consider only those basic blocks that have a predecessor in Order and a
+ // successor that exits the region. The region may contain subregions that
+ // have been structurized and are not included in Order.
+ if (Pred && Succ && Seen.count(Pred) && Succ == ParentRegion->getExit() &&
+ !MoveTo.count(Pred)) {
+ MoveTo[Pred] = I;
+ Moved.set(I);
+ }
+ }
+
+ // If no blocks have been moved then the original order is good.
+ if (!Moved.count())
+ return;
+
+ for (size_t I = 0, E = Order.size(); I < E; ++I) {
+ auto *BB = Order[I]->getEntry();
+ if (MoveTo.count(BB))
+ NewOrder.push_back(Order[MoveTo[BB]]);
+ if (!Moved[I])
+ NewOrder.push_back(Order[I]);
+ }
+
+ Order.assign(NewOrder);
+}
+
/// Determine the end of the loops
void StructurizeCFG::analyzeLoops(RegionNode *N) {
if (N->isSubRegion()) {
@@ -685,7 +739,7 @@ void StructurizeCFG::simplifyAffectedPhis() {
Q.DT = DT;
for (WeakVH VH : AffectedPhis) {
if (auto Phi = dyn_cast_or_null<PHINode>(VH)) {
- if (auto NewValue = SimplifyInstruction(Phi, Q)) {
+ if (auto NewValue = simplifyInstruction(Phi, Q)) {
Phi->replaceAllUsesWith(NewValue);
Phi->eraseFromParent();
Changed = true;
@@ -1085,12 +1139,13 @@ bool StructurizeCFG::run(Region *R, DominatorTree *DT) {
ParentRegion = R;
orderNodes();
+ reorderNodes();
collectInfos();
createFlow();
insertConditions(false);
insertConditions(true);
- simplifyConditions();
setPhiValues();
+ simplifyConditions();
simplifyAffectedPhis();
rebuildSSA();