/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
Line | Count | Source |
1 | | //===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp -------------===// |
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 | | #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" |
10 | | #include "llvm/ADT/BitVector.h" |
11 | | #include "llvm/ADT/STLExtras.h" |
12 | | #include "llvm/ADT/SmallSet.h" |
13 | | #include "llvm/ADT/SmallVector.h" |
14 | | #include "llvm/CodeGen/MachineBasicBlock.h" |
15 | | #include "llvm/CodeGen/MachineFunction.h" |
16 | | #include "llvm/CodeGen/MachineInstr.h" |
17 | | #include "llvm/CodeGen/MachineOperand.h" |
18 | | #include "llvm/CodeGen/TargetLowering.h" |
19 | | #include "llvm/CodeGen/TargetRegisterInfo.h" |
20 | | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
21 | | #include "llvm/IR/DebugInfoMetadata.h" |
22 | | #include "llvm/IR/DebugLoc.h" |
23 | | #include "llvm/MC/MCRegisterInfo.h" |
24 | | #include "llvm/Support/Debug.h" |
25 | | #include "llvm/Support/raw_ostream.h" |
26 | | #include <cassert> |
27 | | #include <map> |
28 | | #include <utility> |
29 | | |
30 | | using namespace llvm; |
31 | | |
32 | | #define DEBUG_TYPE "dwarfdebug" |
33 | | |
34 | | namespace { |
35 | | using EntryIndex = DbgValueHistoryMap::EntryIndex; |
36 | | } |
37 | | |
38 | | // If @MI is a DBG_VALUE with debug value described by a |
39 | | // defined register, returns the number of this register. |
40 | | // In the other case, returns 0. |
41 | 8.00M | static Register isDescribedByReg(const MachineInstr &MI) { |
42 | 8.00M | assert(MI.isDebugValue()); |
43 | 8.00M | assert(MI.getNumOperands() == 4); |
44 | 8.00M | // If the location of variable is an entry value (DW_OP_entry_value) |
45 | 8.00M | // do not consider it as a register location. |
46 | 8.00M | if (MI.getDebugExpression()->isEntryValue()) |
47 | 1 | return 0; |
48 | 8.00M | // If location of variable is described using a register (directly or |
49 | 8.00M | // indirectly), this register is always a first operand. |
50 | 8.00M | return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg()2.29k : Register()8.00M ; |
51 | 8.00M | } |
52 | | |
53 | | bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var, |
54 | | const MachineInstr &MI, |
55 | 5.97k | EntryIndex &NewIndex) { |
56 | 5.97k | // Instruction range should start with a DBG_VALUE instruction for the |
57 | 5.97k | // variable. |
58 | 5.97k | assert(MI.isDebugValue() && "not a DBG_VALUE"); |
59 | 5.97k | auto &Entries = VarEntries[Var]; |
60 | 5.97k | if (!Entries.empty() && Entries.back().isDbgValue()5.20k && |
61 | 5.97k | !Entries.back().isClosed()4.44k && |
62 | 5.97k | Entries.back().getInstr()->isIdenticalTo(MI)4.44k ) { |
63 | 155 | LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n" |
64 | 155 | << "\t" << Entries.back().getInstr() << "\t" << MI |
65 | 155 | << "\n"); |
66 | 155 | return false; |
67 | 155 | } |
68 | 5.81k | Entries.emplace_back(&MI, Entry::DbgValue); |
69 | 5.81k | NewIndex = Entries.size() - 1; |
70 | 5.81k | return true; |
71 | 5.81k | } |
72 | | |
73 | | EntryIndex DbgValueHistoryMap::startClobber(InlinedEntity Var, |
74 | 1.18k | const MachineInstr &MI) { |
75 | 1.18k | auto &Entries = VarEntries[Var]; |
76 | 1.18k | // If an instruction clobbers multiple registers that the variable is |
77 | 1.18k | // described by, then we may have already created a clobbering instruction. |
78 | 1.18k | if (Entries.back().isClobber() && Entries.back().getInstr() == &MI8 ) |
79 | 2 | return Entries.size() - 1; |
80 | 1.18k | Entries.emplace_back(&MI, Entry::Clobber); |
81 | 1.18k | return Entries.size() - 1; |
82 | 1.18k | } |
83 | | |
84 | 1.43k | void DbgValueHistoryMap::Entry::endEntry(EntryIndex Index) { |
85 | 1.43k | // For now, instruction ranges are not allowed to cross basic block |
86 | 1.43k | // boundaries. |
87 | 1.43k | assert(isDbgValue() && "Setting end index for non-debug value"); |
88 | 1.43k | assert(!isClosed() && "End index has already been set"); |
89 | 1.43k | EndIndex = Index; |
90 | 1.43k | } |
91 | | |
92 | 6 | void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) { |
93 | 6 | assert(MI.isDebugLabel() && "not a DBG_LABEL"); |
94 | 6 | LabelInstr[Label] = &MI; |
95 | 6 | } |
96 | | |
97 | | namespace { |
98 | | |
99 | | // Maps physreg numbers to the variables they describe. |
100 | | using InlinedEntity = DbgValueHistoryMap::InlinedEntity; |
101 | | using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>; |
102 | | |
103 | | // Keeps track of the debug value entries that are currently live for each |
104 | | // inlined entity. As the history map entries are stored in a SmallVector, they |
105 | | // may be moved at insertion of new entries, so store indices rather than |
106 | | // pointers. |
107 | | using DbgValueEntriesMap = std::map<InlinedEntity, SmallSet<EntryIndex, 1>>; |
108 | | |
109 | | } // end anonymous namespace |
110 | | |
111 | | // Claim that @Var is not described by @RegNo anymore. |
112 | | static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, |
113 | 184 | InlinedEntity Var) { |
114 | 184 | const auto &I = RegVars.find(RegNo); |
115 | 184 | assert(RegNo != 0U && I != RegVars.end()); |
116 | 184 | auto &VarSet = I->second; |
117 | 184 | const auto &VarPos = llvm::find(VarSet, Var); |
118 | 184 | assert(VarPos != VarSet.end()); |
119 | 184 | VarSet.erase(VarPos); |
120 | 184 | // Don't keep empty sets in a map to keep it as small as possible. |
121 | 184 | if (VarSet.empty()) |
122 | 174 | RegVars.erase(I); |
123 | 184 | } |
124 | | |
125 | | // Claim that @Var is now described by @RegNo. |
126 | | static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, |
127 | 1.51k | InlinedEntity Var) { |
128 | 1.51k | assert(RegNo != 0U); |
129 | 1.51k | auto &VarSet = RegVars[RegNo]; |
130 | 1.51k | assert(!is_contained(VarSet, Var)); |
131 | 1.51k | VarSet.push_back(Var); |
132 | 1.51k | } |
133 | | |
134 | | /// Create a clobbering entry and end all open debug value entries |
135 | | /// for \p Var that are described by \p RegNo using that entry. |
136 | | static void clobberRegEntries(InlinedEntity Var, unsigned RegNo, |
137 | | const MachineInstr &ClobberingInstr, |
138 | | DbgValueEntriesMap &LiveEntries, |
139 | 411 | DbgValueHistoryMap &HistMap) { |
140 | 411 | EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr); |
141 | 411 | |
142 | 411 | // Close all entries whose values are described by the register. |
143 | 411 | SmallVector<EntryIndex, 4> IndicesToErase; |
144 | 435 | for (auto Index : LiveEntries[Var]) { |
145 | 435 | auto &Entry = HistMap.getEntry(Var, Index); |
146 | 435 | assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries"); |
147 | 435 | if (isDescribedByReg(*Entry.getInstr()) == RegNo) { |
148 | 411 | IndicesToErase.push_back(Index); |
149 | 411 | Entry.endEntry(ClobberIndex); |
150 | 411 | } |
151 | 435 | } |
152 | 411 | |
153 | 411 | // Drop all entries that have ended. |
154 | 411 | for (auto Index : IndicesToErase) |
155 | 411 | LiveEntries[Var].erase(Index); |
156 | 411 | } |
157 | | |
158 | | /// Add a new debug value for \p Var. Closes all overlapping debug values. |
159 | | static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV, |
160 | | RegDescribedVarsMap &RegVars, |
161 | | DbgValueEntriesMap &LiveEntries, |
162 | 5.97k | DbgValueHistoryMap &HistMap) { |
163 | 5.97k | EntryIndex NewIndex; |
164 | 5.97k | if (HistMap.startDbgValue(Var, DV, NewIndex)) { |
165 | 5.81k | SmallDenseMap<unsigned, bool, 4> TrackedRegs; |
166 | 5.81k | |
167 | 5.81k | // If we have created a new debug value entry, close all preceding |
168 | 5.81k | // live entries that overlap. |
169 | 5.81k | SmallVector<EntryIndex, 4> IndicesToErase; |
170 | 5.81k | const DIExpression *DIExpr = DV.getDebugExpression(); |
171 | 7.99M | for (auto Index : LiveEntries[Var]) { |
172 | 7.99M | auto &Entry = HistMap.getEntry(Var, Index); |
173 | 7.99M | assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries"); |
174 | 7.99M | const MachineInstr &DV = *Entry.getInstr(); |
175 | 7.99M | bool Overlaps = DIExpr->fragmentsOverlap(DV.getDebugExpression()); |
176 | 7.99M | if (Overlaps) { |
177 | 234 | IndicesToErase.push_back(Index); |
178 | 234 | Entry.endEntry(NewIndex); |
179 | 234 | } |
180 | 7.99M | if (unsigned Reg = isDescribedByReg(DV)) |
181 | 246 | TrackedRegs[Reg] |= !Overlaps; |
182 | 7.99M | } |
183 | 5.81k | |
184 | 5.81k | // If the new debug value is described by a register, add tracking of |
185 | 5.81k | // that register if it is not already tracked. |
186 | 5.81k | if (unsigned NewReg = isDescribedByReg(DV)) { |
187 | 1.52k | if (!TrackedRegs.count(NewReg)) |
188 | 1.51k | addRegDescribedVar(RegVars, NewReg, Var); |
189 | 1.52k | LiveEntries[Var].insert(NewIndex); |
190 | 1.52k | TrackedRegs[NewReg] = true; |
191 | 1.52k | } |
192 | 5.81k | |
193 | 5.81k | // Drop tracking of registers that are no longer used. |
194 | 5.81k | for (auto I : TrackedRegs) |
195 | 1.76k | if (!I.second) |
196 | 184 | dropRegDescribedVar(RegVars, I.first, Var); |
197 | 5.81k | |
198 | 5.81k | // Drop all entries that have ended, and mark the new entry as live. |
199 | 5.81k | for (auto Index : IndicesToErase) |
200 | 234 | LiveEntries[Var].erase(Index); |
201 | 5.81k | LiveEntries[Var].insert(NewIndex); |
202 | 5.81k | } |
203 | 5.97k | } |
204 | | |
205 | | // Terminate the location range for variables described by register at |
206 | | // @I by inserting @ClobberingInstr to their history. |
207 | | static void clobberRegisterUses(RegDescribedVarsMap &RegVars, |
208 | | RegDescribedVarsMap::iterator I, |
209 | | DbgValueHistoryMap &HistMap, |
210 | | DbgValueEntriesMap &LiveEntries, |
211 | 392 | const MachineInstr &ClobberingInstr) { |
212 | 392 | // Iterate over all variables described by this register and add this |
213 | 392 | // instruction to their history, clobbering it. |
214 | 392 | for (const auto &Var : I->second) |
215 | 411 | clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap); |
216 | 392 | RegVars.erase(I); |
217 | 392 | } |
218 | | |
219 | | // Terminate the location range for variables described by register |
220 | | // @RegNo by inserting @ClobberingInstr to their history. |
221 | | static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo, |
222 | | DbgValueHistoryMap &HistMap, |
223 | | DbgValueEntriesMap &LiveEntries, |
224 | 14.5M | const MachineInstr &ClobberingInstr) { |
225 | 14.5M | const auto &I = RegVars.find(RegNo); |
226 | 14.5M | if (I == RegVars.end()) |
227 | 14.5M | return; |
228 | 392 | clobberRegisterUses(RegVars, I, HistMap, LiveEntries, ClobberingInstr); |
229 | 392 | } |
230 | | |
231 | | void llvm::calculateDbgEntityHistory(const MachineFunction *MF, |
232 | | const TargetRegisterInfo *TRI, |
233 | | DbgValueHistoryMap &DbgValues, |
234 | 35.7k | DbgLabelInstrMap &DbgLabels) { |
235 | 35.7k | const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); |
236 | 35.7k | unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); |
237 | 35.7k | unsigned FrameReg = TRI->getFrameRegister(*MF); |
238 | 35.7k | RegDescribedVarsMap RegVars; |
239 | 35.7k | DbgValueEntriesMap LiveEntries; |
240 | 364k | for (const auto &MBB : *MF) { |
241 | 2.58M | for (const auto &MI : MBB) { |
242 | 2.58M | if (MI.isDebugValue()) { |
243 | 5.97k | assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!"); |
244 | 5.97k | // Use the base variable (without any DW_OP_piece expressions) |
245 | 5.97k | // as index into History. The full variables including the |
246 | 5.97k | // piece expressions are attached to the MI. |
247 | 5.97k | const DILocalVariable *RawVar = MI.getDebugVariable(); |
248 | 5.97k | assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) && |
249 | 5.97k | "Expected inlined-at fields to agree"); |
250 | 5.97k | InlinedEntity Var(RawVar, MI.getDebugLoc()->getInlinedAt()); |
251 | 5.97k | |
252 | 5.97k | handleNewDebugValue(Var, MI, RegVars, LiveEntries, DbgValues); |
253 | 2.58M | } else if (MI.isDebugLabel()) { |
254 | 6 | assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!"); |
255 | 6 | const DILabel *RawLabel = MI.getDebugLabel(); |
256 | 6 | assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) && |
257 | 6 | "Expected inlined-at fields to agree"); |
258 | 6 | // When collecting debug information for labels, there is no MCSymbol |
259 | 6 | // generated for it. So, we keep MachineInstr in DbgLabels in order |
260 | 6 | // to query MCSymbol afterward. |
261 | 6 | InlinedEntity L(RawLabel, MI.getDebugLoc()->getInlinedAt()); |
262 | 6 | DbgLabels.addInstr(L, MI); |
263 | 6 | } |
264 | 2.58M | |
265 | 2.58M | if (MI.isDebugInstr()) |
266 | 5.97k | continue; |
267 | 2.58M | |
268 | 2.58M | // Not a DBG_VALUE instruction. It may clobber registers which describe |
269 | 2.58M | // some variables. |
270 | 10.6M | for (const MachineOperand &MO : MI.operands())2.58M { |
271 | 10.6M | if (MO.isReg() && MO.isDef()7.37M && MO.getReg()2.70M ) { |
272 | 2.70M | // Ignore call instructions that claim to clobber SP. The AArch64 |
273 | 2.70M | // backend does this for aggregate function arguments. |
274 | 2.70M | if (MI.isCall() && MO.getReg() == SP481k ) |
275 | 194k | continue; |
276 | 2.51M | // If this is a virtual register, only clobber it since it doesn't |
277 | 2.51M | // have aliases. |
278 | 2.51M | if (TRI->isVirtualRegister(MO.getReg())) |
279 | 312 | clobberRegisterUses(RegVars, MO.getReg(), DbgValues, LiveEntries, |
280 | 312 | MI); |
281 | 2.51M | // If this is a register def operand, it may end a debug value |
282 | 2.51M | // range. Ignore frame-register defs in the epilogue and prologue, |
283 | 2.51M | // we expect debuggers to understand that stack-locations are |
284 | 2.51M | // invalid outside of the function body. |
285 | 2.51M | else if (MO.getReg() != FrameReg || |
286 | 2.51M | (72.5k !MI.getFlag(MachineInstr::FrameDestroy)72.5k && |
287 | 2.44M | !MI.getFlag(MachineInstr::FrameSetup)41.1k )) { |
288 | 17.0M | for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); |
289 | 14.5M | ++AI) |
290 | 14.5M | clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI); |
291 | 2.44M | } |
292 | 7.97M | } else if (MO.isRegMask()) { |
293 | 203k | // If this is a register mask operand, clobber all debug values in |
294 | 203k | // non-CSRs. |
295 | 203k | SmallVector<unsigned, 32> RegsToClobber; |
296 | 203k | // Don't consider SP to be clobbered by register masks. |
297 | 203k | for (auto It : RegVars) { |
298 | 423 | unsigned int Reg = It.first; |
299 | 423 | if (Reg != SP && TRI->isPhysicalRegister(Reg)327 && |
300 | 423 | MO.clobbersPhysReg(Reg)327 ) |
301 | 103 | RegsToClobber.push_back(Reg); |
302 | 423 | } |
303 | 203k | |
304 | 203k | for (unsigned Reg : RegsToClobber) { |
305 | 103 | clobberRegisterUses(RegVars, Reg, DbgValues, LiveEntries, MI); |
306 | 103 | } |
307 | 203k | } |
308 | 10.6M | } // End MO loop. |
309 | 2.58M | } // End instr loop. |
310 | 364k | |
311 | 364k | // Make sure locations for all variables are valid only until the end of |
312 | 364k | // the basic block (unless it's the last basic block, in which case let |
313 | 364k | // their liveness run off to the end of the function). |
314 | 364k | if (!MBB.empty() && &MBB != &MF->back()364k ) { |
315 | 328k | // Iterate over all variables that have open debug values. |
316 | 328k | for (auto &Pair : LiveEntries) { |
317 | 871 | if (Pair.second.empty()) |
318 | 95 | continue; |
319 | 776 | |
320 | 776 | // Create a clobbering entry. |
321 | 776 | EntryIndex ClobIdx = DbgValues.startClobber(Pair.first, MBB.back()); |
322 | 776 | |
323 | 776 | // End all entries. |
324 | 794 | for (EntryIndex Idx : Pair.second) { |
325 | 794 | DbgValueHistoryMap::Entry &Ent = DbgValues.getEntry(Pair.first, Idx); |
326 | 794 | assert(Ent.isDbgValue() && !Ent.isClosed()); |
327 | 794 | Ent.endEntry(ClobIdx); |
328 | 794 | } |
329 | 776 | } |
330 | 328k | |
331 | 328k | LiveEntries.clear(); |
332 | 328k | RegVars.clear(); |
333 | 328k | } |
334 | 364k | } |
335 | 35.7k | } |
336 | | |
337 | | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
338 | | LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const { |
339 | | dbgs() << "DbgValueHistoryMap:\n"; |
340 | | for (const auto &VarRangePair : *this) { |
341 | | const InlinedEntity &Var = VarRangePair.first; |
342 | | const Entries &Entries = VarRangePair.second; |
343 | | |
344 | | const DILocalVariable *LocalVar = cast<DILocalVariable>(Var.first); |
345 | | const DILocation *Location = Var.second; |
346 | | |
347 | | dbgs() << " - " << LocalVar->getName() << " at "; |
348 | | |
349 | | if (Location) |
350 | | dbgs() << Location->getFilename() << ":" << Location->getLine() << ":" |
351 | | << Location->getColumn(); |
352 | | else |
353 | | dbgs() << "<unknown location>"; |
354 | | |
355 | | dbgs() << " --\n"; |
356 | | |
357 | | for (const auto &E : enumerate(Entries)) { |
358 | | const auto &Entry = E.value(); |
359 | | dbgs() << " Entry[" << E.index() << "]: "; |
360 | | if (Entry.isDbgValue()) |
361 | | dbgs() << "Debug value\n"; |
362 | | else |
363 | | dbgs() << "Clobber\n"; |
364 | | dbgs() << " Instr: " << *Entry.getInstr(); |
365 | | if (Entry.isDbgValue()) { |
366 | | if (Entry.getEndIndex() == NoEntry) |
367 | | dbgs() << " - Valid until end of function\n"; |
368 | | else |
369 | | dbgs() << " - Closed by Entry[" << Entry.getEndIndex() << "]\n"; |
370 | | } |
371 | | dbgs() << "\n"; |
372 | | } |
373 | | } |
374 | | } |
375 | | #endif |