[llvm] r369508 - [DebugInfo] Avoid dropping location info across block boundaries
Jeremy Morse via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 21 02:22:31 PDT 2019
Author: jmorse
Date: Wed Aug 21 02:22:31 2019
New Revision: 369508
URL: http://llvm.org/viewvc/llvm-project?rev=369508&view=rev
Log:
[DebugInfo] Avoid dropping location info across block boundaries
LiveDebugValues propagates variable locations between blocks by creating
new DBG_VALUE insts in the successors, then interpreting them when it
passes back through the block at a later time. However, this flushes out
any extra information about the location that LiveDebugValues holds: for
example, connections between variable locations such as discussed in
D65368. And as reported in PR42772 this causes us to lose track of the
fact that a spill-location is actually a spill, not a register location.
This patch fixes that by deferring the creation of propagated DBG_VALUEs
until after propagation has completed: instead location propagation occurs
only by sharing location ID numbers between blocks.
Differential Revision: https://reviews.llvm.org/D66412
Modified:
llvm/trunk/lib/CodeGen/LiveDebugValues.cpp
llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-restore.mir
Modified: llvm/trunk/lib/CodeGen/LiveDebugValues.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugValues.cpp?rev=369508&r1=369507&r2=369508&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveDebugValues.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveDebugValues.cpp Wed Aug 21 02:22:31 2019
@@ -7,14 +7,23 @@
//===----------------------------------------------------------------------===//
///
/// This pass implements a data flow analysis that propagates debug location
-/// information by inserting additional DBG_VALUE instructions into the machine
-/// instruction stream. The pass internally builds debug location liveness
-/// ranges to determine the points where additional DBG_VALUEs need to be
-/// inserted.
+/// information by inserting additional DBG_VALUE insts into the machine
+/// instruction stream. Before running, each DBG_VALUE inst corresponds to a
+/// source assignment of a variable. Afterwards, a DBG_VALUE inst specifies a
+/// variable location for the current basic block (see SourceLevelDebugging.rst).
///
/// This is a separate pass from DbgValueHistoryCalculator to facilitate
/// testing and improve modularity.
///
+/// Each variable location is represented by a VarLoc object that identifies the
+/// source variable, its current machine-location, and the DBG_VALUE inst that
+/// specifies the location. Each VarLoc is indexed in the (function-scope)
+/// VarLocMap, giving each VarLoc a unique index. Rather than operate directly
+/// on machine locations, the dataflow analysis in this pass identifies
+/// locations by their index in the VarLocMap, meaning all the variable
+/// locations in a block can be described by a sparse vector of VarLocMap
+/// indexes.
+///
//===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseMap.h"
@@ -320,6 +329,14 @@ private:
Vars.insert({Var, VarLocID});
}
+ /// Insert a set of ranges.
+ void insertFromLocSet(const VarLocSet &ToLoad, const VarLocMap &Map) {
+ for (unsigned Id : ToLoad) {
+ const VarLoc &Var = Map[Id];
+ insert(Id, Var.Var);
+ }
+ }
+
/// Empty the set.
void clear() {
VarLocs.clear();
@@ -361,10 +378,10 @@ private:
void transferRegisterDef(MachineInstr &MI, OpenRangesSet &OpenRanges,
VarLocMap &VarLocIDs, TransferMap &Transfers,
DebugParamMap &DebugEntryVals);
- bool transferTerminatorInst(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocInMBB &OutLocs, const VarLocMap &VarLocIDs);
+ bool transferTerminator(MachineBasicBlock *MBB, OpenRangesSet &OpenRanges,
+ VarLocInMBB &OutLocs, const VarLocMap &VarLocIDs);
- bool process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ void process(MachineInstr &MI, OpenRangesSet &OpenRanges,
VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
TransferMap &Transfers, DebugParamMap &DebugEntryVals,
bool transferChanges, OverlapMap &OverlapFragments,
@@ -376,7 +393,12 @@ private:
bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
const VarLocMap &VarLocIDs,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
- SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks);
+ SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks,
+ VarLocInMBB &PendingInLocs);
+
+ /// Create DBG_VALUE insts for inlocs that have been propagated but
+ /// had their instruction creation deferred.
+ void flushPendingLocs(VarLocInMBB &PendingInLocs, VarLocMap &VarLocIDs);
bool ExtendRanges(MachineFunction &MF);
@@ -904,14 +926,11 @@ void LiveDebugValues::transferRegisterCo
}
/// Terminate all open ranges at the end of the current basic block.
-bool LiveDebugValues::transferTerminatorInst(MachineInstr &MI,
- OpenRangesSet &OpenRanges,
- VarLocInMBB &OutLocs,
- const VarLocMap &VarLocIDs) {
+bool LiveDebugValues::transferTerminator(MachineBasicBlock *CurMBB,
+ OpenRangesSet &OpenRanges,
+ VarLocInMBB &OutLocs,
+ const VarLocMap &VarLocIDs) {
bool Changed = false;
- const MachineBasicBlock *CurMBB = MI.getParent();
- if (!(MI.isTerminator() || (&MI == &CurMBB->back())))
- return false;
if (OpenRanges.empty())
return false;
@@ -993,13 +1012,12 @@ void LiveDebugValues::accumulateFragment
}
/// This routine creates OpenRanges and OutLocs.
-bool LiveDebugValues::process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+void LiveDebugValues::process(MachineInstr &MI, OpenRangesSet &OpenRanges,
VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
TransferMap &Transfers, DebugParamMap &DebugEntryVals,
bool transferChanges,
OverlapMap &OverlapFragments,
VarToFragments &SeenFragments) {
- bool Changed = false;
transferDebugValue(MI, OpenRanges, VarLocIDs);
transferRegisterDef(MI, OpenRanges, VarLocIDs, Transfers,
DebugEntryVals);
@@ -1011,8 +1029,6 @@ bool LiveDebugValues::process(MachineIns
if (MI.isDebugValue())
accumulateFragmentMap(MI, SeenFragments, OverlapFragments);
}
- Changed = transferTerminatorInst(MI, OpenRanges, OutLocs, VarLocIDs);
- return Changed;
}
/// This routine joins the analysis results of all incoming edges in @MBB by
@@ -1022,7 +1038,8 @@ bool LiveDebugValues::join(
MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
const VarLocMap &VarLocIDs,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
- SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks) {
+ SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks,
+ VarLocInMBB &PendingInLocs) {
LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
bool Changed = false;
@@ -1088,44 +1105,15 @@ bool LiveDebugValues::join(
return false;
VarLocSet &ILS = InLocs[&MBB];
+ VarLocSet &Pending = PendingInLocs[&MBB];
- // Insert DBG_VALUE instructions, if not already inserted.
+ // New locations will have DBG_VALUE insts inserted at the start of the
+ // block, after location propagation has finished. Record the insertions
+ // that we need to perform in the Pending set.
VarLocSet Diff = InLocsT;
Diff.intersectWithComplement(ILS);
for (auto ID : Diff) {
- // This VarLoc is not found in InLocs i.e. it is not yet inserted. So, a
- // new range is started for the var from the mbb's beginning by inserting
- // a new DBG_VALUE. process() will end this range however appropriate.
- const VarLoc &DiffIt = VarLocIDs[ID];
- const MachineInstr *DebugInstr = &DiffIt.MI;
- MachineInstr *MI = nullptr;
- if (DiffIt.isConstant()) {
- MachineOperand MO(DebugInstr->getOperand(0));
- MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
- DebugInstr->getDesc(), false, MO,
- DebugInstr->getDebugVariable(),
- DebugInstr->getDebugExpression());
- } else {
- auto *DebugExpr = DebugInstr->getDebugExpression();
- Register Reg = DebugInstr->getOperand(0).getReg();
- bool IsIndirect = DebugInstr->isIndirectDebugValue();
-
- if (DiffIt.Kind == VarLoc::SpillLocKind) {
- // This is is a spilt location; DebugInstr refers to the unspilt
- // location. We need to rebuild the spilt location expression and
- // point the DBG_VALUE at the frame register.
- DebugExpr = DIExpression::prepend(DebugInstr->getDebugExpression(),
- DIExpression::ApplyOffset,
- DiffIt.Loc.SpillLocation.SpillOffset);
- Reg = TRI->getFrameRegister(*DebugInstr->getMF());
- IsIndirect = true;
- }
-
- MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
- DebugInstr->getDesc(), IsIndirect, Reg,
- DebugInstr->getDebugVariable(), DebugExpr);
- }
- LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
+ Pending.set(ID);
ILS.set(ID);
++NumInserted;
Changed = true;
@@ -1133,6 +1121,53 @@ bool LiveDebugValues::join(
return Changed;
}
+void LiveDebugValues::flushPendingLocs(VarLocInMBB &PendingInLocs,
+ VarLocMap &VarLocIDs) {
+ // PendingInLocs records all locations propagated into blocks, which have
+ // not had DBG_VALUE insts created. Go through and create those insts now.
+ for (auto &Iter : PendingInLocs) {
+ // Map is keyed on a constant pointer, unwrap it so we can insert insts.
+ auto &MBB = const_cast<MachineBasicBlock &>(*Iter.first);
+ VarLocSet &Pending = Iter.second;
+
+ for (unsigned ID : Pending) {
+ // The ID location is live-in to MBB -- work out what kind of machine
+ // location it is and create a DBG_VALUE.
+ const VarLoc &DiffIt = VarLocIDs[ID];
+ const MachineInstr *DebugInstr = &DiffIt.MI;
+ MachineInstr *MI = nullptr;
+
+ if (DiffIt.isConstant()) {
+ MachineOperand MO(DebugInstr->getOperand(0));
+ MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
+ DebugInstr->getDesc(), false, MO,
+ DebugInstr->getDebugVariable(),
+ DebugInstr->getDebugExpression());
+ } else {
+ auto *DebugExpr = DebugInstr->getDebugExpression();
+ Register Reg = DebugInstr->getOperand(0).getReg();
+ bool IsIndirect = DebugInstr->isIndirectDebugValue();
+
+ if (DiffIt.Kind == VarLoc::SpillLocKind) {
+ // This is is a spilt location; DebugInstr refers to the unspilt
+ // location. We need to rebuild the spilt location expression and
+ // point the DBG_VALUE at the frame register.
+ DebugExpr = DIExpression::prepend(
+ DebugInstr->getDebugExpression(), DIExpression::ApplyOffset,
+ DiffIt.Loc.SpillLocation.SpillOffset);
+ Reg = TRI->getFrameRegister(*DebugInstr->getMF());
+ IsIndirect = true;
+ }
+
+ MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
+ DebugInstr->getDesc(), IsIndirect, Reg,
+ DebugInstr->getDebugVariable(), DebugExpr);
+ }
+ LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
+ }
+ }
+}
+
/// Calculate the liveness information for the given machine function and
/// extend ranges across basic blocks.
bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
@@ -1149,6 +1184,9 @@ bool LiveDebugValues::ExtendRanges(Machi
VarLocInMBB OutLocs; // Ranges that exist beyond bb.
VarLocInMBB InLocs; // Ranges that are incoming after joining.
TransferMap Transfers; // DBG_VALUEs associated with spills.
+ VarLocInMBB PendingInLocs; // Ranges that are incoming after joining, but
+ // that we have deferred creating DBG_VALUE insts
+ // for immediately.
VarToFragments SeenFragments;
@@ -1214,6 +1252,7 @@ bool LiveDebugValues::ExtendRanges(Machi
process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers, DebugEntryVals,
dontTransferChanges, OverlapFragments, SeenFragments);
}
+ transferTerminator(&MBB, OpenRanges, OutLocs, VarLocIDs);
// Add any entry DBG_VALUE instructions necessitated by parameter
// clobbering.
for (auto &TR : Transfers) {
@@ -1221,6 +1260,9 @@ bool LiveDebugValues::ExtendRanges(Machi
TR.DebugInst);
}
Transfers.clear();
+
+ // Initialize pending inlocs.
+ PendingInLocs[&MBB] = VarLocSet();
}
auto hasNonArtificialLocation = [](const MachineInstr &MI) -> bool {
@@ -1257,8 +1299,8 @@ bool LiveDebugValues::ExtendRanges(Machi
while (!Worklist.empty()) {
MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
Worklist.pop();
- MBBJoined =
- join(*MBB, OutLocs, InLocs, VarLocIDs, Visited, ArtificialBlocks);
+ MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs, Visited,
+ ArtificialBlocks, PendingInLocs);
Visited.insert(MBB);
if (MBBJoined) {
MBBJoined = false;
@@ -1266,11 +1308,13 @@ bool LiveDebugValues::ExtendRanges(Machi
// Now that we have started to extend ranges across BBs we need to
// examine spill instructions to see whether they spill registers that
// correspond to user variables.
+ // First load any pending inlocs.
+ OpenRanges.insertFromLocSet(PendingInLocs[MBB], VarLocIDs);
for (auto &MI : *MBB)
- OLChanged |=
process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers,
DebugEntryVals, transferChanges, OverlapFragments,
SeenFragments);
+ OLChanged |= transferTerminator(MBB, OpenRanges, OutLocs, VarLocIDs);
// Add any DBG_VALUE instructions necessitated by spills.
for (auto &TR : Transfers)
@@ -1298,6 +1342,10 @@ bool LiveDebugValues::ExtendRanges(Machi
assert(Pending.empty() && "Pending should be empty");
}
+ // Deferred inlocs will not have had any DBG_VALUE insts created; do
+ // that now.
+ flushPendingLocs(PendingInLocs, VarLocIDs);
+
LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs, "Final OutLocs", dbgs()));
LLVM_DEBUG(printVarLocInMBB(MF, InLocs, VarLocIDs, "Final InLocs", dbgs()));
return Changed;
Modified: llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-restore.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-restore.mir?rev=369508&r1=369507&r2=369508&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-restore.mir (original)
+++ llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-restore.mir Wed Aug 21 02:22:31 2019
@@ -3,7 +3,10 @@
# Generated from the following source with:
# clang -g -mllvm -stop-before=livedebugvalues -S -O2 test.c -o test.mir
# Then more functions added to test for extra behaviours with complex
-# expressions.
+# expressions:
+# 'g': test for a crash from PR42773
+# 'h': complex expressions should be restored
+# 'i': spills should be restored across block boundaries
# #define FORCE_SPILL() \
# __asm volatile("" : : : \
@@ -16,10 +19,11 @@
# return *(p + 1);
# }
-# Pick out DILocalVariable numbers for "p", "q" and "r"
+# Pick out DILocalVariable numbers for "p", "q" and "r" etc
# CHECK: ![[PVAR:[0-9]+]] = !DILocalVariable(name: "p",
# CHECK: ![[QVAR:[0-9]+]] = !DILocalVariable(name: "q",
# CHECK: ![[RVAR:[0-9]+]] = !DILocalVariable(name: "r",
+# CHECK: ![[SVAR:[0-9]+]] = !DILocalVariable(name: "s",
# Ascertain that the spill has been recognized and manifested in a DBG_VALUE.
# CHECK: MOV64mr $rsp,{{.*-8.*}}killed{{.*}}$rdi :: (store 8 into %stack.0)
@@ -78,6 +82,24 @@
ret i32 %0, !dbg !228
}
+ define dso_local i32 @i(i32* readonly %p) local_unnamed_addr !dbg !307 {
+ entry:
+ br label %foo
+
+ foo:
+ call void @llvm.dbg.value(metadata i32* %p, metadata !313, metadata !DIExpression()), !dbg !314
+ %tobool = icmp eq i32* %p, null, !dbg !315
+ br i1 %tobool, label %if.end, label %if.then, !dbg !317
+
+ if.then: ; preds = %entry
+ tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !318, !srcloc !320
+ br label %if.end, !dbg !321
+
+ if.end: ; preds = %entry, %if.then
+ %add.ptr = getelementptr inbounds i32, i32* %p, i64 1, !dbg !322
+ %0 = load i32, i32* %add.ptr, align 4, !dbg !323, !tbaa !24
+ ret i32 %0, !dbg !328
+ }
declare void @llvm.dbg.value(metadata, metadata, metadata)
@@ -144,6 +166,21 @@
!222 = !DILocation(line: 109, column: 14, scope: !207)
!223 = !DILocation(line: 109, column: 10, scope: !207)
!228 = !DILocation(line: 109, column: 3, scope: !207)
+ !301 = !DIBasicType(name: "looong int", size: 64, encoding: DW_ATE_signed)
+ !307 = distinct !DISubprogram(name: "g", scope: !0, file: !1, line: 105, type: !8, scopeLine: 105, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !312)
+ !312 = !{!313}
+ !313 = !DILocalVariable(name: "s", arg: 1, scope: !307, file: !1, line: 105, type: !301)
+ !314 = !DILocation(line: 105, column: 12, scope: !307)
+ !315 = !DILocation(line: 106, column: 7, scope: !316)
+ !316 = distinct !DILexicalBlock(scope: !307, file: !1, line: 106, column: 7)
+ !317 = !DILocation(line: 106, column: 7, scope: !307)
+ !318 = !DILocation(line: 107, column: 5, scope: !319)
+ !319 = distinct !DILexicalBlock(scope: !316, file: !1, line: 106, column: 10)
+ !320 = !{i32 -2147471544}
+ !321 = !DILocation(line: 108, column: 3, scope: !319)
+ !322 = !DILocation(line: 109, column: 14, scope: !307)
+ !323 = !DILocation(line: 109, column: 10, scope: !307)
+ !328 = !DILocation(line: 109, column: 3, scope: !307)
...
---
name: f
@@ -439,3 +476,122 @@ body: |
...
+---
+# Function four: test that spill restores are detected across block
+# boundaries. The spill has been moved to bb.1, children of which are
+# bb 2 and 3, neither of which modifies the stack loc. The exit block (3)
+# should still be tracking the spill, and restore it on stack load.
+
+# FIXME: this test too contains a broken spill location.
+
+# Summary: loc is in $rdi in bb0, spills to stack in bb1, remains in stack
+# in bb2, starts in stack then loaded in bb3.
+
+# CHECK-LABEL: name: i
+# CHECK-LABEL: bb.0.entry:
+# CHECK: DBG_VALUE $rdi, $noreg, ![[SVAR]], !DIExpression(DW_OP_plus_uconst, 1)
+# CHECK-LABEL: bb.1.foo:
+# CHECK: DBG_VALUE $rdi, $noreg, ![[SVAR]], !DIExpression(DW_OP_plus_uconst, 1)
+# CHECK: DBG_VALUE $rsp, 0, ![[SVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 1)
+# CHECK-LABEL: bb.2.if.then:
+# CHECK: DBG_VALUE $rsp, 0, ![[SVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 1)
+# CHECK-LABEL: bb.3.if.end
+# CHECK: DBG_VALUE $rsp, 0, ![[SVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 1)
+# CHECK: DBG_VALUE $rdi, $noreg, ![[SVAR]], !DIExpression(DW_OP_plus_uconst, 1)
+name: i
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$rdi', virtual-reg: '' }
+frameInfo:
+ stackSize: 48
+ offsetAdjustment: -48
+ maxAlignment: 8
+ cvBytesOfCalleeSavedRegisters: 48
+ localFrameSize: 0
+fixedStack:
+ - { id: 0, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
+ callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, type: spill-slot, offset: -48, size: 8, alignment: 16, stack-id: default,
+ callee-saved-register: '$r12', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 2, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
+ callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 16, stack-id: default,
+ callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 4, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
+ callee-saved-register: '$r15', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 5, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
+ callee-saved-register: '$rbp', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+stack:
+ - { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants: []
+body: |
+ bb.0.entry:
+ successors: %bb.1
+ liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
+
+ DBG_VALUE $rdi, $noreg, !313, !DIExpression(DW_OP_plus_uconst, 1), debug-location !314
+ JMP_1 %bb.1, debug-location !317
+
+ bb.1.foo:
+ successors: %bb.3(0x30000000), %bb.2(0x50000000)
+ liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
+
+ $rax = COPY $rdi
+ MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rdi :: (store 8 into %stack.0)
+ $rdi = MOV64ri 0
+ TEST64rr $rax, renamable $rax, implicit-def $eflags, debug-location !315
+ JCC_1 %bb.3, 4, implicit $eflags, debug-location !317
+
+ bb.2.if.then:
+ successors: %bb.3(0x80000000)
+ liveins: $rbp, $r15, $r14, $r13, $r12, $rbx
+
+ frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 16
+ frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 24
+ frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 32
+ frame-setup PUSH64r killed $r13, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 40
+ frame-setup PUSH64r killed $r12, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 48
+ frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 56
+ CFI_INSTRUCTION offset $rbx, -56
+ CFI_INSTRUCTION offset $r12, -48
+ CFI_INSTRUCTION offset $r13, -40
+ CFI_INSTRUCTION offset $r14, -32
+ CFI_INSTRUCTION offset $r15, -24
+ CFI_INSTRUCTION offset $rbp, -16
+ INLINEASM &"", 1, 12, implicit-def dead early-clobber $rax, 12, implicit-def dead early-clobber $rbx, 12, implicit-def dead early-clobber $rcx, 12, implicit-def dead early-clobber $rdx, 12, implicit-def dead early-clobber $rsi, 12, implicit-def dead early-clobber $rdi, 12, implicit-def dead early-clobber $rbp, 12, implicit-def dead early-clobber $r8, 12, implicit-def dead early-clobber $r9, 12, implicit-def dead early-clobber $r10, 12, implicit-def dead early-clobber $r11, 12, implicit-def dead early-clobber $r12, 12, implicit-def dead early-clobber $r13, 12, implicit-def dead early-clobber $r14, 12, implicit-def dead early-clobber $r15, 12, implicit-def dead early-clobber $eflags, !320, debug-location !318
+ $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 48
+ $r12 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 40
+ $r13 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 32
+ $r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 24
+ $r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 16
+ $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 8
+
+ bb.3.if.end:
+ liveins: $rbx, $r12, $r13, $r14, $r15, $rbp
+
+ renamable $rdi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
+ renamable $eax = MOV32rm killed renamable $rdi, 1, $noreg, 4, $noreg, debug-location !323 :: (load 4 from %ir.add.ptr, !tbaa !24)
+ RETQ $eax, debug-location !328
+
+...
More information about the llvm-commits
mailing list