21#define DEBUG_TYPE "debug-ssa-updater"
40 OS <<
"[" << BB->BB.getName() <<
", " << DV <<
"] ";
46 : InsertedPHIs(NewPHI) {}
78 bool IsFirstPred =
true;
81 PredValues.
push_back(std::make_pair(PredBB, PredVal));
85 SingularValue = PredVal;
92 if (PredValues.
empty())
103 for (
const auto &PredValue : PredValues)
104 InsertedPHI->
addIncoming(PredValue.first, PredValue.second);
111 InsertedPHIs->push_back(InsertedPHI);
145 : PHI(
P), Idx(PHI->getNumIncomingValues()) {}
186 PHI->addIncoming(Pred, Val);
198 if (
PHI &&
PHI->getNumIncomingValues() == 0)
217 SSAUpdaterImpl<DebugSSAUpdater> Impl(
this, &AV, InsertedPHIs);
218 return Impl.GetValue(BB);
235 int NumRecordsFound = 0;
237 bool DeclareRecordFound =
false;
239 LLVM_DEBUG(
dbgs() <<
"Finding variable info for " << *Var <<
" at "
240 << InlinedAt <<
"\n");
242 for (
auto &BB : *
F) {
243 auto &DbgRecordValues = BlockDbgRecordValues[&BB];
244 bool FoundInstructionInScope =
false;
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;
255 LastRecordFound = &DVR;
256 DbgRecordValues.push_back(&DVR);
259 if (!FoundInstructionInScope &&
I.getDebugLoc()) {
260 if (
I.getDebugLoc().getInlinedAt() == InlinedAt &&
263 FoundInstructionInScope =
true;
264 HasAnyInstructionsInScope.
insert(&BB);
268 LLVM_DEBUG(
dbgs() <<
"DbgRecordValues found in '" << BB.getName() <<
"':\n";
269 for_each(DbgRecordValues, [](
auto *DV) { DV->dump(); }));
272 if (!NumRecordsFound) {
283 if (DeclareRecordFound) {
286 assert(NumRecordsFound == 1 &&
287 "Found multiple records for a #dbg_declare variable!");
288 OrigSingleLocVariableValueTable[DVA] =
DbgValueDef(LastRecordFound);
298 for (
auto &[BB, DVs] : BlockDbgRecordValues) {
302 auto *LastValueInBlock = DVs.back();
304 << *LastValueInBlock <<
"\n");
309 if (!HasAnyInstructionsInScope.
contains(&BB)) {
310 LLVM_DEBUG(
dbgs() <<
"Skipping finding debug ranges for '" << BB.getName()
311 <<
"' due to no in-scope instructions.\n");
314 LLVM_DEBUG(
dbgs() <<
"Finding live-in value for '" << BB.getName()
320 return !DV.IsUndef && DV.Phi ==
nullptr;
325 for (
auto *DVR : BlockDbgRecordValues[&BB]) {
329 if (HasValidValue(LiveValue))
330 BlockDbgRanges.
push_back({LastIt, DVRStartIt, LiveValue});
337 if (HasValidValue(LiveValue))
338 BlockDbgRanges.
push_back({LastIt, BB.end(), LiveValue});
341 if (!BlockDbgRanges.
empty())
342 OrigVariableValueRangeTable[DVA].append(BlockDbgRanges);
355 OS <<
" SingleLoc: " << OrigSingleLocVariableValueTable[DVA] <<
"\n";
358 OS <<
" LocRange:\n";
359 for (
DbgRangeEntry RangeEntry : OrigVariableValueRangeTable[DVA]) {
361 if (RangeEntry.Start == RangeEntry.Start->getParent()->begin() &&
362 RangeEntry.End == RangeEntry.Start->getParent()->end()) {
363 OS << RangeEntry.Start->getParent()->getName();
365 OS << RangeEntry.Start->getParent()->getName() <<
": "
366 << *RangeEntry.Start <<
", ";
367 if (RangeEntry.End == RangeEntry.Start->getParent()->end())
370 OS << *RangeEntry.End;
372 OS <<
") [" << RangeEntry.Value <<
"]\n";
377 auto ExistingID = ValueToIDMap.find(V);
378 if (ExistingID != ValueToIDMap.end())
379 return ExistingID->second;
382 ValueToIDMap.insert({V, NewID});
384 assert(!ValueIDToNameMap.contains(NewID) &&
385 "New value ID already maps to a name?");
386 std::string &ValueText = ValueIDToNameMap[NewID];
388 V->printAsOperand(Stream,
true);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
bool isContained(DIScope *Inner, DIScope *Outer)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
DenseMap< MachineBasicBlock *, Register > AvailableValsTy
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
DILocalScope * getScope() const
Get the local scope for this variable.
Base class for scope-like contexts.
LLVM_ABI DIScope * getScope() const
StringRef getName() const
DebugSSAUpdater & Updater
DbgSSABlock * operator*()
Thin wrapper around a block successor iterator.
DebugSSAUpdater & Updater
DbgSSABlock * operator*()
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.
bool operator!=(const PHI_iterator &X) const
DbgSSABlock * getIncomingBlock()
DbgValueDef getIncomingValue()
PHI_iterator & operator++()
PHI_iterator(DbgSSAPhi *P)
bool operator==(const PHI_iterator &X) const
PHI_iterator(DbgSSAPhi *P, bool)
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)
DbgSSABlockSuccIterator BlkSucc_iterator
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.
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.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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