#include "llvm/Transforms/IPO/HotColdSplitting.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/CodeExtractor.h"
#include <algorithm>
#include <cassert>
#include <limits>
#include <string>
#define DEBUG_TYPE …
STATISTIC(NumColdRegionsFound, "Number of cold regions found.");
STATISTIC(NumColdRegionsOutlined, "Number of cold regions outlined.");
usingnamespacellvm;
static cl::opt<bool> EnableStaticAnalysis("hot-cold-static-analysis",
cl::init(true), cl::Hidden);
static cl::opt<int>
SplittingThreshold("hotcoldsplit-threshold", cl::init(2), cl::Hidden,
cl::desc("Base penalty for splitting cold code (as a "
"multiple of TCC_Basic)"));
static cl::opt<bool> EnableColdSection(
"enable-cold-section", cl::init(false), cl::Hidden,
cl::desc("Enable placement of extracted cold functions"
" into a separate section after hot-cold splitting."));
static cl::opt<std::string>
ColdSectionName("hotcoldsplit-cold-section-name", cl::init("__llvm_cold"),
cl::Hidden,
cl::desc("Name for the section containing cold functions "
"extracted by hot-cold splitting."));
static cl::opt<int> MaxParametersForSplit(
"hotcoldsplit-max-params", cl::init(4), cl::Hidden,
cl::desc("Maximum number of parameters for a split function"));
static cl::opt<int> ColdBranchProbDenom(
"hotcoldsplit-cold-probability-denom", cl::init(100), cl::Hidden,
cl::desc("Divisor of cold branch probability."
"BranchProbability = 1/ColdBranchProbDenom"));
namespace {
bool blockEndsInUnreachable(const BasicBlock &BB) { … }
void analyzeProfMetadata(BasicBlock *BB,
BranchProbability ColdProbThresh,
SmallPtrSetImpl<BasicBlock *> &AnnotatedColdBlocks) { … }
bool unlikelyExecuted(BasicBlock &BB) { … }
static bool mayExtractBlock(const BasicBlock &BB) { … }
static bool markFunctionCold(Function &F, bool UpdateEntryCount = false) { … }
}
bool HotColdSplitting::isFunctionCold(const Function &F) const { … }
bool HotColdSplitting::isBasicBlockCold(
BasicBlock *BB, BranchProbability ColdProbThresh,
SmallPtrSetImpl<BasicBlock *> &AnnotatedColdBlocks,
BlockFrequencyInfo *BFI) const { … }
bool HotColdSplitting::shouldOutlineFrom(const Function &F) const { … }
static InstructionCost getOutliningBenefit(ArrayRef<BasicBlock *> Region,
TargetTransformInfo &TTI) { … }
static int getOutliningPenalty(ArrayRef<BasicBlock *> Region,
unsigned NumInputs, unsigned NumOutputs) { … }
bool HotColdSplitting::isSplittingBeneficial(CodeExtractor &CE,
const BlockSequence &Region,
TargetTransformInfo &TTI) { … }
Function *HotColdSplitting::extractColdRegion(
BasicBlock &EntryPoint, CodeExtractor &CE,
const CodeExtractorAnalysisCache &CEAC, BlockFrequencyInfo *BFI,
TargetTransformInfo &TTI, OptimizationRemarkEmitter &ORE) { … }
BlockTy;
namespace {
class OutliningRegion { … };
}
bool HotColdSplitting::outlineColdRegions(Function &F, bool HasProfileSummary) { … }
bool HotColdSplitting::run(Module &M) { … }
PreservedAnalyses
HotColdSplittingPass::run(Module &M, ModuleAnalysisManager &AM) { … }