[HotColdSplitting] Allow outlining single-block cold regions
It can be profitable to outline single-block cold regions because they
may be large.
Allow outlining single-block regions if they have over some threshold of
non-debug, non-terminator instructions. I chose 3 as the threshold after
experimenting with several internal frameworks.
In practice, reducing the threshold further did not give much
improvement, whereas increasing it resulted in substantial regressions.
Differential Revision: https://reviews.llvm.org/D53824
llvm-svn: 345524
diff --git a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
index 4f371a4..ce8a506 100644
--- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
+++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
@@ -31,6 +31,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
@@ -65,6 +66,10 @@
static cl::opt<bool> EnableStaticAnalyis("hot-cold-static-analysis",
cl::init(true), cl::Hidden);
+static cl::opt<unsigned> MinOutliningInstCount(
+ "min-outlining-inst-count", cl::init(3), cl::Hidden,
+ cl::desc("Minimum number of instructions needed for a single-block region "
+ "to be an outlining candidate"));
namespace {
@@ -130,6 +135,19 @@
return !BB.hasAddressTaken();
}
+/// Check whether \p BB has at least \p Min non-debug, non-terminator
+/// instructions.
+static bool hasMinimumInstCount(const BasicBlock &BB, unsigned Min) {
+ unsigned Count = 0;
+ for (const Instruction &I : BB) {
+ if (isa<DbgInfoIntrinsic>(&I) || &I == BB.getTerminator())
+ continue;
+ if (++Count >= Min)
+ return true;
+ }
+ return false;
+}
+
/// Identify the maximal region of cold blocks which includes \p SinkBB.
///
/// Include all blocks post-dominated by \p SinkBB, \p SinkBB itself, and all
@@ -223,9 +241,8 @@
++SuccIt;
}
- // TODO: Consider outlining regions with just 1 block, but more than some
- // threshold of instructions.
- if (ColdRegion.size() == 1)
+ if (ColdRegion.size() == 1 &&
+ !hasMinimumInstCount(*ColdRegion[0], MinOutliningInstCount))
return {};
return ColdRegion;