LLVM 22.0.0git
ReachingDefAnalysis.h
Go to the documentation of this file.
1//==--- llvm/CodeGen/ReachingDefAnalysis.h - Reaching Def Analysis -*- C++ -*---==//
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 Reaching Defs Analysis pass.
10///
11/// This pass tracks for each instruction what is the "closest" reaching def of
12/// a given register. It is used by BreakFalseDeps (for clearance calculation)
13/// and ExecutionDomainFix (for arbitrating conflicting domains).
14///
15/// Note that this is different from the usual definition notion of liveness.
16/// The CPU doesn't care whether or not we consider a register killed.
17///
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_CODEGEN_REACHINGDEFANALYSIS_H
22#define LLVM_CODEGEN_REACHINGDEFANALYSIS_H
23
24#include "llvm/ADT/DenseMap.h"
30
31namespace llvm {
32
33class MachineBasicBlock;
34class MachineInstr;
35
36/// Thin wrapper around "int" used to store reaching definitions,
37/// using an encoding that makes it compatible with TinyPtrVector.
38/// The 0th LSB is forced zero (and will be used for pointer union tagging),
39/// The 1st LSB is forced one (to make sure the value is non-zero).
41 uintptr_t Encoded;
43 explicit ReachingDef(uintptr_t Encoded) : Encoded(Encoded) {}
44
45public:
46 ReachingDef(std::nullptr_t) : Encoded(0) {}
47 ReachingDef(int Instr) : Encoded(((uintptr_t) Instr << 2) | 2) {}
48 operator int() const { return ((int) Encoded) >> 2; }
49};
50
51template<>
53 static constexpr int NumLowBitsAvailable = 1;
54
55 static inline void *getAsVoidPointer(const ReachingDef &RD) {
56 return reinterpret_cast<void *>(RD.Encoded);
57 }
58
59 static inline ReachingDef getFromVoidPointer(void *P) {
60 return ReachingDef(reinterpret_cast<uintptr_t>(P));
61 }
62
63 static inline ReachingDef getFromVoidPointer(const void *P) {
64 return ReachingDef(reinterpret_cast<uintptr_t>(P));
65 }
66};
67
68// The storage for all reaching definitions.
70public:
71 void init(unsigned NumBlockIDs) { AllReachingDefs.resize(NumBlockIDs); }
72
73 unsigned numBlockIDs() const { return AllReachingDefs.size(); }
74
75 void startBasicBlock(unsigned MBBNumber, unsigned NumRegUnits) {
76 AllReachingDefs[MBBNumber].resize(NumRegUnits);
77 }
78
79 void append(unsigned MBBNumber, unsigned Unit, int Def) {
80 AllReachingDefs[MBBNumber][Unit].push_back(Def);
81 }
82
83 void prepend(unsigned MBBNumber, unsigned Unit, int Def) {
84 auto &Defs = AllReachingDefs[MBBNumber][Unit];
85 Defs.insert(Defs.begin(), Def);
86 }
87
88 void replaceFront(unsigned MBBNumber, unsigned Unit, int Def) {
89 assert(!AllReachingDefs[MBBNumber][Unit].empty());
90 *AllReachingDefs[MBBNumber][Unit].begin() = Def;
91 }
92
93 void clear() { AllReachingDefs.clear(); }
94
95 ArrayRef<ReachingDef> defs(unsigned MBBNumber, unsigned Unit) const {
96 if (AllReachingDefs[MBBNumber].empty())
97 // Block IDs are not necessarily dense.
98 return ArrayRef<ReachingDef>();
99 return AllReachingDefs[MBBNumber][Unit];
100 }
101
102private:
103 /// All reaching defs of a given RegUnit for a given MBB.
104 using MBBRegUnitDefs = TinyPtrVector<ReachingDef>;
105 /// All reaching defs of all reg units for a given MBB
106 using MBBDefsInfo = std::vector<MBBRegUnitDefs>;
107
108 /// All reaching defs of all reg units for all MBBs
109 SmallVector<MBBDefsInfo, 4> AllReachingDefs;
110};
111
112/// This class provides the reaching def analysis.
114private:
115 MachineFunction *MF = nullptr;
116 const TargetRegisterInfo *TRI = nullptr;
117 const TargetInstrInfo *TII = nullptr;
118 LoopTraversal::TraversalOrder TraversedMBBOrder;
119 unsigned NumRegUnits = 0;
120 unsigned NumStackObjects = 0;
121 int ObjectIndexBegin = 0;
122 /// Instruction that defined each register, relative to the beginning of the
123 /// current basic block. When a LiveRegsDefInfo is used to represent a
124 /// live-out register, this value is relative to the end of the basic block,
125 /// so it will be a negative number.
126 using LiveRegsDefInfo = std::vector<int>;
127 LiveRegsDefInfo LiveRegs;
128
129 /// Keeps clearance information for all registers. Note that this
130 /// is different from the usual definition notion of liveness. The CPU
131 /// doesn't care whether or not we consider a register killed.
133 OutRegsInfoMap MBBOutRegsInfos;
134
135 /// Current instruction number.
136 /// The first instruction in each basic block is 0.
137 int CurInstr = -1;
138
139 /// Maps instructions to their instruction Ids, relative to the beginning of
140 /// their basic blocks.
142
143 MBBReachingDefsInfo MBBReachingDefs;
144
145 /// MBBFrameObjsReachingDefs[{i, j}] is a list of instruction indices
146 /// (relative to begining of MBB i) that define frame index j in MBB i. This
147 /// is used in answering reaching definition queries.
150 MBBFrameObjsReachingDefsInfo MBBFrameObjsReachingDefs;
151
152 /// Default values are 'nothing happened a long time ago'.
153 const int ReachingDefDefaultVal = -(1 << 21);
154
157
158public:
159 static char ID; // Pass identification, replacement for typeid
160
163 }
164 void releaseMemory() override;
165
166 void getAnalysisUsage(AnalysisUsage &AU) const override {
167 AU.setPreservesAll();
169 }
170
172 bool runOnMachineFunction(MachineFunction &MF) override;
173
175 return MachineFunctionProperties().setNoVRegs().setTracksLiveness();
176 }
177
178 /// Re-run the analysis.
179 void reset();
180
181 /// Initialize data structures.
182 void init();
183
184 /// Traverse the machine function, mapping definitions.
185 void traverse();
186
187 /// Provides the instruction id of the closest reaching def instruction of
188 /// Reg that reaches MI, relative to the begining of MI's basic block.
189 /// Note that Reg may represent a stack slot.
191
192 /// Return whether A and B use the same def of Reg.
194
195 /// Return whether the reaching def for MI also is live out of its parent
196 /// block.
198
199 /// Return the local MI that produces the live out value for Reg, or
200 /// nullptr for a non-live out or non-local def.
202 Register Reg) const;
203
204 /// If a single MachineInstr creates the reaching definition, then return it.
205 /// Otherwise return null.
207
208 /// If a single MachineInstr creates the reaching definition, for MIs operand
209 /// at Idx, then return it. Otherwise return null.
210 MachineInstr *getMIOperand(MachineInstr *MI, unsigned Idx) const;
211
212 /// If a single MachineInstr creates the reaching definition, for MIs MO,
213 /// then return it. Otherwise return null.
215
216 /// Provide whether the register has been defined in the same basic block as,
217 /// and before, MI.
219
220 /// Return whether the given register is used after MI, whether it's a local
221 /// use or a live out.
223
224 /// Return whether the given register is defined after MI.
226
227 /// Provides the clearance - the number of instructions since the closest
228 /// reaching def instuction of Reg that reaches MI.
230
231 /// Provides the uses, in the same block as MI, of register that MI defines.
232 /// This does not consider live-outs.
234 InstSet &Uses) const;
235
236 /// Search MBB for a definition of Reg and insert it into Defs. If no
237 /// definition is found, recursively search the predecessor blocks for them.
238 void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs,
239 BlockSet &VisitedBBs) const;
240 void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs) const;
241
242 /// For the given block, collect the instructions that use the live-in
243 /// value of the provided register. Return whether the value is still
244 /// live on exit.
245 bool getLiveInUses(MachineBasicBlock *MBB, Register Reg, InstSet &Uses) const;
246
247 /// Collect the users of the value stored in Reg, which is defined
248 /// by MI.
249 void getGlobalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const;
250
251 /// Collect all possible definitions of the value stored in Reg, which is
252 /// used by MI.
254 InstSet &Defs) const;
255
256 /// Return whether From can be moved forwards to just before To.
258
259 /// Return whether From can be moved backwards to just after To.
261
262 /// Assuming MI is dead, recursively search the incoming operands which are
263 /// killed by MI and collect those that would become dead.
264 void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const;
265
266 /// Return whether removing this instruction will have no effect on the
267 /// program, returning the redundant use-def chain.
268 bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const;
269
270 /// Return whether removing this instruction will have no effect on the
271 /// program, ignoring the possible effects on some instructions, returning
272 /// the redundant use-def chain.
273 bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove,
274 InstSet &Ignore) const;
275
276 /// Return whether a MachineInstr could be inserted at MI and safely define
277 /// the given register without affecting the program.
279
280 /// Return whether a MachineInstr could be inserted at MI and safely define
281 /// the given register without affecting the program, ignoring any effects
282 /// on the provided instructions.
283 bool isSafeToDefRegAt(MachineInstr *MI, Register Reg, InstSet &Ignore) const;
284
285private:
286 /// Set up LiveRegs by merging predecessor live-out values.
287 void enterBasicBlock(MachineBasicBlock *MBB);
288
289 /// Update live-out values.
290 void leaveBasicBlock(MachineBasicBlock *MBB);
291
292 /// Process he given basic block.
293 void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
294
295 /// Process block that is part of a loop again.
296 void reprocessBasicBlock(MachineBasicBlock *MBB);
297
298 /// Update def-ages for registers defined by MI.
299 /// Also break dependencies on partial defs and undef uses.
300 void processDefs(MachineInstr *);
301
302 /// Utility function for isSafeToMoveForwards/Backwards.
303 template<typename Iterator>
304 bool isSafeToMove(MachineInstr *From, MachineInstr *To) const;
305
306 /// Return whether removing this instruction will have no effect on the
307 /// program, ignoring the possible effects on some instructions, returning
308 /// the redundant use-def chain.
309 bool isSafeToRemove(MachineInstr *MI, InstSet &Visited,
310 InstSet &ToRemove, InstSet &Ignore) const;
311
312 /// Provides the MI, from the given block, corresponding to the Id or a
313 /// nullptr if the id does not refer to the block.
314 MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId) const;
315
316 /// Provides the instruction of the closest reaching def instruction of
317 /// Reg that reaches MI, relative to the begining of MI's basic block.
318 /// Note that Reg may represent a stack slot.
319 MachineInstr *getReachingLocalMIDef(MachineInstr *MI, Register Reg) const;
320};
321
322} // namespace llvm
323
324#endif // LLVM_CODEGEN_REACHINGDEFANALYSIS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefAnalysis InstSet & ToRemove
ReachingDefAnalysis InstSet InstSet & Ignore
MachineBasicBlock & MBB
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
IRTranslator LLVM IR MI
Register Reg
#define P(N)
Remove Loads Into Fake Uses
std::unordered_set< BasicBlock * > BlockSet
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
void append(unsigned MBBNumber, unsigned Unit, int Def)
ArrayRef< ReachingDef > defs(unsigned MBBNumber, unsigned Unit) const
void replaceFront(unsigned MBBNumber, unsigned Unit, int Def)
void init(unsigned NumBlockIDs)
void prepend(unsigned MBBNumber, unsigned Unit, int Def)
void startBasicBlock(unsigned MBBNumber, unsigned NumRegUnits)
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.
Properties which a MachineFunction may have at a given point in time.
Representation of each machine instruction.
Definition: MachineInstr.h:72
MachineOperand class - Representation of each machine instruction operand.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class provides the reaching def analysis.
MachineInstr * getLocalLiveOutMIDef(MachineBasicBlock *MBB, Register Reg) const
Return the local MI that produces the live out value for Reg, or nullptr for a non-live out or non-lo...
void traverse()
Traverse the machine function, mapping definitions.
bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved forwards to just before To.
bool isRegUsedAfter(MachineInstr *MI, Register Reg) const
Return whether the given register is used after MI, whether it's a local use or a live out.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const
Return whether removing this instruction will have no effect on the program, returning the redundant ...
MachineInstr * getMIOperand(MachineInstr *MI, unsigned Idx) const
If a single MachineInstr creates the reaching definition, for MIs operand at Idx, then return it.
void printAllReachingDefs(MachineFunction &MF)
void reset()
Re-run the analysis.
int getReachingDef(MachineInstr *MI, Register Reg) const
Provides the instruction id of the closest reaching def instruction of Reg that reaches MI,...
void init()
Initialize data structures.
void getGlobalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Collect the users of the value stored in Reg, which is defined by MI.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const
Assuming MI is dead, recursively search the incoming operands which are killed by MI and collect thos...
bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved backwards to just after To.
void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs, BlockSet &VisitedBBs) const
Search MBB for a definition of Reg and insert it into Defs.
int getClearance(MachineInstr *MI, Register Reg) const
Provides the clearance - the number of instructions since the closest reaching def instuction of Reg ...
bool hasLocalDefBefore(MachineInstr *MI, Register Reg) const
Provide whether the register has been defined in the same basic block as, and before,...
bool isReachingDefLiveOut(MachineInstr *MI, Register Reg) const
Return whether the reaching def for MI also is live out of its parent block.
bool getLiveInUses(MachineBasicBlock *MBB, Register Reg, InstSet &Uses) const
For the given block, collect the instructions that use the live-in value of the provided register.
bool isSafeToDefRegAt(MachineInstr *MI, Register Reg) const
Return whether a MachineInstr could be inserted at MI and safely define the given register without af...
bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, Register Reg) const
Return whether A and B use the same def of Reg.
void getReachingLocalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Provides the uses, in the same block as MI, of register that MI defines.
bool isRegDefinedAfter(MachineInstr *MI, Register Reg) const
Return whether the given register is defined after MI.
MachineFunctionProperties getRequiredProperties() const override
MachineInstr * getUniqueReachingMIDef(MachineInstr *MI, Register Reg) const
If a single MachineInstr creates the reaching definition, then return it.
void getGlobalReachingDefs(MachineInstr *MI, Register Reg, InstSet &Defs) const
Collect all possible definitions of the value stored in Reg, which is used by MI.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Thin wrapper around "int" used to store reaching definitions, using an encoding that makes it compati...
ReachingDef(std::nullptr_t)
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:380
size_t size() const
Definition: SmallVector.h:79
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:806
void resize(size_type N)
Definition: SmallVector.h:639
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
Definition: TinyPtrVector.h:29
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI void initializeReachingDefAnalysisPass(PassRegistry &)
static ReachingDef getFromVoidPointer(const void *P)
static ReachingDef getFromVoidPointer(void *P)
static void * getAsVoidPointer(const ReachingDef &RD)
A traits type that is used to handle pointer types and things that are just wrappers for pointers as ...