blob: ce8a5060a3a1201d974b7b4108d4fcbcc575772d [file] [log] [blame]
Aditya Kumar801394a2018-09-07 15:03:49 +00001//===- HotColdSplitting.cpp -- Outline Cold Regions -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Outline cold regions to a separate function.
11// TODO: Update BFI and BPI
12// TODO: Add all the outlined functions to a separate section.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/Statistic.h"
18#include "llvm/Analysis/AliasAnalysis.h"
19#include "llvm/Analysis/BlockFrequencyInfo.h"
20#include "llvm/Analysis/BranchProbabilityInfo.h"
21#include "llvm/Analysis/CFG.h"
22#include "llvm/Analysis/OptimizationRemarkEmitter.h"
23#include "llvm/Analysis/PostDominators.h"
24#include "llvm/Analysis/ProfileSummaryInfo.h"
Sebastian Popa1f20fc2018-09-10 15:08:02 +000025#include "llvm/Analysis/TargetTransformInfo.h"
Aditya Kumar801394a2018-09-07 15:03:49 +000026#include "llvm/IR/BasicBlock.h"
27#include "llvm/IR/CFG.h"
28#include "llvm/IR/DataLayout.h"
29#include "llvm/IR/DiagnosticInfo.h"
30#include "llvm/IR/Dominators.h"
31#include "llvm/IR/Function.h"
32#include "llvm/IR/Instruction.h"
33#include "llvm/IR/Instructions.h"
Vedant Kumardd4be532018-10-29 19:15:39 +000034#include "llvm/IR/IntrinsicInst.h"
Aditya Kumar801394a2018-09-07 15:03:49 +000035#include "llvm/IR/Metadata.h"
36#include "llvm/IR/Module.h"
37#include "llvm/IR/PassManager.h"
38#include "llvm/IR/Type.h"
39#include "llvm/IR/Use.h"
40#include "llvm/IR/User.h"
41#include "llvm/IR/Value.h"
42#include "llvm/Pass.h"
43#include "llvm/Support/BlockFrequency.h"
44#include "llvm/Support/BranchProbability.h"
45#include "llvm/Support/Debug.h"
46#include "llvm/Support/raw_ostream.h"
47#include "llvm/Transforms/IPO.h"
Aditya Kumar9e20ade2018-10-03 05:55:20 +000048#include "llvm/Transforms/IPO/HotColdSplitting.h"
Aditya Kumar801394a2018-09-07 15:03:49 +000049#include "llvm/Transforms/Scalar.h"
50#include "llvm/Transforms/Utils/BasicBlockUtils.h"
51#include "llvm/Transforms/Utils/Cloning.h"
52#include "llvm/Transforms/Utils/CodeExtractor.h"
53#include "llvm/Transforms/Utils/Local.h"
54#include "llvm/Transforms/Utils/SSAUpdater.h"
55#include "llvm/Transforms/Utils/ValueMapper.h"
56#include <algorithm>
57#include <cassert>
58
59#define DEBUG_TYPE "hotcoldsplit"
60
Vedant Kumarc2990062018-10-24 22:15:41 +000061STATISTIC(NumColdRegionsFound, "Number of cold regions found.");
62STATISTIC(NumColdRegionsOutlined, "Number of cold regions outlined.");
Aditya Kumar801394a2018-09-07 15:03:49 +000063
64using namespace llvm;
65
66static cl::opt<bool> EnableStaticAnalyis("hot-cold-static-analysis",
67 cl::init(true), cl::Hidden);
68
Vedant Kumardd4be532018-10-29 19:15:39 +000069static cl::opt<unsigned> MinOutliningInstCount(
70 "min-outlining-inst-count", cl::init(3), cl::Hidden,
71 cl::desc("Minimum number of instructions needed for a single-block region "
72 "to be an outlining candidate"));
Aditya Kumar801394a2018-09-07 15:03:49 +000073
74namespace {
75
76struct PostDomTree : PostDomTreeBase<BasicBlock> {
77 PostDomTree(Function &F) { recalculate(F); }
78};
79
Vedant Kumarc2990062018-10-24 22:15:41 +000080/// A sequence of basic blocks.
81///
82/// A 0-sized SmallVector is slightly cheaper to move than a std::vector.
83using BlockSequence = SmallVector<BasicBlock *, 0>;
Aditya Kumar801394a2018-09-07 15:03:49 +000084
Sebastian Pop542e5222018-10-15 21:43:11 +000085// Same as blockEndsInUnreachable in CodeGen/BranchFolding.cpp. Do not modify
86// this function unless you modify the MBB version as well.
87//
88/// A no successor, non-return block probably ends in unreachable and is cold.
89/// Also consider a block that ends in an indirect branch to be a return block,
90/// since many targets use plain indirect branches to return.
Aditya Kumar801394a2018-09-07 15:03:49 +000091bool blockEndsInUnreachable(const BasicBlock &BB) {
Sebastian Pop542e5222018-10-15 21:43:11 +000092 if (!succ_empty(&BB))
93 return false;
Aditya Kumar801394a2018-09-07 15:03:49 +000094 if (BB.empty())
95 return true;
Chandler Carruthedb12a82018-10-15 10:04:59 +000096 const Instruction *I = BB.getTerminator();
Sebastian Pop542e5222018-10-15 21:43:11 +000097 return !(isa<ReturnInst>(I) || isa<IndirectBrInst>(I));
Aditya Kumar801394a2018-09-07 15:03:49 +000098}
99
Aditya Kumara27014b2018-10-03 06:21:05 +0000100static bool exceptionHandlingFunctions(const CallInst *CI) {
101 auto F = CI->getCalledFunction();
102 if (!F)
103 return false;
104 auto FName = F->getName();
105 return FName == "__cxa_begin_catch" ||
106 FName == "__cxa_free_exception" ||
107 FName == "__cxa_allocate_exception" ||
108 FName == "__cxa_begin_catch" ||
109 FName == "__cxa_end_catch";
110}
111
Sebastian Pop542e5222018-10-15 21:43:11 +0000112static bool unlikelyExecuted(const BasicBlock &BB) {
Aditya Kumar801394a2018-09-07 15:03:49 +0000113 if (blockEndsInUnreachable(BB))
114 return true;
115 // Exception handling blocks are unlikely executed.
116 if (BB.isEHPad())
117 return true;
118 for (const Instruction &I : BB)
119 if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
120 // The block is cold if it calls functions tagged as cold or noreturn.
121 if (CI->hasFnAttr(Attribute::Cold) ||
Aditya Kumara27014b2018-10-03 06:21:05 +0000122 CI->hasFnAttr(Attribute::NoReturn) ||
123 exceptionHandlingFunctions(CI))
Aditya Kumar801394a2018-09-07 15:03:49 +0000124 return true;
125
126 // Assume that inline assembly is hot code.
127 if (isa<InlineAsm>(CI->getCalledValue()))
128 return false;
129 }
130 return false;
131}
132
Vedant Kumarc2990062018-10-24 22:15:41 +0000133/// Check whether it's safe to outline \p BB.
134static bool mayExtractBlock(const BasicBlock &BB) {
135 return !BB.hasAddressTaken();
Sebastian Pop542e5222018-10-15 21:43:11 +0000136}
137
Vedant Kumardd4be532018-10-29 19:15:39 +0000138/// Check whether \p BB has at least \p Min non-debug, non-terminator
139/// instructions.
140static bool hasMinimumInstCount(const BasicBlock &BB, unsigned Min) {
141 unsigned Count = 0;
142 for (const Instruction &I : BB) {
143 if (isa<DbgInfoIntrinsic>(&I) || &I == BB.getTerminator())
144 continue;
145 if (++Count >= Min)
146 return true;
147 }
148 return false;
149}
150
Vedant Kumarc2990062018-10-24 22:15:41 +0000151/// Identify the maximal region of cold blocks which includes \p SinkBB.
152///
153/// Include all blocks post-dominated by \p SinkBB, \p SinkBB itself, and all
154/// blocks dominated by \p SinkBB. Exclude all other blocks, and blocks which
155/// cannot be outlined.
156///
157/// Return an empty sequence if the cold region is too small to outline, or if
158/// the cold region has no warm predecessors.
159static BlockSequence
160findMaximalColdRegion(BasicBlock &SinkBB, DominatorTree &DT, PostDomTree &PDT) {
161 // The maximal cold region.
162 BlockSequence ColdRegion = {};
Sebastian Pop12171602018-09-14 20:36:10 +0000163
Vedant Kumarc2990062018-10-24 22:15:41 +0000164 // The ancestor farthest-away from SinkBB, and also post-dominated by it.
165 BasicBlock *MaxAncestor = &SinkBB;
166 unsigned MaxAncestorHeight = 0;
167
168 // Visit SinkBB's ancestors using inverse DFS.
169 auto PredIt = ++idf_begin(&SinkBB);
170 auto PredEnd = idf_end(&SinkBB);
171 while (PredIt != PredEnd) {
172 BasicBlock &PredBB = **PredIt;
173 bool SinkPostDom = PDT.dominates(&SinkBB, &PredBB);
174
175 // If SinkBB does not post-dominate a predecessor, do not mark the
176 // predecessor (or any of its predecessors) cold.
177 if (!SinkPostDom || !mayExtractBlock(PredBB)) {
178 PredIt.skipChildren();
179 continue;
Sebastian Pop542e5222018-10-15 21:43:11 +0000180 }
Sebastian Pop12171602018-09-14 20:36:10 +0000181
Vedant Kumarc2990062018-10-24 22:15:41 +0000182 // Keep track of the post-dominated ancestor farthest away from the sink.
183 unsigned AncestorHeight = PredIt.getPathLength();
184 if (AncestorHeight > MaxAncestorHeight) {
185 MaxAncestor = &PredBB;
186 MaxAncestorHeight = AncestorHeight;
Aditya Kumar801394a2018-09-07 15:03:49 +0000187 }
Vedant Kumarc2990062018-10-24 22:15:41 +0000188
189 ColdRegion.push_back(&PredBB);
190 ++PredIt;
Aditya Kumar801394a2018-09-07 15:03:49 +0000191 }
192
Vedant Kumarc2990062018-10-24 22:15:41 +0000193 // CodeExtractor requires that all blocks to be extracted must be dominated
194 // by the first block to be extracted.
195 //
196 // To avoid spurious or repeated outlining, require that the max ancestor
197 // has a predecessor. By construction this predecessor is not in the cold
198 // region, i.e. its existence implies we don't outline the whole function.
199 //
200 // TODO: If MaxAncestor has no predecessors, we may be able to outline the
201 // second largest cold region that has a predecessor.
202 if (pred_empty(MaxAncestor) ||
203 MaxAncestor->getSinglePredecessor() == MaxAncestor)
204 return {};
Sebastian Pop12171602018-09-14 20:36:10 +0000205
Vedant Kumarc2990062018-10-24 22:15:41 +0000206 // Filter out predecessors not dominated by the max ancestor.
207 //
208 // TODO: Blocks not dominated by the max ancestor could be extracted as
209 // other cold regions. Marking outlined calls as noreturn when appropriate
210 // and outlining more than once per function could achieve most of the win.
211 auto EraseIt = remove_if(ColdRegion, [&](BasicBlock *PredBB) {
212 return PredBB != MaxAncestor && !DT.dominates(MaxAncestor, PredBB);
213 });
214 ColdRegion.erase(EraseIt, ColdRegion.end());
Sebastian Pop12171602018-09-14 20:36:10 +0000215
Vedant Kumarc2990062018-10-24 22:15:41 +0000216 // Add SinkBB to the cold region.
217 ColdRegion.push_back(&SinkBB);
218
219 // Ensure that the first extracted block is the max ancestor.
220 if (ColdRegion[0] != MaxAncestor) {
221 auto AncestorIt = find(ColdRegion, MaxAncestor);
222 *AncestorIt = ColdRegion[0];
223 ColdRegion[0] = MaxAncestor;
Sebastian Pop12171602018-09-14 20:36:10 +0000224 }
225
Vedant Kumarc2990062018-10-24 22:15:41 +0000226 // Find all successors of SinkBB dominated by SinkBB using DFS.
227 auto SuccIt = ++df_begin(&SinkBB);
228 auto SuccEnd = df_end(&SinkBB);
229 while (SuccIt != SuccEnd) {
230 BasicBlock &SuccBB = **SuccIt;
231 bool SinkDom = DT.dominates(&SinkBB, &SuccBB);
232
233 // If SinkBB does not dominate a successor, do not mark the successor (or
234 // any of its successors) cold.
235 if (!SinkDom || !mayExtractBlock(SuccBB)) {
236 SuccIt.skipChildren();
237 continue;
238 }
239
240 ColdRegion.push_back(&SuccBB);
241 ++SuccIt;
242 }
243
Vedant Kumardd4be532018-10-29 19:15:39 +0000244 if (ColdRegion.size() == 1 &&
245 !hasMinimumInstCount(*ColdRegion[0], MinOutliningInstCount))
Vedant Kumarc2990062018-10-24 22:15:41 +0000246 return {};
247
248 return ColdRegion;
249}
250
251/// Get the largest cold region in \p F.
252static BlockSequence getLargestColdRegion(Function &F, ProfileSummaryInfo &PSI,
253 BlockFrequencyInfo *BFI,
254 DominatorTree &DT, PostDomTree &PDT) {
255 // Keep track of the largest cold region.
256 BlockSequence LargestColdRegion = {};
257
258 for (BasicBlock &BB : F) {
259 // Identify cold blocks.
260 if (!mayExtractBlock(BB))
261 continue;
262 bool Cold =
263 PSI.isColdBB(&BB, BFI) || (EnableStaticAnalyis && unlikelyExecuted(BB));
264 if (!Cold)
Sebastian Pop12171602018-09-14 20:36:10 +0000265 continue;
266
Vedant Kumarc2990062018-10-24 22:15:41 +0000267 LLVM_DEBUG({
268 dbgs() << "Found cold block:\n";
269 BB.dump();
270 });
271
272 // Find a maximal cold region we can outline.
273 BlockSequence ColdRegion = findMaximalColdRegion(BB, DT, PDT);
274 if (ColdRegion.empty()) {
275 LLVM_DEBUG(dbgs() << " Skipping (block not profitable to extract)\n");
Sebastian Pop542e5222018-10-15 21:43:11 +0000276 continue;
Sebastian Pop12171602018-09-14 20:36:10 +0000277 }
Vedant Kumarc2990062018-10-24 22:15:41 +0000278
279 ++NumColdRegionsFound;
280
281 LLVM_DEBUG({
282 llvm::dbgs() << "Identified cold region with " << ColdRegion.size()
283 << " blocks:\n";
284 for (BasicBlock *BB : ColdRegion)
285 BB->dump();
286 });
287
288 // TODO: Outline more than one region.
289 if (ColdRegion.size() > LargestColdRegion.size())
290 LargestColdRegion = std::move(ColdRegion);
Sebastian Pop12171602018-09-14 20:36:10 +0000291 }
292
Vedant Kumarc2990062018-10-24 22:15:41 +0000293 return LargestColdRegion;
Aditya Kumar801394a2018-09-07 15:03:49 +0000294}
295
296class HotColdSplitting {
297public:
298 HotColdSplitting(ProfileSummaryInfo *ProfSI,
299 function_ref<BlockFrequencyInfo *(Function &)> GBFI,
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000300 function_ref<TargetTransformInfo &(Function &)> GTTI,
Aditya Kumar801394a2018-09-07 15:03:49 +0000301 std::function<OptimizationRemarkEmitter &(Function &)> *GORE)
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000302 : PSI(ProfSI), GetBFI(GBFI), GetTTI(GTTI), GetORE(GORE) {}
Aditya Kumar801394a2018-09-07 15:03:49 +0000303 bool run(Module &M);
304
305private:
306 bool shouldOutlineFrom(const Function &F) const;
Vedant Kumarc2990062018-10-24 22:15:41 +0000307 Function *extractColdRegion(const BlockSequence &Region, DominatorTree &DT,
308 BlockFrequencyInfo *BFI,
Teresa Johnsonc8dba682018-10-24 18:53:47 +0000309 OptimizationRemarkEmitter &ORE, unsigned Count);
Aditya Kumar801394a2018-09-07 15:03:49 +0000310 SmallPtrSet<const Function *, 2> OutlinedFunctions;
311 ProfileSummaryInfo *PSI;
312 function_ref<BlockFrequencyInfo *(Function &)> GetBFI;
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000313 function_ref<TargetTransformInfo &(Function &)> GetTTI;
Aditya Kumar801394a2018-09-07 15:03:49 +0000314 std::function<OptimizationRemarkEmitter &(Function &)> *GetORE;
315};
316
317class HotColdSplittingLegacyPass : public ModulePass {
318public:
319 static char ID;
320 HotColdSplittingLegacyPass() : ModulePass(ID) {
321 initializeHotColdSplittingLegacyPassPass(*PassRegistry::getPassRegistry());
322 }
323
324 void getAnalysisUsage(AnalysisUsage &AU) const override {
325 AU.addRequired<AssumptionCacheTracker>();
326 AU.addRequired<BlockFrequencyInfoWrapperPass>();
327 AU.addRequired<ProfileSummaryInfoWrapperPass>();
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000328 AU.addRequired<TargetTransformInfoWrapperPass>();
Aditya Kumar801394a2018-09-07 15:03:49 +0000329 }
330
331 bool runOnModule(Module &M) override;
332};
333
334} // end anonymous namespace
335
336// Returns false if the function should not be considered for hot-cold split
Sebastian Pop0f30f082018-09-14 20:36:19 +0000337// optimization.
Aditya Kumar801394a2018-09-07 15:03:49 +0000338bool HotColdSplitting::shouldOutlineFrom(const Function &F) const {
Sebastian Pop0f30f082018-09-14 20:36:19 +0000339 // Do not try to outline again from an already outlined cold function.
340 if (OutlinedFunctions.count(&F))
341 return false;
342
Aditya Kumar801394a2018-09-07 15:03:49 +0000343 if (F.size() <= 2)
344 return false;
345
Vedant Kumarc2990062018-10-24 22:15:41 +0000346 // TODO: Consider only skipping functions marked `optnone` or `cold`.
347
Aditya Kumar801394a2018-09-07 15:03:49 +0000348 if (F.hasAddressTaken())
349 return false;
350
351 if (F.hasFnAttribute(Attribute::AlwaysInline))
352 return false;
353
354 if (F.hasFnAttribute(Attribute::NoInline))
355 return false;
356
357 if (F.getCallingConv() == CallingConv::Cold)
358 return false;
359
360 if (PSI->isFunctionEntryCold(&F))
361 return false;
362 return true;
363}
364
Vedant Kumarc2990062018-10-24 22:15:41 +0000365Function *HotColdSplitting::extractColdRegion(const BlockSequence &Region,
366 DominatorTree &DT,
367 BlockFrequencyInfo *BFI,
368 OptimizationRemarkEmitter &ORE,
369 unsigned Count) {
Teresa Johnsonf431a2f2018-10-22 19:06:42 +0000370 assert(!Region.empty());
Aditya Kumar801394a2018-09-07 15:03:49 +0000371 LLVM_DEBUG(for (auto *BB : Region)
372 llvm::dbgs() << "\nExtracting: " << *BB;);
Sebastian Pop12171602018-09-14 20:36:10 +0000373
Aditya Kumar801394a2018-09-07 15:03:49 +0000374 // TODO: Pass BFI and BPI to update profile information.
Vedant Kumarc2990062018-10-24 22:15:41 +0000375 CodeExtractor CE(Region, &DT, /* AggregateArgs */ false, /* BFI */ nullptr,
Teresa Johnsonc8dba682018-10-24 18:53:47 +0000376 /* BPI */ nullptr, /* AllowVarArgs */ false,
377 /* AllowAlloca */ false,
378 /* Suffix */ "cold." + std::to_string(Count));
Aditya Kumar801394a2018-09-07 15:03:49 +0000379
380 SetVector<Value *> Inputs, Outputs, Sinks;
381 CE.findInputsOutputs(Inputs, Outputs, Sinks);
382
383 // Do not extract regions that have live exit variables.
Vedant Kumarc2990062018-10-24 22:15:41 +0000384 if (Outputs.size() > 0) {
385 LLVM_DEBUG(llvm::dbgs() << "Not outlining; live outputs\n");
Aditya Kumar801394a2018-09-07 15:03:49 +0000386 return nullptr;
Vedant Kumarc2990062018-10-24 22:15:41 +0000387 }
Aditya Kumar801394a2018-09-07 15:03:49 +0000388
Vedant Kumarc2990062018-10-24 22:15:41 +0000389 // TODO: Run MergeBasicBlockIntoOnlyPred on the outlined function.
Teresa Johnsonf431a2f2018-10-22 19:06:42 +0000390 Function *OrigF = Region[0]->getParent();
Aditya Kumar801394a2018-09-07 15:03:49 +0000391 if (Function *OutF = CE.extractCodeRegion()) {
392 User *U = *OutF->user_begin();
393 CallInst *CI = cast<CallInst>(U);
394 CallSite CS(CI);
Vedant Kumarc2990062018-10-24 22:15:41 +0000395 NumColdRegionsOutlined++;
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000396 if (GetTTI(*OutF).useColdCCForColdCall(*OutF)) {
397 OutF->setCallingConv(CallingConv::Cold);
398 CS.setCallingConv(CallingConv::Cold);
399 }
Aditya Kumar801394a2018-09-07 15:03:49 +0000400 CI->setIsNoInline();
Vedant Kumar50315462018-10-23 19:41:12 +0000401
402 // Try to make the outlined code as small as possible on the assumption
403 // that it's cold.
404 assert(!OutF->hasFnAttribute(Attribute::OptimizeNone) &&
405 "An outlined function should never be marked optnone");
406 OutF->addFnAttr(Attribute::MinSize);
407
Sebastian Pop0f30f082018-09-14 20:36:19 +0000408 LLVM_DEBUG(llvm::dbgs() << "Outlined Region: " << *OutF);
Teresa Johnsonf431a2f2018-10-22 19:06:42 +0000409 ORE.emit([&]() {
410 return OptimizationRemark(DEBUG_TYPE, "HotColdSplit",
411 &*Region[0]->begin())
412 << ore::NV("Original", OrigF) << " split cold code into "
413 << ore::NV("Split", OutF);
414 });
Aditya Kumar801394a2018-09-07 15:03:49 +0000415 return OutF;
416 }
417
418 ORE.emit([&]() {
419 return OptimizationRemarkMissed(DEBUG_TYPE, "ExtractFailed",
420 &*Region[0]->begin())
421 << "Failed to extract region at block "
422 << ore::NV("Block", Region.front());
423 });
424 return nullptr;
425}
426
Aditya Kumar801394a2018-09-07 15:03:49 +0000427bool HotColdSplitting::run(Module &M) {
Vedant Kumarc2990062018-10-24 22:15:41 +0000428 bool Changed = false;
Aditya Kumar801394a2018-09-07 15:03:49 +0000429 for (auto &F : M) {
Vedant Kumarc2990062018-10-24 22:15:41 +0000430 if (!shouldOutlineFrom(F)) {
431 LLVM_DEBUG(llvm::dbgs() << "Not outlining in " << F.getName() << "\n");
Aditya Kumar801394a2018-09-07 15:03:49 +0000432 continue;
Vedant Kumarc2990062018-10-24 22:15:41 +0000433 }
434
435 LLVM_DEBUG(llvm::dbgs() << "Outlining in " << F.getName() << "\n");
Aditya Kumar801394a2018-09-07 15:03:49 +0000436 DominatorTree DT(F);
437 PostDomTree PDT(F);
438 PDT.recalculate(F);
Vedant Kumarc2990062018-10-24 22:15:41 +0000439 BlockFrequencyInfo *BFI = GetBFI(F);
Aditya Kumar801394a2018-09-07 15:03:49 +0000440
Vedant Kumarc2990062018-10-24 22:15:41 +0000441 BlockSequence ColdRegion = getLargestColdRegion(F, *PSI, BFI, DT, PDT);
442 if (ColdRegion.empty())
443 continue;
444
445 OptimizationRemarkEmitter &ORE = (*GetORE)(F);
446 Function *Outlined =
447 extractColdRegion(ColdRegion, DT, BFI, ORE, /*Count=*/1);
448 if (Outlined) {
Aditya Kumar801394a2018-09-07 15:03:49 +0000449 OutlinedFunctions.insert(Outlined);
Vedant Kumarc2990062018-10-24 22:15:41 +0000450 Changed = true;
451 }
Aditya Kumar801394a2018-09-07 15:03:49 +0000452 }
Vedant Kumarc2990062018-10-24 22:15:41 +0000453 return Changed;
Aditya Kumar801394a2018-09-07 15:03:49 +0000454}
455
456bool HotColdSplittingLegacyPass::runOnModule(Module &M) {
457 if (skipModule(M))
458 return false;
459 ProfileSummaryInfo *PSI =
460 getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000461 auto GTTI = [this](Function &F) -> TargetTransformInfo & {
462 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
463 };
Aditya Kumar801394a2018-09-07 15:03:49 +0000464 auto GBFI = [this](Function &F) {
465 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
466 };
467 std::unique_ptr<OptimizationRemarkEmitter> ORE;
468 std::function<OptimizationRemarkEmitter &(Function &)> GetORE =
469 [&ORE](Function &F) -> OptimizationRemarkEmitter & {
470 ORE.reset(new OptimizationRemarkEmitter(&F));
471 return *ORE.get();
472 };
473
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000474 return HotColdSplitting(PSI, GBFI, GTTI, &GetORE).run(M);
Aditya Kumar801394a2018-09-07 15:03:49 +0000475}
476
Aditya Kumar9e20ade2018-10-03 05:55:20 +0000477PreservedAnalyses
478HotColdSplittingPass::run(Module &M, ModuleAnalysisManager &AM) {
479 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
480
481 std::function<AssumptionCache &(Function &)> GetAssumptionCache =
482 [&FAM](Function &F) -> AssumptionCache & {
483 return FAM.getResult<AssumptionAnalysis>(F);
484 };
485
486 auto GBFI = [&FAM](Function &F) {
487 return &FAM.getResult<BlockFrequencyAnalysis>(F);
488 };
489
490 std::function<TargetTransformInfo &(Function &)> GTTI =
491 [&FAM](Function &F) -> TargetTransformInfo & {
492 return FAM.getResult<TargetIRAnalysis>(F);
493 };
494
495 std::unique_ptr<OptimizationRemarkEmitter> ORE;
496 std::function<OptimizationRemarkEmitter &(Function &)> GetORE =
497 [&ORE](Function &F) -> OptimizationRemarkEmitter & {
498 ORE.reset(new OptimizationRemarkEmitter(&F));
499 return *ORE.get();
500 };
501
502 ProfileSummaryInfo *PSI = &AM.getResult<ProfileSummaryAnalysis>(M);
503
504 if (HotColdSplitting(PSI, GBFI, GTTI, &GetORE).run(M))
505 return PreservedAnalyses::none();
506 return PreservedAnalyses::all();
507}
508
Aditya Kumar801394a2018-09-07 15:03:49 +0000509char HotColdSplittingLegacyPass::ID = 0;
510INITIALIZE_PASS_BEGIN(HotColdSplittingLegacyPass, "hotcoldsplit",
511 "Hot Cold Splitting", false, false)
512INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
513INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
514INITIALIZE_PASS_END(HotColdSplittingLegacyPass, "hotcoldsplit",
515 "Hot Cold Splitting", false, false)
516
517ModulePass *llvm::createHotColdSplittingPass() {
518 return new HotColdSplittingLegacyPass();
519}