LLVM 23.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"
31
32namespace llvm {
33
35class MachineInstr;
36
37/// Thin wrapper around "int" used to store reaching definitions,
38/// using an encoding that makes it compatible with TinyPtrVector.
39/// The 0th LSB is forced zero (and will be used for pointer union tagging),
40/// The 1st LSB is forced one (to make sure the value is non-zero).
41class ReachingDef {
42 uintptr_t Encoded;
43 friend struct PointerLikeTypeTraits<ReachingDef>;
44 explicit ReachingDef(uintptr_t Encoded) : Encoded(Encoded) {}
45
46public:
47 ReachingDef(std::nullptr_t) : Encoded(0) {}
48 ReachingDef(int Instr) : Encoded(((uintptr_t) Instr << 2) | 2) {}
49 operator int() const { return ((int) Encoded) >> 2; }
50};
51
52template<>
54 static constexpr int NumLowBitsAvailable = 1;
55
56 static inline void *getAsVoidPointer(const ReachingDef &RD) {
57 return reinterpret_cast<void *>(RD.Encoded);
58 }
59
60 static inline ReachingDef getFromVoidPointer(void *P) {
61 return ReachingDef(reinterpret_cast<uintptr_t>(P));
62 }
63
64 static inline ReachingDef getFromVoidPointer(const void *P) {
65 return ReachingDef(reinterpret_cast<uintptr_t>(P));
66 }
67};
68
69// The storage for all reaching definitions.
71public:
72 void init(unsigned NumBlockIDs) { AllReachingDefs.resize(NumBlockIDs); }
73
74 unsigned numBlockIDs() const { return AllReachingDefs.size(); }
75
76 void startBasicBlock(unsigned MBBNumber, unsigned NumRegUnits) {
77 AllReachingDefs[MBBNumber].resize(NumRegUnits);
78 }
79
80 void append(unsigned MBBNumber, MCRegUnit Unit, int Def) {
81 AllReachingDefs[MBBNumber][static_cast<unsigned>(Unit)].push_back(Def);
82 }
83
84 void prepend(unsigned MBBNumber, MCRegUnit Unit, int Def) {
85 auto &Defs = AllReachingDefs[MBBNumber][static_cast<unsigned>(Unit)];
86 Defs.insert(Defs.begin(), Def);
87 }
88
89 void replaceFront(unsigned MBBNumber, MCRegUnit Unit, int Def) {
90 assert(!AllReachingDefs[MBBNumber][static_cast<unsigned>(Unit)].empty());
91 *AllReachingDefs[MBBNumber][static_cast<unsigned>(Unit)].begin() = Def;
92 }
93
94 void clear() { AllReachingDefs.clear(); }
95
96 ArrayRef<ReachingDef> defs(unsigned MBBNumber, MCRegUnit Unit) const {
97 if (AllReachingDefs[MBBNumber].empty())
98 // Block IDs are not necessarily dense.
99 return ArrayRef<ReachingDef>();
100 return AllReachingDefs[MBBNumber][static_cast<unsigned>(Unit)];
101 }
102
103private:
104 /// All reaching defs of a given RegUnit for a given MBB.
105 using MBBRegUnitDefs = TinyPtrVector<ReachingDef>;
106 /// All reaching defs of all reg units for a given MBB
107 using MBBDefsInfo = std::vector<MBBRegUnitDefs>;
108
109 /// All reaching defs of all reg units for all MBBs
110 SmallVector<MBBDefsInfo, 4> AllReachingDefs;
111};
112
113/// This class provides the reaching def analysis.
115private:
116 MachineFunction *MF = nullptr;
117 const TargetRegisterInfo *TRI = nullptr;
118 const TargetInstrInfo *TII = nullptr;
119 LoopTraversal::TraversalOrder TraversedMBBOrder;
120 unsigned NumRegUnits = 0;
121 unsigned NumStackObjects = 0;
122 int ObjectIndexBegin = 0;
123 /// Instruction that defined each register, relative to the beginning of the
124 /// current basic block. When a LiveRegsDefInfo is used to represent a
125 /// live-out register, this value is relative to the end of the basic block,
126 /// so it will be a negative number.
127 using LiveRegsDefInfo = std::vector<int>;
128 LiveRegsDefInfo LiveRegs;
129
130 /// Keeps clearance information for all registers. Note that this
131 /// is different from the usual definition notion of liveness. The CPU
132 /// doesn't care whether or not we consider a register killed.
133 using OutRegsInfoMap = SmallVector<LiveRegsDefInfo, 4>;
134 OutRegsInfoMap MBBOutRegsInfos;
135
136 /// Current instruction number.
137 /// The first instruction in each basic block is 0.
138 int CurInstr = -1;
139
140 /// Maps instructions to their instruction Ids, relative to the beginning of
141 /// their basic blocks.
143
144 MBBReachingDefsInfo MBBReachingDefs;
145
146 /// MBBFrameObjsReachingDefs[{i, j}] is a list of instruction indices
147 /// (relative to begining of MBB i) that define frame index j in MBB i. This
148 /// is used in answering reaching definition queries.
149 using MBBFrameObjsReachingDefsInfo =
151 MBBFrameObjsReachingDefsInfo MBBFrameObjsReachingDefs;
152
153 /// Default values are 'nothing happened a long time ago'.
154 static constexpr int ReachingDefDefaultVal = -(1 << 21);
155 /// Special values for function live-ins.
156 static constexpr int FunctionLiveInMarker = -1;
157
158 using InstSet = SmallPtrSetImpl<MachineInstr*>;
160
161public:
165 /// Handle invalidation explicitly.
167 MachineFunctionAnalysisManager::Invalidator &);
168
169 LLVM_ABI void run(MachineFunction &mf);
170 LLVM_ABI void print(raw_ostream &OS);
171 LLVM_ABI void releaseMemory();
172
173 /// Re-run the analysis.
174 LLVM_ABI void reset();
175
176 /// Initialize data structures.
177 LLVM_ABI void init();
178
179 /// Traverse the machine function, mapping definitions.
180 LLVM_ABI void traverse();
181
182 /// Provides the instruction id of the closest reaching def instruction of
183 /// Reg that reaches MI, relative to the begining of MI's basic block.
184 /// Note that Reg may represent a stack slot.
186
187 /// Return whether A and B use the same def of Reg.
189 Register Reg) const;
190
191 /// Return whether the reaching def for MI also is live out of its parent
192 /// block.
194
195 /// Return the local MI that produces the live out value for Reg, or
196 /// nullptr for a non-live out or non-local def.
198 Register Reg) const;
199
200 /// If a single MachineInstr creates the reaching definition, then return it.
201 /// Otherwise return null.
203 Register Reg) const;
204
205 /// If a single MachineInstr creates the reaching definition, for MIs operand
206 /// at Idx, then return it. Otherwise return null.
207 LLVM_ABI MachineInstr *getMIOperand(MachineInstr *MI, unsigned Idx) const;
208
209 /// If a single MachineInstr creates the reaching definition, for MIs MO,
210 /// then return it. Otherwise return null.
212 MachineOperand &MO) const;
213
214 /// Provide whether the register has been defined in the same basic block as,
215 /// and before, MI.
217
218 /// Return whether the given register is used after MI, whether it's a local
219 /// use or a live out.
221
222 /// Return whether the given register is defined after MI.
224
225 /// Provides the clearance - the number of instructions since the closest
226 /// reaching def instuction of Reg that reaches MI.
228
229 /// Provides the uses, in the same block as MI, of register that MI defines.
230 /// This does not consider live-outs.
232 InstSet &Uses) const;
233
234 /// Search MBB for a definition of Reg and insert it into Defs. If no
235 /// definition is found, recursively search the predecessor blocks for them.
237 BlockSet &VisitedBBs) const;
239 InstSet &Defs) const;
240
241 /// For the given block, collect the instructions that use the live-in
242 /// value of the provided register. Return whether the value is still
243 /// live on exit.
245 InstSet &Uses) const;
246
247 /// Collect the users of the value stored in Reg, which is defined
248 /// by MI.
250 InstSet &Uses) const;
251
252 /// Collect all possible definitions of the value stored in Reg, which is
253 /// used by MI.
255 InstSet &Defs) const;
256
257 /// Return whether From can be moved forwards to just before To.
259 MachineInstr *To) const;
260
261 /// Return whether From can be moved backwards to just after To.
263 MachineInstr *To) const;
264
265 /// Assuming MI is dead, recursively search the incoming operands which are
266 /// killed by MI and collect those that would become dead.
267 LLVM_ABI void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const;
268
269 /// Return whether removing this instruction will have no effect on the
270 /// program, returning the redundant use-def chain.
271 LLVM_ABI bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const;
272
273 /// Return whether removing this instruction will have no effect on the
274 /// program, ignoring the possible effects on some instructions, returning
275 /// the redundant use-def chain.
277 InstSet &Ignore) const;
278
279 /// Return whether a MachineInstr could be inserted at MI and safely define
280 /// the given register without affecting the program.
282
283 /// Return whether a MachineInstr could be inserted at MI and safely define
284 /// the given register without affecting the program, ignoring any effects
285 /// on the provided instructions.
287 InstSet &Ignore) const;
288
289private:
290 /// Set up LiveRegs by merging predecessor live-out values.
291 void enterBasicBlock(MachineBasicBlock *MBB);
292
293 /// Update live-out values.
294 void leaveBasicBlock(MachineBasicBlock *MBB);
295
296 /// Process he given basic block.
297 void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
298
299 /// Process block that is part of a loop again.
300 void reprocessBasicBlock(MachineBasicBlock *MBB);
301
302 /// Update def-ages for registers defined by MI.
303 /// Also break dependencies on partial defs and undef uses.
304 void processDefs(MachineInstr *);
305
306 /// Utility function for isSafeToMoveForwards/Backwards.
307 template<typename Iterator>
308 bool isSafeToMove(MachineInstr *From, MachineInstr *To) const;
309
310 /// Return whether removing this instruction will have no effect on the
311 /// program, ignoring the possible effects on some instructions, returning
312 /// the redundant use-def chain.
313 bool isSafeToRemove(MachineInstr *MI, InstSet &Visited,
314 InstSet &ToRemove, InstSet &Ignore) const;
315
316 /// Provides the MI, from the given block, corresponding to the Id or a
317 /// nullptr if the id does not refer to the block.
318 MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId) const;
319
320 /// Provides the instruction of the closest reaching def instruction of
321 /// Reg that reaches MI, relative to the begining of MI's basic block.
322 /// Note that Reg may represent a stack slot.
323 MachineInstr *getReachingLocalMIDef(MachineInstr *MI, Register Reg) const;
324};
325
326class ReachingDefAnalysis : public AnalysisInfoMixin<ReachingDefAnalysis> {
328 static AnalysisKey Key;
329
330public:
332
335};
336
337/// Printer pass for the \c ReachingDefInfo results.
339 : public RequiredPassInfoMixin<ReachingDefPrinterPass> {
340 raw_ostream &OS;
341
342public:
343 explicit ReachingDefPrinterPass(raw_ostream &OS) : OS(OS) {}
344
347};
348
350 ReachingDefInfo RDI;
351
352public:
353 static char ID;
354
356
357 void getAnalysisUsage(AnalysisUsage &AU) const override;
359 bool runOnMachineFunction(MachineFunction &F) override;
360 void releaseMemory() override { RDI.releaseMemory(); }
361
362 ReachingDefInfo &getRDI() { return RDI; }
363 const ReachingDefInfo &getRDI() const { return RDI; }
364};
365
366} // namespace llvm
367
368#endif // LLVM_CODEGEN_REACHINGDEFANALYSIS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet InstSet & Ignore
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock & MBB
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:213
This file defines the DenseMap class.
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
Register Reg
#define P(N)
Remove Loads Into Fake Uses
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
SmallVector< TraversedMBBInfo, 4 > TraversalOrder
Identifies basic blocks that are part of loops and should to be visited twice and returns efficient t...
void prepend(unsigned MBBNumber, MCRegUnit Unit, int Def)
void replaceFront(unsigned MBBNumber, MCRegUnit Unit, int Def)
ArrayRef< ReachingDef > defs(unsigned MBBNumber, MCRegUnit Unit) const
void init(unsigned NumBlockIDs)
void append(unsigned MBBNumber, MCRegUnit Unit, int Def)
void startBasicBlock(unsigned MBBNumber, unsigned NumRegUnits)
Properties which a MachineFunction may have at a given point in time.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool runOnMachineFunction(MachineFunction &F) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const ReachingDefInfo & getRDI() const
MachineFunctionProperties getRequiredProperties() const override
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
This class provides the reaching def analysis.
LLVM_ABI MachineInstr * getUniqueReachingMIDef(MachineInstr *MI, Register Reg) const
If a single MachineInstr creates the reaching definition, then return it.
LLVM_ABI bool isReachingDefLiveOut(MachineInstr *MI, Register Reg) const
Return whether the reaching def for MI also is live out of its parent block.
LLVM_ABI bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved forwards to just before To.
LLVM_ABI int getReachingDef(MachineInstr *MI, Register Reg) const
Provides the instruction id of the closest reaching def instruction of Reg that reaches MI,...
LLVM_ABI void run(MachineFunction &mf)
LLVM_ABI void getReachingLocalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Provides the uses, in the same block as MI, of register that MI defines.
LLVM_ABI int getClearance(MachineInstr *MI, Register Reg) const
Provides the clearance - the number of instructions since the closest reaching def instuction of Reg ...
LLVM_ABI bool isRegDefinedAfter(MachineInstr *MI, Register Reg) const
Return whether the given register is defined after MI.
LLVM_ABI void init()
Initialize data structures.
LLVM_ABI void print(raw_ostream &OS)
LLVM_ABI bool hasLocalDefBefore(MachineInstr *MI, Register Reg) const
Provide whether the register has been defined in the same basic block as, and before,...
LLVM_ABI void reset()
Re-run the analysis.
LLVM_ABI void getGlobalUses(MachineInstr *MI, Register Reg, InstSet &Uses) const
Collect the users of the value stored in Reg, which is defined by MI.
LLVM_ABI MachineInstr * getMIOperand(MachineInstr *MI, unsigned Idx) const
If a single MachineInstr creates the reaching definition, for MIs operand at Idx, then return it.
LLVM_ABI void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs, BlockSet &VisitedBBs) const
Search MBB for a definition of Reg and insert it into Defs.
LLVM_ABI void traverse()
Traverse the machine function, mapping definitions.
LLVM_ABI ReachingDefInfo()
LLVM_ABI bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved backwards to just after To.
LLVM_ABI void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const
Assuming MI is dead, recursively search the incoming operands which are killed by MI and collect thos...
LLVM_ABI ~ReachingDefInfo()
LLVM_ABI bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, Register Reg) const
Return whether A and B use the same def of Reg.
LLVM_ABI 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.
LLVM_ABI void getGlobalReachingDefs(MachineInstr *MI, Register Reg, InstSet &Defs) const
Collect all possible definitions of the value stored in Reg, which is used by MI.
LLVM_ABI bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const
Return whether removing this instruction will have no effect on the program, returning the redundant ...
LLVM_ABI ReachingDefInfo(ReachingDefInfo &&)
LLVM_ABI 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...
LLVM_ABI bool invalidate(MachineFunction &F, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &)
Handle invalidation explicitly.
LLVM_ABI 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.
LLVM_ABI bool isSafeToDefRegAt(MachineInstr *MI, Register Reg) const
Return whether a MachineInstr could be inserted at MI and safely define the given register without af...
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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:20
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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...
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
@ Dead
Unused definition.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
ArrayRef(const T &OneElt) -> ArrayRef< T >
A CRTP mix-in that provides informational APIs needed for analysis passes.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
static ReachingDef getFromVoidPointer(const 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 ...
A CRTP mix-in for passes that should not be skipped.