LLVM: lib/CodeGen/BasicBlockPathCloning.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
47
48using namespace llvm;
49
50namespace {
51
52
53
55 unsigned CloneID) {
57 auto TII = MF.getSubtarget().getInstrInfo();
58
62
63
64 for (auto &I : OrigBB.instrs()) {
65
66 if (I.isBundledWithPred())
67 continue;
68 TII->duplicate(*CloneBB, CloneBB->end(), I);
69 }
70
71
72
75
76 if (auto FT = OrigBB.getFallThrough(false)) {
77
78
79
80
82 }
83 return CloneBB;
84}
85
86
87
88
93 for (size_t I = 0; I < ClonePath.size(); ++I) {
94 unsigned BBID = ClonePath[I];
96 if (!PathBB) {
97 WithColor::warning() << "no block with id " << BBID << " in function "
99 return false;
100 }
101
102 if (PrevBB) {
105 << "block #" << BBID << " is not a successor of block #"
106 << PrevBB->getBBID()->BaseID << " in function " << MF.getName()
107 << "\n";
108 return false;
109 }
110
111 for (auto &MI : *PathBB) {
112
113
114
115 if (MI.isNotDuplicable() && .isCFIInstruction()) {
117 << "block #" << BBID
118 << " has non-duplicable instructions in function " << MF.getName()
119 << "\n";
120 return false;
121 }
122 }
123 if (PathBB->isMachineBlockAddressTaken()) {
124
125
127 << "block #" << BBID
128 << " has its machine block address taken in function "
130 return false;
131 }
132 if (PathBB->isInlineAsmBrIndirectTarget()) {
133
135 << "block #" << BBID
136 << " is a branch target of an 'asm goto' in function "
138 return false;
139 }
140 }
141
142 if (I != ClonePath.size() - 1 && !PathBB->empty() &&
143 PathBB->back().isIndirectBranch()) {
145 << "block #" << BBID
146 << " has indirect branch and appears as the non-tail block of a "
147 "path in function "
149 return false;
150 }
151 PrevBB = PathBB;
152 }
153 return true;
154}
155
156
157
160 if (ClonePaths.empty())
161 return false;
162 bool AnyPathsCloned = false;
163
165 for (auto &BB : MF)
166 BBIDToBlock.try_emplace(BB.getBBID()->BaseID, &BB);
167
169 auto TII = MF.getSubtarget().getInstrInfo();
170 for (const auto &ClonePath : ClonePaths) {
171 if (!IsValidCloning(MF, BBIDToBlock, ClonePath)) {
172
173
174 for (unsigned BBID : ClonePath)
175 ++NClonesForBBID[BBID];
176 continue;
177 }
179 for (unsigned BBID : ClonePath) {
181 if (PrevBB == nullptr) {
182
183
184
185 if (auto FT = OrigBB->getFallThrough(false)) {
186 TII->insertUnconditionalBranch(*OrigBB, FT,
188 }
189 PrevBB = OrigBB;
190 continue;
191 }
193 CloneMachineBasicBlock(*OrigBB, ++NClonesForBBID[BBID]);
194
195
196
197
199
200
201 for (auto &LiveIn : OrigBB->liveins())
203
204 PrevBB = CloneBB;
205 }
206 AnyPathsCloned = true;
207 }
208 return AnyPathsCloned;
209}
210
212public:
213 static char ID;
214
215 BasicBlockSectionsProfileReaderWrapperPass *BBSectionsProfileReader = nullptr;
216
217 BasicBlockPathCloning() : MachineFunctionPass(ID) {
219 }
220
221 StringRef getPassName() const override { return "Basic Block Path Cloning"; }
222
223 void getAnalysisUsage(AnalysisUsage &AU) const override;
224
225
226
227 bool runOnMachineFunction(MachineFunction &MF) override;
228};
229
230}
231
232char BasicBlockPathCloning::ID = 0;
234 BasicBlockPathCloning, "bb-path-cloning",
235 "Applies path clonings for the -basic-block-sections=list option", false,
236 false)
239 BasicBlockPathCloning, "bb-path-cloning",
240 "Applies path clonings for the -basic-block-sections=list option", false,
242
243bool BasicBlockPathCloning::runOnMachineFunction(MachineFunction &MF) {
245 "BB Sections list not enabled!");
247 return false;
248
249 return ApplyCloning(MF,
250 getAnalysis()
251 .getClonePathsForFunction(MF.getName()));
252}
253
254void BasicBlockPathCloning::getAnalysisUsage(AnalysisUsage &AU) const {
256 AU.addRequired();
258}
259
261 return new BasicBlockPathCloning();
262}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
ValueT & at(const_arg_type_t< KeyT > Val)
at - Return the entry for the specified key, or abort if no such entry exists.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
LLVM_ABI MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
iterator_range< livein_iterator > liveins() const
void push_back(MachineInstr *MI)
std::optional< UniqueBBID > getBBID() const
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
succ_iterator succ_begin()
LLVM_ABI void copySuccessor(const MachineBasicBlock *Orig, succ_iterator I)
Copy a successor (and any probability info) from original block to this block's.
LLVM_ABI void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Given a machine basic block that branched to 'Old', change the code and CFG so that it branches to 'N...
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI DebugLoc findBranchDebugLoc()
Find and return the merged DebugLoc of the branch instructions of the block.
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
This is an optimization pass for GlobalISel generic memory operations.
bool hasInstrProfHashMismatch(MachineFunction &MF)
This checks if the source of this function has drifted since this binary was profiled previously.
LLVM_ABI void initializeBasicBlockPathCloningPass(PassRegistry &)
LLVM_ABI MachineFunctionPass * createBasicBlockPathCloningPass()