blob: 4f371a494e99d4d9c5969819416b0a4259e3de7e [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"
34#include "llvm/IR/Metadata.h"
35#include "llvm/IR/Module.h"
36#include "llvm/IR/PassManager.h"
37#include "llvm/IR/Type.h"
38#include "llvm/IR/Use.h"
39#include "llvm/IR/User.h"
40#include "llvm/IR/Value.h"
41#include "llvm/Pass.h"
42#include "llvm/Support/BlockFrequency.h"
43#include "llvm/Support/BranchProbability.h"
44#include "llvm/Support/Debug.h"
45#include "llvm/Support/raw_ostream.h"
46#include "llvm/Transforms/IPO.h"
Aditya Kumar9e20ade2018-10-03 05:55:20 +000047#include "llvm/Transforms/IPO/HotColdSplitting.h"
Aditya Kumar801394a2018-09-07 15:03:49 +000048#include "llvm/Transforms/Scalar.h"
49#include "llvm/Transforms/Utils/BasicBlockUtils.h"
50#include "llvm/Transforms/Utils/Cloning.h"
51#include "llvm/Transforms/Utils/CodeExtractor.h"
52#include "llvm/Transforms/Utils/Local.h"
53#include "llvm/Transforms/Utils/SSAUpdater.h"
54#include "llvm/Transforms/Utils/ValueMapper.h"
55#include <algorithm>
56#include <cassert>
57
58#define DEBUG_TYPE "hotcoldsplit"
59
Vedant Kumarc2990062018-10-24 22:15:41 +000060STATISTIC(NumColdRegionsFound, "Number of cold regions found.");
61STATISTIC(NumColdRegionsOutlined, "Number of cold regions outlined.");
Aditya Kumar801394a2018-09-07 15:03:49 +000062
63using namespace llvm;
64
65static cl::opt<bool> EnableStaticAnalyis("hot-cold-static-analysis",
66 cl::init(true), cl::Hidden);
67
68
69namespace {
70
71struct PostDomTree : PostDomTreeBase<BasicBlock> {
72 PostDomTree(Function &F) { recalculate(F); }
73};
74
Vedant Kumarc2990062018-10-24 22:15:41 +000075/// A sequence of basic blocks.
76///
77/// A 0-sized SmallVector is slightly cheaper to move than a std::vector.
78using BlockSequence = SmallVector<BasicBlock *, 0>;
Aditya Kumar801394a2018-09-07 15:03:49 +000079
Sebastian Pop542e5222018-10-15 21:43:11 +000080// Same as blockEndsInUnreachable in CodeGen/BranchFolding.cpp. Do not modify
81// this function unless you modify the MBB version as well.
82//
83/// A no successor, non-return block probably ends in unreachable and is cold.
84/// Also consider a block that ends in an indirect branch to be a return block,
85/// since many targets use plain indirect branches to return.
Aditya Kumar801394a2018-09-07 15:03:49 +000086bool blockEndsInUnreachable(const BasicBlock &BB) {
Sebastian Pop542e5222018-10-15 21:43:11 +000087 if (!succ_empty(&BB))
88 return false;
Aditya Kumar801394a2018-09-07 15:03:49 +000089 if (BB.empty())
90 return true;
Chandler Carruthedb12a82018-10-15 10:04:59 +000091 const Instruction *I = BB.getTerminator();
Sebastian Pop542e5222018-10-15 21:43:11 +000092 return !(isa<ReturnInst>(I) || isa<IndirectBrInst>(I));
Aditya Kumar801394a2018-09-07 15:03:49 +000093}
94
Aditya Kumara27014b2018-10-03 06:21:05 +000095static bool exceptionHandlingFunctions(const CallInst *CI) {
96 auto F = CI->getCalledFunction();
97 if (!F)
98 return false;
99 auto FName = F->getName();
100 return FName == "__cxa_begin_catch" ||
101 FName == "__cxa_free_exception" ||
102 FName == "__cxa_allocate_exception" ||
103 FName == "__cxa_begin_catch" ||
104 FName == "__cxa_end_catch";
105}
106
Sebastian Pop542e5222018-10-15 21:43:11 +0000107static bool unlikelyExecuted(const BasicBlock &BB) {
Aditya Kumar801394a2018-09-07 15:03:49 +0000108 if (blockEndsInUnreachable(BB))
109 return true;
110 // Exception handling blocks are unlikely executed.
111 if (BB.isEHPad())
112 return true;
113 for (const Instruction &I : BB)
114 if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
115 // The block is cold if it calls functions tagged as cold or noreturn.
116 if (CI->hasFnAttr(Attribute::Cold) ||
Aditya Kumara27014b2018-10-03 06:21:05 +0000117 CI->hasFnAttr(Attribute::NoReturn) ||
118 exceptionHandlingFunctions(CI))
Aditya Kumar801394a2018-09-07 15:03:49 +0000119 return true;
120
121 // Assume that inline assembly is hot code.
122 if (isa<InlineAsm>(CI->getCalledValue()))
123 return false;
124 }
125 return false;
126}
127
Vedant Kumarc2990062018-10-24 22:15:41 +0000128/// Check whether it's safe to outline \p BB.
129static bool mayExtractBlock(const BasicBlock &BB) {
130 return !BB.hasAddressTaken();
Sebastian Pop542e5222018-10-15 21:43:11 +0000131}
132
Vedant Kumarc2990062018-10-24 22:15:41 +0000133/// Identify the maximal region of cold blocks which includes \p SinkBB.
134///
135/// Include all blocks post-dominated by \p SinkBB, \p SinkBB itself, and all
136/// blocks dominated by \p SinkBB. Exclude all other blocks, and blocks which
137/// cannot be outlined.
138///
139/// Return an empty sequence if the cold region is too small to outline, or if
140/// the cold region has no warm predecessors.
141static BlockSequence
142findMaximalColdRegion(BasicBlock &SinkBB, DominatorTree &DT, PostDomTree &PDT) {
143 // The maximal cold region.
144 BlockSequence ColdRegion = {};
Sebastian Pop12171602018-09-14 20:36:10 +0000145
Vedant Kumarc2990062018-10-24 22:15:41 +0000146 // The ancestor farthest-away from SinkBB, and also post-dominated by it.
147 BasicBlock *MaxAncestor = &SinkBB;
148 unsigned MaxAncestorHeight = 0;
149
150 // Visit SinkBB's ancestors using inverse DFS.
151 auto PredIt = ++idf_begin(&SinkBB);
152 auto PredEnd = idf_end(&SinkBB);
153 while (PredIt != PredEnd) {
154 BasicBlock &PredBB = **PredIt;
155 bool SinkPostDom = PDT.dominates(&SinkBB, &PredBB);
156
157 // If SinkBB does not post-dominate a predecessor, do not mark the
158 // predecessor (or any of its predecessors) cold.
159 if (!SinkPostDom || !mayExtractBlock(PredBB)) {
160 PredIt.skipChildren();
161 continue;
Sebastian Pop542e5222018-10-15 21:43:11 +0000162 }
Sebastian Pop12171602018-09-14 20:36:10 +0000163
Vedant Kumarc2990062018-10-24 22:15:41 +0000164 // Keep track of the post-dominated ancestor farthest away from the sink.
165 unsigned AncestorHeight = PredIt.getPathLength();
166 if (AncestorHeight > MaxAncestorHeight) {
167 MaxAncestor = &PredBB;
168 MaxAncestorHeight = AncestorHeight;
Aditya Kumar801394a2018-09-07 15:03:49 +0000169 }
Vedant Kumarc2990062018-10-24 22:15:41 +0000170
171 ColdRegion.push_back(&PredBB);
172 ++PredIt;
Aditya Kumar801394a2018-09-07 15:03:49 +0000173 }
174
Vedant Kumarc2990062018-10-24 22:15:41 +0000175 // CodeExtractor requires that all blocks to be extracted must be dominated
176 // by the first block to be extracted.
177 //
178 // To avoid spurious or repeated outlining, require that the max ancestor
179 // has a predecessor. By construction this predecessor is not in the cold
180 // region, i.e. its existence implies we don't outline the whole function.
181 //
182 // TODO: If MaxAncestor has no predecessors, we may be able to outline the
183 // second largest cold region that has a predecessor.
184 if (pred_empty(MaxAncestor) ||
185 MaxAncestor->getSinglePredecessor() == MaxAncestor)
186 return {};
Sebastian Pop12171602018-09-14 20:36:10 +0000187
Vedant Kumarc2990062018-10-24 22:15:41 +0000188 // Filter out predecessors not dominated by the max ancestor.
189 //
190 // TODO: Blocks not dominated by the max ancestor could be extracted as
191 // other cold regions. Marking outlined calls as noreturn when appropriate
192 // and outlining more than once per function could achieve most of the win.
193 auto EraseIt = remove_if(ColdRegion, [&](BasicBlock *PredBB) {
194 return PredBB != MaxAncestor && !DT.dominates(MaxAncestor, PredBB);
195 });
196 ColdRegion.erase(EraseIt, ColdRegion.end());
Sebastian Pop12171602018-09-14 20:36:10 +0000197
Vedant Kumarc2990062018-10-24 22:15:41 +0000198 // Add SinkBB to the cold region.
199 ColdRegion.push_back(&SinkBB);
200
201 // Ensure that the first extracted block is the max ancestor.
202 if (ColdRegion[0] != MaxAncestor) {
203 auto AncestorIt = find(ColdRegion, MaxAncestor);
204 *AncestorIt = ColdRegion[0];
205 ColdRegion[0] = MaxAncestor;
Sebastian Pop12171602018-09-14 20:36:10 +0000206 }
207
Vedant Kumarc2990062018-10-24 22:15:41 +0000208 // Find all successors of SinkBB dominated by SinkBB using DFS.
209 auto SuccIt = ++df_begin(&SinkBB);
210 auto SuccEnd = df_end(&SinkBB);
211 while (SuccIt != SuccEnd) {
212 BasicBlock &SuccBB = **SuccIt;
213 bool SinkDom = DT.dominates(&SinkBB, &SuccBB);
214
215 // If SinkBB does not dominate a successor, do not mark the successor (or
216 // any of its successors) cold.
217 if (!SinkDom || !mayExtractBlock(SuccBB)) {
218 SuccIt.skipChildren();
219 continue;
220 }
221
222 ColdRegion.push_back(&SuccBB);
223 ++SuccIt;
224 }
225
226 // TODO: Consider outlining regions with just 1 block, but more than some
227 // threshold of instructions.
228 if (ColdRegion.size() == 1)
229 return {};
230
231 return ColdRegion;
232}
233
234/// Get the largest cold region in \p F.
235static BlockSequence getLargestColdRegion(Function &F, ProfileSummaryInfo &PSI,
236 BlockFrequencyInfo *BFI,
237 DominatorTree &DT, PostDomTree &PDT) {
238 // Keep track of the largest cold region.
239 BlockSequence LargestColdRegion = {};
240
241 for (BasicBlock &BB : F) {
242 // Identify cold blocks.
243 if (!mayExtractBlock(BB))
244 continue;
245 bool Cold =
246 PSI.isColdBB(&BB, BFI) || (EnableStaticAnalyis && unlikelyExecuted(BB));
247 if (!Cold)
Sebastian Pop12171602018-09-14 20:36:10 +0000248 continue;
249
Vedant Kumarc2990062018-10-24 22:15:41 +0000250 LLVM_DEBUG({
251 dbgs() << "Found cold block:\n";
252 BB.dump();
253 });
254
255 // Find a maximal cold region we can outline.
256 BlockSequence ColdRegion = findMaximalColdRegion(BB, DT, PDT);
257 if (ColdRegion.empty()) {
258 LLVM_DEBUG(dbgs() << " Skipping (block not profitable to extract)\n");
Sebastian Pop542e5222018-10-15 21:43:11 +0000259 continue;
Sebastian Pop12171602018-09-14 20:36:10 +0000260 }
Vedant Kumarc2990062018-10-24 22:15:41 +0000261
262 ++NumColdRegionsFound;
263
264 LLVM_DEBUG({
265 llvm::dbgs() << "Identified cold region with " << ColdRegion.size()
266 << " blocks:\n";
267 for (BasicBlock *BB : ColdRegion)
268 BB->dump();
269 });
270
271 // TODO: Outline more than one region.
272 if (ColdRegion.size() > LargestColdRegion.size())
273 LargestColdRegion = std::move(ColdRegion);
Sebastian Pop12171602018-09-14 20:36:10 +0000274 }
275
Vedant Kumarc2990062018-10-24 22:15:41 +0000276 return LargestColdRegion;
Aditya Kumar801394a2018-09-07 15:03:49 +0000277}
278
279class HotColdSplitting {
280public:
281 HotColdSplitting(ProfileSummaryInfo *ProfSI,
282 function_ref<BlockFrequencyInfo *(Function &)> GBFI,
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000283 function_ref<TargetTransformInfo &(Function &)> GTTI,
Aditya Kumar801394a2018-09-07 15:03:49 +0000284 std::function<OptimizationRemarkEmitter &(Function &)> *GORE)
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000285 : PSI(ProfSI), GetBFI(GBFI), GetTTI(GTTI), GetORE(GORE) {}
Aditya Kumar801394a2018-09-07 15:03:49 +0000286 bool run(Module &M);
287
288private:
289 bool shouldOutlineFrom(const Function &F) const;
Vedant Kumarc2990062018-10-24 22:15:41 +0000290 Function *extractColdRegion(const BlockSequence &Region, DominatorTree &DT,
291 BlockFrequencyInfo *BFI,
Teresa Johnsonc8dba682018-10-24 18:53:47 +0000292 OptimizationRemarkEmitter &ORE, unsigned Count);
Aditya Kumar801394a2018-09-07 15:03:49 +0000293 SmallPtrSet<const Function *, 2> OutlinedFunctions;
294 ProfileSummaryInfo *PSI;
295 function_ref<BlockFrequencyInfo *(Function &)> GetBFI;
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000296 function_ref<TargetTransformInfo &(Function &)> GetTTI;
Aditya Kumar801394a2018-09-07 15:03:49 +0000297 std::function<OptimizationRemarkEmitter &(Function &)> *GetORE;
298};
299
300class HotColdSplittingLegacyPass : public ModulePass {
301public:
302 static char ID;
303 HotColdSplittingLegacyPass() : ModulePass(ID) {
304 initializeHotColdSplittingLegacyPassPass(*PassRegistry::getPassRegistry());
305 }
306
307 void getAnalysisUsage(AnalysisUsage &AU) const override {
308 AU.addRequired<AssumptionCacheTracker>();
309 AU.addRequired<BlockFrequencyInfoWrapperPass>();
310 AU.addRequired<ProfileSummaryInfoWrapperPass>();
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000311 AU.addRequired<TargetTransformInfoWrapperPass>();
Aditya Kumar801394a2018-09-07 15:03:49 +0000312 }
313
314 bool runOnModule(Module &M) override;
315};
316
317} // end anonymous namespace
318
319// Returns false if the function should not be considered for hot-cold split
Sebastian Pop0f30f082018-09-14 20:36:19 +0000320// optimization.
Aditya Kumar801394a2018-09-07 15:03:49 +0000321bool HotColdSplitting::shouldOutlineFrom(const Function &F) const {
Sebastian Pop0f30f082018-09-14 20:36:19 +0000322 // Do not try to outline again from an already outlined cold function.
323 if (OutlinedFunctions.count(&F))
324 return false;
325
Aditya Kumar801394a2018-09-07 15:03:49 +0000326 if (F.size() <= 2)
327 return false;
328
Vedant Kumarc2990062018-10-24 22:15:41 +0000329 // TODO: Consider only skipping functions marked `optnone` or `cold`.
330
Aditya Kumar801394a2018-09-07 15:03:49 +0000331 if (F.hasAddressTaken())
332 return false;
333
334 if (F.hasFnAttribute(Attribute::AlwaysInline))
335 return false;
336
337 if (F.hasFnAttribute(Attribute::NoInline))
338 return false;
339
340 if (F.getCallingConv() == CallingConv::Cold)
341 return false;
342
343 if (PSI->isFunctionEntryCold(&F))
344 return false;
345 return true;
346}
347
Vedant Kumarc2990062018-10-24 22:15:41 +0000348Function *HotColdSplitting::extractColdRegion(const BlockSequence &Region,
349 DominatorTree &DT,
350 BlockFrequencyInfo *BFI,
351 OptimizationRemarkEmitter &ORE,
352 unsigned Count) {
Teresa Johnsonf431a2f2018-10-22 19:06:42 +0000353 assert(!Region.empty());
Aditya Kumar801394a2018-09-07 15:03:49 +0000354 LLVM_DEBUG(for (auto *BB : Region)
355 llvm::dbgs() << "\nExtracting: " << *BB;);
Sebastian Pop12171602018-09-14 20:36:10 +0000356
Aditya Kumar801394a2018-09-07 15:03:49 +0000357 // TODO: Pass BFI and BPI to update profile information.
Vedant Kumarc2990062018-10-24 22:15:41 +0000358 CodeExtractor CE(Region, &DT, /* AggregateArgs */ false, /* BFI */ nullptr,
Teresa Johnsonc8dba682018-10-24 18:53:47 +0000359 /* BPI */ nullptr, /* AllowVarArgs */ false,
360 /* AllowAlloca */ false,
361 /* Suffix */ "cold." + std::to_string(Count));
Aditya Kumar801394a2018-09-07 15:03:49 +0000362
363 SetVector<Value *> Inputs, Outputs, Sinks;
364 CE.findInputsOutputs(Inputs, Outputs, Sinks);
365
366 // Do not extract regions that have live exit variables.
Vedant Kumarc2990062018-10-24 22:15:41 +0000367 if (Outputs.size() > 0) {
368 LLVM_DEBUG(llvm::dbgs() << "Not outlining; live outputs\n");
Aditya Kumar801394a2018-09-07 15:03:49 +0000369 return nullptr;
Vedant Kumarc2990062018-10-24 22:15:41 +0000370 }
Aditya Kumar801394a2018-09-07 15:03:49 +0000371
Vedant Kumarc2990062018-10-24 22:15:41 +0000372 // TODO: Run MergeBasicBlockIntoOnlyPred on the outlined function.
Teresa Johnsonf431a2f2018-10-22 19:06:42 +0000373 Function *OrigF = Region[0]->getParent();
Aditya Kumar801394a2018-09-07 15:03:49 +0000374 if (Function *OutF = CE.extractCodeRegion()) {
375 User *U = *OutF->user_begin();
376 CallInst *CI = cast<CallInst>(U);
377 CallSite CS(CI);
Vedant Kumarc2990062018-10-24 22:15:41 +0000378 NumColdRegionsOutlined++;
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000379 if (GetTTI(*OutF).useColdCCForColdCall(*OutF)) {
380 OutF->setCallingConv(CallingConv::Cold);
381 CS.setCallingConv(CallingConv::Cold);
382 }
Aditya Kumar801394a2018-09-07 15:03:49 +0000383 CI->setIsNoInline();
Vedant Kumar50315462018-10-23 19:41:12 +0000384
385 // Try to make the outlined code as small as possible on the assumption
386 // that it's cold.
387 assert(!OutF->hasFnAttribute(Attribute::OptimizeNone) &&
388 "An outlined function should never be marked optnone");
389 OutF->addFnAttr(Attribute::MinSize);
390
Sebastian Pop0f30f082018-09-14 20:36:19 +0000391 LLVM_DEBUG(llvm::dbgs() << "Outlined Region: " << *OutF);
Teresa Johnsonf431a2f2018-10-22 19:06:42 +0000392 ORE.emit([&]() {
393 return OptimizationRemark(DEBUG_TYPE, "HotColdSplit",
394 &*Region[0]->begin())
395 << ore::NV("Original", OrigF) << " split cold code into "
396 << ore::NV("Split", OutF);
397 });
Aditya Kumar801394a2018-09-07 15:03:49 +0000398 return OutF;
399 }
400
401 ORE.emit([&]() {
402 return OptimizationRemarkMissed(DEBUG_TYPE, "ExtractFailed",
403 &*Region[0]->begin())
404 << "Failed to extract region at block "
405 << ore::NV("Block", Region.front());
406 });
407 return nullptr;
408}
409
Aditya Kumar801394a2018-09-07 15:03:49 +0000410bool HotColdSplitting::run(Module &M) {
Vedant Kumarc2990062018-10-24 22:15:41 +0000411 bool Changed = false;
Aditya Kumar801394a2018-09-07 15:03:49 +0000412 for (auto &F : M) {
Vedant Kumarc2990062018-10-24 22:15:41 +0000413 if (!shouldOutlineFrom(F)) {
414 LLVM_DEBUG(llvm::dbgs() << "Not outlining in " << F.getName() << "\n");
Aditya Kumar801394a2018-09-07 15:03:49 +0000415 continue;
Vedant Kumarc2990062018-10-24 22:15:41 +0000416 }
417
418 LLVM_DEBUG(llvm::dbgs() << "Outlining in " << F.getName() << "\n");
Aditya Kumar801394a2018-09-07 15:03:49 +0000419 DominatorTree DT(F);
420 PostDomTree PDT(F);
421 PDT.recalculate(F);
Vedant Kumarc2990062018-10-24 22:15:41 +0000422 BlockFrequencyInfo *BFI = GetBFI(F);
Aditya Kumar801394a2018-09-07 15:03:49 +0000423
Vedant Kumarc2990062018-10-24 22:15:41 +0000424 BlockSequence ColdRegion = getLargestColdRegion(F, *PSI, BFI, DT, PDT);
425 if (ColdRegion.empty())
426 continue;
427
428 OptimizationRemarkEmitter &ORE = (*GetORE)(F);
429 Function *Outlined =
430 extractColdRegion(ColdRegion, DT, BFI, ORE, /*Count=*/1);
431 if (Outlined) {
Aditya Kumar801394a2018-09-07 15:03:49 +0000432 OutlinedFunctions.insert(Outlined);
Vedant Kumarc2990062018-10-24 22:15:41 +0000433 Changed = true;
434 }
Aditya Kumar801394a2018-09-07 15:03:49 +0000435 }
Vedant Kumarc2990062018-10-24 22:15:41 +0000436 return Changed;
Aditya Kumar801394a2018-09-07 15:03:49 +0000437}
438
439bool HotColdSplittingLegacyPass::runOnModule(Module &M) {
440 if (skipModule(M))
441 return false;
442 ProfileSummaryInfo *PSI =
443 getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000444 auto GTTI = [this](Function &F) -> TargetTransformInfo & {
445 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
446 };
Aditya Kumar801394a2018-09-07 15:03:49 +0000447 auto GBFI = [this](Function &F) {
448 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
449 };
450 std::unique_ptr<OptimizationRemarkEmitter> ORE;
451 std::function<OptimizationRemarkEmitter &(Function &)> GetORE =
452 [&ORE](Function &F) -> OptimizationRemarkEmitter & {
453 ORE.reset(new OptimizationRemarkEmitter(&F));
454 return *ORE.get();
455 };
456
Sebastian Popa1f20fc2018-09-10 15:08:02 +0000457 return HotColdSplitting(PSI, GBFI, GTTI, &GetORE).run(M);
Aditya Kumar801394a2018-09-07 15:03:49 +0000458}
459
Aditya Kumar9e20ade2018-10-03 05:55:20 +0000460PreservedAnalyses
461HotColdSplittingPass::run(Module &M, ModuleAnalysisManager &AM) {
462 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
463
464 std::function<AssumptionCache &(Function &)> GetAssumptionCache =
465 [&FAM](Function &F) -> AssumptionCache & {
466 return FAM.getResult<AssumptionAnalysis>(F);
467 };
468
469 auto GBFI = [&FAM](Function &F) {
470 return &FAM.getResult<BlockFrequencyAnalysis>(F);
471 };
472
473 std::function<TargetTransformInfo &(Function &)> GTTI =
474 [&FAM](Function &F) -> TargetTransformInfo & {
475 return FAM.getResult<TargetIRAnalysis>(F);
476 };
477
478 std::unique_ptr<OptimizationRemarkEmitter> ORE;
479 std::function<OptimizationRemarkEmitter &(Function &)> GetORE =
480 [&ORE](Function &F) -> OptimizationRemarkEmitter & {
481 ORE.reset(new OptimizationRemarkEmitter(&F));
482 return *ORE.get();
483 };
484
485 ProfileSummaryInfo *PSI = &AM.getResult<ProfileSummaryAnalysis>(M);
486
487 if (HotColdSplitting(PSI, GBFI, GTTI, &GetORE).run(M))
488 return PreservedAnalyses::none();
489 return PreservedAnalyses::all();
490}
491
Aditya Kumar801394a2018-09-07 15:03:49 +0000492char HotColdSplittingLegacyPass::ID = 0;
493INITIALIZE_PASS_BEGIN(HotColdSplittingLegacyPass, "hotcoldsplit",
494 "Hot Cold Splitting", false, false)
495INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
496INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
497INITIALIZE_PASS_END(HotColdSplittingLegacyPass, "hotcoldsplit",
498 "Hot Cold Splitting", false, false)
499
500ModulePass *llvm::createHotColdSplittingPass() {
501 return new HotColdSplittingLegacyPass();
502}