Index: include/llvm/Transforms/IPO/HotColdSplitting.h =================================================================== --- /dev/null +++ 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 { +public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H + Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ 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" @@ -191,6 +192,9 @@ cl::desc("Run synthetic function entry count generation " "pass")); +static cl::opt EnableHotColdSplit("npm-hot-cold-split", cl::init(false), + cl::Hidden, cl::desc("Enable hot-cold splitting pass")); + static Regex DefaultAliasRegex( "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$"); @@ -614,6 +618,9 @@ 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 Index: lib/Transforms/IPO/HotColdSplitting.cpp =================================================================== --- lib/Transforms/IPO/HotColdSplitting.cpp +++ 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 @@ return HotColdSplitting(PSI, GBFI, GTTI, &GetORE).run(M); } +PreservedAnalyses +HotColdSplittingPass::run(Module &M, ModuleAnalysisManager &AM) { + auto &FAM = AM.getResult(M).getManager(); + + std::function GetAssumptionCache = + [&FAM](Function &F) -> AssumptionCache & { + return FAM.getResult(F); + }; + + auto GBFI = [&FAM](Function &F) { + return &FAM.getResult(F); + }; + + std::function GTTI = + [&FAM](Function &F) -> TargetTransformInfo & { + return FAM.getResult(F); + }; + + std::unique_ptr ORE; + std::function GetORE = + [&ORE](Function &F) -> OptimizationRemarkEmitter & { + ORE.reset(new OptimizationRemarkEmitter(&F)); + return *ORE.get(); + }; + + ProfileSummaryInfo *PSI = &AM.getResult(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) Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -104,9 +104,8 @@ EnablePrepareForThinLTO("prepare-for-thinlto", cl::init(false), cl::Hidden, cl::desc("Enable preparation for ThinLTO.")); -cl::opt EnableHotColdSplit("hot-cold-split", cl::init(false), cl::Hidden, - cl::desc("Enable hot-cold splitting pass")); - +static cl::opt EnableHotColdSplit("hot-cold-split", cl::init(false), + cl::Hidden, cl::desc("Enable hot-cold splitting pass")); static cl::opt RunPGOInstrGen( "profile-generate", cl::init(false), cl::Hidden,