1 | //===- TailDuplication.cpp - Duplicate blocks into predecessors' tails ----===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | /// \file This pass duplicates basic blocks ending in unconditional branches |
10 | /// into the tails of their predecessors, using the TailDuplicator utility |
11 | /// class. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #include "llvm/CodeGen/TailDuplication.h" |
16 | #include "llvm/Analysis/ProfileSummaryInfo.h" |
17 | #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" |
18 | #include "llvm/CodeGen/MBFIWrapper.h" |
19 | #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" |
20 | #include "llvm/CodeGen/MachineFunction.h" |
21 | #include "llvm/CodeGen/MachineFunctionPass.h" |
22 | #include "llvm/CodeGen/MachinePassManager.h" |
23 | #include "llvm/CodeGen/TailDuplicator.h" |
24 | #include "llvm/IR/Analysis.h" |
25 | #include "llvm/InitializePasses.h" |
26 | #include "llvm/Pass.h" |
27 | #include "llvm/PassRegistry.h" |
28 | |
29 | using namespace llvm; |
30 | |
31 | #define DEBUG_TYPE "tailduplication" |
32 | |
33 | namespace { |
34 | |
35 | class TailDuplicateBaseLegacy : public MachineFunctionPass { |
36 | TailDuplicator Duplicator; |
37 | std::unique_ptr<MBFIWrapper> MBFIW; |
38 | bool PreRegAlloc; |
39 | public: |
40 | TailDuplicateBaseLegacy(char &PassID, bool PreRegAlloc) |
41 | : MachineFunctionPass(PassID), PreRegAlloc(PreRegAlloc) {} |
42 | |
43 | bool runOnMachineFunction(MachineFunction &MF) override; |
44 | |
45 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
46 | AU.addRequired<MachineBranchProbabilityInfoWrapperPass>(); |
47 | AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); |
48 | AU.addRequired<ProfileSummaryInfoWrapperPass>(); |
49 | MachineFunctionPass::getAnalysisUsage(AU); |
50 | } |
51 | }; |
52 | |
53 | class TailDuplicateLegacy : public TailDuplicateBaseLegacy { |
54 | public: |
55 | static char ID; |
56 | TailDuplicateLegacy() : TailDuplicateBaseLegacy(ID, false) { |
57 | initializeTailDuplicateLegacyPass(*PassRegistry::getPassRegistry()); |
58 | } |
59 | }; |
60 | |
61 | class EarlyTailDuplicateLegacy : public TailDuplicateBaseLegacy { |
62 | public: |
63 | static char ID; |
64 | EarlyTailDuplicateLegacy() : TailDuplicateBaseLegacy(ID, true) { |
65 | initializeEarlyTailDuplicateLegacyPass(*PassRegistry::getPassRegistry()); |
66 | } |
67 | |
68 | MachineFunctionProperties getClearedProperties() const override { |
69 | return MachineFunctionProperties().setNoPHIs(); |
70 | } |
71 | }; |
72 | |
73 | } // end anonymous namespace |
74 | |
75 | char TailDuplicateLegacy::ID; |
76 | char EarlyTailDuplicateLegacy::ID; |
77 | |
78 | char &llvm::TailDuplicateLegacyID = TailDuplicateLegacy::ID; |
79 | char &llvm::EarlyTailDuplicateLegacyID = EarlyTailDuplicateLegacy::ID; |
80 | |
81 | INITIALIZE_PASS(TailDuplicateLegacy, DEBUG_TYPE, "Tail Duplication" , false, |
82 | false) |
83 | INITIALIZE_PASS(EarlyTailDuplicateLegacy, "early-tailduplication" , |
84 | "Early Tail Duplication" , false, false) |
85 | |
86 | bool TailDuplicateBaseLegacy::runOnMachineFunction(MachineFunction &MF) { |
87 | if (skipFunction(F: MF.getFunction())) |
88 | return false; |
89 | |
90 | auto MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI(); |
91 | auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); |
92 | auto *MBFI = (PSI && PSI->hasProfileSummary()) ? |
93 | &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI() : |
94 | nullptr; |
95 | if (MBFI) |
96 | MBFIW = std::make_unique<MBFIWrapper>(args&: *MBFI); |
97 | Duplicator.initMF(MF, PreRegAlloc, MBPI, MBFI: MBFI ? MBFIW.get() : nullptr, PSI, |
98 | /*LayoutMode=*/false); |
99 | |
100 | bool MadeChange = false; |
101 | while (Duplicator.tailDuplicateBlocks()) |
102 | MadeChange = true; |
103 | |
104 | return MadeChange; |
105 | } |
106 | |
107 | template <typename DerivedT, bool PreRegAlloc> |
108 | PreservedAnalyses TailDuplicatePassBase<DerivedT, PreRegAlloc>::run( |
109 | MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) { |
110 | MFPropsModifier _(static_cast<DerivedT &>(*this), MF); |
111 | |
112 | auto *MBPI = &MFAM.getResult<MachineBranchProbabilityAnalysis>(IR&: MF); |
113 | auto *PSI = MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(IR&: MF) |
114 | .getCachedResult<ProfileSummaryAnalysis>( |
115 | IR&: *MF.getFunction().getParent()); |
116 | auto *MBFI = (PSI && PSI->hasProfileSummary() |
117 | ? &MFAM.getResult<MachineBlockFrequencyAnalysis>(IR&: MF) |
118 | : nullptr); |
119 | if (MBFI) |
120 | MBFIW = std::make_unique<MBFIWrapper>(args&: *MBFI); |
121 | |
122 | TailDuplicator Duplicator; |
123 | Duplicator.initMF(MF, PreRegAlloc, MBPI, MBFI: MBFI ? MBFIW.get() : nullptr, PSI, |
124 | /*LayoutMode=*/false); |
125 | bool MadeChange = false; |
126 | while (Duplicator.tailDuplicateBlocks()) |
127 | MadeChange = true; |
128 | |
129 | if (!MadeChange) |
130 | return PreservedAnalyses::all(); |
131 | return getMachineFunctionPassPreservedAnalyses(); |
132 | } |
133 | |
134 | template class llvm::TailDuplicatePassBase<TailDuplicatePass, false>; |
135 | template class llvm::TailDuplicatePassBase<EarlyTailDuplicatePass, true>; |
136 | |