LLVM 22.0.0git
DebugSSAUpdater.cpp
Go to the documentation of this file.
1//===- DebugSSAUpdater.cpp - Debug Variable SSA Update Tool ---------------===//
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 implements the DebugSSAUpdater class.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/IR/CFG.h"
15#include "llvm/IR/DebugInfo.h"
18
19using namespace llvm;
20
21#define DEBUG_TYPE "debug-ssa-updater"
22
24 OS << "DbgVal{ ";
25 if (IsUndef) {
26 OS << "undef }";
27 return;
28 }
29 if (Phi) {
30 OS << *Phi << "}";
31 return;
32 }
33 OS << (IsMemory ? "Mem: " : "Def: ") << *Locations << " - " << *Expression
34 << " }";
35}
36
38 OS << "DbgPhi ";
39 for (auto &[BB, DV] : IncomingValues)
40 OS << "[" << BB->BB.getName() << ", " << DV << "] ";
41}
42
44
47
48void DebugSSAUpdater::initialize() { AV.clear(); }
49
51 return AV.count(BB);
52}
53
55 return AV.lookup(BB);
56}
57
61
63 DbgValueDef Res = getValueAtEndOfBlockInternal(BB);
64 return Res;
65}
66
68 // If there is no definition of the renamed variable in this block, just use
69 // 'getValueAtEndOfBlock' to do our work.
70 if (!hasValueForBlock(BB))
71 return getValueAtEndOfBlock(BB);
72
73 // Otherwise, we have the hard case. Get the live-in values for each
74 // predecessor.
76 DbgValueDef SingularValue;
77
78 bool IsFirstPred = true;
79 for (DbgSSABlock *PredBB : BB->predecessors()) {
80 DbgValueDef PredVal = getValueAtEndOfBlock(PredBB);
81 PredValues.push_back(std::make_pair(PredBB, PredVal));
82
83 // Compute SingularValue.
84 if (IsFirstPred) {
85 SingularValue = PredVal;
86 IsFirstPred = false;
87 } else if (!PredVal.agreesWith(SingularValue))
88 SingularValue = DbgValueDef();
89 }
90
91 // If there are no predecessors, just return undef.
92 if (PredValues.empty())
93 return DbgValueDef();
94
95 // Otherwise, if all the merged values are the same, just use it.
96 if (!SingularValue.IsUndef)
97 return SingularValue;
98
99 // Ok, we have no way out, insert a new one now.
100 DbgSSAPhi *InsertedPHI = BB->newPHI();
101
102 // Fill in all the predecessors of the PHI.
103 for (const auto &PredValue : PredValues)
104 InsertedPHI->addIncoming(PredValue.first, PredValue.second);
105
106 // See if the PHI node can be merged to a single value. This can happen in
107 // loop cases when we get a PHI of itself and one other value.
108
109 // If the client wants to know about all new instructions, tell it.
110 if (InsertedPHIs)
111 InsertedPHIs->push_back(InsertedPHI);
112
113 LLVM_DEBUG(dbgs() << " Inserted PHI: " << *InsertedPHI << "\n");
114 return InsertedPHI;
115}
116
118 return Updater.getDbgSSABlock(*SuccIt);
119}
121 return Updater.getDbgSSABlock(*PredIt);
122}
123
124namespace llvm {
125
127public:
132
133 static BlkSucc_iterator BlkSucc_begin(BlkT *BB) { return BB->succ_begin(); }
134 static BlkSucc_iterator BlkSucc_end(BlkT *BB) { return BB->succ_end(); }
135
137 private:
138 DbgSSAPhi *PHI;
139 unsigned Idx;
140
141 public:
142 explicit PHI_iterator(DbgSSAPhi *P) // begin iterator
143 : PHI(P), Idx(0) {}
144 PHI_iterator(DbgSSAPhi *P, bool) // end iterator
145 : PHI(P), Idx(PHI->getNumIncomingValues()) {}
146
148 ++Idx;
149 return *this;
150 }
151 bool operator==(const PHI_iterator &X) const { return Idx == X.Idx; }
152 bool operator!=(const PHI_iterator &X) const { return !operator==(X); }
153
154 DbgValueDef getIncomingValue() { return PHI->getIncomingValue(Idx); }
155 DbgSSABlock *getIncomingBlock() { return PHI->getIncomingBlock(Idx); }
156 };
157
159 static PHI_iterator PHI_end(PhiT *PHI) { return PHI_iterator(PHI, true); }
160
161 /// FindPredecessorBlocks - Put the predecessors of BB into the Preds
162 /// vector.
165 for (auto PredIt = BB->pred_begin(); PredIt != BB->pred_end(); ++PredIt)
166 Preds->push_back(*PredIt);
167 }
168
169 /// GetPoisonVal - Get an undefined value of the same type as the value
170 /// being handled.
172 return DbgValueDef();
173 }
174
175 /// CreateEmptyPHI - Create a new debug PHI entry for the specified block.
176 static DbgSSAPhi *CreateEmptyPHI(DbgSSABlock *BB, unsigned NumPreds,
177 DebugSSAUpdater *Updater) {
178 DbgSSAPhi *PHI = BB->newPHI();
179 return PHI;
180 }
181
182 /// AddPHIOperand - Add the specified value as an operand of the PHI for
183 /// the specified predecessor block.
185 DbgSSABlock *Pred) {
186 PHI->addIncoming(Pred, Val);
187 }
188
189 /// ValueIsPHI - Check if a value is a PHI.
191 return Val.Phi;
192 }
193
194 /// ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source
195 /// operands, i.e., it was just added.
197 DbgSSAPhi *PHI = ValueIsPHI(Val, Updater);
198 if (PHI && PHI->getNumIncomingValues() == 0)
199 return PHI;
200 return nullptr;
201 }
202
203 /// GetPHIValue - For the specified PHI instruction, return the value
204 /// that it defines.
206};
207
208} // end namespace llvm
209
210/// Check to see if AvailableVals has an entry for the specified BB and if so,
211/// return it. If not, construct SSA form by first calculating the required
212/// placement of PHIs and then inserting new PHIs where needed.
213DbgValueDef DebugSSAUpdater::getValueAtEndOfBlockInternal(DbgSSABlock *BB) {
214 if (AV.contains(BB))
215 return AV[BB];
216
217 SSAUpdaterImpl<DebugSSAUpdater> Impl(this, &AV, InsertedPHIs);
218 return Impl.GetValue(BB);
219}
220
221bool isContained(DIScope *Inner, DIScope *Outer) {
222 if (Inner == Outer)
223 return true;
224 if (!Inner->getScope())
225 return false;
226 return isContained(Inner->getScope(), Outer);
227}
228
230 const DILocalVariable *Var = DVA.getVariable();
231 const DILocation *InlinedAt = DVA.getInlinedAt();
232
234 DenseSet<BasicBlock *> HasAnyInstructionsInScope;
235 int NumRecordsFound = 0;
236 DbgVariableRecord *LastRecordFound = nullptr;
237 bool DeclareRecordFound = false;
238
239 LLVM_DEBUG(dbgs() << "Finding variable info for " << *Var << " at "
240 << InlinedAt << "\n");
241
242 for (auto &BB : *F) {
243 auto &DbgRecordValues = BlockDbgRecordValues[&BB];
244 bool FoundInstructionInScope = false;
245 for (auto &I : BB) {
246 LLVM_DEBUG(dbgs() << "Instruction: '" << I << "'\n");
247
248 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
249 if (DVR.getVariable() == Var &&
250 DVR.getDebugLoc().getInlinedAt() == InlinedAt) {
251 assert(!DVR.isDbgAssign() && "No support for #dbg_assign yet.");
252 if (DVR.isDbgDeclare())
253 DeclareRecordFound = true;
254 ++NumRecordsFound;
255 LastRecordFound = &DVR;
256 DbgRecordValues.push_back(&DVR);
257 }
258 }
259 if (!FoundInstructionInScope && I.getDebugLoc()) {
260 if (I.getDebugLoc().getInlinedAt() == InlinedAt &&
261 isContained(cast<DILocalScope>(I.getDebugLoc().getScope()),
262 Var->getScope())) {
263 FoundInstructionInScope = true;
264 HasAnyInstructionsInScope.insert(&BB);
265 }
266 }
267 }
268 LLVM_DEBUG(dbgs() << "DbgRecordValues found in '" << BB.getName() << "':\n";
269 for_each(DbgRecordValues, [](auto *DV) { DV->dump(); }));
270 }
271
272 if (!NumRecordsFound) {
273 LLVM_DEBUG(dbgs() << "No dbg_records found for variable!\n");
274 return;
275 }
276
277 // Now that we have all the DbgValues, we can start defining available values
278 // for each block. The end goal is to have, for every block with any
279 // instructions in scope, a LiveIn value.
280 // Currently we anticipate that either a variable has a set of #dbg_values, in
281 // which case we need a complete SSA liveness analysis to determine live-in
282 // values per-block, or a variable has a single #dbg_declare.
283 if (DeclareRecordFound) {
284 // FIXME: This should be changed for fragments!
285 LLVM_DEBUG(dbgs() << "Single location found for variable!\n");
286 assert(NumRecordsFound == 1 &&
287 "Found multiple records for a #dbg_declare variable!");
288 OrigSingleLocVariableValueTable[DVA] = DbgValueDef(LastRecordFound);
289 return;
290 }
291
292 // We don't have a single location for the variable's entire scope, so instead
293 // we must now perform a liveness analysis to create a location list.
295 SmallVector<DbgSSAPhi *> HypotheticalPHIs;
296 DebugSSAUpdater SSAUpdater(&HypotheticalPHIs);
297 SSAUpdater.initialize();
298 for (auto &[BB, DVs] : BlockDbgRecordValues) {
299 auto *DbgBB = SSAUpdater.getDbgSSABlock(BB);
300 if (DVs.empty())
301 continue;
302 auto *LastValueInBlock = DVs.back();
303 LLVM_DEBUG(dbgs() << "Last value in " << BB->getName() << ": "
304 << *LastValueInBlock << "\n");
305 SSAUpdater.addAvailableValue(DbgBB, DbgValueDef(LastValueInBlock));
306 }
307
308 for (BasicBlock &BB : *F) {
309 if (!HasAnyInstructionsInScope.contains(&BB)) {
310 LLVM_DEBUG(dbgs() << "Skipping finding debug ranges for '" << BB.getName()
311 << "' due to no in-scope instructions.\n");
312 continue;
313 }
314 LLVM_DEBUG(dbgs() << "Finding live-in value for '" << BB.getName()
315 << "'...\n");
316 DbgValueDef LiveValue =
317 SSAUpdater.getValueInMiddleOfBlock(SSAUpdater.getDbgSSABlock(&BB));
318 LLVM_DEBUG(dbgs() << "Found live-in: " << LiveValue << "\n");
319 auto HasValidValue = [](DbgValueDef DV) {
320 return !DV.IsUndef && DV.Phi == nullptr;
321 };
322
323 SmallVector<DbgRangeEntry> BlockDbgRanges;
324 BasicBlock::iterator LastIt = BB.begin();
325 for (auto *DVR : BlockDbgRecordValues[&BB]) {
326 // Create a range that ends as of DVR.
327 BasicBlock::iterator DVRStartIt =
328 const_cast<Instruction *>(DVR->getInstruction())->getIterator();
329 if (HasValidValue(LiveValue))
330 BlockDbgRanges.push_back({LastIt, DVRStartIt, LiveValue});
331 LiveValue = DbgValueDef(DVR);
332 LastIt = DVRStartIt;
333 }
334
335 // After considering all in-block debug values, if any, create a range
336 // covering the remainder of the block.
337 if (HasValidValue(LiveValue))
338 BlockDbgRanges.push_back({LastIt, BB.end(), LiveValue});
339 LLVM_DEBUG(dbgs() << "Create set of ranges with " << BlockDbgRanges.size()
340 << " entries!\n");
341 if (!BlockDbgRanges.empty())
342 OrigVariableValueRangeTable[DVA].append(BlockDbgRanges);
343 }
344}
345
347 raw_ostream &OS) {
348 OS << "Variable Table for '" << DVA.getVariable()->getName() << "' (at "
349 << DVA.getInlinedAt() << "):\n";
350 if (!hasVariableEntry(DVA)) {
351 OS << " Empty!\n";
352 return;
353 }
354 if (hasSingleLocEntry(DVA)) {
355 OS << " SingleLoc: " << OrigSingleLocVariableValueTable[DVA] << "\n";
356 return;
357 }
358 OS << " LocRange:\n";
359 for (DbgRangeEntry RangeEntry : OrigVariableValueRangeTable[DVA]) {
360 OS << " (";
361 if (RangeEntry.Start == RangeEntry.Start->getParent()->begin() &&
362 RangeEntry.End == RangeEntry.Start->getParent()->end()) {
363 OS << RangeEntry.Start->getParent()->getName();
364 } else {
365 OS << RangeEntry.Start->getParent()->getName() << ": "
366 << *RangeEntry.Start << ", ";
367 if (RangeEntry.End == RangeEntry.Start->getParent()->end())
368 OS << "..";
369 else
370 OS << *RangeEntry.End;
371 }
372 OS << ") [" << RangeEntry.Value << "]\n";
373 }
374}
375
377 auto ExistingID = ValueToIDMap.find(V);
378 if (ExistingID != ValueToIDMap.end())
379 return ExistingID->second;
380 // First, get a new ID and Map V to it.
381 ValueID NewID = NextID++;
382 ValueToIDMap.insert({V, NewID});
383 // Then, get the name string for V and map NewID to it.
384 assert(!ValueIDToNameMap.contains(NewID) &&
385 "New value ID already maps to a name?");
386 std::string &ValueText = ValueIDToNameMap[NewID];
387 raw_string_ostream Stream(ValueText);
388 V->printAsOperand(Stream, true);
389 return NewID;
390}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
bool isContained(DIScope *Inner, DIScope *Outer)
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:55
#define I(x, y, z)
Definition MD5.cpp:58
DenseMap< MachineBasicBlock *, Register > AvailableValsTy
#define P(N)
#define LLVM_DEBUG(...)
Definition Debug.h:114
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LLVM Basic Block Representation.
Definition BasicBlock.h:62
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
DILocalScope * getScope() const
Get the local scope for this variable.
Base class for scope-like contexts.
LLVM_ABI DIScope * getScope() const
StringRef getName() const
Thin wrapper around a block successor iterator.
iterator_range< DbgSSABlockPredIterator > predecessors()
DbgSSABlockSuccIterator succ_end()
DbgSSABlockPredIterator pred_end()
DbgSSABlockPredIterator pred_begin()
DbgSSABlockSuccIterator succ_begin()
DbgSSAPhi * newPHI()
SSAUpdater has requested a PHI: create that within this block record.
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)
void print(raw_ostream &OS) const
void printValues(DebugVariableAggregate DVA, raw_ostream &OS)
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....
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.
DbgValueDef findValueForBlock(DbgSSABlock *BB) const
Return the value for the specified block if the DebugSSAUpdater has one, otherwise return nullptr.
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.
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).
const DILocation * getInlinedAt() const
const DILocalVariable * getVariable() const
Implements a dense probed hash-table based set.
Definition DenseSet.h:269
static void FindPredecessorBlocks(DbgSSABlock *BB, SmallVectorImpl< DbgSSABlock * > *Preds)
FindPredecessorBlocks - Put the predecessors of BB into the Preds vector.
static DbgSSAPhi * ValueIsPHI(DbgValueDef Val, DebugSSAUpdater *Updater)
ValueIsPHI - Check if a value is a PHI.
static PHI_iterator PHI_end(PhiT *PHI)
static void AddPHIOperand(DbgSSAPhi *PHI, DbgValueDef Val, DbgSSABlock *Pred)
AddPHIOperand - Add the specified value as an operand of the PHI for the specified predecessor block.
static DbgValueDef GetPHIValue(DbgSSAPhi *PHI)
GetPHIValue - For the specified PHI instruction, return the value that it defines.
static DbgSSAPhi * CreateEmptyPHI(DbgSSABlock *BB, unsigned NumPreds, DebugSSAUpdater *Updater)
CreateEmptyPHI - Create a new debug PHI entry for the specified block.
static BlkSucc_iterator BlkSucc_end(BlkT *BB)
static PHI_iterator PHI_begin(PhiT *PHI)
static BlkSucc_iterator BlkSucc_begin(BlkT *BB)
static DbgSSAPhi * ValueIsNewPHI(DbgValueDef Val, DebugSSAUpdater *Updater)
ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source operands, i....
static DbgValueDef GetPoisonVal(DbgSSABlock *BB, DebugSSAUpdater *Updater)
GetPoisonVal - Get an undefined value of the same type as the value being handled.
Helper class for SSA formation on a set of values defined in multiple blocks.
Definition SSAUpdater.h:39
ValueID addValue(Value *V)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
Definition Value.h:75
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:194
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:169
self_iterator getIterator()
Definition ilist_node.h:130
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
This is an optimization pass for GlobalISel generic memory operations.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1698
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
A definition of a variable; can represent either a debug value, no definition (the variable has not y...
void print(raw_ostream &OS) const
DIExpression * Expression
bool agreesWith(DbgValueDef Other) const