llvm.org GIT mirror llvm / b310704
Revert "Implement a new pass - LiveDebugValues - to compute the set of live DEBUG_VALUEs at each basic block and insert them. Reviewed and accepted at: http://reviews.llvm.org/D11933" This reverts commit r255096. Break the bots: http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-incremental_check/16378/ From: Mehdi Amini <mehdi.amini@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255101 91177308-0d34-0410-b5e6-96231b3b80d8 Mehdi Amini 4 years ago
14 changed file(s) with 5 addition(s) and 1132 deletion(s). Raw diff Collapse all Expand all
639639 /// the intrinsic for later emission to the StackMap.
640640 extern char &StackMapLivenessID;
641641
642 /// LiveDebugValues pass
643 extern char &LiveDebugValuesID;
644
645642 /// createJumpInstrTables - This pass creates jump-instruction tables.
646643 ModulePass *createJumpInstrTablesPass();
647644
288288 void initializeMachineFunctionPrinterPassPass(PassRegistry&);
289289 void initializeMIRPrintingPassPass(PassRegistry&);
290290 void initializeStackMapLivenessPass(PassRegistry&);
291 void initializeLiveDebugValuesPass(PassRegistry&);
292291 void initializeMachineCombinerPass(PassRegistry &);
293292 void initializeLoadCombinePass(PassRegistry&);
294293 void initializeRewriteSymbolsPass(PassRegistry&);
2424 ExecutionDepsFix.cpp
2525 ExpandISelPseudos.cpp
2626 ExpandPostRAPseudos.cpp
27 LiveDebugValues.cpp
2827 FaultMaps.cpp
2928 FuncletLayout.cpp
3029 GCMetadata.cpp
6666 initializeSlotIndexesPass(Registry);
6767 initializeStackColoringPass(Registry);
6868 initializeStackMapLivenessPass(Registry);
69 initializeLiveDebugValuesPass(Registry);
7069 initializeStackProtectorPass(Registry);
7170 initializeStackSlotColoringPass(Registry);
7271 initializeTailDuplicatePassPass(Registry);
+0
-402
lib/CodeGen/LiveDebugValues.cpp less more
None //===------ LiveDebugValues.cpp - Tracking Debug Value MIs ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// This pass implements a data flow analysis that propagates debug location
10 /// information by inserting additional DBG_VALUE instructions into the machine
11 /// instruction stream. The pass internally builds debug location liveness
12 /// ranges to determine the points where additional DBG_VALUEs need to be
13 /// inserted.
14 ///
15 /// This is a separate pass from DbgValueHistoryCalculator to facilitate
16 /// testing and improve modularity.
17 ///
18 //===----------------------------------------------------------------------===//
19
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/Passes.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Target/TargetRegisterInfo.h"
30 #include "llvm/Target/TargetInstrInfo.h"
31 #include "llvm/Target/TargetSubtargetInfo.h"
32 #include
33 #include
34
35 using namespace llvm;
36
37 #define DEBUG_TYPE "live-debug-values"
38
39 STATISTIC(NumInserted, "Number of DBG_VALUE instructions inserted");
40
41 namespace {
42
43 class LiveDebugValues : public MachineFunctionPass {
44
45 private:
46 const TargetRegisterInfo *TRI;
47 const TargetInstrInfo *TII;
48
49 typedef std::pair
50 InlinedVariable;
51
52 /// A potentially inlined instance of a variable.
53 struct DebugVariable {
54 const DILocalVariable *Var;
55 const DILocation *InlinedAt;
56
57 DebugVariable(const DILocalVariable *_var, const DILocation *_inlinedAt)
58 : Var(_var), InlinedAt(_inlinedAt) {}
59
60 bool operator==(const DebugVariable &DV) const {
61 return (Var == DV.Var) && (InlinedAt == DV.InlinedAt);
62 }
63 };
64
65 /// Member variables and functions for Range Extension across basic blocks.
66 struct VarLoc {
67 DebugVariable Var;
68 const MachineInstr *MI; // MachineInstr should be a DBG_VALUE instr.
69
70 VarLoc(DebugVariable _var, const MachineInstr *_mi) : Var(_var), MI(_mi) {}
71
72 bool operator==(const VarLoc &V) const;
73 };
74
75 typedef std::list VarLocList;
76 typedef SmallDenseMap VarLocInMBB;
77
78 bool OLChanged; // OutgoingLocs got changed for this bb.
79 bool MBBJoined; // The MBB was joined.
80
81 void transferDebugValue(MachineInstr &MI, VarLocList &OpenRanges);
82 void transferRegisterDef(MachineInstr &MI, VarLocList &OpenRanges);
83 void transferTerminatorInst(MachineInstr &MI, VarLocList &OpenRanges,
84 VarLocInMBB &OutLocs);
85 void transfer(MachineInstr &MI, VarLocList &OpenRanges, VarLocInMBB &OutLocs);
86
87 void join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs);
88
89 bool ExtendRanges(MachineFunction &MF);
90
91 public:
92 static char ID;
93
94 /// Default construct and initialize the pass.
95 LiveDebugValues();
96
97 /// Tell the pass manager which passes we depend on and what
98 /// information we preserve.
99 void getAnalysisUsage(AnalysisUsage &AU) const override;
100
101 /// Print to ostream with a message.
102 void printVarLocInMBB(const VarLocInMBB &V, const char *msg,
103 raw_ostream &Out) const;
104
105 /// Calculate the liveness information for the given machine function.
106 bool runOnMachineFunction(MachineFunction &MF) override;
107 };
108 } // namespace
109
110 //===----------------------------------------------------------------------===//
111 // Implementation
112 //===----------------------------------------------------------------------===//
113
114 char LiveDebugValues::ID = 0;
115 char &llvm::LiveDebugValuesID = LiveDebugValues::ID;
116 INITIALIZE_PASS(LiveDebugValues, "livedebugvalues", "Live DEBUG_VALUE analysis",
117 false, false)
118
119 /// Default construct and initialize the pass.
120 LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
121 initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry());
122 }
123
124 /// Tell the pass manager which passes we depend on and what information we
125 /// preserve.
126 void LiveDebugValues::getAnalysisUsage(AnalysisUsage &AU) const {
127 MachineFunctionPass::getAnalysisUsage(AU);
128 }
129
130 // \brief If @MI is a DBG_VALUE with debug value described by a defined
131 // register, returns the number of this register. In the other case, returns 0.
132 static unsigned isDescribedByReg(const MachineInstr &MI) {
133 assert(MI.isDebugValue());
134 assert(MI.getNumOperands() == 4);
135 // If location of variable is described using a register (directly or
136 // indirecltly), this register is always a first operand.
137 return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
138 }
139
140 // \brief This function takes two DBG_VALUE instructions and returns true
141 // if their offsets are equal; otherwise returns false.
142 static bool areOffsetsEqual(const MachineInstr &MI1, const MachineInstr &MI2) {
143 assert(MI1.isDebugValue());
144 assert(MI1.getNumOperands() == 4);
145
146 assert(MI2.isDebugValue());
147 assert(MI2.getNumOperands() == 4);
148
149 if (!MI1.isIndirectDebugValue() && !MI2.isIndirectDebugValue())
150 return true;
151
152 // Check if both MIs are indirect and they are equal.
153 if (MI1.isIndirectDebugValue() && MI2.isIndirectDebugValue())
154 return MI1.getOperand(1).getImm() == MI2.getOperand(1).getImm();
155
156 return false;
157 }
158
159 //===----------------------------------------------------------------------===//
160 // Debug Range Extension Implementation
161 //===----------------------------------------------------------------------===//
162
163 void LiveDebugValues::printVarLocInMBB(const VarLocInMBB &V, const char *msg,
164 raw_ostream &Out) const {
165 Out << "Printing " << msg << ":\n";
166 for (const auto &L : V) {
167 Out << "MBB: " << L.first->getName() << ":\n";
168 for (const auto &VLL : L.second) {
169 Out << " Var: " << VLL.Var.Var->getName();
170 Out << " MI: ";
171 (*VLL.MI).dump();
172 Out << "\n";
173 }
174 }
175 Out << "\n";
176 }
177
178 bool LiveDebugValues::VarLoc::operator==(const VarLoc &V) const {
179 return (Var == V.Var) && (isDescribedByReg(*MI) == isDescribedByReg(*V.MI)) &&
180 (areOffsetsEqual(*MI, *V.MI));
181 }
182
183 /// End all previous ranges related to @MI and start a new range from @MI
184 /// if it is a DBG_VALUE instr.
185 void LiveDebugValues::transferDebugValue(MachineInstr &MI,
186 VarLocList &OpenRanges) {
187 if (!MI.isDebugValue())
188 return;
189 const DILocalVariable *RawVar = MI.getDebugVariable();
190 assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
191 "Expected inlined-at fields to agree");
192 DebugVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
193
194 // End all previous ranges of Var.
195 OpenRanges.erase(
196 std::remove_if(OpenRanges.begin(), OpenRanges.end(),
197 [&](const VarLoc &V) { return (Var == V.Var); }),
198 OpenRanges.end());
199
200 // Add Var to OpenRanges from this DBG_VALUE.
201 // TODO: Currently handles DBG_VALUE which has only reg as location.
202 if (isDescribedByReg(MI)) {
203 VarLoc V(Var, &MI);
204 OpenRanges.push_back(std::move(V));
205 }
206 }
207
208 /// A definition of a register may mark the end of a range.
209 void LiveDebugValues::transferRegisterDef(MachineInstr &MI,
210 VarLocList &OpenRanges) {
211 for (const MachineOperand &MO : MI.operands()) {
212 if (!(MO.isReg() && MO.isDef() && MO.getReg()))
213 continue;
214 // Remove ranges of all aliased registers.
215 for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)
216 OpenRanges.erase(std::remove_if(OpenRanges.begin(), OpenRanges.end(),
217 [&](const VarLoc &V) {
218 return (*RAI == isDescribedByReg(*V.MI));
219 }),
220 OpenRanges.end());
221 }
222 }
223
224 /// Terminate all open ranges at the end of the current basic block.
225 void LiveDebugValues::transferTerminatorInst(MachineInstr &MI,
226 VarLocList &OpenRanges,
227 VarLocInMBB &OutLocs) {
228 const MachineBasicBlock *CurMBB = MI.getParent();
229 if (!(MI.isTerminator() || (&MI == &CurMBB->instr_back())))
230 return;
231
232 if (OpenRanges.empty())
233 return;
234
235 if (OutLocs.find(CurMBB) == OutLocs.end()) {
236 // Create space for new Outgoing locs entries.
237 VarLocList VLL;
238 OutLocs.insert(std::make_pair(CurMBB, std::move(VLL)));
239 }
240 auto OL = OutLocs.find(CurMBB);
241 assert(OL != OutLocs.end());
242 VarLocList &VLL = OL->second;
243
244 for (auto OR : OpenRanges) {
245 // Copy OpenRanges to OutLocs, if not already present.
246 assert(OR.MI->isDebugValue());
247 DEBUG(dbgs() << "Add to OutLocs: "; OR.MI->dump(););
248 if (std::find_if(VLL.begin(), VLL.end(),
249 [&](const VarLoc &V) { return (OR == V); }) == VLL.end()) {
250 VLL.push_back(std::move(OR));
251 OLChanged = true;
252 }
253 }
254 OpenRanges.clear();
255 }
256
257 /// This routine creates OpenRanges and OutLocs.
258 void LiveDebugValues::transfer(MachineInstr &MI, VarLocList &OpenRanges,
259 VarLocInMBB &OutLocs) {
260 transferDebugValue(MI, OpenRanges);
261 transferRegisterDef(MI, OpenRanges);
262 transferTerminatorInst(MI, OpenRanges, OutLocs);
263 }
264
265 /// This routine joins the analysis results of all incoming edges in @MBB by
266 /// inserting a new DBG_VALUE instruction at the start of the @MBB - if the same
267 /// source variable in all the predecessors of @MBB reside in the same location.
268 void LiveDebugValues::join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs,
269 VarLocInMBB &InLocs) {
270 DEBUG(dbgs() << "join MBB: " << MBB.getName() << "\n");
271
272 MBBJoined = false;
273
274 VarLocList InLocsT; // Temporary incoming locations.
275
276 // For all predecessors of this MBB, find the set of VarLocs that can be
277 // joined.
278 for (auto p : MBB.predecessors()) {
279 auto OL = OutLocs.find(p);
280 // Join is null in case of empty OutLocs from any of the pred.
281 if (OL == OutLocs.end())
282 return;
283
284 // Just copy over the Out locs to incoming locs for the first predecessor.
285 if (p == *MBB.pred_begin()) {
286 InLocsT = OL->second;
287 continue;
288 }
289
290 // Join with this predecessor.
291 VarLocList &VLL = OL->second;
292 InLocsT.erase(
293 std::remove_if(InLocsT.begin(), InLocsT.end(), [&](VarLoc &ILT) {
294 return (std::find_if(VLL.begin(), VLL.end(), [&](const VarLoc &V) {
295 return (ILT == V);
296 }) == VLL.end());
297 }),
298 InLocsT.end());
299 }
300
301 if (InLocsT.empty())
302 return;
303
304 if (InLocs.find(&MBB) == InLocs.end()) {
305 // Create space for new Incoming locs entries.
306 VarLocList VLL;
307 InLocs.insert(std::make_pair(&MBB, std::move(VLL)));
308 }
309 auto IL = InLocs.find(&MBB);
310 assert(IL != InLocs.end());
311 VarLocList &ILL = IL->second;
312
313 // Insert DBG_VALUE instructions, if not already inserted.
314 for (auto ILT : InLocsT) {
315 if (std::find_if(ILL.begin(), ILL.end(), [&](const VarLoc &I) {
316 return (ILT == I);
317 }) == ILL.end()) {
318 // This VarLoc is not found in InLocs i.e. it is not yet inserted. So, a
319 // new range is started for the var from the mbb's beginning by inserting
320 // a new DBG_VALUE. transfer() will end this range however appropriate.
321 const MachineInstr *DMI = ILT.MI;
322 MachineInstr *MI =
323 BuildMI(MBB, MBB.instr_begin(), DMI->getDebugLoc(), DMI->getDesc(),
324 DMI->isIndirectDebugValue(), DMI->getOperand(0).getReg(), 0,
325 DMI->getDebugVariable(), DMI->getDebugExpression());
326 if (DMI->isIndirectDebugValue())
327 MI->getOperand(1).setImm(DMI->getOperand(1).getImm());
328 DEBUG(dbgs() << "Inserted: "; MI->dump(););
329 ++NumInserted;
330 MBBJoined = true; // rerun transfer().
331
332 VarLoc V(ILT.Var, MI);
333 ILL.push_back(std::move(V));
334 }
335 }
336 }
337
338 /// Calculate the liveness information for the given machine function and
339 /// extend ranges across basic blocks.
340 bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
341
342 DEBUG(dbgs() << "\nDebug Range Extension\n");
343
344 bool Changed = false;
345 OLChanged = MBBJoined = false;
346
347 VarLocList OpenRanges; // Ranges that are open until end of bb.
348 VarLocInMBB OutLocs; // Ranges that exist beyond bb.
349 VarLocInMBB InLocs; // Ranges that are incoming after joining.
350
351 std::deque BBWorklist;
352
353 // Initialize every mbb with OutLocs.
354 for (auto &MBB : MF)
355 for (auto &MI : MBB)
356 transfer(MI, OpenRanges, OutLocs);
357 DEBUG(printVarLocInMBB(OutLocs, "OutLocs after initialization", dbgs()));
358
359 // Construct a worklist of MBBs.
360 for (auto &MBB : MF)
361 BBWorklist.push_back(&MBB);
362
363 // Perform join() and transfer() using the worklist until the ranges converge
364 // Ranges have converged when the worklist is empty.
365 while (!BBWorklist.empty()) {
366 MachineBasicBlock *MBB = BBWorklist.front();
367 BBWorklist.pop_front();
368
369 join(*MBB, OutLocs, InLocs);
370
371 if (MBBJoined) {
372 Changed = true;
373 for (auto &MI : *MBB)
374 transfer(MI, OpenRanges, OutLocs);
375 DEBUG(printVarLocInMBB(OutLocs, "OutLocs after propagating", dbgs()));
376 DEBUG(printVarLocInMBB(InLocs, "InLocs after propagating", dbgs()));
377
378 if (OLChanged) {
379 OLChanged = false;
380 for (auto s : MBB->successors())
381 if (std::find(BBWorklist.begin(), BBWorklist.end(), s) ==
382 BBWorklist.end()) // add if not already present.
383 BBWorklist.push_back(s);
384 }
385 }
386 }
387 DEBUG(printVarLocInMBB(OutLocs, "Final OutLocs", dbgs()));
388 DEBUG(printVarLocInMBB(InLocs, "Final InLocs", dbgs()));
389 return Changed;
390 }
391
392 bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
393 TRI = MF.getSubtarget().getRegisterInfo();
394 TII = MF.getSubtarget().getInstrInfo();
395
396 bool Changed = false;
397
398 Changed |= ExtendRanges(MF);
399
400 return Changed;
401 }
596596 addPass(&FuncletLayoutID, false);
597597
598598 addPass(&StackMapLivenessID, false);
599 addPass(&LiveDebugValuesID);
600599
601600 AddingMachinePasses = false;
602601 }
+0
-2
test/DebugInfo/MIR/X86/lit.local.cfg less more
None if not 'X86' in config.root.targets:
1 config.unsupported = True
+0
-299
test/DebugInfo/MIR/X86/live-debug-values-3preds.mir less more
None # RUN: llc -run-pass=livedebugvalues -march=x86-64 -o /dev/null %s | FileCheck %s
1
2 # Test the extension of debug ranges from 3 predecessors.
3 # Generated from the source file LiveDebugValues-3preds.c:
4 # #include
5 # int add(int x, int y, int z, int a) {
6 # int i;
7 # for (i = 0; i < x * y; i++) {
8 # if (i < x) {
9 # a = a * x;
10 # break;
11 # }
12 # if (i < y) {
13 # a = a * y;
14 # break;
15 # }
16 # if (i < z) {
17 # a = a * z;
18 # break;
19 # }
20 # }
21 # return a;
22 # }
23 # with clang -g -O1 -c -emit-llvm LiveDebugValues-3preds.c -S -o live-debug-values-3preds.ll
24 # then llc -stop-after stackmap-liveness live-debug-values-3preds.ll -o /dev/null > live-debug-values-3preds.mir
25
26 # DBG_VALUE for variables "x", "y" and "z" are extended into BB#9 from its
27 # predecessors BB#0, BB#2 and BB#8.
28 # CHECK: bb.9.for.end:
29 # CHECK: DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
30 # CHECK-NEXT: DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
31 # CHECK-NEXT: DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
32
33
34 --- |
35 ; ModuleID = 'live-debug-values-3preds.ll'
36 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
37 target triple = "x86_64-unknown-linux-gnu"
38
39 ; Function Attrs: norecurse nounwind readnone uwtable
40 define i32 @add(i32 %x, i32 %y, i32 %z, i32 %a) #0 !dbg !4 {
41 entry:
42 tail call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !9, metadata !17), !dbg !18
43 tail call void @llvm.dbg.value(metadata i32 %y, i64 0, metadata !10, metadata !17), !dbg !19
44 tail call void @llvm.dbg.value(metadata i32 %z, i64 0, metadata !11, metadata !17), !dbg !21
45 tail call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !12, metadata !17), !dbg !23
46 tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !13, metadata !17), !dbg !25
47 %mul = mul nsw i32 %y, %x, !dbg !26
48 %cmp.24 = icmp sgt i32 %mul, 0, !dbg !30
49 br i1 %cmp.24, label %for.body.preheader, label %for.end, !dbg !31
50
51 for.body.preheader: ; preds = %entry
52 br label %for.body, !dbg !32
53
54 for.cond: ; preds = %if.end.6
55 %cmp = icmp slt i32 %inc, %mul, !dbg !30
56 br i1 %cmp, label %for.body, label %for.end, !dbg !31
57
58 for.body: ; preds = %for.cond, %for.body.preheader
59 %i.025 = phi i32 [ %inc, %for.cond ], [ 0, %for.body.preheader ]
60 %0 = icmp sgt i32 %x, 0
61 br i1 %0, label %if.then, label %if.end, !dbg !35
62
63 if.then: ; preds = %for.body
64 %mul2 = mul nsw i32 %a, %x, !dbg !36
65 tail call void @llvm.dbg.value(metadata i32 %mul2, i64 0, metadata !12, metadata !17), !dbg !23
66 br label %for.end, !dbg !38
67
68 if.end: ; preds = %for.body
69 %1 = icmp sgt i32 %y, 0
70 br i1 %1, label %if.then.4, label %if.end.6, !dbg !39
71
72 if.then.4: ; preds = %if.end
73 %mul5 = mul nsw i32 %a, %y, !dbg !40
74 tail call void @llvm.dbg.value(metadata i32 %mul5, i64 0, metadata !12, metadata !17), !dbg !23
75 br label %for.end, !dbg !43
76
77 if.end.6: ; preds = %if.end
78 %2 = icmp sgt i32 %z, 0
79 %inc = add nuw nsw i32 %i.025, 1, !dbg !44
80 tail call void @llvm.dbg.value(metadata i32 %inc, i64 0, metadata !13, metadata !17), !dbg !25
81 br i1 %2, label %if.then.8, label %for.cond, !dbg !45
82
83 if.then.8: ; preds = %if.end.6
84 %mul9 = mul nsw i32 %a, %z, !dbg !46
85 tail call void @llvm.dbg.value(metadata i32 %mul9, i64 0, metadata !12, metadata !17), !dbg !23
86 br label %for.end, !dbg !49
87
88 for.end: ; preds = %for.cond, %if.then.8, %if.then.4, %if.then, %entry
89 %a.addr.0 = phi i32 [ %mul2, %if.then ], [ %mul5, %if.then.4 ], [ %mul9, %if.then.8 ], [ %a, %entry ], [ %a, %for.cond ]
90 ret i32 %a.addr.0, !dbg !50
91 }
92
93 ; Function Attrs: nounwind readnone
94 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
95
96 attributes #0 = { norecurse nounwind readnone uwtable }
97 attributes #1 = { nounwind readnone }
98
99 !llvm.dbg.cu = !{!0}
100 !llvm.module.flags = !{!14, !15}
101 !llvm.ident = !{!16}
102
103 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 253049) ", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
104 !1 = !DIFile(filename: "LiveDebugValues-3preds.c", directory: "/home/vt/julia/test/tvvikram")
105 !2 = !{}
106 !3 = !{!4}
107 !4 = distinct !DISubprogram(name: "add", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, variables: !8)
108 !5 = !DISubroutineType(types: !6)
109 !6 = !{!7, !7, !7, !7, !7}
110 !7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
111 !8 = !{!9, !10, !11, !12, !13}
112 !9 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !1, line: 1, type: !7)
113 !10 = !DILocalVariable(name: "y", arg: 2, scope: !4, file: !1, line: 1, type: !7)
114 !11 = !DILocalVariable(name: "z", arg: 3, scope: !4, file: !1, line: 1, type: !7)
115 !12 = !DILocalVariable(name: "a", arg: 4, scope: !4, file: !1, line: 1, type: !7)
116 !13 = !DILocalVariable(name: "i", scope: !4, file: !1, line: 2, type: !7)
117 !14 = !{i32 2, !"Dwarf Version", i32 4}
118 !15 = !{i32 2, !"Debug Info Version", i32 3}
119 !16 = !{!"clang version 3.8.0 (trunk 253049) "}
120 !17 = !DIExpression()
121 !18 = !DILocation(line: 1, column: 13, scope: !4)
122 !19 = !DILocation(line: 1, column: 20, scope: !20)
123 !20 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 1)
124 !21 = !DILocation(line: 1, column: 27, scope: !22)
125 !22 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 2)
126 !23 = !DILocation(line: 1, column: 34, scope: !24)
127 !24 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 3)
128 !25 = !DILocation(line: 2, column: 7, scope: !20)
129 !26 = !DILocation(line: 3, column: 21, scope: !27)
130 !27 = !DILexicalBlockFile(scope: !28, file: !1, discriminator: 1)
131 !28 = distinct !DILexicalBlock(scope: !29, file: !1, line: 3, column: 3)
132 !29 = distinct !DILexicalBlock(scope: !4, file: !1, line: 3, column: 3)
133 !30 = !DILocation(line: 3, column: 17, scope: !27)
134 !31 = !DILocation(line: 3, column: 3, scope: !27)
135 !32 = !DILocation(line: 4, column: 11, scope: !33)
136 !33 = distinct !DILexicalBlock(scope: !34, file: !1, line: 4, column: 9)
137 !34 = distinct !DILexicalBlock(scope: !28, file: !1, line: 3, column: 31)
138 !35 = !DILocation(line: 4, column: 9, scope: !34)
139 !36 = !DILocation(line: 5, column: 13, scope: !37)
140 !37 = distinct !DILexicalBlock(scope: !33, file: !1, line: 4, column: 16)
141 !38 = !DILocation(line: 6, column: 7, scope: !37)
142 !39 = !DILocation(line: 8, column: 9, scope: !34)
143 !40 = !DILocation(line: 9, column: 13, scope: !41)
144 !41 = distinct !DILexicalBlock(scope: !42, file: !1, line: 8, column: 16)
145 !42 = distinct !DILexicalBlock(scope: !34, file: !1, line: 8, column: 9)
146 !43 = !DILocation(line: 10, column: 7, scope: !41)
147 !44 = !DILocation(line: 3, column: 27, scope: !28)
148 !45 = !DILocation(line: 12, column: 9, scope: !34)
149 !46 = !DILocation(line: 13, column: 13, scope: !47)
150 !47 = distinct !DILexicalBlock(scope: !48, file: !1, line: 12, column: 16)
151 !48 = distinct !DILexicalBlock(scope: !34, file: !1, line: 12, column: 9)
152 !49 = !DILocation(line: 14, column: 7, scope: !47)
153 !50 = !DILocation(line: 17, column: 3, scope: !4)
154
155 ...
156 ---
157 name: add
158 alignment: 4
159 exposesReturnsTwice: false
160 hasInlineAsm: false
161 isSSA: false
162 tracksRegLiveness: true
163 tracksSubRegLiveness: false
164 liveins:
165 - { reg: '%edi' }
166 - { reg: '%esi' }
167 - { reg: '%edx' }
168 - { reg: '%ecx' }
169 frameInfo:
170 isFrameAddressTaken: false
171 isReturnAddressTaken: false
172 hasStackMap: false
173 hasPatchPoint: false
174 stackSize: 0
175 offsetAdjustment: 0
176 maxAlignment: 0
177 adjustsStack: false
178 hasCalls: false
179 maxCallFrameSize: 0
180 hasOpaqueSPAdjustment: false
181 hasVAStart: false
182 hasMustTailInVarArgFunc: false
183 body: |
184 bb.0.entry:
185 successors: %bb.1.for.body.preheader(20), %bb.9.for.end(12)
186 liveins: %ecx, %edi, %edx, %esi
187
188 DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
189 DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
190 DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
191 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
192 DBG_VALUE 0, 0, !13, !17, debug-location !25
193 %r8d = MOV32rr %esi, debug-location !26
194 %r8d = IMUL32rr killed %r8d, %edi, implicit-def dead %eflags, debug-location !26
195 TEST32rr %r8d, %r8d, implicit-def %eflags, debug-location !31
196 JLE_1 %bb.9.for.end, implicit %eflags
197
198 bb.1.for.body.preheader:
199 successors: %bb.3.for.body(0)
200 liveins: %ecx, %edi, %edx, %esi, %r8d
201
202 DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
203 DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
204 DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
205 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
206 DBG_VALUE 0, 0, !13, !17, debug-location !25
207 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
208
209 bb.3.for.body (align 4):
210 successors: %bb.4.if.then(4), %bb.5.if.end(124)
211 liveins: %eax, %ecx, %edi, %edx, %esi, %r8d
212
213 DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
214 DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
215 DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
216 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
217 DBG_VALUE 0, 0, !13, !17, debug-location !25
218 TEST32rr %edi, %edi, implicit-def %eflags, debug-location !35
219 JG_1 %bb.4.if.then, implicit %eflags
220
221 bb.5.if.end:
222 successors: %bb.6.if.then.4(4), %bb.7.if.end.6(124)
223 liveins: %eax, %ecx, %edi, %edx, %esi, %r8d
224
225 DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
226 DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
227 DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
228 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
229 DBG_VALUE 0, 0, !13, !17, debug-location !25
230 TEST32rr %esi, %esi, implicit-def %eflags, debug-location !39
231 JG_1 %bb.6.if.then.4, implicit %eflags
232
233 bb.7.if.end.6:
234 successors: %bb.8.if.then.8(4), %bb.2.for.cond(124)
235 liveins: %eax, %ecx, %edi, %edx, %esi, %r8d
236
237 DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
238 DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
239 DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
240 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
241 DBG_VALUE 0, 0, !13, !17, debug-location !25
242 TEST32rr %edx, %edx, implicit-def %eflags, debug-location !45
243 JG_1 %bb.8.if.then.8, implicit %eflags
244
245 bb.2.for.cond:
246 successors: %bb.3.for.body(124), %bb.9.for.end(4)
247 liveins: %eax, %ecx, %edi, %edx, %esi, %r8d
248
249 DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
250 DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
251 DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
252 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
253 DBG_VALUE 0, 0, !13, !17, debug-location !25
254 %eax = INC32r killed %eax, implicit-def dead %eflags, debug-location !44
255 DBG_VALUE debug-use %eax, debug-use _, !13, !17, debug-location !25
256 CMP32rr %eax, %r8d, implicit-def %eflags, debug-location !31
257 JL_1 %bb.3.for.body, implicit %eflags
258 JMP_1 %bb.9.for.end
259
260 bb.4.if.then:
261 liveins: %ecx, %edi
262
263 DBG_VALUE debug-use %edi, debug-use _, !9, !17, debug-location !18
264 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
265 DBG_VALUE 0, 0, !13, !17, debug-location !25
266 %ecx = IMUL32rr killed %ecx, killed %edi, implicit-def dead %eflags, debug-location !36
267 DBG_VALUE 0, 0, !13, !17, debug-location !25
268 %eax = MOV32rr killed %ecx, debug-location !50
269 RETQ %eax, debug-location !50
270
271 bb.6.if.then.4:
272 liveins: %ecx, %esi
273
274 DBG_VALUE debug-use %esi, debug-use _, !10, !17, debug-location !19
275 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
276 DBG_VALUE 0, 0, !13, !17, debug-location !25
277 %ecx = IMUL32rr killed %ecx, killed %esi, implicit-def dead %eflags, debug-location !40
278 DBG_VALUE 0, 0, !13, !17, debug-location !25
279 %eax = MOV32rr killed %ecx, debug-location !50
280 RETQ %eax, debug-location !50
281
282 bb.8.if.then.8:
283 successors: %bb.9.for.end(0)
284 liveins: %ecx, %edx
285
286 DBG_VALUE debug-use %edx, debug-use _, !11, !17, debug-location !21
287 DBG_VALUE debug-use %ecx, debug-use _, !12, !17, debug-location !23
288 DBG_VALUE 0, 0, !13, !17, debug-location !25
289 %ecx = IMUL32rr killed %ecx, killed %edx, implicit-def dead %eflags, debug-location !46
290
291 bb.9.for.end:
292 liveins: %ecx
293
294 DBG_VALUE 0, 0, !13, !17, debug-location !25
295 %eax = MOV32rr killed %ecx, debug-location !50
296 RETQ %eax, debug-location !50
297
298 ...
+0
-260
test/DebugInfo/MIR/X86/live-debug-values.mir less more
None # RUN: llc -run-pass=livedebugvalues -march=x86-64 -o /dev/null %s | FileCheck %s
1
2 # Test the extension of debug ranges from predecessors.
3 # Generated from the source file LiveDebugValues.c:
4 # #include
5 # int m;
6 # extern int inc(int n);
7 # extern int change(int n);
8 # extern int modify(int n);
9 # int main(int argc, char **argv) {
10 # int n;
11 # if (argc != 2)
12 # n = 2;
13 # else
14 # n = atoi(argv[1]);
15 # n = change(n);
16 # if (n > 10) {
17 # m = modify(n);
18 # m = m + n; // var `m' doesn't has a dbg.value
19 # }
20 # else
21 # m = inc(n); // var `m' doesn't has a dbg.value
22 # printf("m(main): %d\n", m);
23 # return 0;
24 # }
25 # with clang -g -O3 -c -emit-llvm LiveDebugValues.c -S -o live-debug-values.ll
26 # then llc -stop-after stackmap-liveness live-debug-values.ll -o /dev/null > live-debug-values.mir
27 # This case will also produce multiple locations but only the debug range
28 # extension is tested here. This test case is tested with DWARF information under
29 # llvm/test/DebugInfo/live-debug-values.ll and present here for testing under
30 # MIR->MIR serialization.
31
32 # DBG_VALUE for variable "n" is extended into BB#5 from its predecessors BB#3
33 # and BB#4.
34 # CHECK: bb.5.if.end.7:
35 # CHECK: DBG_VALUE debug-use %rsi, debug-use _, !13, !20, debug-location !22
36 # CHECK-NEXT: DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33
37
38
39 --- |
40 ; ModuleID = 'live-debug-values.ll'
41 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
42 target triple = "x86_64-unknown-linux-gnu"
43
44 @m = common global i32 0, align 4
45 @.str = private unnamed_addr constant [13 x i8] c"m(main): %d\0A\00", align 1
46
47 ; Function Attrs: nounwind uwtable
48 define i32 @main(i32 %argc, i8** nocapture readonly %argv) #0 !dbg !4 {
49 entry:
50 tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !12, metadata !20), !dbg !21
51 tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !13, metadata !20), !dbg !22
52 %cmp = icmp eq i32 %argc, 2, !dbg !24
53 br i1 %cmp, label %if.else, label %if.end, !dbg !26
54
55 if.else: ; preds = %entry
56 %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 1, !dbg !27
57 %0 = load i8*, i8** %arrayidx, align 8, !dbg !27, !tbaa !28
58 %call = tail call i32 (i8*, ...) bitcast (i32 (...)* @atoi to i32 (i8*, ...)*)(i8* %0) #4, !dbg !32
59 tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !14, metadata !20), !dbg !33
60 br label %if.end
61
62 if.end: ; preds = %if.else, %entry
63 %n.0 = phi i32 [ %call, %if.else ], [ 2, %entry ]
64 %call1 = tail call i32 @change(i32 %n.0) #4, !dbg !34
65 tail call void @llvm.dbg.value(metadata i32 %call1, i64 0, metadata !14, metadata !20), !dbg !33
66 %cmp2 = icmp sgt i32 %call1, 10, !dbg !35
67 br i1 %cmp2, label %if.then.3, label %if.else.5, !dbg !37
68
69 if.then.3: ; preds = %if.end
70 %call4 = tail call i32 @modify(i32 %call1) #4, !dbg !38
71 %add = add nsw i32 %call4, %call1, !dbg !40
72 br label %if.end.7, !dbg !41
73
74 if.else.5: ; preds = %if.end
75 %call6 = tail call i32 @inc(i32 %call1) #4, !dbg !42
76 br label %if.end.7
77
78 if.end.7: ; preds = %if.else.5, %if.then.3
79 %storemerge = phi i32 [ %call6, %if.else.5 ], [ %add, %if.then.3 ]
80 store i32 %storemerge, i32* @m, align 4, !dbg !43, !tbaa !44
81 %call8 = tail call i32 (i8*, ...) @printf(i8* nonnull getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i32 %storemerge) #4, !dbg !46
82 ret i32 0, !dbg !47
83 }
84
85 declare i32 @atoi(...) #1
86
87 declare i32 @change(i32) #1
88
89 declare i32 @modify(i32) #1
90
91 declare i32 @inc(i32) #1
92
93 ; Function Attrs: nounwind
94 declare i32 @printf(i8* nocapture readonly, ...) #2
95
96 ; Function Attrs: nounwind readnone
97 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #3
98
99 attributes #0 = { nounwind uwtable }
100 attributes #1 = { nounwind }
101 attributes #2 = { nounwind }
102 attributes #3 = { nounwind readnone }
103 attributes #4 = { nounwind }
104
105 !llvm.dbg.cu = !{!0}
106 !llvm.module.flags = !{!17, !18}
107 !llvm.ident = !{!19}
108
109 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 253049) ", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !15)
110 !1 = !DIFile(filename: "LiveDebugValues.c", directory: "/home/vt/julia/test/tvvikram")
111 !2 = !{}
112 !3 = !{!4}
113 !4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true, variables: !11)
114 !5 = !DISubroutineType(types: !6)
115 !6 = !{!7, !7, !8}
116 !7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
117 !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64, align: 64)
118 !9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, align: 64)
119 !10 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
120 !11 = !{!12, !13, !14}
121 !12 = !DILocalVariable(name: "argc", arg: 1, scope: !4, file: !1, line: 6, type: !7)
122 !13 = !DILocalVariable(name: "argv", arg: 2, scope: !4, file: !1, line: 6, type: !8)
123 !14 = !DILocalVariable(name: "n", scope: !4, file: !1, line: 7, type: !7)
124 !15 = !{!16}
125 !16 = !DIGlobalVariable(name: "m", scope: !0, file: !1, line: 2, type: !7, isLocal: false, isDefinition: true, variable: i32* @m)
126 !17 = !{i32 2, !"Dwarf Version", i32 4}
127 !18 = !{i32 2, !"Debug Info Version", i32 3}
128 !19 = !{!"clang version 3.8.0 (trunk 253049)"}
129 !20 = !DIExpression()
130 !21 = !DILocation(line: 6, column: 14, scope: !4)
131 !22 = !DILocation(line: 6, column: 27, scope: !23)
132 !23 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 1)
133 !24 = !DILocation(line: 8, column: 12, scope: !25)
134 !25 = distinct !DILexicalBlock(scope: !4, file: !1, line: 8, column: 7)
135 !26 = !DILocation(line: 8, column: 7, scope: !4)
136 !27 = !DILocation(line: 11, column: 14, scope: !25)
137 !28 = !{!29, !29, i64 0}
138 !29 = !{!"any pointer", !30, i64 0}
139 !30 = !{!"omnipotent char", !31, i64 0}
140 !31 = !{!"Simple C/C++ TBAA"}
141 !32 = !DILocation(line: 11, column: 9, scope: !25)
142 !33 = !DILocation(line: 7, column: 7, scope: !23)
143 !34 = !DILocation(line: 12, column: 7, scope: !4)
144 !35 = !DILocation(line: 13, column: 9, scope: !36)
145 !36 = distinct !DILexicalBlock(scope: !4, file: !1, line: 13, column: 7)
146 !37 = !DILocation(line: 13, column: 7, scope: !4)
147 !38 = !DILocation(line: 14, column: 9, scope: !39)
148 !39 = distinct !DILexicalBlock(scope: !36, file: !1, line: 13, column: 15)
149 !40 = !DILocation(line: 15, column: 11, scope: !39)
150 !41 = !DILocation(line: 16, column: 3, scope: !39)
151 !42 = !DILocation(line: 18, column: 9, scope: !36)
152 !43 = !DILocation(line: 15, column: 7, scope: !39)
153 !44 = !{!45, !45, i64 0}
154 !45 = !{!"int", !30, i64 0}
155 !46 = !DILocation(line: 19, column: 3, scope: !4)
156 !47 = !DILocation(line: 20, column: 3, scope: !4)
157
158 ...
159 ---
160 name: main
161 alignment: 4
162 exposesReturnsTwice: false
163 hasInlineAsm: false
164 isSSA: false
165 tracksRegLiveness: true
166 tracksSubRegLiveness: false
167 liveins:
168 - { reg: '%edi' }
169 - { reg: '%rsi' }
170 calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
171 '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
172 '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
173 '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
174 frameInfo:
175 isFrameAddressTaken: false
176 isReturnAddressTaken: false
177 hasStackMap: false
178 hasPatchPoint: false
179 stackSize: 8
180 offsetAdjustment: 0
181 maxAlignment: 0
182 adjustsStack: true
183 hasCalls: true
184 maxCallFrameSize: 0
185 hasOpaqueSPAdjustment: false
186 hasVAStart: false
187 hasMustTailInVarArgFunc: false
188 fixedStack:
189 - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%rbx' }
190 body: |
191 bb.0.entry:
192 successors: %bb.1.if.else(16), %bb.2.if.end(16)
193 liveins: %edi, %rsi, %rbx
194
195 frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp
196 CFI_INSTRUCTION .cfi_def_cfa_offset 16
197 CFI_INSTRUCTION .cfi_offset %rbx, -16
198 DBG_VALUE debug-use %edi, debug-use _, !12, !20, debug-location !21
199 DBG_VALUE debug-use %rsi, debug-use _, !13, !20, debug-location !22
200 %eax = MOV32rr %edi
201 DBG_VALUE debug-use %eax, debug-use _, !12, !20, debug-location !21
202 %edi = MOV32ri 2
203 CMP32ri8 killed %eax, 2, implicit-def %eflags, debug-location !26
204 JNE_1 %bb.2.if.end, implicit %eflags
205
206 bb.1.if.else:
207 successors: %bb.2.if.end(0)
208 liveins: %rsi
209
210 DBG_VALUE debug-use %rsi, debug-use _, !13, !20, debug-location !22
211 %rdi = MOV64rm killed %rsi, 1, _, 8, _, debug-location !27 :: (load 8 from %ir.arrayidx, !tbaa !28)
212 dead %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags, implicit-def %al, debug-location !32
213 CALL64pcrel32 @atoi, csr_64, implicit %rsp, implicit %rdi, implicit %al, implicit-def %rsp, implicit-def %eax, debug-location !32
214 %edi = MOV32rr %eax, debug-location !32
215 DBG_VALUE debug-use %edi, debug-use _, !14, !20, debug-location !33
216
217 bb.2.if.end:
218 successors: %bb.3.if.then.3(16), %bb.4.if.else.5(16)
219 liveins: %edi
220
221 CALL64pcrel32 @change, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax, debug-location !34
222 %ebx = MOV32rr %eax, debug-location !34
223 DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33
224 CMP32ri8 %ebx, 11, implicit-def %eflags, debug-location !37
225 JL_1 %bb.4.if.else.5, implicit killed %eflags, debug-location !37
226
227 bb.3.if.then.3:
228 successors: %bb.5.if.end.7(0)
229 liveins: %ebx
230
231 DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33
232 %edi = MOV32rr %ebx, debug-location !38
233 CALL64pcrel32 @modify, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax, debug-location !38
234 %ecx = MOV32rr %eax, debug-location !38
235 %ecx = ADD32rr killed %ecx, killed %ebx, implicit-def dead %eflags, debug-location !40
236 JMP_1 %bb.5.if.end.7
237
238 bb.4.if.else.5:
239 successors: %bb.5.if.end.7(0)
240 liveins: %ebx
241
242 DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33
243 %edi = MOV32rr killed %ebx, debug-location !42
244 CALL64pcrel32 @inc, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax, debug-location !42
245 %ecx = MOV32rr %eax, debug-location !42
246
247 bb.5.if.end.7:
248 liveins: %ecx
249
250 MOV32mr %rip, 1, _, @m, _, %ecx, debug-location !43 :: (store 4 into @m, !tbaa !44)
251 dead undef %edi = MOV32ri64 @.str, implicit-def %rdi, debug-location !46
252 dead %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags, implicit-def %al, debug-location !47
253 %esi = MOV32rr killed %ecx, debug-location !46
254 CALL64pcrel32 @printf, csr_64, implicit %rsp, implicit %rdi, implicit %esi, implicit %al, implicit-def %rsp, implicit-def dead %eax, debug-location !46
255 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags, debug-location !47
256 %rbx = POP64r implicit-def %rsp, implicit %rsp, debug-location !47
257 RETQ %eax, debug-location !47
258
259 ...
+0
-2
test/DebugInfo/MIR/lit.local.cfg less more
None config.suffixes = ['.mir']
1
1515 ; Test that we only emit register-indirect locations for the array array.
1616 ; rdar://problem/14874886
1717 ;
18 ; CHECK: ##DEBUG_VALUE: main:array <- [%R{{.*}}+0]
19 ; CHECK: ##DEBUG_VALUE: main:array <- [%R{{.*}}+0]
2018 ; CHECK: ##DEBUG_VALUE: main:array <- [%R{{.*}}+0]
2119 ; CHECK-NOT: ##DEBUG_VALUE: main:array <- %R{{.*}}
2220 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
2828 ; CHECK-NEXT: Location description: 11 00
2929 ; CHECK-NEXT: {{^$}}
3030 ; CHECK-NEXT: Beginning address index: 3
31 ; CHECK-NEXT: Length: 25
31 ; CHECK-NEXT: Length: 21
3232 ; CHECK-NEXT: Location description: 50 93 04
3333 ; CHECK: [[E]]: Beginning address index: 4
34 ; CHECK-NEXT: Length: 23
34 ; CHECK-NEXT: Length: 19
3535 ; CHECK-NEXT: Location description: 50 93 04
3636 ; CHECK: [[B]]: Beginning address index: 5
37 ; CHECK-NEXT: Length: 21
37 ; CHECK-NEXT: Length: 17
3838 ; CHECK-NEXT: Location description: 50 93 04
3939 ; CHECK: [[D]]: Beginning address index: 6
40 ; CHECK-NEXT: Length: 21
40 ; CHECK-NEXT: Length: 17
4141 ; CHECK-NEXT: Location description: 50 93 04
4242
4343 ; Make sure we don't produce any relocations in any .dwo section (though in particular, debug_info.dwo)
2525 ; CHECK: .debug_loc
2626 ; CHECK: [[LOC]]:
2727 ; CHECK: Beginning address offset: 0x0000000000000000
28 ; CHECK: Ending address offset: 0x0000000000000008
28 ; CHECK: Ending address offset: 0x0000000000000004
2929 ; rdi, piece 0x00000008, piece 0x00000004, rsi, piece 0x00000004
3030 ; CHECK: Location description: 55 93 08 93 04 54 93 04
3131 ;
+0
-153
test/DebugInfo/live-debug-values.ll less more
None ; RUN: llc -filetype=asm %s -o - | FileCheck %s
1
2 ; Test the extension of debug ranges from predecessors.
3 ; Generated from the source file LiveDebugValues.c:
4 ; #include
5 ; int m;
6 ; extern int inc(int n);
7 ; extern int change(int n);
8 ; extern int modify(int n);
9 ; int main(int argc, char **argv) {
10 ; int n;
11 ; if (argc != 2)
12 ; n = 2;
13 ; else
14 ; n = atoi(argv[1]);
15 ; n = change(n);
16 ; if (n > 10) {
17 ; m = modify(n);
18 ; m = m + n; // var `m' doesn't has a dbg.value
19 ; }
20 ; else
21 ; m = inc(n); // var `m' doesn't has a dbg.value
22 ; printf("m(main): %d\n", m);
23 ; return 0;
24 ; }
25 ; with clang -g -O3 -emit-llvm -c LiveDebugValues.c -S -o live-debug-values.ll
26 ; This case will also produce multiple locations but only the debug range
27 ; extension is tested here.
28
29 ; DBG_VALUE for variable "n" is extended into BB#5 from its predecessors BB#3
30 ; and BB#4.
31 ; CHECK: .LBB0_5:
32 ; CHECK-NEXT: #DEBUG_VALUE: main:argv <- %RSI
33 ; CHECK-NEXT: #DEBUG_VALUE: main:n <- %EBX
34
35
36 ; ModuleID = 'LiveDebugValues.c'
37 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
38 target triple = "x86_64-unknown-linux-gnu"
39
40 @m = common global i32 0, align 4
41 @.str = private unnamed_addr constant [13 x i8] c"m(main): %d\0A\00", align 1
42
43 ; Function Attrs: nounwind uwtable
44 define i32 @main(i32 %argc, i8** nocapture readonly %argv) #0 !dbg !4 {
45 entry:
46 tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !12, metadata !20), !dbg !21
47 tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !13, metadata !20), !dbg !22
48 %cmp = icmp eq i32 %argc, 2, !dbg !24
49 br i1 %cmp, label %if.else, label %if.end, !dbg !26
50
51 if.else: ; preds = %entry
52 %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 1, !dbg !27
53 %0 = load i8*, i8** %arrayidx, align 8, !dbg !27, !tbaa !28
54 %call = tail call i32 (i8*, ...) bitcast (i32 (...)* @atoi to i32 (i8*, ...)*)(i8* %0) #4, !dbg !32
55 tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !14, metadata !20), !dbg !33
56 br label %if.end
57
58 if.end: ; preds = %entry, %if.else
59 %n.0 = phi i32 [ %call, %if.else ], [ 2, %entry ]
60 %call1 = tail call i32 @change(i32 %n.0) #4, !dbg !34
61 tail call void @llvm.dbg.value(metadata i32 %call1, i64 0, metadata !14, metadata !20), !dbg !33
62 %cmp2 = icmp sgt i32 %call1, 10, !dbg !35
63 br i1 %cmp2, label %if.then.3, label %if.else.5, !dbg !37
64
65 if.then.3: ; preds = %if.end
66 %call4 = tail call i32 @modify(i32 %call1) #4, !dbg !38
67 %add = add nsw i32 %call4, %call1, !dbg !40
68 br label %if.end.7, !dbg !41
69
70 if.else.5: ; preds = %if.end
71 %call6 = tail call i32 @inc(i32 %call1) #4, !dbg !42
72 br label %if.end.7
73
74 if.end.7: ; preds = %if.else.5, %if.then.3
75 %storemerge = phi i32 [ %call6, %if.else.5 ], [ %add, %if.then.3 ]
76 store i32 %storemerge, i32* @m, align 4, !dbg !43, !tbaa !44
77 %call8 = tail call i32 (i8*, ...) @printf(i8* nonnull getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i32 %storemerge) #4, !dbg !46
78 ret i32 0, !dbg !47
79 }
80
81 declare i32 @atoi(...) #1
82
83 declare i32 @change(i32) #1
84
85 declare i32 @modify(i32) #1
86
87 declare i32 @inc(i32) #1
88
89 ; Function Attrs: nounwind
90 declare i32 @printf(i8* nocapture readonly, ...) #2
91
92 ; Function Attrs: nounwind readnone
93 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #3
94
95 attributes #0 = { nounwind uwtable }
96 attributes #1 = { nounwind }
97 attributes #2 = { nounwind }
98 attributes #3 = { nounwind readnone }
99 attributes #4 = { nounwind }
100
101 !llvm.dbg.cu = !{!0}
102 !llvm.module.flags = !{!17, !18}
103 !llvm.ident = !{!19}
104
105 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 253049) ", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !15)
106 !1 = !DIFile(filename: "LiveDebugValues.c", directory: "/home/vt/julia/test/tvvikram")
107 !2 = !{}
108 !3 = !{!4}
109 !4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true, variables: !11)
110 !5 = !DISubroutineType(types: !6)
111 !6 = !{!7, !7, !8}
112 !7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
113 !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64, align: 64)
114 !9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, align: 64)
115 !10 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
116 !11 = !{!12, !13, !14}
117 !12 = !DILocalVariable(name: "argc", arg: 1, scope: !4, file: !1, line: 6, type: !7)
118 !13 = !DILocalVariable(name: "argv", arg: 2, scope: !4, file: !1, line: 6, type: !8)
119 !14 = !DILocalVariable(name: "n", scope: !4, file: !1, line: 7, type: !7)
120 !15 = !{!16}
121 !16 = !DIGlobalVariable(name: "m", scope: !0, file: !1, line: 2, type: !7, isLocal: false, isDefinition: true, variable: i32* @m)
122 !17 = !{i32 2, !"Dwarf Version", i32 4}
123 !18 = !{i32 2, !"Debug Info Version", i32 3}
124 !19 = !{!"clang version 3.8.0 (trunk 253049) "}
125 !20 = !DIExpression()
126 !21 = !DILocation(line: 6, column: 14, scope: !4)
127 !22 = !DILocation(line: 6, column: 27, scope: !23)
128 !23 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 1)
129 !24 = !DILocation(line: 8, column: 12, scope: !25)
130 !25 = distinct !DILexicalBlock(scope: !4, file: !1, line: 8, column: 7)
131 !26 = !DILocation(line: 8, column: 7, scope: !4)
132 !27 = !DILocation(line: 11, column: 14, scope: !25)
133 !28 = !{!29, !29, i64 0}
134 !29 = !{!"any pointer", !30, i64 0}
135 !30 = !{!"omnipotent char", !31, i64 0}
136 !31 = !{!"Simple C/C++ TBAA"}
137 !32 = !DILocation(line: 11, column: 9, scope: !25)
138 !33 = !DILocation(line: 7, column: 7, scope: !23)
139 !34 = !DILocation(line: 12, column: 7, scope: !4)
140 !35 = !DILocation(line: 13, column: 9, scope: !36)
141 !36 = distinct !DILexicalBlock(scope: !4, file: !1, line: 13, column: 7)
142 !37 = !DILocation(line: 13, column: 7, scope: !4)
143 !38 = !DILocation(line: 14, column: 9, scope: !39)
144 !39 = distinct !DILexicalBlock(scope: !36, file: !1, line: 13, column: 15)
145 !40 = !DILocation(line: 15, column: 11, scope: !39)
146 !41 = !DILocation(line: 16, column: 3, scope: !39)
147 !42 = !DILocation(line: 18, column: 9, scope: !36)
148 !43 = !DILocation(line: 15, column: 7, scope: !39)
149 !44 = !{!45, !45, i64 0}
150 !45 = !{!"int", !30, i64 0}
151 !46 = !DILocation(line: 19, column: 3, scope: !4)
152 !47 = !DILocation(line: 20, column: 3, scope: !4)