[llvm] r336978 - [LiveDebugValues] Tracking copying value between registers
Petar Jovanovic via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 13 01:24:27 PDT 2018
Author: petarj
Date: Fri Jul 13 01:24:26 2018
New Revision: 336978
URL: http://llvm.org/viewvc/llvm-project?rev=336978&view=rev
Log:
[LiveDebugValues] Tracking copying value between registers
During the execution of long functions or functions that have a lot of
inlined code it could come to the situation where tracked value could be
transferred from one register to another. The transfer is recognized only if
destination register is a callee saved register and if source register is
killed. We do not salvage caller-saved registers since there is a great
chance that killed register would outlive it.
Patch by Nikola Prica.
Differential Revision: https://reviews.llvm.org/D44016
Added:
llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir
llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir
llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir
Modified:
llvm/trunk/lib/CodeGen/LiveDebugValues.cpp
Modified: llvm/trunk/lib/CodeGen/LiveDebugValues.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugValues.cpp?rev=336978&r1=336977&r2=336978&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveDebugValues.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveDebugValues.cpp Fri Jul 13 01:24:26 2018
@@ -40,6 +40,7 @@
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
@@ -82,6 +83,7 @@ private:
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
const TargetFrameLowering *TFI;
+ BitVector CalleeSavedRegs;
LexicalScopes LS;
/// Keeps track of lexical scopes associated with a user value's source
@@ -179,11 +181,11 @@ private:
using VarLocMap = UniqueVector<VarLoc>;
using VarLocSet = SparseBitVector<>;
using VarLocInMBB = SmallDenseMap<const MachineBasicBlock *, VarLocSet>;
- struct SpillDebugPair {
- MachineInstr *SpillInst;
+ struct TransferDebugPair {
+ MachineInstr *TransferInst;
MachineInstr *DebugInst;
};
- using SpillMap = SmallVector<SpillDebugPair, 4>;
+ using TransferMap = SmallVector<TransferDebugPair, 4>;
/// This holds the working set of currently open ranges. For fast
/// access, this is done both as a set of VarLocIDs, and a map of
@@ -236,18 +238,23 @@ private:
bool isSpillInstruction(const MachineInstr &MI, MachineFunction *MF,
unsigned &Reg);
int extractSpillBaseRegAndOffset(const MachineInstr &MI, unsigned &Reg);
+ void insertTransferDebugPair(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ TransferMap &Transfers, VarLocMap &VarLocIDs,
+ unsigned OldVarID, unsigned NewReg = 0);
void transferDebugValue(const MachineInstr &MI, OpenRangesSet &OpenRanges,
VarLocMap &VarLocIDs);
void transferSpillInst(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocMap &VarLocIDs, SpillMap &Spills);
+ VarLocMap &VarLocIDs, TransferMap &Transfers);
+ void transferRegisterCopy(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs, TransferMap &Transfers);
void transferRegisterDef(MachineInstr &MI, OpenRangesSet &OpenRanges,
const VarLocMap &VarLocIDs);
bool transferTerminatorInst(MachineInstr &MI, OpenRangesSet &OpenRanges,
VarLocInMBB &OutLocs, const VarLocMap &VarLocIDs);
- bool transfer(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocInMBB &OutLocs, VarLocMap &VarLocIDs, SpillMap &Spills,
- bool transferSpills);
+ bool process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
+ TransferMap &Transfers, bool transferChanges);
bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
const VarLocMap &VarLocIDs,
@@ -370,6 +377,54 @@ void LiveDebugValues::transferDebugValue
}
}
+/// Create new TransferDebugPair and insert it in \p Transfers. The VarLoc
+/// with \p OldVarID should be deleted form \p OpenRanges and replaced with
+/// new VarLoc. If \p NewReg is different than default zero value then the
+/// new location will be register location created by the copy like instruction,
+/// otherwise it is variable's location on the stack.
+void LiveDebugValues::insertTransferDebugPair(
+ MachineInstr &MI, OpenRangesSet &OpenRanges, TransferMap &Transfers,
+ VarLocMap &VarLocIDs, unsigned OldVarID, unsigned NewReg) {
+ const MachineInstr *DMI = &VarLocIDs[OldVarID].MI;
+ MachineFunction *MF = MI.getParent()->getParent();
+ MachineInstr *NewDMI;
+ if (NewReg) {
+ // Create a DBG_VALUE instruction to describe the Var in its new
+ // register location.
+ NewDMI = BuildMI(*MF, DMI->getDebugLoc(), DMI->getDesc(),
+ DMI->isIndirectDebugValue(), NewReg,
+ DMI->getDebugVariable(), DMI->getDebugExpression());
+ if (DMI->isIndirectDebugValue())
+ NewDMI->getOperand(1).setImm(DMI->getOperand(1).getImm());
+ LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register copy: ";
+ NewDMI->print(dbgs(), false, false, false, TII));
+ } else {
+ // Create a DBG_VALUE instruction to describe the Var in its spilled
+ // location.
+ unsigned SpillBase;
+ int SpillOffset = extractSpillBaseRegAndOffset(MI, SpillBase);
+ auto *SpillExpr = DIExpression::prepend(DMI->getDebugExpression(),
+ DIExpression::NoDeref, SpillOffset);
+ NewDMI = BuildMI(*MF, DMI->getDebugLoc(), DMI->getDesc(), true, SpillBase,
+ DMI->getDebugVariable(), SpillExpr);
+ LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for spill: ";
+ NewDMI->print(dbgs(), false, false, false, TII));
+ }
+
+ // The newly created DBG_VALUE instruction NewDMI must be inserted after
+ // MI. Keep track of the pairing.
+ TransferDebugPair MIP = {&MI, NewDMI};
+ Transfers.push_back(MIP);
+
+ // End all previous ranges of Var.
+ OpenRanges.erase(VarLocIDs[OldVarID].Var);
+
+ // Add the VarLoc to OpenRanges.
+ VarLoc VL(*NewDMI, LS);
+ unsigned LocID = VarLocIDs.insert(VL);
+ OpenRanges.insert(LocID, VL.Var);
+}
+
/// A definition of a register may mark the end of a range.
void LiveDebugValues::transferRegisterDef(MachineInstr &MI,
OpenRangesSet &OpenRanges,
@@ -464,14 +519,14 @@ bool LiveDebugValues::isSpillInstruction
/// A spilled register may indicate that we have to end the current range of
/// a variable and create a new one for the spill location.
-/// We don't want to insert any instructions in transfer(), so we just create
-/// the DBG_VALUE witout inserting it and keep track of it in @Spills.
+/// We don't want to insert any instructions in process(), so we just create
+/// the DBG_VALUE without inserting it and keep track of it in \p Transfers.
/// It will be inserted into the BB when we're done iterating over the
/// instructions.
void LiveDebugValues::transferSpillInst(MachineInstr &MI,
OpenRangesSet &OpenRanges,
VarLocMap &VarLocIDs,
- SpillMap &Spills) {
+ TransferMap &Transfers) {
unsigned Reg;
MachineFunction *MF = MI.getMF();
if (!isSpillInstruction(MI, MF, Reg))
@@ -482,33 +537,47 @@ void LiveDebugValues::transferSpillInst(
if (VarLocIDs[ID].isDescribedByReg() == Reg) {
LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('
<< VarLocIDs[ID].Var.getVar()->getName() << ")\n");
+ insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, ID);
+ return;
+ }
+ }
+}
- // Create a DBG_VALUE instruction to describe the Var in its spilled
- // location, but don't insert it yet to avoid invalidating the
- // iterator in our caller.
- unsigned SpillBase;
- int SpillOffset = extractSpillBaseRegAndOffset(MI, SpillBase);
- const MachineInstr *DMI = &VarLocIDs[ID].MI;
- auto *SpillExpr = DIExpression::prepend(
- DMI->getDebugExpression(), DIExpression::NoDeref, SpillOffset);
- MachineInstr *SpDMI =
- BuildMI(*MF, DMI->getDebugLoc(), DMI->getDesc(), true, SpillBase,
- DMI->getDebugVariable(), SpillExpr);
- LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for spill: ";
- SpDMI->print(dbgs(), false, TII));
-
- // The newly created DBG_VALUE instruction SpDMI must be inserted after
- // MI. Keep track of the pairing.
- SpillDebugPair MIP = {&MI, SpDMI};
- Spills.push_back(MIP);
-
- // End all previous ranges of Var.
- OpenRanges.erase(VarLocIDs[ID].Var);
-
- // Add the VarLoc to OpenRanges.
- VarLoc VL(*SpDMI, LS);
- unsigned SpillLocID = VarLocIDs.insert(VL);
- OpenRanges.insert(SpillLocID, VL.Var);
+/// If \p MI is a register copy instruction, that copies a previously tracked
+/// value from one register to another register that is callee saved, we
+/// create new DBG_VALUE instruction described with copy destination register.
+void LiveDebugValues::transferRegisterCopy(MachineInstr &MI,
+ OpenRangesSet &OpenRanges,
+ VarLocMap &VarLocIDs,
+ TransferMap &Transfers) {
+ const MachineOperand *SrcRegOp, *DestRegOp;
+
+ if (!TII->isCopyInstr(MI, SrcRegOp, DestRegOp) || !SrcRegOp->isKill() ||
+ !DestRegOp->isDef())
+ return;
+
+ auto isCalleSavedReg = [&](unsigned Reg) {
+ for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)
+ if (CalleeSavedRegs.test(*RAI))
+ return true;
+ return false;
+ };
+
+ unsigned SrcReg = SrcRegOp->getReg();
+ unsigned DestReg = DestRegOp->getReg();
+
+ // We want to recognize instructions where destination register is callee
+ // saved register. If register that could be clobbered by the call is
+ // included, there would be a great chance that it is going to be clobbered
+ // soon. It is more likely that previous register location, which is callee
+ // saved, is going to stay unclobbered longer, even if it is killed.
+ if (!isCalleSavedReg(DestReg))
+ return;
+
+ for (unsigned ID : OpenRanges.getVarLocs()) {
+ if (VarLocIDs[ID].isDescribedByReg() == SrcReg) {
+ insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, ID,
+ DestReg);
return;
}
}
@@ -540,14 +609,16 @@ bool LiveDebugValues::transferTerminator
}
/// This routine creates OpenRanges and OutLocs.
-bool LiveDebugValues::transfer(MachineInstr &MI, OpenRangesSet &OpenRanges,
- VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
- SpillMap &Spills, bool transferSpills) {
+bool LiveDebugValues::process(MachineInstr &MI, OpenRangesSet &OpenRanges,
+ VarLocInMBB &OutLocs, VarLocMap &VarLocIDs,
+ TransferMap &Transfers, bool transferChanges) {
bool Changed = false;
transferDebugValue(MI, OpenRanges, VarLocIDs);
transferRegisterDef(MI, OpenRanges, VarLocIDs);
- if (transferSpills)
- transferSpillInst(MI, OpenRanges, VarLocIDs, Spills);
+ if (transferChanges) {
+ transferRegisterCopy(MI, OpenRanges, VarLocIDs, Transfers);
+ transferSpillInst(MI, OpenRanges, VarLocIDs, Transfers);
+ }
Changed = transferTerminatorInst(MI, OpenRanges, OutLocs, VarLocIDs);
return Changed;
}
@@ -609,7 +680,7 @@ bool LiveDebugValues::join(MachineBasicB
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. transfer() will end this range however appropriate.
+ // a new DBG_VALUE. process() will end this range however appropriate.
const VarLoc &DiffIt = VarLocIDs[ID];
const MachineInstr *DMI = &DiffIt.MI;
MachineInstr *MI =
@@ -639,7 +710,7 @@ bool LiveDebugValues::ExtendRanges(Machi
OpenRangesSet OpenRanges; // Ranges that are open until end of bb.
VarLocInMBB OutLocs; // Ranges that exist beyond bb.
VarLocInMBB InLocs; // Ranges that are incoming after joining.
- SpillMap Spills; // DBG_VALUEs associated with spills.
+ TransferMap Transfers; // DBG_VALUEs associated with spills.
DenseMap<unsigned int, MachineBasicBlock *> OrderToBB;
DenseMap<MachineBasicBlock *, unsigned int> BBToOrder;
@@ -650,6 +721,8 @@ bool LiveDebugValues::ExtendRanges(Machi
std::greater<unsigned int>>
Pending;
+ enum : bool { dontTransferChanges = false, transferChanges = true };
+
// Initialize every mbb with OutLocs.
// We are not looking at any spill instructions during the initial pass
// over the BBs. The LiveDebugVariables pass has already created DBG_VALUE
@@ -657,8 +730,8 @@ bool LiveDebugValues::ExtendRanges(Machi
// within the BB in which the spill occurs.
for (auto &MBB : MF)
for (auto &MI : MBB)
- transfer(MI, OpenRanges, OutLocs, VarLocIDs, Spills,
- /*transferSpills=*/false);
+ process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers,
+ dontTransferChanges);
LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
"OutLocs after initialization", dbgs()));
@@ -672,7 +745,7 @@ bool LiveDebugValues::ExtendRanges(Machi
++RPONumber;
}
// This is a standard "union of predecessor outs" dataflow problem.
- // To solve it, we perform join() and transfer() using the two worklist method
+ // To solve it, we perform join() and process() using the two worklist method
// until the ranges converge.
// Ranges have converged when both worklists are empty.
SmallPtrSet<const MachineBasicBlock *, 16> Visited;
@@ -694,14 +767,14 @@ bool LiveDebugValues::ExtendRanges(Machi
// examine spill instructions to see whether they spill registers that
// correspond to user variables.
for (auto &MI : *MBB)
- OLChanged |= transfer(MI, OpenRanges, OutLocs, VarLocIDs, Spills,
- /*transferSpills=*/true);
+ OLChanged |= process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers,
+ transferChanges);
// Add any DBG_VALUE instructions necessitated by spills.
- for (auto &SP : Spills)
- MBB->insertAfter(MachineBasicBlock::iterator(*SP.SpillInst),
- SP.DebugInst);
- Spills.clear();
+ for (auto &TR : Transfers)
+ MBB->insertAfter(MachineBasicBlock::iterator(*TR.TransferInst),
+ TR.DebugInst);
+ Transfers.clear();
LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
"OutLocs after propagating", dbgs()));
@@ -741,6 +814,8 @@ bool LiveDebugValues::runOnMachineFuncti
TRI = MF.getSubtarget().getRegisterInfo();
TII = MF.getSubtarget().getInstrInfo();
TFI = MF.getSubtarget().getFrameLowering();
+ TFI->determineCalleeSaves(MF, CalleeSavedRegs,
+ make_unique<RegScavenger>().get());
LS.initialize(MF);
bool Changed = ExtendRanges(MF);
Added: llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir?rev=336978&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir (added)
+++ llvm/trunk/test/DebugInfo/MIR/ARM/live-debug-values-reg-copy.mir Fri Jul 13 01:24:26 2018
@@ -0,0 +1,147 @@
+# RUN: llc -run-pass=livedebugvalues %s -o - | FileCheck %s
+#
+# This test tests tracking variables value transferring from one register to another.
+# This example is altered additionally in order to test transferring from one float register
+# to another. The altered instructions are labeled below.
+#
+# CHECK: ![[ARG1:.*]] = !DILocalVariable(name: "arg1"
+# CHECK: DBG_VALUE debug-use $r4, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+# CHECK: $r5 = MOVr killed $r4, 14, $noreg, $noreg, debug-location
+# CHECK-NEXT: DBG_VALUE debug-use $r5, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+--- |
+ ; ModuleID = 'live-debug-values-reg-copy.ll'
+ source_filename = "live-debug-values-reg-copy.c"
+ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+ target triple = "armv4t--"
+
+ define dso_local arm_aapcscc i32 @foo(i32 %arg1) local_unnamed_addr !dbg !8 {
+ entry:
+ call void @llvm.dbg.value(metadata i32 %arg1, metadata !13, metadata !DIExpression()), !dbg !16
+ %cmp = icmp sgt i32 %arg1, 10, !dbg !16
+ br i1 %cmp, label %if.end, label %if.else, !dbg !16
+
+ if.else: ; preds = %entry
+ %add5 = add nsw i32 %arg1, 10, !dbg !16
+ call void @llvm.dbg.value(metadata i32 %add5, metadata !13, metadata !DIExpression()), !dbg !16
+ %call6 = tail call arm_aapcscc i32 @externFunc2(i32 %add5), !dbg !16
+ %call8 = tail call arm_aapcscc i32 @externFunc(i32 %add5), !dbg !16
+ ret i32 %call6, !dbg !16
+
+ if.end: ; preds = %entry
+ %call = tail call arm_aapcscc i32 @externFunc(i32 %arg1), !dbg !16
+ ret i32 1, !dbg !16
+ }
+
+ declare dso_local arm_aapcscc i32 @externFunc(i32) local_unnamed_addr
+
+ declare dso_local arm_aapcscc i32 @externFunc2(i32) local_unnamed_addr
+
+ ; Function Attrs: nounwind readnone speculatable
+ declare void @llvm.dbg.value(metadata, metadata, metadata) #0
+
+ ; Function Attrs: nounwind
+ declare void @llvm.stackprotector(i8*, i8**) #1
+
+ attributes #0 = { nounwind readnone speculatable }
+ attributes #1 = { nounwind }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!3, !4, !5, !6}
+ !llvm.ident = !{!7}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+ !1 = !DIFile(filename: "live-debug-values-reg-copy.c", directory: "/")
+ !2 = !{}
+ !3 = !{i32 2, !"Dwarf Version", i32 4}
+ !4 = !{i32 2, !"Debug Info Version", i32 3}
+ !5 = !{i32 1, !"wchar_size", i32 4}
+ !6 = !{i32 1, !"min_enum_size", i32 4}
+ !7 = !{!"clang version 7.0.0"}
+ !8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 4, type: !9, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !12)
+ !9 = !DISubroutineType(types: !10)
+ !10 = !{!11, !11}
+ !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !12 = !{!13}
+ !13 = !DILocalVariable(name: "arg1", arg: 1, scope: !8, file: !1, line: 4, type: !11)
+ !16 = !DILocation(line: 4, column: 13, scope: !8)
+
+...
+---
+name: foo
+alignment: 2
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+tracksRegLiveness: false
+registers:
+liveins:
+ - { reg: '$r0', virtual-reg: '' }
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 16
+ offsetAdjustment: 0
+ maxAlignment: 4
+ adjustsStack: true
+ hasCalls: true
+ stackProtector: ''
+ maxCallFrameSize: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ savePoint: ''
+ restorePoint: ''
+fixedStack:
+stack:
+ - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4,
+ stack-id: 0, callee-saved-register: '$lr', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4,
+ stack-id: 0, callee-saved-register: '$r11', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 2, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4,
+ stack-id: 0, callee-saved-register: '$r5', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 3, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4,
+ stack-id: 0, callee-saved-register: '$r4', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants:
+body: |
+ bb.0.entry:
+ successors: %bb.1(0x40000000), %bb.2(0x40000000)
+
+ $sp = frame-setup STMDB_UPD $sp, 14, $noreg, killed $r4, killed $r5, killed $r11, killed $lr
+ frame-setup CFI_INSTRUCTION def_cfa_offset 16
+ frame-setup CFI_INSTRUCTION offset $lr, -4
+ frame-setup CFI_INSTRUCTION offset $r11, -8
+ frame-setup CFI_INSTRUCTION offset $r5, -12
+ frame-setup CFI_INSTRUCTION offset $r4, -16
+ DBG_VALUE debug-use $r0, debug-use $noreg, !13, !DIExpression(), debug-location !16
+ DBG_VALUE debug-use $r0, debug-use $noreg, !13, !DIExpression(), debug-location !16
+ CMPri renamable $r0, 10, 14, $noreg, implicit-def $cpsr, debug-location !16
+ Bcc %bb.2, 13, killed $cpsr, debug-location !16
+
+ bb.1.if.end:
+ BL @externFunc, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def dead $r0, debug-location !16
+ $r0 = MOVi 1, 14, $noreg, $noreg, debug-location !16
+ $sp = LDMIA_UPD $sp, 14, $noreg, def $r4, def $r5, def $r11, def $lr, debug-location !16
+ BX_RET 14, $noreg, implicit killed $r0, debug-location !16
+
+ bb.2.if.else:
+ renamable $r4 = ADDri killed renamable $r0, 10, 14, $noreg, $noreg, debug-location !16
+ DBG_VALUE debug-use $r4, debug-use $noreg, !13, !DIExpression(), debug-location !16
+ $r0 = MOVr $r4, 14, $noreg, $noreg, debug-location !16
+ BL @externFunc2, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def $r0, debug-location !16
+ $r5 = MOVr killed $r0, 14, $noreg, $noreg, debug-location !16
+ $r0 = MOVr $r4, 14, $noreg, $noreg, debug-location !16
+ BL @externFunc, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def dead $r0, debug-location !16
+ $r0 = MOVr killed $r5, 14, $noreg, $noreg, debug-location !16
+ ; Instruction below is added in order to test moving variable's value from one register to another.
+ $r5 = MOVr killed $r4, 14, $noreg, $noreg, debug-location !16
+ $sp = LDMIA_UPD $sp, 14, $noreg, def $r4, def $r5, def $r11, def $lr, debug-location !16
+ BX_RET 14, $noreg, implicit killed $r0, debug-location !16
+
+...
Added: llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir?rev=336978&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir (added)
+++ llvm/trunk/test/DebugInfo/MIR/Mips/live-debug-values-reg-copy.mir Fri Jul 13 01:24:26 2018
@@ -0,0 +1,241 @@
+# RUN: llc -run-pass=livedebugvalues %s -o - | FileCheck %s
+#
+# This test tests tracking variables value transferring from one register to another.
+# This example is altered additionally in order to test transferring from one float register
+# to another. The altered instructions are labeled below.
+#
+# CHECK: ![[ARG1:.*]] = !DILocalVariable(name: "arg1"
+# CHECK: ![[ARG2:.*]] = !DILocalVariable(name: "arg2"
+# CHECK: DBG_VALUE debug-use $s0_64, debug-use $noreg, ![[ARG2]], !DIExpression(), debug-location
+# CHECK: $s1_64 = OR64 killed $s0_64, $zero_64, debug-location
+# CHECK-NEXT: DBG_VALUE debug-use $s1_64, debug-use $noreg, ![[ARG2]], !DIExpression(), debug-location
+# CHECK: DBG_VALUE debug-use $f24, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+# CHECK: $f26 = FMOV_S killed $f24, debug-location
+# CHECK-NEXT: DBG_VALUE debug-use $f26, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+
+--- |
+ ; ModuleID = 'live-debug-values-reg-copy.ll'
+ source_filename = "live-debug-values-reg-copy.c"
+ target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+ target triple = "mips64-octeon-linux"
+
+ define float @foo(float %arg1, i32 signext %arg2) local_unnamed_addr !dbg !8 {
+ entry:
+ call void @llvm.dbg.value(metadata float %arg1, metadata !14, metadata !DIExpression()), !dbg !19
+ call void @llvm.dbg.value(metadata i32 %arg2, metadata !15, metadata !DIExpression()), !dbg !19
+ %conv = fpext float %arg1 to double, !dbg !19
+ %cmp = fcmp ogt double %conv, 1.012310e+01, !dbg !19
+ br i1 %cmp, label %if.then, label %if.else, !dbg !19
+
+ if.then: ; preds = %entry
+ %call = tail call float @externFunc(float %arg1), !dbg !19
+ %call5 = tail call i32 @externFunc3(i32 signext %arg2), !dbg !19
+ %conv6 = sitofp i32 %call5 to float, !dbg !19
+ %add7 = fadd float %conv6, 0x3FF522D0E0000000, !dbg !19
+ br label %if.end, !dbg !19
+
+ if.else: ; preds = %entry
+ %add8 = fadd float %arg1, 1.000000e+01, !dbg !19
+ call void @llvm.dbg.value(metadata float %add8, metadata !14, metadata !DIExpression()), !dbg !19
+ %call9 = tail call float @externFunc2(float %add8), !dbg !19
+ %call10 = tail call i32 @externFunc4(i32 signext %arg2), !dbg !19
+ %conv11 = sitofp i32 %call10 to float, !dbg !19
+ %add12 = fadd float %call9, %conv11, !dbg !19
+ %call14 = tail call float @externFunc(float %add8), !dbg !19
+ br label %if.end
+
+ if.end: ; preds = %if.else, %if.then
+ %local.0 = phi float [ %add7, %if.then ], [ %add12, %if.else ]
+ ret float %local.0, !dbg !19
+ }
+
+ declare float @externFunc(float) local_unnamed_addr
+
+ declare i32 @externFunc3(i32 signext) local_unnamed_addr
+
+ declare float @externFunc2(float) local_unnamed_addr
+
+ declare i32 @externFunc4(i32 signext) local_unnamed_addr
+
+ ; Function Attrs: nounwind readnone speculatable
+ declare void @llvm.dbg.value(metadata, metadata, metadata) #0
+
+ ; Function Attrs: nounwind
+ declare void @llvm.stackprotector(i8*, i8**) #1
+
+ attributes #0 = { nounwind readnone speculatable }
+ attributes #1 = { nounwind }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!3, !4, !5, !6}
+ !llvm.ident = !{!7}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+ !1 = !DIFile(filename: "live-debug-values-reg-copy.c", directory: "/")
+ !2 = !{}
+ !3 = !{i32 2, !"Dwarf Version", i32 4}
+ !4 = !{i32 2, !"Debug Info Version", i32 3}
+ !5 = !{i32 1, !"wchar_size", i32 4}
+ !6 = !{i32 7, !"PIC Level", i32 2}
+ !7 = !{!"clang version 7.0.0 "}
+ !8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 6, type: !9, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !13)
+ !9 = !DISubroutineType(types: !10)
+ !10 = !{!11, !11, !12}
+ !11 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+ !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !13 = !{!14, !15}
+ !14 = !DILocalVariable(name: "arg1", arg: 1, scope: !8, file: !1, line: 6, type: !11)
+ !15 = !DILocalVariable(name: "arg2", arg: 2, scope: !8, file: !1, line: 6, type: !12)
+ !19 = !DILocation(line: 6, column: 17, scope: !8)
+
+...
+---
+name: foo
+alignment: 3
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+tracksRegLiveness: false
+registers:
+liveins:
+ - { reg: '$f12', virtual-reg: '' }
+ - { reg: '$a1_64', virtual-reg: '' }
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 32
+ offsetAdjustment: 0
+ maxAlignment: 8
+ adjustsStack: true
+ hasCalls: true
+ stackProtector: ''
+ maxCallFrameSize: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ savePoint: ''
+ restorePoint: ''
+fixedStack:
+stack:
+ - { id: 0, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8,
+ stack-id: 0, callee-saved-register: '$d25_64', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8,
+ stack-id: 0, callee-saved-register: '$d24_64', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 2, name: '', type: spill-slot, offset: -24, size: 8, alignment: 8,
+ stack-id: 0, callee-saved-register: '$ra_64', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 3, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8,
+ stack-id: 0, callee-saved-register: '$s0_64', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants:
+ - id: 0
+ value: 'double 1.012310e+01'
+ alignment: 8
+ isTargetSpecific: false
+ - id: 1
+ value: 'float 1.000000e+01'
+ alignment: 4
+ isTargetSpecific: false
+ - id: 2
+ value: float 0x3FF522D0E0000000
+ alignment: 4
+ isTargetSpecific: false
+body: |
+ bb.0.entry:
+ successors: %bb.1(0x40000000), %bb.2(0x40000000)
+
+ $sp_64 = DADDiu $sp_64, -32
+ CFI_INSTRUCTION def_cfa_offset 32
+ SDC164 killed $d25_64, $sp_64, 24 :: (store 8 into %stack.0)
+ SDC164 killed $d24_64, $sp_64, 16 :: (store 8 into %stack.1)
+ SD killed $ra_64, $sp_64, 8 :: (store 8 into %stack.2)
+ SD killed $s0_64, $sp_64, 0 :: (store 8 into %stack.3)
+ CFI_INSTRUCTION offset $d26_64, -8
+ CFI_INSTRUCTION offset $d25_64, -4
+ CFI_INSTRUCTION offset $d25_64, -16
+ CFI_INSTRUCTION offset $d24_64, -12
+ CFI_INSTRUCTION offset $ra_64, -24
+ CFI_INSTRUCTION offset $s0_64, -32
+ DBG_VALUE debug-use $f12, debug-use $noreg, !14, !DIExpression(), debug-location !19
+ DBG_VALUE debug-use $a1_64, debug-use $noreg, !15, !DIExpression(), debug-location !19
+ DBG_VALUE debug-use $s0, debug-use $noreg, !15, !DIExpression(), debug-location !19
+ DBG_VALUE debug-use $s0_64, debug-use $noreg, !15, !DIExpression(), debug-location !19
+ DBG_VALUE debug-use $f12, debug-use $noreg, !14, !DIExpression(), debug-location !19
+ renamable $d0_64 = CVT_D64_S renamable $f12, debug-location !19
+ renamable $at_64 = LUi64 target-flags(mips-highest) %const.0
+ renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-higher) %const.0
+ renamable $at_64 = DSLL killed renamable $at_64, 16
+ renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-abs-hi) %const.0
+ renamable $at_64 = DSLL killed renamable $at_64, 16
+ renamable $d1_64 = LDC164 killed renamable $at_64, target-flags(mips-abs-lo) %const.0, debug-location !19 :: (load 8 from constant-pool)
+ FCMP_D64 killed renamable $d0_64, killed renamable $d1_64, 7, implicit-def $fcc0, debug-location !19
+ BC1T killed $fcc0, %bb.2, implicit-def $at, debug-location !19 {
+ $s0_64 = OR64 $a1_64, $zero_64
+ }
+
+ bb.1.if.then:
+ successors: %bb.3(0x80000000)
+
+ JAL @externFunc, csr_n64, implicit-def dead $ra, implicit $f12, implicit-def $sp, implicit-def dead $f0, debug-location !19 {
+ NOP debug-location !19
+ }
+ JAL @externFunc3, csr_n64, implicit-def dead $ra, implicit $a0_64, implicit-def $sp, implicit-def $v0, debug-location !19 {
+ renamable $a0_64 = SLL64_32 renamable $s0, implicit $s0_64, debug-location !19
+ }
+ $f0 = MTC1 killed $v0, debug-location !19
+ $f0 = CVT_S_W killed $f0, debug-location !19
+ ; This instruction is inserted additionally in order to test moving from one register to another
+ $s1_64 = OR64 killed $s0_64, $zero_64, debug-location !19
+ renamable $at_64 = LUi64 target-flags(mips-highest) %const.2
+ renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-higher) %const.2
+ renamable $at_64 = DSLL killed renamable $at_64, 16
+ renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-abs-hi) %const.2
+ renamable $at_64 = DSLL killed renamable $at_64, 16
+ renamable $f1 = LWC1 killed renamable $at_64, target-flags(mips-abs-lo) %const.2, debug-location !19 :: (load 4 from constant-pool)
+ J %bb.3, implicit-def dead $at, debug-location !19 {
+ renamable $f0 = FADD_S killed renamable $f0, killed renamable $f1, debug-location !19
+ }
+
+ bb.2.if.else:
+ successors: %bb.3(0x80000000)
+
+ renamable $at_64 = LUi64 target-flags(mips-highest) %const.1
+ renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-higher) %const.1
+ renamable $at_64 = DSLL killed renamable $at_64, 16
+ renamable $at_64 = DADDiu killed renamable $at_64, target-flags(mips-abs-hi) %const.1
+ renamable $at_64 = DSLL killed renamable $at_64, 16
+ renamable $f0 = LWC1 killed renamable $at_64, target-flags(mips-abs-lo) %const.1, debug-location !19 :: (load 4 from constant-pool)
+ renamable $f24 = FADD_S killed renamable $f12, killed renamable $f0, debug-location !19
+ DBG_VALUE debug-use $f24, debug-use $noreg, !14, !DIExpression(), debug-location !19
+ JAL @externFunc2, csr_n64, implicit-def dead $ra, implicit $f12, implicit-def $sp, implicit-def $f0, debug-location !19 {
+ $f12 = FMOV_S $f24, debug-location !19
+ }
+ $f25 = FMOV_S $f0, debug-location !19
+ JAL @externFunc4, csr_n64, implicit-def dead $ra, implicit $a0_64, implicit-def $sp, implicit-def $v0, debug-location !19 {
+ renamable $a0_64 = SLL64_32 renamable $s0, implicit killed $s0_64, debug-location !19
+ }
+ $s0 = OR $v0, $zero, debug-location !19
+ JAL @externFunc, csr_n64, implicit-def dead $ra, implicit $f12, implicit-def $sp, implicit-def dead $f0, debug-location !19 {
+ $f12 = FMOV_S $f24, debug-location !19
+ }
+ $f0 = MTC1 killed $s0, debug-location !19
+ $f0 = CVT_S_W killed $f0, debug-location !19
+ renamable $f0 = FADD_S renamable $f25, killed renamable $f0, debug-location !19
+ ; This instruction is inserted additionally in order to test moving variable's value from one float register to another.
+ $f26 = FMOV_S killed $f24, debug-location !19
+
+ bb.3.if.end:
+ $s0_64 = LD $sp_64, 0, debug-location !19 :: (load 8 from %stack.3)
+ $ra_64 = LD $sp_64, 8, debug-location !19 :: (load 8 from %stack.2)
+ $d24_64 = LDC164 $sp_64, 16, debug-location !19 :: (load 8 from %stack.1)
+ $d25_64 = LDC164 $sp_64, 24, debug-location !19 :: (load 8 from %stack.0)
+ PseudoReturn64 undef $ra_64, implicit $f0, debug-location !19 {
+ $sp_64 = DADDiu $sp_64, 32
+ }
+
+...
Added: llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir?rev=336978&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir (added)
+++ llvm/trunk/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir Fri Jul 13 01:24:26 2018
@@ -0,0 +1,190 @@
+# RUN: llc -run-pass=livedebugvalues %s -o - | FileCheck %s
+#
+# This test tests tracking variables value transferring from one register to another.
+# This example is altered additionally in order to test transferring from one float register
+# to another. The altered instructions are labeled below.
+#
+# CHECK: ![[ARG1:.*]] = !DILocalVariable(name: "arg1"
+# CHECK: DBG_VALUE debug-use $ebx, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+# CHECK: $r12d = MOV32rr killed $ebx, implicit-def $r12
+# CHECK-NEXT: DBG_VALUE debug-use $r12d, debug-use $noreg, ![[ARG1]], !DIExpression(), debug-location
+--- |
+ ; ModuleID = 'live-debug-values-reg-copy.ll'
+ source_filename = "live-debug-values-reg-copy.c"
+ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+ target triple = "x86_64-unknown-linux-gnu"
+
+ define dso_local i32 @foo(i32 %arg1) local_unnamed_addr !dbg !7 {
+ entry:
+ %local1 = alloca i32, align 4
+ call void @llvm.dbg.value(metadata i32 %arg1, metadata !12, metadata !DIExpression()), !dbg !15
+ %0 = bitcast i32* %local1 to i8*, !dbg !15
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0), !dbg !15
+ call void @init(i32* nonnull %local1), !dbg !15
+ %1 = load i32, i32* %local1, align 4, !dbg !15, !tbaa !20
+ %add = add nsw i32 %1, %arg1, !dbg !15
+ %call = call i32 @coeficient(i32 %add), !dbg !15
+ %cmp = icmp sgt i32 %call, 32, !dbg !15
+ br i1 %cmp, label %if.then, label %if.else, !dbg !15
+
+ if.then: ; preds = %entry
+ %call1 = call i32 @externFunc(i32 %arg1), !dbg !15
+ %2 = load i32, i32* %local1, align 4, !dbg !15, !tbaa !20
+ %add2 = add nsw i32 %2, %call1, !dbg !15
+ br label %if.end, !dbg !15
+
+ if.else: ; preds = %entry
+ %call3 = call i32 @externFunc2(i32 %arg1), !dbg !15
+ %3 = load i32, i32* %local1, align 4, !dbg !15, !tbaa !20
+ %add4 = add nsw i32 %3, %call3, !dbg !15
+ br label %if.end
+
+ if.end: ; preds = %if.else, %if.then
+ %storemerge = phi i32 [ %add4, %if.else ], [ %add2, %if.then ]
+ %4 = bitcast i32* %local1 to i8*
+ %mul = shl nsw i32 %arg1, 2, !dbg !15
+ %add5 = add nsw i32 %storemerge, %mul, !dbg !15
+ %mul6 = mul nsw i32 %add5, %call, !dbg !15
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %4), !dbg !15
+ ret i32 %mul6, !dbg !15
+ }
+
+ ; Function Attrs: argmemonly nounwind
+ declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #0
+
+ declare dso_local void @init(i32*) local_unnamed_addr
+
+ declare dso_local i32 @coeficient(i32) local_unnamed_addr
+
+ declare dso_local i32 @externFunc(i32) local_unnamed_addr
+
+ declare dso_local i32 @externFunc2(i32) local_unnamed_addr
+
+ ; Function Attrs: argmemonly nounwind
+ declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #0
+
+ ; Function Attrs: nounwind readnone speculatable
+ declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+ ; Function Attrs: nounwind
+ declare void @llvm.stackprotector(i8*, i8**) #2
+
+ attributes #0 = { argmemonly nounwind }
+ attributes #1 = { nounwind readnone speculatable }
+ attributes #2 = { nounwind }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!3, !4, !5}
+ !llvm.ident = !{!6}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+ !1 = !DIFile(filename: "live-debug-values-reg-copy.c", directory: "/")
+ !2 = !{}
+ !3 = !{i32 2, !"Dwarf Version", i32 4}
+ !4 = !{i32 2, !"Debug Info Version", i32 3}
+ !5 = !{i32 1, !"wchar_size", i32 4}
+ !6 = !{!"clang version 7.0.0 "}
+ !7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 6, type: !8, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
+ !8 = !DISubroutineType(types: !9)
+ !9 = !{!10, !10}
+ !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !11 = !{!12}
+ !12 = !DILocalVariable(name: "arg1", arg: 1, scope: !7, file: !1, line: 6, type: !10)
+ !15 = !DILocation(line: 6, column: 13, scope: !7)
+ !20 = !{!21, !21, i64 0}
+ !21 = !{!"int", !22, i64 0}
+ !22 = !{!"omnipotent char", !23, i64 0}
+ !23 = !{!"Simple C/C++ TBAA"}
+
+...
+---
+name: foo
+alignment: 4
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+liveins:
+ - { reg: '$edi', virtual-reg: '' }
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 24
+ offsetAdjustment: 0
+ maxAlignment: 4
+ adjustsStack: true
+ hasCalls: true
+ stackProtector: ''
+ maxCallFrameSize: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ savePoint: ''
+ restorePoint: ''
+fixedStack:
+ - { id: 0, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: 0,
+ callee-saved-register: '$rbx', callee-saved-restored: true }
+ - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: 0,
+ callee-saved-register: '$rbp', callee-saved-restored: true }
+stack:
+ - { id: 0, name: local1, type: default, offset: -28, size: 4, alignment: 4,
+ stack-id: 0, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants:
+body: |
+ bb.0.entry:
+ successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ liveins: $edi, $rbp, $rbx
+
+ frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 16
+ frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 24
+ frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 32
+ CFI_INSTRUCTION offset $rbx, -24
+ CFI_INSTRUCTION offset $rbp, -16
+ DBG_VALUE debug-use $edi, debug-use $noreg, !12, !DIExpression(), debug-location !15
+ $ebx = MOV32rr $edi, implicit-def $rbx
+ DBG_VALUE debug-use $ebx, debug-use $noreg, !12, !DIExpression(), debug-location !15
+ renamable $rdi = LEA64r $rsp, 1, $noreg, 4, $noreg
+ CALL64pcrel32 @init, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, debug-location !15
+ renamable $edi = MOV32rm $rsp, 1, $noreg, 4, $noreg :: (dereferenceable load 4 from %ir.local1, !tbaa !20)
+ renamable $edi = ADD32rr killed renamable $edi, renamable $ebx, implicit-def dead $eflags, debug-location !15
+ CALL64pcrel32 @coeficient, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !15
+ $ebp = MOV32rr $eax, debug-location !15
+ $edi = MOV32rr $ebx, debug-location !15
+ CMP32ri8 renamable $ebp, 33, implicit-def $eflags, debug-location !15
+ JL_1 %bb.2, implicit killed $eflags, debug-location !15
+
+ bb.1.if.then:
+ successors: %bb.3(0x80000000)
+ liveins: $ebp, $edi
+
+ CALL64pcrel32 @externFunc, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !15
+ JMP_1 %bb.3
+
+ bb.2.if.else:
+ successors: %bb.3(0x80000000)
+ liveins: $ebp, $edi
+
+ CALL64pcrel32 @externFunc2, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !15
+
+ bb.3.if.end:
+ liveins: $ebp, $ebx, $eax
+ ; Instruction below is added in order to test moving variable's value from one register to another.
+ $r12d = MOV32rr killed $ebx, implicit-def $r12
+ renamable $eax = KILL $eax, implicit-def $rax
+ renamable $eax = ADD32rm renamable $eax, $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax :: (dereferenceable load 4 from %ir.local1, !tbaa !20)
+ renamable $eax = LEA64_32r killed renamable $rax, 4, killed renamable $r12, 0, $noreg, debug-location !15
+ renamable $eax = IMUL32rr killed renamable $eax, killed renamable $ebp, implicit-def dead $eflags, debug-location !15
+ $rsp = frame-destroy ADD64ri8 $rsp, 8, implicit-def dead $eflags, debug-location !15
+ $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !15
+ $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !15
+ RETQ $eax, debug-location !15
+
+...
More information about the llvm-commits
mailing list