10b57cec5SDimitry Andric //===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
100b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
110b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
120b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
13e8d8bef9SDimitry Andric #include "llvm/CodeGen/LexicalScopes.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
150b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
210b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
220b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
240b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
260b57cec5SDimitry Andric #include <cassert>
270b57cec5SDimitry Andric #include <map>
28bdd1243dSDimitry Andric #include <optional>
290b57cec5SDimitry Andric #include <utility>
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric using namespace llvm;
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric #define DEBUG_TYPE "dwarfdebug"
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric namespace {
360b57cec5SDimitry Andric using EntryIndex = DbgValueHistoryMap::EntryIndex;
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric
initialize(const MachineFunction & MF)39e8d8bef9SDimitry Andric void InstructionOrdering::initialize(const MachineFunction &MF) {
40e8d8bef9SDimitry Andric // We give meta instructions the same ordinal as the preceding instruction
41e8d8bef9SDimitry Andric // because this class is written for the task of comparing positions of
42e8d8bef9SDimitry Andric // variable location ranges against scope ranges. To reflect what we'll see
43e8d8bef9SDimitry Andric // in the binary, when we look at location ranges we must consider all
44e8d8bef9SDimitry Andric // DBG_VALUEs between two real instructions at the same position. And a
45e8d8bef9SDimitry Andric // scope range which ends on a meta instruction should be considered to end
46e8d8bef9SDimitry Andric // at the last seen real instruction. E.g.
47e8d8bef9SDimitry Andric //
48e8d8bef9SDimitry Andric // 1 instruction p Both the variable location for x and for y start
49e8d8bef9SDimitry Andric // 1 DBG_VALUE for "x" after instruction p so we give them all the same
50e8d8bef9SDimitry Andric // 1 DBG_VALUE for "y" number. If a scope range ends at DBG_VALUE for "y",
51e8d8bef9SDimitry Andric // 2 instruction q we should treat it as ending after instruction p
52e8d8bef9SDimitry Andric // because it will be the last real instruction in the
53e8d8bef9SDimitry Andric // range. DBG_VALUEs at or after this position for
54e8d8bef9SDimitry Andric // variables declared in the scope will have no effect.
55e8d8bef9SDimitry Andric clear();
56e8d8bef9SDimitry Andric unsigned Position = 0;
57e8d8bef9SDimitry Andric for (const MachineBasicBlock &MBB : MF)
58e8d8bef9SDimitry Andric for (const MachineInstr &MI : MBB)
59e8d8bef9SDimitry Andric InstNumberMap[&MI] = MI.isMetaInstruction() ? Position : ++Position;
60e8d8bef9SDimitry Andric }
61e8d8bef9SDimitry Andric
isBefore(const MachineInstr * A,const MachineInstr * B) const62e8d8bef9SDimitry Andric bool InstructionOrdering::isBefore(const MachineInstr *A,
63e8d8bef9SDimitry Andric const MachineInstr *B) const {
64e8d8bef9SDimitry Andric assert(A->getParent() && B->getParent() && "Operands must have a parent");
65e8d8bef9SDimitry Andric assert(A->getMF() == B->getMF() &&
66e8d8bef9SDimitry Andric "Operands must be in the same MachineFunction");
67e8d8bef9SDimitry Andric return InstNumberMap.lookup(A) < InstNumberMap.lookup(B);
68e8d8bef9SDimitry Andric }
69e8d8bef9SDimitry Andric
startDbgValue(InlinedEntity Var,const MachineInstr & MI,EntryIndex & NewIndex)700b57cec5SDimitry Andric bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var,
710b57cec5SDimitry Andric const MachineInstr &MI,
720b57cec5SDimitry Andric EntryIndex &NewIndex) {
730b57cec5SDimitry Andric // Instruction range should start with a DBG_VALUE instruction for the
740b57cec5SDimitry Andric // variable.
750b57cec5SDimitry Andric assert(MI.isDebugValue() && "not a DBG_VALUE");
760b57cec5SDimitry Andric auto &Entries = VarEntries[Var];
770b57cec5SDimitry Andric if (!Entries.empty() && Entries.back().isDbgValue() &&
780b57cec5SDimitry Andric !Entries.back().isClosed() &&
79bdd1243dSDimitry Andric Entries.back().getInstr()->isEquivalentDbgInstr(MI)) {
800b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
810b57cec5SDimitry Andric << "\t" << Entries.back().getInstr() << "\t" << MI
820b57cec5SDimitry Andric << "\n");
830b57cec5SDimitry Andric return false;
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric Entries.emplace_back(&MI, Entry::DbgValue);
860b57cec5SDimitry Andric NewIndex = Entries.size() - 1;
870b57cec5SDimitry Andric return true;
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric
startClobber(InlinedEntity Var,const MachineInstr & MI)900b57cec5SDimitry Andric EntryIndex DbgValueHistoryMap::startClobber(InlinedEntity Var,
910b57cec5SDimitry Andric const MachineInstr &MI) {
920b57cec5SDimitry Andric auto &Entries = VarEntries[Var];
930b57cec5SDimitry Andric // If an instruction clobbers multiple registers that the variable is
940b57cec5SDimitry Andric // described by, then we may have already created a clobbering instruction.
950b57cec5SDimitry Andric if (Entries.back().isClobber() && Entries.back().getInstr() == &MI)
960b57cec5SDimitry Andric return Entries.size() - 1;
970b57cec5SDimitry Andric Entries.emplace_back(&MI, Entry::Clobber);
980b57cec5SDimitry Andric return Entries.size() - 1;
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric
endEntry(EntryIndex Index)1010b57cec5SDimitry Andric void DbgValueHistoryMap::Entry::endEntry(EntryIndex Index) {
1020b57cec5SDimitry Andric // For now, instruction ranges are not allowed to cross basic block
1030b57cec5SDimitry Andric // boundaries.
1040b57cec5SDimitry Andric assert(isDbgValue() && "Setting end index for non-debug value");
1050b57cec5SDimitry Andric assert(!isClosed() && "End index has already been set");
1060b57cec5SDimitry Andric EndIndex = Index;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric
109e8d8bef9SDimitry Andric /// Check if the instruction range [StartMI, EndMI] intersects any instruction
110e8d8bef9SDimitry Andric /// range in Ranges. EndMI can be nullptr to indicate that the range is
111e8d8bef9SDimitry Andric /// unbounded. Assumes Ranges is ordered and disjoint. Returns true and points
112e8d8bef9SDimitry Andric /// to the first intersecting scope range if one exists.
113bdd1243dSDimitry Andric static std::optional<ArrayRef<InsnRange>::iterator>
intersects(const MachineInstr * StartMI,const MachineInstr * EndMI,const ArrayRef<InsnRange> & Ranges,const InstructionOrdering & Ordering)114e8d8bef9SDimitry Andric intersects(const MachineInstr *StartMI, const MachineInstr *EndMI,
115e8d8bef9SDimitry Andric const ArrayRef<InsnRange> &Ranges,
116e8d8bef9SDimitry Andric const InstructionOrdering &Ordering) {
117e8d8bef9SDimitry Andric for (auto RangesI = Ranges.begin(), RangesE = Ranges.end();
118e8d8bef9SDimitry Andric RangesI != RangesE; ++RangesI) {
119e8d8bef9SDimitry Andric if (EndMI && Ordering.isBefore(EndMI, RangesI->first))
120bdd1243dSDimitry Andric return std::nullopt;
121e8d8bef9SDimitry Andric if (EndMI && !Ordering.isBefore(RangesI->second, EndMI))
122e8d8bef9SDimitry Andric return RangesI;
123e8d8bef9SDimitry Andric if (Ordering.isBefore(StartMI, RangesI->second))
124e8d8bef9SDimitry Andric return RangesI;
125e8d8bef9SDimitry Andric }
126bdd1243dSDimitry Andric return std::nullopt;
127e8d8bef9SDimitry Andric }
128e8d8bef9SDimitry Andric
trimLocationRanges(const MachineFunction & MF,LexicalScopes & LScopes,const InstructionOrdering & Ordering)129e8d8bef9SDimitry Andric void DbgValueHistoryMap::trimLocationRanges(
130e8d8bef9SDimitry Andric const MachineFunction &MF, LexicalScopes &LScopes,
131e8d8bef9SDimitry Andric const InstructionOrdering &Ordering) {
132e8d8bef9SDimitry Andric // The indices of the entries we're going to remove for each variable.
133e8d8bef9SDimitry Andric SmallVector<EntryIndex, 4> ToRemove;
134e8d8bef9SDimitry Andric // Entry reference count for each variable. Clobbers left with no references
135e8d8bef9SDimitry Andric // will be removed.
136e8d8bef9SDimitry Andric SmallVector<int, 4> ReferenceCount;
137e8d8bef9SDimitry Andric // Entries reference other entries by index. Offsets is used to remap these
138e8d8bef9SDimitry Andric // references if any entries are removed.
139e8d8bef9SDimitry Andric SmallVector<size_t, 4> Offsets;
140e8d8bef9SDimitry Andric
141*06c3fb27SDimitry Andric LLVM_DEBUG(dbgs() << "Trimming location ranges for function '" << MF.getName()
142*06c3fb27SDimitry Andric << "'\n");
143*06c3fb27SDimitry Andric
144e8d8bef9SDimitry Andric for (auto &Record : VarEntries) {
145e8d8bef9SDimitry Andric auto &HistoryMapEntries = Record.second;
146e8d8bef9SDimitry Andric if (HistoryMapEntries.empty())
147e8d8bef9SDimitry Andric continue;
148e8d8bef9SDimitry Andric
149e8d8bef9SDimitry Andric InlinedEntity Entity = Record.first;
150e8d8bef9SDimitry Andric const DILocalVariable *LocalVar = cast<DILocalVariable>(Entity.first);
151e8d8bef9SDimitry Andric
152e8d8bef9SDimitry Andric LexicalScope *Scope = nullptr;
153e8d8bef9SDimitry Andric if (const DILocation *InlinedAt = Entity.second) {
154e8d8bef9SDimitry Andric Scope = LScopes.findInlinedScope(LocalVar->getScope(), InlinedAt);
155e8d8bef9SDimitry Andric } else {
156e8d8bef9SDimitry Andric Scope = LScopes.findLexicalScope(LocalVar->getScope());
157e8d8bef9SDimitry Andric // Ignore variables for non-inlined function level scopes. The scope
158e8d8bef9SDimitry Andric // ranges (from scope->getRanges()) will not include any instructions
159e8d8bef9SDimitry Andric // before the first one with a debug-location, which could cause us to
160e8d8bef9SDimitry Andric // incorrectly drop a location. We could introduce special casing for
161e8d8bef9SDimitry Andric // these variables, but it doesn't seem worth it because no out-of-scope
162e8d8bef9SDimitry Andric // locations have been observed for variables declared in function level
163e8d8bef9SDimitry Andric // scopes.
164e8d8bef9SDimitry Andric if (Scope &&
165e8d8bef9SDimitry Andric (Scope->getScopeNode() == Scope->getScopeNode()->getSubprogram()) &&
166e8d8bef9SDimitry Andric (Scope->getScopeNode() == LocalVar->getScope()))
167e8d8bef9SDimitry Andric continue;
168e8d8bef9SDimitry Andric }
169e8d8bef9SDimitry Andric
170e8d8bef9SDimitry Andric // If there is no scope for the variable then something has probably gone
171e8d8bef9SDimitry Andric // wrong.
172e8d8bef9SDimitry Andric if (!Scope)
173e8d8bef9SDimitry Andric continue;
174e8d8bef9SDimitry Andric
175e8d8bef9SDimitry Andric ToRemove.clear();
176e8d8bef9SDimitry Andric // Zero the reference counts.
177e8d8bef9SDimitry Andric ReferenceCount.assign(HistoryMapEntries.size(), 0);
178e8d8bef9SDimitry Andric // Index of the DBG_VALUE which marks the start of the current location
179e8d8bef9SDimitry Andric // range.
180e8d8bef9SDimitry Andric EntryIndex StartIndex = 0;
181e8d8bef9SDimitry Andric ArrayRef<InsnRange> ScopeRanges(Scope->getRanges());
182e8d8bef9SDimitry Andric for (auto EI = HistoryMapEntries.begin(), EE = HistoryMapEntries.end();
183e8d8bef9SDimitry Andric EI != EE; ++EI, ++StartIndex) {
184e8d8bef9SDimitry Andric // Only DBG_VALUEs can open location ranges so skip anything else.
185e8d8bef9SDimitry Andric if (!EI->isDbgValue())
186e8d8bef9SDimitry Andric continue;
187e8d8bef9SDimitry Andric
188e8d8bef9SDimitry Andric // Index of the entry which closes this range.
189e8d8bef9SDimitry Andric EntryIndex EndIndex = EI->getEndIndex();
190e8d8bef9SDimitry Andric // If this range is closed bump the reference count of the closing entry.
191e8d8bef9SDimitry Andric if (EndIndex != NoEntry)
192e8d8bef9SDimitry Andric ReferenceCount[EndIndex] += 1;
193e8d8bef9SDimitry Andric // Skip this location range if the opening entry is still referenced. It
194e8d8bef9SDimitry Andric // may close a location range which intersects a scope range.
195e8d8bef9SDimitry Andric // TODO: We could be 'smarter' and trim these kinds of ranges such that
196e8d8bef9SDimitry Andric // they do not leak out of the scope ranges if they partially overlap.
197e8d8bef9SDimitry Andric if (ReferenceCount[StartIndex] > 0)
198e8d8bef9SDimitry Andric continue;
199e8d8bef9SDimitry Andric
200e8d8bef9SDimitry Andric const MachineInstr *StartMI = EI->getInstr();
201e8d8bef9SDimitry Andric const MachineInstr *EndMI = EndIndex != NoEntry
202e8d8bef9SDimitry Andric ? HistoryMapEntries[EndIndex].getInstr()
203e8d8bef9SDimitry Andric : nullptr;
204e8d8bef9SDimitry Andric // Check if the location range [StartMI, EndMI] intersects with any scope
205e8d8bef9SDimitry Andric // range for the variable.
206e8d8bef9SDimitry Andric if (auto R = intersects(StartMI, EndMI, ScopeRanges, Ordering)) {
207e8d8bef9SDimitry Andric // Adjust ScopeRanges to exclude ranges which subsequent location ranges
208e8d8bef9SDimitry Andric // cannot possibly intersect.
20981ad6265SDimitry Andric ScopeRanges = ArrayRef<InsnRange>(*R, ScopeRanges.end());
210e8d8bef9SDimitry Andric } else {
211e8d8bef9SDimitry Andric // If the location range does not intersect any scope range then the
212e8d8bef9SDimitry Andric // DBG_VALUE which opened this location range is usless, mark it for
213e8d8bef9SDimitry Andric // removal.
214e8d8bef9SDimitry Andric ToRemove.push_back(StartIndex);
215e8d8bef9SDimitry Andric // Because we'll be removing this entry we need to update the reference
216e8d8bef9SDimitry Andric // count of the closing entry, if one exists.
217e8d8bef9SDimitry Andric if (EndIndex != NoEntry)
218e8d8bef9SDimitry Andric ReferenceCount[EndIndex] -= 1;
219*06c3fb27SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping value outside scope range of variable: ";
220*06c3fb27SDimitry Andric StartMI->print(llvm::dbgs()););
221e8d8bef9SDimitry Andric }
222e8d8bef9SDimitry Andric }
223e8d8bef9SDimitry Andric
224e8d8bef9SDimitry Andric // If there is nothing to remove then jump to next variable.
225e8d8bef9SDimitry Andric if (ToRemove.empty())
226e8d8bef9SDimitry Andric continue;
227e8d8bef9SDimitry Andric
228e8d8bef9SDimitry Andric // Mark clobbers that will no longer close any location ranges for removal.
229e8d8bef9SDimitry Andric for (size_t i = 0; i < HistoryMapEntries.size(); ++i)
230e8d8bef9SDimitry Andric if (ReferenceCount[i] <= 0 && HistoryMapEntries[i].isClobber())
231e8d8bef9SDimitry Andric ToRemove.push_back(i);
232e8d8bef9SDimitry Andric
233e8d8bef9SDimitry Andric llvm::sort(ToRemove);
234e8d8bef9SDimitry Andric
235e8d8bef9SDimitry Andric // Build an offset map so we can update the EndIndex of the remaining
236e8d8bef9SDimitry Andric // entries.
237e8d8bef9SDimitry Andric // Zero the offsets.
238e8d8bef9SDimitry Andric Offsets.assign(HistoryMapEntries.size(), 0);
239e8d8bef9SDimitry Andric size_t CurOffset = 0;
240e8d8bef9SDimitry Andric auto ToRemoveItr = ToRemove.begin();
241e8d8bef9SDimitry Andric for (size_t EntryIdx = *ToRemoveItr; EntryIdx < HistoryMapEntries.size();
242e8d8bef9SDimitry Andric ++EntryIdx) {
243e8d8bef9SDimitry Andric // Check if this is an entry which will be removed.
244e8d8bef9SDimitry Andric if (ToRemoveItr != ToRemove.end() && *ToRemoveItr == EntryIdx) {
245e8d8bef9SDimitry Andric ++ToRemoveItr;
246e8d8bef9SDimitry Andric ++CurOffset;
247e8d8bef9SDimitry Andric }
248e8d8bef9SDimitry Andric Offsets[EntryIdx] = CurOffset;
249e8d8bef9SDimitry Andric }
250e8d8bef9SDimitry Andric
251e8d8bef9SDimitry Andric // Update the EndIndex of the entries to account for those which will be
252e8d8bef9SDimitry Andric // removed.
253e8d8bef9SDimitry Andric for (auto &Entry : HistoryMapEntries)
254e8d8bef9SDimitry Andric if (Entry.isClosed())
255e8d8bef9SDimitry Andric Entry.EndIndex -= Offsets[Entry.EndIndex];
256e8d8bef9SDimitry Andric
257e8d8bef9SDimitry Andric // Now actually remove the entries. Iterate backwards so that our remaining
258e8d8bef9SDimitry Andric // ToRemove indices are valid after each erase.
259349cc55cSDimitry Andric for (EntryIndex Idx : llvm::reverse(ToRemove))
260349cc55cSDimitry Andric HistoryMapEntries.erase(HistoryMapEntries.begin() + Idx);
261*06c3fb27SDimitry Andric LLVM_DEBUG(llvm::dbgs() << "New HistoryMap('" << LocalVar->getName()
262*06c3fb27SDimitry Andric << "') size: " << HistoryMapEntries.size() << "\n");
263e8d8bef9SDimitry Andric }
264e8d8bef9SDimitry Andric }
265e8d8bef9SDimitry Andric
hasNonEmptyLocation(const Entries & Entries) const266fe6060f1SDimitry Andric bool DbgValueHistoryMap::hasNonEmptyLocation(const Entries &Entries) const {
267fe6060f1SDimitry Andric for (const auto &Entry : Entries) {
268fe6060f1SDimitry Andric if (!Entry.isDbgValue())
269fe6060f1SDimitry Andric continue;
270fe6060f1SDimitry Andric
271fe6060f1SDimitry Andric const MachineInstr *MI = Entry.getInstr();
272fe6060f1SDimitry Andric assert(MI->isDebugValue());
273fe6060f1SDimitry Andric // A DBG_VALUE $noreg is an empty variable location
274bdd1243dSDimitry Andric if (MI->isUndefDebugValue())
275fe6060f1SDimitry Andric continue;
276fe6060f1SDimitry Andric
277fe6060f1SDimitry Andric return true;
278fe6060f1SDimitry Andric }
279fe6060f1SDimitry Andric
280fe6060f1SDimitry Andric return false;
281fe6060f1SDimitry Andric }
282fe6060f1SDimitry Andric
addInstr(InlinedEntity Label,const MachineInstr & MI)2830b57cec5SDimitry Andric void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) {
2840b57cec5SDimitry Andric assert(MI.isDebugLabel() && "not a DBG_LABEL");
2850b57cec5SDimitry Andric LabelInstr[Label] = &MI;
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric
2880b57cec5SDimitry Andric namespace {
2890b57cec5SDimitry Andric
2900b57cec5SDimitry Andric // Maps physreg numbers to the variables they describe.
2910b57cec5SDimitry Andric using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
2920b57cec5SDimitry Andric using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>;
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andric // Keeps track of the debug value entries that are currently live for each
2950b57cec5SDimitry Andric // inlined entity. As the history map entries are stored in a SmallVector, they
2960b57cec5SDimitry Andric // may be moved at insertion of new entries, so store indices rather than
2970b57cec5SDimitry Andric // pointers.
2980b57cec5SDimitry Andric using DbgValueEntriesMap = std::map<InlinedEntity, SmallSet<EntryIndex, 1>>;
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andric } // end anonymous namespace
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric // Claim that @Var is not described by @RegNo anymore.
dropRegDescribedVar(RegDescribedVarsMap & RegVars,unsigned RegNo,InlinedEntity Var)3030b57cec5SDimitry Andric static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
3040b57cec5SDimitry Andric InlinedEntity Var) {
3050b57cec5SDimitry Andric const auto &I = RegVars.find(RegNo);
3060b57cec5SDimitry Andric assert(RegNo != 0U && I != RegVars.end());
3070b57cec5SDimitry Andric auto &VarSet = I->second;
3080b57cec5SDimitry Andric const auto &VarPos = llvm::find(VarSet, Var);
3090b57cec5SDimitry Andric assert(VarPos != VarSet.end());
3100b57cec5SDimitry Andric VarSet.erase(VarPos);
3110b57cec5SDimitry Andric // Don't keep empty sets in a map to keep it as small as possible.
3120b57cec5SDimitry Andric if (VarSet.empty())
3130b57cec5SDimitry Andric RegVars.erase(I);
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric // Claim that @Var is now described by @RegNo.
addRegDescribedVar(RegDescribedVarsMap & RegVars,unsigned RegNo,InlinedEntity Var)3170b57cec5SDimitry Andric static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
3180b57cec5SDimitry Andric InlinedEntity Var) {
3190b57cec5SDimitry Andric assert(RegNo != 0U);
3200b57cec5SDimitry Andric auto &VarSet = RegVars[RegNo];
3210b57cec5SDimitry Andric assert(!is_contained(VarSet, Var));
3220b57cec5SDimitry Andric VarSet.push_back(Var);
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andric /// Create a clobbering entry and end all open debug value entries
326fe6060f1SDimitry Andric /// for \p Var that are described by \p RegNo using that entry. Inserts into \p
327fe6060f1SDimitry Andric /// FellowRegisters the set of Registers that were also used to describe \p Var
328fe6060f1SDimitry Andric /// alongside \p RegNo.
clobberRegEntries(InlinedEntity Var,unsigned RegNo,const MachineInstr & ClobberingInstr,DbgValueEntriesMap & LiveEntries,DbgValueHistoryMap & HistMap,SmallVectorImpl<Register> & FellowRegisters)3290b57cec5SDimitry Andric static void clobberRegEntries(InlinedEntity Var, unsigned RegNo,
3300b57cec5SDimitry Andric const MachineInstr &ClobberingInstr,
3310b57cec5SDimitry Andric DbgValueEntriesMap &LiveEntries,
332fe6060f1SDimitry Andric DbgValueHistoryMap &HistMap,
333fe6060f1SDimitry Andric SmallVectorImpl<Register> &FellowRegisters) {
3340b57cec5SDimitry Andric EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr);
3350b57cec5SDimitry Andric // Close all entries whose values are described by the register.
3360b57cec5SDimitry Andric SmallVector<EntryIndex, 4> IndicesToErase;
337fe6060f1SDimitry Andric // If a given register appears in a live DBG_VALUE_LIST for Var alongside the
338fe6060f1SDimitry Andric // clobbered register, and never appears in a live DBG_VALUE* for Var without
339fe6060f1SDimitry Andric // the clobbered register, then it is no longer linked to the variable.
340fe6060f1SDimitry Andric SmallSet<Register, 4> MaybeRemovedRegisters;
341fe6060f1SDimitry Andric SmallSet<Register, 4> KeepRegisters;
3420b57cec5SDimitry Andric for (auto Index : LiveEntries[Var]) {
3430b57cec5SDimitry Andric auto &Entry = HistMap.getEntry(Var, Index);
3440b57cec5SDimitry Andric assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
345fe6060f1SDimitry Andric if (Entry.getInstr()->isDebugEntryValue())
346fe6060f1SDimitry Andric continue;
347fe6060f1SDimitry Andric if (Entry.getInstr()->hasDebugOperandForReg(RegNo)) {
3480b57cec5SDimitry Andric IndicesToErase.push_back(Index);
3490b57cec5SDimitry Andric Entry.endEntry(ClobberIndex);
350fcaf7f86SDimitry Andric for (const auto &MO : Entry.getInstr()->debug_operands())
351fe6060f1SDimitry Andric if (MO.isReg() && MO.getReg() && MO.getReg() != RegNo)
352fe6060f1SDimitry Andric MaybeRemovedRegisters.insert(MO.getReg());
353fe6060f1SDimitry Andric } else {
354fcaf7f86SDimitry Andric for (const auto &MO : Entry.getInstr()->debug_operands())
355fe6060f1SDimitry Andric if (MO.isReg() && MO.getReg())
356fe6060f1SDimitry Andric KeepRegisters.insert(MO.getReg());
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric
360fe6060f1SDimitry Andric for (Register Reg : MaybeRemovedRegisters)
361fe6060f1SDimitry Andric if (!KeepRegisters.contains(Reg))
362fe6060f1SDimitry Andric FellowRegisters.push_back(Reg);
363fe6060f1SDimitry Andric
3640b57cec5SDimitry Andric // Drop all entries that have ended.
3650b57cec5SDimitry Andric for (auto Index : IndicesToErase)
3660b57cec5SDimitry Andric LiveEntries[Var].erase(Index);
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andric /// Add a new debug value for \p Var. Closes all overlapping debug values.
handleNewDebugValue(InlinedEntity Var,const MachineInstr & DV,RegDescribedVarsMap & RegVars,DbgValueEntriesMap & LiveEntries,DbgValueHistoryMap & HistMap)3700b57cec5SDimitry Andric static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV,
3710b57cec5SDimitry Andric RegDescribedVarsMap &RegVars,
3720b57cec5SDimitry Andric DbgValueEntriesMap &LiveEntries,
3730b57cec5SDimitry Andric DbgValueHistoryMap &HistMap) {
3740b57cec5SDimitry Andric EntryIndex NewIndex;
3750b57cec5SDimitry Andric if (HistMap.startDbgValue(Var, DV, NewIndex)) {
3760b57cec5SDimitry Andric SmallDenseMap<unsigned, bool, 4> TrackedRegs;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric // If we have created a new debug value entry, close all preceding
3790b57cec5SDimitry Andric // live entries that overlap.
3800b57cec5SDimitry Andric SmallVector<EntryIndex, 4> IndicesToErase;
3810b57cec5SDimitry Andric const DIExpression *DIExpr = DV.getDebugExpression();
3820b57cec5SDimitry Andric for (auto Index : LiveEntries[Var]) {
3830b57cec5SDimitry Andric auto &Entry = HistMap.getEntry(Var, Index);
3840b57cec5SDimitry Andric assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
3850b57cec5SDimitry Andric const MachineInstr &DV = *Entry.getInstr();
3860b57cec5SDimitry Andric bool Overlaps = DIExpr->fragmentsOverlap(DV.getDebugExpression());
3870b57cec5SDimitry Andric if (Overlaps) {
3880b57cec5SDimitry Andric IndicesToErase.push_back(Index);
3890b57cec5SDimitry Andric Entry.endEntry(NewIndex);
3900b57cec5SDimitry Andric }
391fe6060f1SDimitry Andric if (!DV.isDebugEntryValue())
392fe6060f1SDimitry Andric for (const MachineOperand &Op : DV.debug_operands())
393fe6060f1SDimitry Andric if (Op.isReg() && Op.getReg())
394fe6060f1SDimitry Andric TrackedRegs[Op.getReg()] |= !Overlaps;
3950b57cec5SDimitry Andric }
3960b57cec5SDimitry Andric
3970b57cec5SDimitry Andric // If the new debug value is described by a register, add tracking of
3980b57cec5SDimitry Andric // that register if it is not already tracked.
399fe6060f1SDimitry Andric if (!DV.isDebugEntryValue()) {
400fe6060f1SDimitry Andric for (const MachineOperand &Op : DV.debug_operands()) {
401fe6060f1SDimitry Andric if (Op.isReg() && Op.getReg()) {
402fe6060f1SDimitry Andric Register NewReg = Op.getReg();
4030b57cec5SDimitry Andric if (!TrackedRegs.count(NewReg))
4040b57cec5SDimitry Andric addRegDescribedVar(RegVars, NewReg, Var);
4050b57cec5SDimitry Andric LiveEntries[Var].insert(NewIndex);
4060b57cec5SDimitry Andric TrackedRegs[NewReg] = true;
4070b57cec5SDimitry Andric }
408fe6060f1SDimitry Andric }
409fe6060f1SDimitry Andric }
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andric // Drop tracking of registers that are no longer used.
4120b57cec5SDimitry Andric for (auto I : TrackedRegs)
4130b57cec5SDimitry Andric if (!I.second)
4140b57cec5SDimitry Andric dropRegDescribedVar(RegVars, I.first, Var);
4150b57cec5SDimitry Andric
4160b57cec5SDimitry Andric // Drop all entries that have ended, and mark the new entry as live.
4170b57cec5SDimitry Andric for (auto Index : IndicesToErase)
4180b57cec5SDimitry Andric LiveEntries[Var].erase(Index);
4190b57cec5SDimitry Andric LiveEntries[Var].insert(NewIndex);
4200b57cec5SDimitry Andric }
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric // Terminate the location range for variables described by register at
4240b57cec5SDimitry Andric // @I by inserting @ClobberingInstr to their history.
clobberRegisterUses(RegDescribedVarsMap & RegVars,RegDescribedVarsMap::iterator I,DbgValueHistoryMap & HistMap,DbgValueEntriesMap & LiveEntries,const MachineInstr & ClobberingInstr)4250b57cec5SDimitry Andric static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
4260b57cec5SDimitry Andric RegDescribedVarsMap::iterator I,
4270b57cec5SDimitry Andric DbgValueHistoryMap &HistMap,
4280b57cec5SDimitry Andric DbgValueEntriesMap &LiveEntries,
4290b57cec5SDimitry Andric const MachineInstr &ClobberingInstr) {
4300b57cec5SDimitry Andric // Iterate over all variables described by this register and add this
431fe6060f1SDimitry Andric // instruction to their history, clobbering it. All registers that also
432fe6060f1SDimitry Andric // describe the clobbered variables (i.e. in variadic debug values) will have
433fe6060f1SDimitry Andric // those Variables removed from their DescribedVars.
434fe6060f1SDimitry Andric for (const auto &Var : I->second) {
435fe6060f1SDimitry Andric SmallVector<Register, 4> FellowRegisters;
436fe6060f1SDimitry Andric clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap,
437fe6060f1SDimitry Andric FellowRegisters);
438fe6060f1SDimitry Andric for (Register RegNo : FellowRegisters)
439fe6060f1SDimitry Andric dropRegDescribedVar(RegVars, RegNo, Var);
440fe6060f1SDimitry Andric }
4410b57cec5SDimitry Andric RegVars.erase(I);
4420b57cec5SDimitry Andric }
4430b57cec5SDimitry Andric
4440b57cec5SDimitry Andric // Terminate the location range for variables described by register
4450b57cec5SDimitry Andric // @RegNo by inserting @ClobberingInstr to their history.
clobberRegisterUses(RegDescribedVarsMap & RegVars,unsigned RegNo,DbgValueHistoryMap & HistMap,DbgValueEntriesMap & LiveEntries,const MachineInstr & ClobberingInstr)4460b57cec5SDimitry Andric static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo,
4470b57cec5SDimitry Andric DbgValueHistoryMap &HistMap,
4480b57cec5SDimitry Andric DbgValueEntriesMap &LiveEntries,
4490b57cec5SDimitry Andric const MachineInstr &ClobberingInstr) {
4500b57cec5SDimitry Andric const auto &I = RegVars.find(RegNo);
4510b57cec5SDimitry Andric if (I == RegVars.end())
4520b57cec5SDimitry Andric return;
4530b57cec5SDimitry Andric clobberRegisterUses(RegVars, I, HistMap, LiveEntries, ClobberingInstr);
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric
calculateDbgEntityHistory(const MachineFunction * MF,const TargetRegisterInfo * TRI,DbgValueHistoryMap & DbgValues,DbgLabelInstrMap & DbgLabels)4560b57cec5SDimitry Andric void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
4570b57cec5SDimitry Andric const TargetRegisterInfo *TRI,
4580b57cec5SDimitry Andric DbgValueHistoryMap &DbgValues,
4590b57cec5SDimitry Andric DbgLabelInstrMap &DbgLabels) {
4600b57cec5SDimitry Andric const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
461e8d8bef9SDimitry Andric Register SP = TLI->getStackPointerRegisterToSaveRestore();
4628bcb0991SDimitry Andric Register FrameReg = TRI->getFrameRegister(*MF);
4630b57cec5SDimitry Andric RegDescribedVarsMap RegVars;
4640b57cec5SDimitry Andric DbgValueEntriesMap LiveEntries;
4650b57cec5SDimitry Andric for (const auto &MBB : *MF) {
4660b57cec5SDimitry Andric for (const auto &MI : MBB) {
4670b57cec5SDimitry Andric if (MI.isDebugValue()) {
4680b57cec5SDimitry Andric assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
4690b57cec5SDimitry Andric // Use the base variable (without any DW_OP_piece expressions)
4700b57cec5SDimitry Andric // as index into History. The full variables including the
4710b57cec5SDimitry Andric // piece expressions are attached to the MI.
4720b57cec5SDimitry Andric const DILocalVariable *RawVar = MI.getDebugVariable();
4730b57cec5SDimitry Andric assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
4740b57cec5SDimitry Andric "Expected inlined-at fields to agree");
4750b57cec5SDimitry Andric InlinedEntity Var(RawVar, MI.getDebugLoc()->getInlinedAt());
4760b57cec5SDimitry Andric
4770b57cec5SDimitry Andric handleNewDebugValue(Var, MI, RegVars, LiveEntries, DbgValues);
4780b57cec5SDimitry Andric } else if (MI.isDebugLabel()) {
4790b57cec5SDimitry Andric assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!");
4800b57cec5SDimitry Andric const DILabel *RawLabel = MI.getDebugLabel();
4810b57cec5SDimitry Andric assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
4820b57cec5SDimitry Andric "Expected inlined-at fields to agree");
4830b57cec5SDimitry Andric // When collecting debug information for labels, there is no MCSymbol
4840b57cec5SDimitry Andric // generated for it. So, we keep MachineInstr in DbgLabels in order
4850b57cec5SDimitry Andric // to query MCSymbol afterward.
4860b57cec5SDimitry Andric InlinedEntity L(RawLabel, MI.getDebugLoc()->getInlinedAt());
4870b57cec5SDimitry Andric DbgLabels.addInstr(L, MI);
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric
490480093f4SDimitry Andric // Meta Instructions have no output and do not change any values and so
491480093f4SDimitry Andric // can be safely ignored.
492480093f4SDimitry Andric if (MI.isMetaInstruction())
4930b57cec5SDimitry Andric continue;
4940b57cec5SDimitry Andric
4950b57cec5SDimitry Andric // Not a DBG_VALUE instruction. It may clobber registers which describe
4960b57cec5SDimitry Andric // some variables.
4970b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) {
4980b57cec5SDimitry Andric if (MO.isReg() && MO.isDef() && MO.getReg()) {
4990b57cec5SDimitry Andric // Ignore call instructions that claim to clobber SP. The AArch64
5000b57cec5SDimitry Andric // backend does this for aggregate function arguments.
5010b57cec5SDimitry Andric if (MI.isCall() && MO.getReg() == SP)
5020b57cec5SDimitry Andric continue;
5030b57cec5SDimitry Andric // If this is a virtual register, only clobber it since it doesn't
5040b57cec5SDimitry Andric // have aliases.
505bdd1243dSDimitry Andric if (MO.getReg().isVirtual())
5060b57cec5SDimitry Andric clobberRegisterUses(RegVars, MO.getReg(), DbgValues, LiveEntries,
5070b57cec5SDimitry Andric MI);
5080b57cec5SDimitry Andric // If this is a register def operand, it may end a debug value
5090b57cec5SDimitry Andric // range. Ignore frame-register defs in the epilogue and prologue,
5100b57cec5SDimitry Andric // we expect debuggers to understand that stack-locations are
5110b57cec5SDimitry Andric // invalid outside of the function body.
5120b57cec5SDimitry Andric else if (MO.getReg() != FrameReg ||
5130b57cec5SDimitry Andric (!MI.getFlag(MachineInstr::FrameDestroy) &&
5140b57cec5SDimitry Andric !MI.getFlag(MachineInstr::FrameSetup))) {
5150b57cec5SDimitry Andric for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
5160b57cec5SDimitry Andric ++AI)
5170b57cec5SDimitry Andric clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI);
5180b57cec5SDimitry Andric }
5190b57cec5SDimitry Andric } else if (MO.isRegMask()) {
5200b57cec5SDimitry Andric // If this is a register mask operand, clobber all debug values in
5210b57cec5SDimitry Andric // non-CSRs.
5220b57cec5SDimitry Andric SmallVector<unsigned, 32> RegsToClobber;
5230b57cec5SDimitry Andric // Don't consider SP to be clobbered by register masks.
5240b57cec5SDimitry Andric for (auto It : RegVars) {
5250b57cec5SDimitry Andric unsigned int Reg = It.first;
5268bcb0991SDimitry Andric if (Reg != SP && Register::isPhysicalRegister(Reg) &&
5270b57cec5SDimitry Andric MO.clobbersPhysReg(Reg))
5280b57cec5SDimitry Andric RegsToClobber.push_back(Reg);
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric for (unsigned Reg : RegsToClobber) {
5320b57cec5SDimitry Andric clobberRegisterUses(RegVars, Reg, DbgValues, LiveEntries, MI);
5330b57cec5SDimitry Andric }
5340b57cec5SDimitry Andric }
5350b57cec5SDimitry Andric } // End MO loop.
5360b57cec5SDimitry Andric } // End instr loop.
5370b57cec5SDimitry Andric
5380b57cec5SDimitry Andric // Make sure locations for all variables are valid only until the end of
5390b57cec5SDimitry Andric // the basic block (unless it's the last basic block, in which case let
5400b57cec5SDimitry Andric // their liveness run off to the end of the function).
5410b57cec5SDimitry Andric if (!MBB.empty() && &MBB != &MF->back()) {
5420b57cec5SDimitry Andric // Iterate over all variables that have open debug values.
5430b57cec5SDimitry Andric for (auto &Pair : LiveEntries) {
5440b57cec5SDimitry Andric if (Pair.second.empty())
5450b57cec5SDimitry Andric continue;
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric // Create a clobbering entry.
5480b57cec5SDimitry Andric EntryIndex ClobIdx = DbgValues.startClobber(Pair.first, MBB.back());
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric // End all entries.
5510b57cec5SDimitry Andric for (EntryIndex Idx : Pair.second) {
5520b57cec5SDimitry Andric DbgValueHistoryMap::Entry &Ent = DbgValues.getEntry(Pair.first, Idx);
5530b57cec5SDimitry Andric assert(Ent.isDbgValue() && !Ent.isClosed());
5540b57cec5SDimitry Andric Ent.endEntry(ClobIdx);
5550b57cec5SDimitry Andric }
5560b57cec5SDimitry Andric }
5570b57cec5SDimitry Andric
5580b57cec5SDimitry Andric LiveEntries.clear();
5590b57cec5SDimitry Andric RegVars.clear();
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric
5640b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump(StringRef FuncName) const565*06c3fb27SDimitry Andric LLVM_DUMP_METHOD void DbgValueHistoryMap::dump(StringRef FuncName) const {
566*06c3fb27SDimitry Andric dbgs() << "DbgValueHistoryMap('" << FuncName << "'):\n";
5670b57cec5SDimitry Andric for (const auto &VarRangePair : *this) {
5680b57cec5SDimitry Andric const InlinedEntity &Var = VarRangePair.first;
5690b57cec5SDimitry Andric const Entries &Entries = VarRangePair.second;
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andric const DILocalVariable *LocalVar = cast<DILocalVariable>(Var.first);
5720b57cec5SDimitry Andric const DILocation *Location = Var.second;
5730b57cec5SDimitry Andric
5740b57cec5SDimitry Andric dbgs() << " - " << LocalVar->getName() << " at ";
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric if (Location)
5770b57cec5SDimitry Andric dbgs() << Location->getFilename() << ":" << Location->getLine() << ":"
5780b57cec5SDimitry Andric << Location->getColumn();
5790b57cec5SDimitry Andric else
5800b57cec5SDimitry Andric dbgs() << "<unknown location>";
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric dbgs() << " --\n";
5830b57cec5SDimitry Andric
5840b57cec5SDimitry Andric for (const auto &E : enumerate(Entries)) {
5850b57cec5SDimitry Andric const auto &Entry = E.value();
5860b57cec5SDimitry Andric dbgs() << " Entry[" << E.index() << "]: ";
5870b57cec5SDimitry Andric if (Entry.isDbgValue())
5880b57cec5SDimitry Andric dbgs() << "Debug value\n";
5890b57cec5SDimitry Andric else
5900b57cec5SDimitry Andric dbgs() << "Clobber\n";
5910b57cec5SDimitry Andric dbgs() << " Instr: " << *Entry.getInstr();
5920b57cec5SDimitry Andric if (Entry.isDbgValue()) {
5930b57cec5SDimitry Andric if (Entry.getEndIndex() == NoEntry)
5940b57cec5SDimitry Andric dbgs() << " - Valid until end of function\n";
5950b57cec5SDimitry Andric else
5960b57cec5SDimitry Andric dbgs() << " - Closed by Entry[" << Entry.getEndIndex() << "]\n";
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric dbgs() << "\n";
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric }
6020b57cec5SDimitry Andric #endif
603