12532ac88SHsiangkai Wang //===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp -------------===//
22532ac88SHsiangkai Wang //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62532ac88SHsiangkai Wang //
72532ac88SHsiangkai Wang //===----------------------------------------------------------------------===//
82532ac88SHsiangkai Wang
961b189e0SYonghong Song #include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
10ce6de374SOCHyams #include "llvm/ADT/Optional.h"
112532ac88SHsiangkai Wang #include "llvm/ADT/STLExtras.h"
125ffec6deSDavid Stenberg #include "llvm/ADT/SmallSet.h"
132532ac88SHsiangkai Wang #include "llvm/ADT/SmallVector.h"
14ce6de374SOCHyams #include "llvm/CodeGen/LexicalScopes.h"
152532ac88SHsiangkai Wang #include "llvm/CodeGen/MachineBasicBlock.h"
162532ac88SHsiangkai Wang #include "llvm/CodeGen/MachineFunction.h"
172532ac88SHsiangkai Wang #include "llvm/CodeGen/MachineInstr.h"
182532ac88SHsiangkai Wang #include "llvm/CodeGen/MachineOperand.h"
192532ac88SHsiangkai Wang #include "llvm/CodeGen/TargetLowering.h"
202532ac88SHsiangkai Wang #include "llvm/CodeGen/TargetRegisterInfo.h"
212532ac88SHsiangkai Wang #include "llvm/CodeGen/TargetSubtargetInfo.h"
222532ac88SHsiangkai Wang #include "llvm/IR/DebugInfoMetadata.h"
232532ac88SHsiangkai Wang #include "llvm/IR/DebugLoc.h"
242532ac88SHsiangkai Wang #include "llvm/MC/MCRegisterInfo.h"
252532ac88SHsiangkai Wang #include "llvm/Support/Debug.h"
262532ac88SHsiangkai Wang #include "llvm/Support/raw_ostream.h"
272532ac88SHsiangkai Wang #include <cassert>
282532ac88SHsiangkai Wang #include <map>
292532ac88SHsiangkai Wang #include <utility>
302532ac88SHsiangkai Wang
312532ac88SHsiangkai Wang using namespace llvm;
322532ac88SHsiangkai Wang
332532ac88SHsiangkai Wang #define DEBUG_TYPE "dwarfdebug"
342532ac88SHsiangkai Wang
355ffec6deSDavid Stenberg namespace {
365ffec6deSDavid Stenberg using EntryIndex = DbgValueHistoryMap::EntryIndex;
375ffec6deSDavid Stenberg }
385ffec6deSDavid Stenberg
initialize(const MachineFunction & MF)39e048ea7bSOCHyams void InstructionOrdering::initialize(const MachineFunction &MF) {
40e048ea7bSOCHyams // We give meta instructions the same ordinal as the preceding instruction
41e048ea7bSOCHyams // because this class is written for the task of comparing positions of
42e048ea7bSOCHyams // variable location ranges against scope ranges. To reflect what we'll see
43e048ea7bSOCHyams // in the binary, when we look at location ranges we must consider all
44e048ea7bSOCHyams // DBG_VALUEs between two real instructions at the same position. And a
45e048ea7bSOCHyams // scope range which ends on a meta instruction should be considered to end
46e048ea7bSOCHyams // at the last seen real instruction. E.g.
47e048ea7bSOCHyams //
48e048ea7bSOCHyams // 1 instruction p Both the variable location for x and for y start
49e048ea7bSOCHyams // 1 DBG_VALUE for "x" after instruction p so we give them all the same
50e048ea7bSOCHyams // 1 DBG_VALUE for "y" number. If a scope range ends at DBG_VALUE for "y",
51e048ea7bSOCHyams // 2 instruction q we should treat it as ending after instruction p
52e048ea7bSOCHyams // because it will be the last real instruction in the
53e048ea7bSOCHyams // range. DBG_VALUEs at or after this position for
54e048ea7bSOCHyams // variables declared in the scope will have no effect.
55e048ea7bSOCHyams clear();
56e048ea7bSOCHyams unsigned Position = 0;
57e048ea7bSOCHyams for (const MachineBasicBlock &MBB : MF)
58e048ea7bSOCHyams for (const MachineInstr &MI : MBB)
59e048ea7bSOCHyams InstNumberMap[&MI] = MI.isMetaInstruction() ? Position : ++Position;
60e048ea7bSOCHyams }
61e048ea7bSOCHyams
isBefore(const MachineInstr * A,const MachineInstr * B) const62e048ea7bSOCHyams bool InstructionOrdering::isBefore(const MachineInstr *A,
63e048ea7bSOCHyams const MachineInstr *B) const {
64e048ea7bSOCHyams assert(A->getParent() && B->getParent() && "Operands must have a parent");
65e048ea7bSOCHyams assert(A->getMF() == B->getMF() &&
66e048ea7bSOCHyams "Operands must be in the same MachineFunction");
67e048ea7bSOCHyams return InstNumberMap.lookup(A) < InstNumberMap.lookup(B);
68e048ea7bSOCHyams }
69e048ea7bSOCHyams
startDbgValue(InlinedEntity Var,const MachineInstr & MI,EntryIndex & NewIndex)705ffec6deSDavid Stenberg bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var,
715ffec6deSDavid Stenberg const MachineInstr &MI,
725ffec6deSDavid Stenberg EntryIndex &NewIndex) {
732532ac88SHsiangkai Wang // Instruction range should start with a DBG_VALUE instruction for the
742532ac88SHsiangkai Wang // variable.
752532ac88SHsiangkai Wang assert(MI.isDebugValue() && "not a DBG_VALUE");
766feef56dSDavid Stenberg auto &Entries = VarEntries[Var];
775ffec6deSDavid Stenberg if (!Entries.empty() && Entries.back().isDbgValue() &&
785ffec6deSDavid Stenberg !Entries.back().isClosed() &&
795ffec6deSDavid Stenberg Entries.back().getInstr()->isIdenticalTo(MI)) {
802532ac88SHsiangkai Wang LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
815ffec6deSDavid Stenberg << "\t" << Entries.back().getInstr() << "\t" << MI
823739979cSDavid Stenberg << "\n");
835ffec6deSDavid Stenberg return false;
842532ac88SHsiangkai Wang }
855ffec6deSDavid Stenberg Entries.emplace_back(&MI, Entry::DbgValue);
865ffec6deSDavid Stenberg NewIndex = Entries.size() - 1;
875ffec6deSDavid Stenberg return true;
882532ac88SHsiangkai Wang }
892532ac88SHsiangkai Wang
startClobber(InlinedEntity Var,const MachineInstr & MI)905ffec6deSDavid Stenberg EntryIndex DbgValueHistoryMap::startClobber(InlinedEntity Var,
915ffec6deSDavid Stenberg const MachineInstr &MI) {
926feef56dSDavid Stenberg auto &Entries = VarEntries[Var];
93b96943b6SDavid Stenberg // If an instruction clobbers multiple registers that the variable is
94b96943b6SDavid Stenberg // described by, then we may have already created a clobbering instruction.
95b96943b6SDavid Stenberg if (Entries.back().isClobber() && Entries.back().getInstr() == &MI)
96b96943b6SDavid Stenberg return Entries.size() - 1;
975ffec6deSDavid Stenberg Entries.emplace_back(&MI, Entry::Clobber);
985ffec6deSDavid Stenberg return Entries.size() - 1;
993739979cSDavid Stenberg }
1003739979cSDavid Stenberg
endEntry(EntryIndex Index)1015ffec6deSDavid Stenberg void DbgValueHistoryMap::Entry::endEntry(EntryIndex Index) {
1022532ac88SHsiangkai Wang // For now, instruction ranges are not allowed to cross basic block
1032532ac88SHsiangkai Wang // boundaries.
1045ffec6deSDavid Stenberg assert(isDbgValue() && "Setting end index for non-debug value");
1055ffec6deSDavid Stenberg assert(!isClosed() && "End index has already been set");
1065ffec6deSDavid Stenberg EndIndex = Index;
1072532ac88SHsiangkai Wang }
1082532ac88SHsiangkai Wang
109ce6de374SOCHyams /// Check if the instruction range [StartMI, EndMI] intersects any instruction
110ce6de374SOCHyams /// range in Ranges. EndMI can be nullptr to indicate that the range is
111ce6de374SOCHyams /// unbounded. Assumes Ranges is ordered and disjoint. Returns true and points
112ce6de374SOCHyams /// to the first intersecting scope range if one exists.
113ce6de374SOCHyams static Optional<ArrayRef<InsnRange>::iterator>
intersects(const MachineInstr * StartMI,const MachineInstr * EndMI,const ArrayRef<InsnRange> & Ranges,const InstructionOrdering & Ordering)114ce6de374SOCHyams intersects(const MachineInstr *StartMI, const MachineInstr *EndMI,
115e048ea7bSOCHyams const ArrayRef<InsnRange> &Ranges,
116e048ea7bSOCHyams const InstructionOrdering &Ordering) {
117ce6de374SOCHyams for (auto RangesI = Ranges.begin(), RangesE = Ranges.end();
118ce6de374SOCHyams RangesI != RangesE; ++RangesI) {
119e048ea7bSOCHyams if (EndMI && Ordering.isBefore(EndMI, RangesI->first))
120ce6de374SOCHyams return None;
121e048ea7bSOCHyams if (EndMI && !Ordering.isBefore(RangesI->second, EndMI))
122ce6de374SOCHyams return RangesI;
123e048ea7bSOCHyams if (Ordering.isBefore(StartMI, RangesI->second))
124ce6de374SOCHyams return RangesI;
125ce6de374SOCHyams }
126ce6de374SOCHyams return None;
127ce6de374SOCHyams }
128ce6de374SOCHyams
trimLocationRanges(const MachineFunction & MF,LexicalScopes & LScopes,const InstructionOrdering & Ordering)1290b5a8050SOCHyams void DbgValueHistoryMap::trimLocationRanges(
1300b5a8050SOCHyams const MachineFunction &MF, LexicalScopes &LScopes,
1310b5a8050SOCHyams const InstructionOrdering &Ordering) {
132ce6de374SOCHyams // The indices of the entries we're going to remove for each variable.
133ce6de374SOCHyams SmallVector<EntryIndex, 4> ToRemove;
134ce6de374SOCHyams // Entry reference count for each variable. Clobbers left with no references
135ce6de374SOCHyams // will be removed.
136ce6de374SOCHyams SmallVector<int, 4> ReferenceCount;
137ce6de374SOCHyams // Entries reference other entries by index. Offsets is used to remap these
138ce6de374SOCHyams // references if any entries are removed.
139ce6de374SOCHyams SmallVector<size_t, 4> Offsets;
140ce6de374SOCHyams
141ce6de374SOCHyams for (auto &Record : VarEntries) {
142ce6de374SOCHyams auto &HistoryMapEntries = Record.second;
143ce6de374SOCHyams if (HistoryMapEntries.empty())
144ce6de374SOCHyams continue;
145ce6de374SOCHyams
146ce6de374SOCHyams InlinedEntity Entity = Record.first;
147ce6de374SOCHyams const DILocalVariable *LocalVar = cast<DILocalVariable>(Entity.first);
148ce6de374SOCHyams
149ce6de374SOCHyams LexicalScope *Scope = nullptr;
150ce6de374SOCHyams if (const DILocation *InlinedAt = Entity.second) {
151ce6de374SOCHyams Scope = LScopes.findInlinedScope(LocalVar->getScope(), InlinedAt);
152ce6de374SOCHyams } else {
153ce6de374SOCHyams Scope = LScopes.findLexicalScope(LocalVar->getScope());
154ce6de374SOCHyams // Ignore variables for non-inlined function level scopes. The scope
155ce6de374SOCHyams // ranges (from scope->getRanges()) will not include any instructions
156ce6de374SOCHyams // before the first one with a debug-location, which could cause us to
157ce6de374SOCHyams // incorrectly drop a location. We could introduce special casing for
158ce6de374SOCHyams // these variables, but it doesn't seem worth it because no out-of-scope
159ce6de374SOCHyams // locations have been observed for variables declared in function level
160ce6de374SOCHyams // scopes.
161ce6de374SOCHyams if (Scope &&
162ce6de374SOCHyams (Scope->getScopeNode() == Scope->getScopeNode()->getSubprogram()) &&
163ce6de374SOCHyams (Scope->getScopeNode() == LocalVar->getScope()))
164ce6de374SOCHyams continue;
165ce6de374SOCHyams }
166ce6de374SOCHyams
167ce6de374SOCHyams // If there is no scope for the variable then something has probably gone
168ce6de374SOCHyams // wrong.
169ce6de374SOCHyams if (!Scope)
170ce6de374SOCHyams continue;
171ce6de374SOCHyams
172ce6de374SOCHyams ToRemove.clear();
173ce6de374SOCHyams // Zero the reference counts.
174ce6de374SOCHyams ReferenceCount.assign(HistoryMapEntries.size(), 0);
175ce6de374SOCHyams // Index of the DBG_VALUE which marks the start of the current location
176ce6de374SOCHyams // range.
177ce6de374SOCHyams EntryIndex StartIndex = 0;
178ce6de374SOCHyams ArrayRef<InsnRange> ScopeRanges(Scope->getRanges());
179ce6de374SOCHyams for (auto EI = HistoryMapEntries.begin(), EE = HistoryMapEntries.end();
180ce6de374SOCHyams EI != EE; ++EI, ++StartIndex) {
181ce6de374SOCHyams // Only DBG_VALUEs can open location ranges so skip anything else.
182ce6de374SOCHyams if (!EI->isDbgValue())
183ce6de374SOCHyams continue;
184ce6de374SOCHyams
185ce6de374SOCHyams // Index of the entry which closes this range.
186ce6de374SOCHyams EntryIndex EndIndex = EI->getEndIndex();
187ce6de374SOCHyams // If this range is closed bump the reference count of the closing entry.
188ce6de374SOCHyams if (EndIndex != NoEntry)
189ce6de374SOCHyams ReferenceCount[EndIndex] += 1;
190ce6de374SOCHyams // Skip this location range if the opening entry is still referenced. It
191ce6de374SOCHyams // may close a location range which intersects a scope range.
192ce6de374SOCHyams // TODO: We could be 'smarter' and trim these kinds of ranges such that
193ce6de374SOCHyams // they do not leak out of the scope ranges if they partially overlap.
194ce6de374SOCHyams if (ReferenceCount[StartIndex] > 0)
195ce6de374SOCHyams continue;
196ce6de374SOCHyams
197ce6de374SOCHyams const MachineInstr *StartMI = EI->getInstr();
198ce6de374SOCHyams const MachineInstr *EndMI = EndIndex != NoEntry
199ce6de374SOCHyams ? HistoryMapEntries[EndIndex].getInstr()
200ce6de374SOCHyams : nullptr;
201ce6de374SOCHyams // Check if the location range [StartMI, EndMI] intersects with any scope
202ce6de374SOCHyams // range for the variable.
203ce6de374SOCHyams if (auto R = intersects(StartMI, EndMI, ScopeRanges, Ordering)) {
204ce6de374SOCHyams // Adjust ScopeRanges to exclude ranges which subsequent location ranges
205ce6de374SOCHyams // cannot possibly intersect.
2067a47ee51SKazu Hirata ScopeRanges = ArrayRef<InsnRange>(*R, ScopeRanges.end());
207ce6de374SOCHyams } else {
208ce6de374SOCHyams // If the location range does not intersect any scope range then the
209ce6de374SOCHyams // DBG_VALUE which opened this location range is usless, mark it for
210ce6de374SOCHyams // removal.
211ce6de374SOCHyams ToRemove.push_back(StartIndex);
212ce6de374SOCHyams // Because we'll be removing this entry we need to update the reference
213ce6de374SOCHyams // count of the closing entry, if one exists.
214ce6de374SOCHyams if (EndIndex != NoEntry)
215ce6de374SOCHyams ReferenceCount[EndIndex] -= 1;
216ce6de374SOCHyams }
217ce6de374SOCHyams }
218ce6de374SOCHyams
219ce6de374SOCHyams // If there is nothing to remove then jump to next variable.
220ce6de374SOCHyams if (ToRemove.empty())
221ce6de374SOCHyams continue;
222ce6de374SOCHyams
223ce6de374SOCHyams // Mark clobbers that will no longer close any location ranges for removal.
224ce6de374SOCHyams for (size_t i = 0; i < HistoryMapEntries.size(); ++i)
225ce6de374SOCHyams if (ReferenceCount[i] <= 0 && HistoryMapEntries[i].isClobber())
226ce6de374SOCHyams ToRemove.push_back(i);
227ce6de374SOCHyams
2289bcc0d10SKazu Hirata llvm::sort(ToRemove);
229ce6de374SOCHyams
230ce6de374SOCHyams // Build an offset map so we can update the EndIndex of the remaining
231ce6de374SOCHyams // entries.
232ce6de374SOCHyams // Zero the offsets.
233ce6de374SOCHyams Offsets.assign(HistoryMapEntries.size(), 0);
234ce6de374SOCHyams size_t CurOffset = 0;
235ce6de374SOCHyams auto ToRemoveItr = ToRemove.begin();
236ce6de374SOCHyams for (size_t EntryIdx = *ToRemoveItr; EntryIdx < HistoryMapEntries.size();
237ce6de374SOCHyams ++EntryIdx) {
238ce6de374SOCHyams // Check if this is an entry which will be removed.
239ce6de374SOCHyams if (ToRemoveItr != ToRemove.end() && *ToRemoveItr == EntryIdx) {
240ce6de374SOCHyams ++ToRemoveItr;
241ce6de374SOCHyams ++CurOffset;
242ce6de374SOCHyams }
243ce6de374SOCHyams Offsets[EntryIdx] = CurOffset;
244ce6de374SOCHyams }
245ce6de374SOCHyams
246ce6de374SOCHyams // Update the EndIndex of the entries to account for those which will be
247ce6de374SOCHyams // removed.
248ce6de374SOCHyams for (auto &Entry : HistoryMapEntries)
249ce6de374SOCHyams if (Entry.isClosed())
250ce6de374SOCHyams Entry.EndIndex -= Offsets[Entry.EndIndex];
251ce6de374SOCHyams
252ce6de374SOCHyams // Now actually remove the entries. Iterate backwards so that our remaining
253ce6de374SOCHyams // ToRemove indices are valid after each erase.
254843d1edaSKazu Hirata for (EntryIndex Idx : llvm::reverse(ToRemove))
255843d1edaSKazu Hirata HistoryMapEntries.erase(HistoryMapEntries.begin() + Idx);
256ce6de374SOCHyams }
257ce6de374SOCHyams }
258ce6de374SOCHyams
hasNonEmptyLocation(const Entries & Entries) const2591d68e0a0SJeremy Morse bool DbgValueHistoryMap::hasNonEmptyLocation(const Entries &Entries) const {
2601d68e0a0SJeremy Morse for (const auto &Entry : Entries) {
2611d68e0a0SJeremy Morse if (!Entry.isDbgValue())
2621d68e0a0SJeremy Morse continue;
2631d68e0a0SJeremy Morse
2641d68e0a0SJeremy Morse const MachineInstr *MI = Entry.getInstr();
2651d68e0a0SJeremy Morse assert(MI->isDebugValue());
2661d68e0a0SJeremy Morse // A DBG_VALUE $noreg is an empty variable location
2671d68e0a0SJeremy Morse if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg() == 0)
2681d68e0a0SJeremy Morse continue;
2691d68e0a0SJeremy Morse
2701d68e0a0SJeremy Morse return true;
2711d68e0a0SJeremy Morse }
2721d68e0a0SJeremy Morse
2731d68e0a0SJeremy Morse return false;
2741d68e0a0SJeremy Morse }
2751d68e0a0SJeremy Morse
addInstr(InlinedEntity Label,const MachineInstr & MI)276760c1ab1SHsiangkai Wang void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) {
2772532ac88SHsiangkai Wang assert(MI.isDebugLabel() && "not a DBG_LABEL");
2782532ac88SHsiangkai Wang LabelInstr[Label] = &MI;
2792532ac88SHsiangkai Wang }
2802532ac88SHsiangkai Wang
2812532ac88SHsiangkai Wang namespace {
2822532ac88SHsiangkai Wang
2832532ac88SHsiangkai Wang // Maps physreg numbers to the variables they describe.
284760c1ab1SHsiangkai Wang using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
285760c1ab1SHsiangkai Wang using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>;
2862532ac88SHsiangkai Wang
2875ffec6deSDavid Stenberg // Keeps track of the debug value entries that are currently live for each
2885ffec6deSDavid Stenberg // inlined entity. As the history map entries are stored in a SmallVector, they
2895ffec6deSDavid Stenberg // may be moved at insertion of new entries, so store indices rather than
2905ffec6deSDavid Stenberg // pointers.
2915ffec6deSDavid Stenberg using DbgValueEntriesMap = std::map<InlinedEntity, SmallSet<EntryIndex, 1>>;
2925ffec6deSDavid Stenberg
2932532ac88SHsiangkai Wang } // end anonymous namespace
2942532ac88SHsiangkai Wang
2952532ac88SHsiangkai Wang // Claim that @Var is not described by @RegNo anymore.
dropRegDescribedVar(RegDescribedVarsMap & RegVars,unsigned RegNo,InlinedEntity Var)2962532ac88SHsiangkai Wang static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
297760c1ab1SHsiangkai Wang InlinedEntity Var) {
2982532ac88SHsiangkai Wang const auto &I = RegVars.find(RegNo);
2992532ac88SHsiangkai Wang assert(RegNo != 0U && I != RegVars.end());
3002532ac88SHsiangkai Wang auto &VarSet = I->second;
3012532ac88SHsiangkai Wang const auto &VarPos = llvm::find(VarSet, Var);
3022532ac88SHsiangkai Wang assert(VarPos != VarSet.end());
3032532ac88SHsiangkai Wang VarSet.erase(VarPos);
3042532ac88SHsiangkai Wang // Don't keep empty sets in a map to keep it as small as possible.
3052532ac88SHsiangkai Wang if (VarSet.empty())
3062532ac88SHsiangkai Wang RegVars.erase(I);
3072532ac88SHsiangkai Wang }
3082532ac88SHsiangkai Wang
3092532ac88SHsiangkai Wang // Claim that @Var is now described by @RegNo.
addRegDescribedVar(RegDescribedVarsMap & RegVars,unsigned RegNo,InlinedEntity Var)3102532ac88SHsiangkai Wang static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
311760c1ab1SHsiangkai Wang InlinedEntity Var) {
3122532ac88SHsiangkai Wang assert(RegNo != 0U);
3132532ac88SHsiangkai Wang auto &VarSet = RegVars[RegNo];
3142532ac88SHsiangkai Wang assert(!is_contained(VarSet, Var));
3152532ac88SHsiangkai Wang VarSet.push_back(Var);
3162532ac88SHsiangkai Wang }
3172532ac88SHsiangkai Wang
318b96943b6SDavid Stenberg /// Create a clobbering entry and end all open debug value entries
319e64f3cccSStephen Tozer /// for \p Var that are described by \p RegNo using that entry. Inserts into \p
320e64f3cccSStephen Tozer /// FellowRegisters the set of Registers that were also used to describe \p Var
321e64f3cccSStephen Tozer /// alongside \p RegNo.
clobberRegEntries(InlinedEntity Var,unsigned RegNo,const MachineInstr & ClobberingInstr,DbgValueEntriesMap & LiveEntries,DbgValueHistoryMap & HistMap,SmallVectorImpl<Register> & FellowRegisters)3225ffec6deSDavid Stenberg static void clobberRegEntries(InlinedEntity Var, unsigned RegNo,
3235ffec6deSDavid Stenberg const MachineInstr &ClobberingInstr,
3245ffec6deSDavid Stenberg DbgValueEntriesMap &LiveEntries,
325e64f3cccSStephen Tozer DbgValueHistoryMap &HistMap,
326e64f3cccSStephen Tozer SmallVectorImpl<Register> &FellowRegisters) {
3275ffec6deSDavid Stenberg EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr);
328b96943b6SDavid Stenberg // Close all entries whose values are described by the register.
329b96943b6SDavid Stenberg SmallVector<EntryIndex, 4> IndicesToErase;
330e64f3cccSStephen Tozer // If a given register appears in a live DBG_VALUE_LIST for Var alongside the
331e64f3cccSStephen Tozer // clobbered register, and never appears in a live DBG_VALUE* for Var without
332e64f3cccSStephen Tozer // the clobbered register, then it is no longer linked to the variable.
333e64f3cccSStephen Tozer SmallSet<Register, 4> MaybeRemovedRegisters;
334e64f3cccSStephen Tozer SmallSet<Register, 4> KeepRegisters;
335b96943b6SDavid Stenberg for (auto Index : LiveEntries[Var]) {
336b96943b6SDavid Stenberg auto &Entry = HistMap.getEntry(Var, Index);
337b96943b6SDavid Stenberg assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
338e64f3cccSStephen Tozer if (Entry.getInstr()->isDebugEntryValue())
339e64f3cccSStephen Tozer continue;
340e64f3cccSStephen Tozer if (Entry.getInstr()->hasDebugOperandForReg(RegNo)) {
341b96943b6SDavid Stenberg IndicesToErase.push_back(Index);
342b96943b6SDavid Stenberg Entry.endEntry(ClobberIndex);
343*9e6d1f4bSKazu Hirata for (const auto &MO : Entry.getInstr()->debug_operands())
344e64f3cccSStephen Tozer if (MO.isReg() && MO.getReg() && MO.getReg() != RegNo)
345e64f3cccSStephen Tozer MaybeRemovedRegisters.insert(MO.getReg());
346e64f3cccSStephen Tozer } else {
347*9e6d1f4bSKazu Hirata for (const auto &MO : Entry.getInstr()->debug_operands())
348e64f3cccSStephen Tozer if (MO.isReg() && MO.getReg())
349e64f3cccSStephen Tozer KeepRegisters.insert(MO.getReg());
350b96943b6SDavid Stenberg }
351b96943b6SDavid Stenberg }
352b96943b6SDavid Stenberg
353e64f3cccSStephen Tozer for (Register Reg : MaybeRemovedRegisters)
354e64f3cccSStephen Tozer if (!KeepRegisters.contains(Reg))
355e64f3cccSStephen Tozer FellowRegisters.push_back(Reg);
356e64f3cccSStephen Tozer
357b96943b6SDavid Stenberg // Drop all entries that have ended.
358b96943b6SDavid Stenberg for (auto Index : IndicesToErase)
359b96943b6SDavid Stenberg LiveEntries[Var].erase(Index);
3605ffec6deSDavid Stenberg }
3615ffec6deSDavid Stenberg
3625ffec6deSDavid Stenberg /// 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)3635ffec6deSDavid Stenberg static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV,
3645ffec6deSDavid Stenberg RegDescribedVarsMap &RegVars,
3655ffec6deSDavid Stenberg DbgValueEntriesMap &LiveEntries,
3665ffec6deSDavid Stenberg DbgValueHistoryMap &HistMap) {
3675ffec6deSDavid Stenberg EntryIndex NewIndex;
3685ffec6deSDavid Stenberg if (HistMap.startDbgValue(Var, DV, NewIndex)) {
369b96943b6SDavid Stenberg SmallDenseMap<unsigned, bool, 4> TrackedRegs;
370b96943b6SDavid Stenberg
3715ffec6deSDavid Stenberg // If we have created a new debug value entry, close all preceding
3725ffec6deSDavid Stenberg // live entries that overlap.
3735ffec6deSDavid Stenberg SmallVector<EntryIndex, 4> IndicesToErase;
3745ffec6deSDavid Stenberg const DIExpression *DIExpr = DV.getDebugExpression();
3755ffec6deSDavid Stenberg for (auto Index : LiveEntries[Var]) {
3765ffec6deSDavid Stenberg auto &Entry = HistMap.getEntry(Var, Index);
3775ffec6deSDavid Stenberg assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
3785ffec6deSDavid Stenberg const MachineInstr &DV = *Entry.getInstr();
379b96943b6SDavid Stenberg bool Overlaps = DIExpr->fragmentsOverlap(DV.getDebugExpression());
380b96943b6SDavid Stenberg if (Overlaps) {
3815ffec6deSDavid Stenberg IndicesToErase.push_back(Index);
3825ffec6deSDavid Stenberg Entry.endEntry(NewIndex);
3835ffec6deSDavid Stenberg }
384e64f3cccSStephen Tozer if (!DV.isDebugEntryValue())
385e64f3cccSStephen Tozer for (const MachineOperand &Op : DV.debug_operands())
386e64f3cccSStephen Tozer if (Op.isReg() && Op.getReg())
387e64f3cccSStephen Tozer TrackedRegs[Op.getReg()] |= !Overlaps;
3885ffec6deSDavid Stenberg }
389b96943b6SDavid Stenberg
390b96943b6SDavid Stenberg // If the new debug value is described by a register, add tracking of
391b96943b6SDavid Stenberg // that register if it is not already tracked.
392e64f3cccSStephen Tozer if (!DV.isDebugEntryValue()) {
393e64f3cccSStephen Tozer for (const MachineOperand &Op : DV.debug_operands()) {
394e64f3cccSStephen Tozer if (Op.isReg() && Op.getReg()) {
395e64f3cccSStephen Tozer Register NewReg = Op.getReg();
396b96943b6SDavid Stenberg if (!TrackedRegs.count(NewReg))
397b96943b6SDavid Stenberg addRegDescribedVar(RegVars, NewReg, Var);
398b96943b6SDavid Stenberg LiveEntries[Var].insert(NewIndex);
399b96943b6SDavid Stenberg TrackedRegs[NewReg] = true;
400b96943b6SDavid Stenberg }
401e64f3cccSStephen Tozer }
402e64f3cccSStephen Tozer }
403b96943b6SDavid Stenberg
404b96943b6SDavid Stenberg // Drop tracking of registers that are no longer used.
405b96943b6SDavid Stenberg for (auto I : TrackedRegs)
406b96943b6SDavid Stenberg if (!I.second)
407b96943b6SDavid Stenberg dropRegDescribedVar(RegVars, I.first, Var);
408b96943b6SDavid Stenberg
4095ffec6deSDavid Stenberg // Drop all entries that have ended, and mark the new entry as live.
4105ffec6deSDavid Stenberg for (auto Index : IndicesToErase)
4115ffec6deSDavid Stenberg LiveEntries[Var].erase(Index);
4125ffec6deSDavid Stenberg LiveEntries[Var].insert(NewIndex);
4135ffec6deSDavid Stenberg }
4145ffec6deSDavid Stenberg }
4155ffec6deSDavid Stenberg
4162532ac88SHsiangkai Wang // Terminate the location range for variables described by register at
4172532ac88SHsiangkai Wang // @I by inserting @ClobberingInstr to their history.
clobberRegisterUses(RegDescribedVarsMap & RegVars,RegDescribedVarsMap::iterator I,DbgValueHistoryMap & HistMap,DbgValueEntriesMap & LiveEntries,const MachineInstr & ClobberingInstr)4182532ac88SHsiangkai Wang static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
4192532ac88SHsiangkai Wang RegDescribedVarsMap::iterator I,
4202532ac88SHsiangkai Wang DbgValueHistoryMap &HistMap,
4215ffec6deSDavid Stenberg DbgValueEntriesMap &LiveEntries,
4222532ac88SHsiangkai Wang const MachineInstr &ClobberingInstr) {
4232532ac88SHsiangkai Wang // Iterate over all variables described by this register and add this
424e64f3cccSStephen Tozer // instruction to their history, clobbering it. All registers that also
425e64f3cccSStephen Tozer // describe the clobbered variables (i.e. in variadic debug values) will have
426e64f3cccSStephen Tozer // those Variables removed from their DescribedVars.
427e64f3cccSStephen Tozer for (const auto &Var : I->second) {
428e64f3cccSStephen Tozer SmallVector<Register, 4> FellowRegisters;
429e64f3cccSStephen Tozer clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap,
430e64f3cccSStephen Tozer FellowRegisters);
431e64f3cccSStephen Tozer for (Register RegNo : FellowRegisters)
432e64f3cccSStephen Tozer dropRegDescribedVar(RegVars, RegNo, Var);
433e64f3cccSStephen Tozer }
4342532ac88SHsiangkai Wang RegVars.erase(I);
4352532ac88SHsiangkai Wang }
4362532ac88SHsiangkai Wang
4372532ac88SHsiangkai Wang // Terminate the location range for variables described by register
4382532ac88SHsiangkai Wang // @RegNo by inserting @ClobberingInstr to their history.
clobberRegisterUses(RegDescribedVarsMap & RegVars,unsigned RegNo,DbgValueHistoryMap & HistMap,DbgValueEntriesMap & LiveEntries,const MachineInstr & ClobberingInstr)4392532ac88SHsiangkai Wang static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo,
4402532ac88SHsiangkai Wang DbgValueHistoryMap &HistMap,
4415ffec6deSDavid Stenberg DbgValueEntriesMap &LiveEntries,
4422532ac88SHsiangkai Wang const MachineInstr &ClobberingInstr) {
4432532ac88SHsiangkai Wang const auto &I = RegVars.find(RegNo);
4442532ac88SHsiangkai Wang if (I == RegVars.end())
4452532ac88SHsiangkai Wang return;
4465ffec6deSDavid Stenberg clobberRegisterUses(RegVars, I, HistMap, LiveEntries, ClobberingInstr);
4472532ac88SHsiangkai Wang }
4482532ac88SHsiangkai Wang
calculateDbgEntityHistory(const MachineFunction * MF,const TargetRegisterInfo * TRI,DbgValueHistoryMap & DbgValues,DbgLabelInstrMap & DbgLabels)4492532ac88SHsiangkai Wang void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
4502532ac88SHsiangkai Wang const TargetRegisterInfo *TRI,
4512532ac88SHsiangkai Wang DbgValueHistoryMap &DbgValues,
4522532ac88SHsiangkai Wang DbgLabelInstrMap &DbgLabels) {
4532532ac88SHsiangkai Wang const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
4544634ad6cSGaurav Jain Register SP = TLI->getStackPointerRegisterToSaveRestore();
4550c476111SDaniel Sanders Register FrameReg = TRI->getFrameRegister(*MF);
4562532ac88SHsiangkai Wang RegDescribedVarsMap RegVars;
4575ffec6deSDavid Stenberg DbgValueEntriesMap LiveEntries;
4582532ac88SHsiangkai Wang for (const auto &MBB : *MF) {
4592532ac88SHsiangkai Wang for (const auto &MI : MBB) {
4602532ac88SHsiangkai Wang if (MI.isDebugValue()) {
4612532ac88SHsiangkai Wang assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
4622532ac88SHsiangkai Wang // Use the base variable (without any DW_OP_piece expressions)
4632532ac88SHsiangkai Wang // as index into History. The full variables including the
4642532ac88SHsiangkai Wang // piece expressions are attached to the MI.
4652532ac88SHsiangkai Wang const DILocalVariable *RawVar = MI.getDebugVariable();
4662532ac88SHsiangkai Wang assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
4672532ac88SHsiangkai Wang "Expected inlined-at fields to agree");
468760c1ab1SHsiangkai Wang InlinedEntity Var(RawVar, MI.getDebugLoc()->getInlinedAt());
4692532ac88SHsiangkai Wang
4705ffec6deSDavid Stenberg handleNewDebugValue(Var, MI, RegVars, LiveEntries, DbgValues);
4712532ac88SHsiangkai Wang } else if (MI.isDebugLabel()) {
4722532ac88SHsiangkai Wang assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!");
4732532ac88SHsiangkai Wang const DILabel *RawLabel = MI.getDebugLabel();
4742532ac88SHsiangkai Wang assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
4752532ac88SHsiangkai Wang "Expected inlined-at fields to agree");
4762532ac88SHsiangkai Wang // When collecting debug information for labels, there is no MCSymbol
4772532ac88SHsiangkai Wang // generated for it. So, we keep MachineInstr in DbgLabels in order
4782532ac88SHsiangkai Wang // to query MCSymbol afterward.
479760c1ab1SHsiangkai Wang InlinedEntity L(RawLabel, MI.getDebugLoc()->getInlinedAt());
4802532ac88SHsiangkai Wang DbgLabels.addInstr(L, MI);
4812532ac88SHsiangkai Wang }
482bcff4172SJeremy Morse
483453dc4d7STom Weaver // Meta Instructions have no output and do not change any values and so
484453dc4d7STom Weaver // can be safely ignored.
485453dc4d7STom Weaver if (MI.isMetaInstruction())
486bcff4172SJeremy Morse continue;
487bcff4172SJeremy Morse
488bcff4172SJeremy Morse // Not a DBG_VALUE instruction. It may clobber registers which describe
489bcff4172SJeremy Morse // some variables.
490bcff4172SJeremy Morse for (const MachineOperand &MO : MI.operands()) {
491bcff4172SJeremy Morse if (MO.isReg() && MO.isDef() && MO.getReg()) {
492bcff4172SJeremy Morse // Ignore call instructions that claim to clobber SP. The AArch64
493bcff4172SJeremy Morse // backend does this for aggregate function arguments.
494bcff4172SJeremy Morse if (MI.isCall() && MO.getReg() == SP)
495bcff4172SJeremy Morse continue;
496bcff4172SJeremy Morse // If this is a virtual register, only clobber it since it doesn't
497bcff4172SJeremy Morse // have aliases.
4982bea69bfSDaniel Sanders if (Register::isVirtualRegister(MO.getReg()))
499bcff4172SJeremy Morse clobberRegisterUses(RegVars, MO.getReg(), DbgValues, LiveEntries,
500bcff4172SJeremy Morse MI);
501bcff4172SJeremy Morse // If this is a register def operand, it may end a debug value
502181bf0ceSJeremy Morse // range. Ignore frame-register defs in the epilogue and prologue,
503181bf0ceSJeremy Morse // we expect debuggers to understand that stack-locations are
504181bf0ceSJeremy Morse // invalid outside of the function body.
505bcff4172SJeremy Morse else if (MO.getReg() != FrameReg ||
506181bf0ceSJeremy Morse (!MI.getFlag(MachineInstr::FrameDestroy) &&
507181bf0ceSJeremy Morse !MI.getFlag(MachineInstr::FrameSetup))) {
508bcff4172SJeremy Morse for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
509bcff4172SJeremy Morse ++AI)
510bcff4172SJeremy Morse clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI);
511bcff4172SJeremy Morse }
512bcff4172SJeremy Morse } else if (MO.isRegMask()) {
513bcff4172SJeremy Morse // If this is a register mask operand, clobber all debug values in
514bcff4172SJeremy Morse // non-CSRs.
515bcff4172SJeremy Morse SmallVector<unsigned, 32> RegsToClobber;
516bcff4172SJeremy Morse // Don't consider SP to be clobbered by register masks.
517bcff4172SJeremy Morse for (auto It : RegVars) {
518bcff4172SJeremy Morse unsigned int Reg = It.first;
5192bea69bfSDaniel Sanders if (Reg != SP && Register::isPhysicalRegister(Reg) &&
520bcff4172SJeremy Morse MO.clobbersPhysReg(Reg))
521bcff4172SJeremy Morse RegsToClobber.push_back(Reg);
5222532ac88SHsiangkai Wang }
5232532ac88SHsiangkai Wang
524bcff4172SJeremy Morse for (unsigned Reg : RegsToClobber) {
525bcff4172SJeremy Morse clobberRegisterUses(RegVars, Reg, DbgValues, LiveEntries, MI);
5262532ac88SHsiangkai Wang }
5272532ac88SHsiangkai Wang }
528bcff4172SJeremy Morse } // End MO loop.
529bcff4172SJeremy Morse } // End instr loop.
530bcff4172SJeremy Morse
531bcff4172SJeremy Morse // Make sure locations for all variables are valid only until the end of
532bcff4172SJeremy Morse // the basic block (unless it's the last basic block, in which case let
533bcff4172SJeremy Morse // their liveness run off to the end of the function).
534bcff4172SJeremy Morse if (!MBB.empty() && &MBB != &MF->back()) {
535bcff4172SJeremy Morse // Iterate over all variables that have open debug values.
536bcff4172SJeremy Morse for (auto &Pair : LiveEntries) {
537bcff4172SJeremy Morse if (Pair.second.empty())
538bcff4172SJeremy Morse continue;
539bcff4172SJeremy Morse
540bcff4172SJeremy Morse // Create a clobbering entry.
541bcff4172SJeremy Morse EntryIndex ClobIdx = DbgValues.startClobber(Pair.first, MBB.back());
542bcff4172SJeremy Morse
543bcff4172SJeremy Morse // End all entries.
544bcff4172SJeremy Morse for (EntryIndex Idx : Pair.second) {
545bcff4172SJeremy Morse DbgValueHistoryMap::Entry &Ent = DbgValues.getEntry(Pair.first, Idx);
546bcff4172SJeremy Morse assert(Ent.isDbgValue() && !Ent.isClosed());
547bcff4172SJeremy Morse Ent.endEntry(ClobIdx);
548bcff4172SJeremy Morse }
549bcff4172SJeremy Morse }
550bcff4172SJeremy Morse
551bcff4172SJeremy Morse LiveEntries.clear();
552bcff4172SJeremy Morse RegVars.clear();
553bcff4172SJeremy Morse }
5542532ac88SHsiangkai Wang }
5552532ac88SHsiangkai Wang }
5562532ac88SHsiangkai Wang
5572532ac88SHsiangkai Wang #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const5582532ac88SHsiangkai Wang LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const {
5592532ac88SHsiangkai Wang dbgs() << "DbgValueHistoryMap:\n";
5602532ac88SHsiangkai Wang for (const auto &VarRangePair : *this) {
561760c1ab1SHsiangkai Wang const InlinedEntity &Var = VarRangePair.first;
5626feef56dSDavid Stenberg const Entries &Entries = VarRangePair.second;
5632532ac88SHsiangkai Wang
564760c1ab1SHsiangkai Wang const DILocalVariable *LocalVar = cast<DILocalVariable>(Var.first);
5652532ac88SHsiangkai Wang const DILocation *Location = Var.second;
5662532ac88SHsiangkai Wang
5672532ac88SHsiangkai Wang dbgs() << " - " << LocalVar->getName() << " at ";
5682532ac88SHsiangkai Wang
5692532ac88SHsiangkai Wang if (Location)
5702532ac88SHsiangkai Wang dbgs() << Location->getFilename() << ":" << Location->getLine() << ":"
5712532ac88SHsiangkai Wang << Location->getColumn();
5722532ac88SHsiangkai Wang else
5732532ac88SHsiangkai Wang dbgs() << "<unknown location>";
5742532ac88SHsiangkai Wang
5752532ac88SHsiangkai Wang dbgs() << " --\n";
5762532ac88SHsiangkai Wang
5775ffec6deSDavid Stenberg for (const auto &E : enumerate(Entries)) {
5785ffec6deSDavid Stenberg const auto &Entry = E.value();
5795ffec6deSDavid Stenberg dbgs() << " Entry[" << E.index() << "]: ";
5805ffec6deSDavid Stenberg if (Entry.isDbgValue())
5815ffec6deSDavid Stenberg dbgs() << "Debug value\n";
5825ffec6deSDavid Stenberg else
5835ffec6deSDavid Stenberg dbgs() << "Clobber\n";
5845ffec6deSDavid Stenberg dbgs() << " Instr: " << *Entry.getInstr();
5855ffec6deSDavid Stenberg if (Entry.isDbgValue()) {
5865ffec6deSDavid Stenberg if (Entry.getEndIndex() == NoEntry)
5875ffec6deSDavid Stenberg dbgs() << " - Valid until end of function\n";
5885ffec6deSDavid Stenberg else
5895ffec6deSDavid Stenberg dbgs() << " - Closed by Entry[" << Entry.getEndIndex() << "]\n";
5905ffec6deSDavid Stenberg }
5912532ac88SHsiangkai Wang dbgs() << "\n";
5922532ac88SHsiangkai Wang }
5932532ac88SHsiangkai Wang }
5942532ac88SHsiangkai Wang }
5952532ac88SHsiangkai Wang #endif
596