LLVM 22.0.0git
DebugSSAUpdater.h
Go to the documentation of this file.
1//===- DebugSSAUpdater.h - Debug SSA Update Tool ----------------*- 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// This file declares the DebugSSAUpdater class, which is used to evaluate the
10// live values of debug variables in IR. This uses SSA construction, treating
11// debug value records as definitions, to determine at each point in the program
12// which definition(s) are live at a given point. This is useful for analysis of
13// the state of debug variables, such as measuring the change in values of a
14// variable over time, or calculating coverage stats.
15//
16// NB: This is an expensive analysis that is generally not suitable for use in
17// LLVM passes, but may be useful for standalone tools.
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_TRANSFORMS_UTILS_DEBUGSSAUPDATER_H
22#define LLVM_TRANSFORMS_UTILS_DEBUGSSAUPDATER_H
23
25#include "llvm/IR/BasicBlock.h"
26#include "llvm/IR/CFG.h"
29#include "llvm/IR/Instruction.h"
30#include "llvm/IR/ValueHandle.h"
31#include "llvm/IR/ValueMap.h"
33#include <cstdint>
34
35namespace llvm {
36
37////////////////////////////////////////
38// SSAUpdater specialization classes
39
40class DbgSSAPhi;
41template <typename T> class SSAUpdaterTraits;
42
43/// A definition of a variable; can represent either a debug value, no
44/// definition (the variable has not yet been defined), or a phi value*.
45/// *Meaning multiple definitions that are live-in to a block from different
46/// predecessors, not a debug value that uses an IR PHINode.
49 bool IsUndef;
53
55 : Phi(nullptr), IsUndef(true), IsMemory(false), Locations(nullptr),
56 Expression(nullptr) {}
58 : Phi(nullptr), IsUndef(true), IsMemory(false), Locations(nullptr),
59 Expression(nullptr) {}
64 assert(!DVR->isDbgAssign() && "#dbg_assign not yet supported");
65 IsUndef = DVR->isKillLocation();
69 }
73
75 if (IsUndef && Other.IsUndef)
76 return true;
77 return std::tie(Phi, IsUndef, IsMemory, Locations, Expression) ==
78 std::tie(Other.Phi, Other.IsUndef, Other.IsMemory, Other.Locations,
79 Other.Expression);
80 }
81
82 operator bool() const { return !IsUndef; }
83 bool operator==(DbgValueDef Other) const { return agreesWith(Other); }
84 bool operator!=(DbgValueDef Other) const { return !agreesWith(Other); }
85
86 void print(raw_ostream &OS) const;
87};
88
89class DbgSSABlock;
90class DebugSSAUpdater;
91
92/// Represents the live-in definitions of a variable to a block with multiple
93/// predecessors.
94class DbgSSAPhi {
95public:
99
101 unsigned getNumIncomingValues() const { return IncomingValues.size(); }
103 return IncomingValues[Idx].first;
104 }
106 return IncomingValues[Idx].second;
107 }
109 IncomingValues.push_back({BB, DV});
110 }
111
112 void print(raw_ostream &OS) const;
113};
114
116 DV.print(OS);
117 return OS;
118}
120 PHI.print(OS);
121 return OS;
122}
123
124/// Thin wrapper around a block successor iterator.
144
145/// Thin wrapper around a block successor iterator.
165
167public:
171 /// List of PHIs in this block. There should only ever be one, but this needs
172 /// to be a list for the SSAUpdater.
174
177
181
185
189
193
197
201
202 /// SSAUpdater has requested a PHI: create that within this block record.
204 assert(PHIList.empty() &&
205 "Only one PHI should exist per-block per-variable");
206 PHIList.emplace_back(this);
207 return &PHIList.back();
208 }
209
210 /// SSAUpdater wishes to know what PHIs already exist in this block.
211 PHIListT &phis() { return PHIList; }
212};
213
214/// Class used to determine the live ranges of debug variables in IR using
215/// SSA construction (via the SSAUpdaterImpl class), used for analysis purposes.
217 friend class SSAUpdaterTraits<DebugSSAUpdater>;
218 using AvailableValsTy = DenseMap<DbgSSABlock *, DbgValueDef>;
219
220private:
221 /// This keeps track of which value to use on a per-block basis. When we
222 /// insert PHI nodes, we keep track of them here.
223 AvailableValsTy AV;
224
225 /// Pointer to an optionally-passed vector into which, if it is non-null,
226 /// the PHIs that describe ambiguous variable locations will be inserted.
227 SmallVectorImpl<DbgSSAPhi *> *InsertedPHIs;
228
230
231public:
232 /// If InsertedPHIs is specified, it will be filled
233 /// in with all PHI Nodes created by rewriting.
234 explicit DebugSSAUpdater(
235 SmallVectorImpl<DbgSSAPhi *> *InsertedPHIs = nullptr);
238
240 for (auto &Block : BlockMap)
241 delete Block.second;
242 }
243
244 void reset() {
245 for (auto &Block : BlockMap)
246 delete Block.second;
247
248 if (InsertedPHIs)
249 InsertedPHIs->clear();
250 BlockMap.clear();
251 }
252
253 void initialize();
254
255 /// For a given BB, create a wrapper block for it. Stores it in the
256 /// DebugSSAUpdater block map.
258 auto it = BlockMap.find(BB);
259 if (it == BlockMap.end()) {
260 BlockMap[BB] = new DbgSSABlock(*BB, *this);
261 it = BlockMap.find(BB);
262 }
263 return it->second;
264 }
265
266 /// Indicate that a rewritten value is available in the specified block
267 /// with the specified value.
269
270 /// Return true if the DebugSSAUpdater already has a value for the specified
271 /// block.
272 bool hasValueForBlock(DbgSSABlock *BB) const;
273
274 /// Return the value for the specified block if the DebugSSAUpdater has one,
275 /// otherwise return nullptr.
277
278 /// Construct SSA form, materializing a value that is live at the end
279 /// of the specified block.
281
282 /// Construct SSA form, materializing a value that is live in the
283 /// middle of the specified block.
284 ///
285 /// \c getValueInMiddleOfBlock is the same as \c GetValueAtEndOfBlock except
286 /// in one important case: if there is a definition of the rewritten value
287 /// after the 'use' in BB. Consider code like this:
288 ///
289 /// \code
290 /// X1 = ...
291 /// SomeBB:
292 /// use(X)
293 /// X2 = ...
294 /// br Cond, SomeBB, OutBB
295 /// \endcode
296 ///
297 /// In this case, there are two values (X1 and X2) added to the AvailableVals
298 /// set by the client of the rewriter, and those values are both live out of
299 /// their respective blocks. However, the use of X happens in the *middle* of
300 /// a block. Because of this, we need to insert a new PHI node in SomeBB to
301 /// merge the appropriate values, and this value isn't live out of the block.
303
304private:
305 DbgValueDef getValueAtEndOfBlockInternal(DbgSSABlock *BB);
306};
307
314
315/// Utility class used to store the names of SSA values after their owning
316/// modules have been destroyed. Values are added via \c addValue to receive a
317/// corresponding ID, which can then be used to retrieve the name of the SSA
318/// value via \c getName at any point. Adding the same value multiple times
319/// returns the same ID, making \c addValue idempotent.
321 struct Config : ValueMapConfig<Value *> {
322 enum { FollowRAUW = false };
323 };
324
325public:
328 std::string getName(ValueID ID) { return ValueIDToNameMap[ID]; }
329
330private:
331 DenseMap<ValueID, std::string> ValueIDToNameMap;
333 ValueID NextID = 0;
334};
335
336/// Utility class used to find and store the live debug ranges for variables in
337/// a module. This class uses the DebugSSAUpdater for each variable added with
338/// \c addVariable to find either a single-location value, e.g. #dbg_declare, or
339/// a set of live value ranges corresponding to the set of #dbg_value records.
342 OrigVariableValueRangeTable;
343 DenseMap<DebugVariableAggregate, DbgValueDef> OrigSingleLocVariableValueTable;
344
345public:
348 return OrigVariableValueRangeTable.contains(DVA) ||
349 OrigSingleLocVariableValueTable.contains(DVA);
350 }
352 return OrigSingleLocVariableValueTable.contains(DVA);
353 }
355 return OrigVariableValueRangeTable[DVA];
356 }
358 return OrigSingleLocVariableValueTable[DVA];
359 }
360
362};
363
364} // end namespace llvm
365
366#endif // LLVM_TRANSFORMS_UTILS_DEBUGSSAUPDATER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
#define LLVM_ABI_FOR_TEST
Definition Compiler.h:218
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
#define F(x, y, z)
Definition MD5.cpp:54
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
DWARF expression.
Thin wrapper around a block successor iterator.
DbgSSABlockPredIterator(pred_iterator PredIt, DebugSSAUpdater &Updater)
bool operator!=(const DbgSSABlockPredIterator &OtherIt) const
DbgSSABlockPredIterator & operator++()
Thin wrapper around a block successor iterator.
DbgSSABlockSuccIterator(succ_iterator SuccIt, DebugSSAUpdater &Updater)
bool operator!=(const DbgSSABlockSuccIterator &OtherIt) const
DbgSSABlockSuccIterator & operator++()
DebugSSAUpdater & Updater
iterator_range< DbgSSABlockPredIterator > predecessors()
DbgSSABlockSuccIterator succ_end()
SmallVector< DbgSSAPhi, 1 > PHIListT
DbgSSABlockPredIterator pred_end()
DbgSSABlockPredIterator pred_begin()
DbgSSABlockSuccIterator succ_begin()
PHIListT & phis()
SSAUpdater wishes to know what PHIs already exist in this block.
PHIListT PHIList
List of PHIs in this block.
DbgSSAPhi * newPHI()
SSAUpdater has requested a PHI: create that within this block record.
iterator_range< DbgSSABlockSuccIterator > successors()
DbgSSABlock(BasicBlock &BB, DebugSSAUpdater &Updater)
Represents the live-in definitions of a variable to a block with multiple predecessors.
SmallVector< std::pair< DbgSSABlock *, DbgValueDef >, 4 > IncomingValues
void addIncoming(DbgSSABlock *BB, DbgValueDef DV)
DbgSSABlock * getParent()
DbgSSAPhi(DbgSSABlock *ParentBlock)
void print(raw_ostream &OS) const
DbgSSABlock * ParentBlock
DbgValueDef getIncomingValue(size_t Idx)
unsigned getNumIncomingValues() const
DbgSSABlock * getIncomingBlock(size_t Idx)
Utility class used to find and store the live debug ranges for variables in a module.
DbgValueDef getSingleLoc(DebugVariableAggregate DVA)
ArrayRef< DbgRangeEntry > getVariableRanges(DebugVariableAggregate DVA)
void printValues(DebugVariableAggregate DVA, raw_ostream &OS)
LLVM_ABI_FOR_TEST void addVariable(Function *F, DebugVariableAggregate DVA)
bool hasSingleLocEntry(DebugVariableAggregate DVA) const
bool hasVariableEntry(DebugVariableAggregate DVA) const
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LLVM_ABI bool isKillLocation() const
bool isAddressOfVariable() const
Does this describe the address of a local variable.
DIExpression * getExpression() const
Metadata * getRawLocation() const
Returns the metadata operand for the first location description.
Class used to determine the live ranges of debug variables in IR using SSA construction (via the SSAU...
DebugSSAUpdater(SmallVectorImpl< DbgSSAPhi * > *InsertedPHIs=nullptr)
If InsertedPHIs is specified, it will be filled in with all PHI Nodes created by rewriting.
DebugSSAUpdater & operator=(const DebugSSAUpdater &)=delete
DbgValueDef findValueForBlock(DbgSSABlock *BB) const
Return the value for the specified block if the DebugSSAUpdater has one, otherwise return nullptr.
DebugSSAUpdater(const DebugSSAUpdater &)=delete
void addAvailableValue(DbgSSABlock *BB, DbgValueDef DV)
Indicate that a rewritten value is available in the specified block with the specified value.
DbgValueDef getValueAtEndOfBlock(DbgSSABlock *BB)
Construct SSA form, materializing a value that is live at the end of the specified block.
DbgSSABlock * getDbgSSABlock(BasicBlock *BB)
For a given BB, create a wrapper block for it.
DbgValueDef getValueInMiddleOfBlock(DbgSSABlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
bool hasValueForBlock(DbgSSABlock *BB) const
Return true if the DebugSSAUpdater already has a value for the specified block.
Identifies a unique instance of a whole variable (discards/ignores fragment information).
Root of the metadata hierarchy.
Definition Metadata.h:64
Utility class used to store the names of SSA values after their owning modules have been destroyed.
std::string getName(ValueID ID)
ValueID addValue(Value *V)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
See the file comment.
Definition ValueMap.h:84
LLVM Value Representation.
Definition Value.h:75
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
auto pred_end(const MachineBasicBlock *BB)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ Other
Any other memory.
Definition ModRef.h:68
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
PredIterator< BasicBlock, Value::user_iterator > pred_iterator
Definition CFG.h:105
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
auto pred_begin(const MachineBasicBlock *BB)
SuccIterator< Instruction, BasicBlock > succ_iterator
Definition CFG.h:244
BasicBlock::iterator End
BasicBlock::iterator Start
A definition of a variable; can represent either a debug value, no definition (the variable has not y...
DbgValueDef(DbgVariableRecord *DVR)
DbgValueDef(DbgSSAPhi *Phi)
bool operator!=(DbgValueDef Other) const
void print(raw_ostream &OS) const
DIExpression * Expression
bool operator==(DbgValueDef Other) const
DbgValueDef(bool IsMemory, Metadata *Locations, DIExpression *Expression)
bool agreesWith(DbgValueDef Other) const
This class defines the default behavior for configurable aspects of ValueMap<>.
Definition ValueMap.h:53