summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Transforms/IPO/HotColdSplitting.h31
-rw-r--r--llvm/lib/Passes/PassBuilder.cpp6
-rw-r--r--llvm/lib/Passes/PassRegistry.def1
-rw-r--r--llvm/lib/Transforms/IPO/HotColdSplitting.cpp33
-rw-r--r--llvm/test/Transforms/HotColdSplit/split-cold-1.ll1
-rw-r--r--llvm/test/Transforms/HotColdSplit/split-cold-2.ll1
6 files changed, 73 insertions, 0 deletions
diff --git a/llvm/include/llvm/Transforms/IPO/HotColdSplitting.h b/llvm/include/llvm/Transforms/IPO/HotColdSplitting.h
new file mode 100644
index 00000000000..57e9a9e6918
--- /dev/null
+++ b/llvm/include/llvm/Transforms/IPO/HotColdSplitting.h
@@ -0,0 +1,31 @@
+//===- HotColdSplitting.h ---- Outline Cold Regions -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// This pass outlines cold regions to a separate function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H
+#define LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+/// Pass to outline cold regions.
+class HotColdSplittingPass : public PassInfoMixin<HotColdSplittingPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H
+
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index d7b9dfca34a..a880befc0d5 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -75,6 +75,7 @@
#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Transforms/IPO/GlobalOpt.h"
#include "llvm/Transforms/IPO/GlobalSplit.h"
+#include "llvm/Transforms/IPO/HotColdSplitting.h"
#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
#include "llvm/Transforms/IPO/Inliner.h"
#include "llvm/Transforms/IPO/Internalize.h"
@@ -198,6 +199,8 @@ static cl::opt<bool>
EnableCHR("enable-chr-npm", cl::init(true), cl::Hidden,
cl::desc("Enable control height reduction optimization (CHR)"));
+extern cl::opt<bool> EnableHotColdSplit;
+
static bool isOptimizingForSize(PassBuilder::OptimizationLevel Level) {
switch (Level) {
case PassBuilder::O0:
@@ -614,6 +617,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
true));
}
+ if (EnableHotColdSplit)
+ MPM.addPass(HotColdSplittingPass());
+
// Interprocedural constant propagation now that basic cleanup has occurred
// and prior to optimizing globals.
// FIXME: This position in the pipeline hasn't been carefully considered in
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index b070b0ed303..8de4541a772 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -51,6 +51,7 @@ MODULE_PASS("function-import", FunctionImportPass())
MODULE_PASS("globaldce", GlobalDCEPass())
MODULE_PASS("globalopt", GlobalOptPass())
MODULE_PASS("globalsplit", GlobalSplitPass())
+MODULE_PASS("hotcoldsplit", HotColdSplittingPass())
MODULE_PASS("inferattrs", InferFunctionAttrsPass())
MODULE_PASS("insert-gcov-profiling", GCOVProfilerPass())
MODULE_PASS("instrprof", InstrProfiling())
diff --git a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
index be64da5d808..820d08316d6 100644
--- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
+++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
@@ -44,6 +44,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/HotColdSplitting.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
@@ -409,6 +410,38 @@ bool HotColdSplittingLegacyPass::runOnModule(Module &M) {
return HotColdSplitting(PSI, GBFI, GTTI, &GetORE).run(M);
}
+PreservedAnalyses
+HotColdSplittingPass::run(Module &M, ModuleAnalysisManager &AM) {
+ auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+
+ std::function<AssumptionCache &(Function &)> GetAssumptionCache =
+ [&FAM](Function &F) -> AssumptionCache & {
+ return FAM.getResult<AssumptionAnalysis>(F);
+ };
+
+ auto GBFI = [&FAM](Function &F) {
+ return &FAM.getResult<BlockFrequencyAnalysis>(F);
+ };
+
+ std::function<TargetTransformInfo &(Function &)> GTTI =
+ [&FAM](Function &F) -> TargetTransformInfo & {
+ return FAM.getResult<TargetIRAnalysis>(F);
+ };
+
+ std::unique_ptr<OptimizationRemarkEmitter> ORE;
+ std::function<OptimizationRemarkEmitter &(Function &)> GetORE =
+ [&ORE](Function &F) -> OptimizationRemarkEmitter & {
+ ORE.reset(new OptimizationRemarkEmitter(&F));
+ return *ORE.get();
+ };
+
+ ProfileSummaryInfo *PSI = &AM.getResult<ProfileSummaryAnalysis>(M);
+
+ if (HotColdSplitting(PSI, GBFI, GTTI, &GetORE).run(M))
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
+}
+
char HotColdSplittingLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(HotColdSplittingLegacyPass, "hotcoldsplit",
"Hot Cold Splitting", false, false)
diff --git a/llvm/test/Transforms/HotColdSplit/split-cold-1.ll b/llvm/test/Transforms/HotColdSplit/split-cold-1.ll
index fdb3eb003c6..60ec234ab83 100644
--- a/llvm/test/Transforms/HotColdSplit/split-cold-1.ll
+++ b/llvm/test/Transforms/HotColdSplit/split-cold-1.ll
@@ -1,4 +1,5 @@
; RUN: opt -hotcoldsplit -S < %s | FileCheck %s
+; RUN: opt -passes=hotcoldsplit -S < %s | FileCheck %s
; Outlined function is called from a basic block named codeRepl
; CHECK: codeRepl:
diff --git a/llvm/test/Transforms/HotColdSplit/split-cold-2.ll b/llvm/test/Transforms/HotColdSplit/split-cold-2.ll
index ce8e7b554d5..101bc11cba9 100644
--- a/llvm/test/Transforms/HotColdSplit/split-cold-2.ll
+++ b/llvm/test/Transforms/HotColdSplit/split-cold-2.ll
@@ -1,4 +1,5 @@
; RUN: opt -hotcoldsplit -S < %s
+; RUN: opt -passes=hotcoldsplit -S < %s
; Make sure this compiles. This test used to fail with an invalid phi node: the
; two predecessors were outlined and the SSA representation was invalid.
OpenPOWER on IntegriCloud