Skip to content

Commit

Permalink
Change the informal convention of DBG_VALUE so that we can express a
Browse files Browse the repository at this point in the history
register-indirect address with an offset of 0.
It used to be that a DBG_VALUE is a register-indirect value if the offset
(operand 1) is nonzero. The new convention is that a DBG_VALUE is
register-indirect if the first operand is a register and the second
operand is an immediate. For plain registers use the combination reg, reg.

rdar://problem/13658587

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180816 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
adrian-prantl committed Apr 30, 2013
1 parent f13fc1b commit a2b5669
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 45 deletions.
45 changes: 45 additions & 0 deletions include/llvm/CodeGen/MachineInstrBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,51 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
}

/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
/// for either a value in a register or a register-indirect+offset
/// address. The convention is that a DBG_VALUE is indirect iff the
/// second operand is an immediate.
///
inline MachineInstrBuilder BuildMI(MachineFunction &MF,
DebugLoc DL,
const MCInstrDesc &MCID,
bool IsIndirect,
unsigned Reg,
unsigned Offset,
const MDNode *MD) {
if (IsIndirect)
return BuildMI(MF, DL, MCID)
.addReg(Reg, RegState::Debug)
.addImm(Offset)
.addMetadata(MD);
else {
assert(Offset == 0 && "A direct address cannot have an offset.");
return BuildMI(MF, DL, MCID)
.addReg(Reg, RegState::Debug)
.addReg(0U, RegState::Debug)
.addMetadata(MD);
}
}

/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
/// for either a value in a register or a register-indirect+offset
/// address and inserts it at position I.
///
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
DebugLoc DL,
const MCInstrDesc &MCID,
bool IsIndirect,
unsigned Reg,
unsigned Offset,
const MDNode *MD) {
MachineFunction &MF = *BB.getParent();
MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, MD);
BB.insert(I, MI);
return MachineInstrBuilder(MF, MI);
}


inline unsigned getDefRegState(bool B) {
return B ? RegState::Define : 0;
}
Expand Down
4 changes: 3 additions & 1 deletion lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg());
}

OS << '+' << MI->getOperand(1).getImm();
// It's only an offset if it's an immediate.
if (MI->getOperand(1).isImm())
OS << '+' << MI->getOperand(1).getImm();
// NOTE: Want this comment at start of line, don't emit with AddComment.
AP.OutStreamer.EmitRawText(OS.str());
return true;
Expand Down
12 changes: 6 additions & 6 deletions lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,8 @@ static bool isDbgValueInDefinedReg(const MachineInstr *MI) {
assert(MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!");
return MI->getNumOperands() == 3 &&
MI->getOperand(0).isReg() && MI->getOperand(0).getReg() &&
MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0;
(MI->getOperand(1).isImm() ||
(MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == 0U));
}

// Get .debug_loc entry for the instruction range starting at MI.
Expand All @@ -1129,12 +1130,11 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
MachineLocation MLoc = Asm->getDebugValueLocation(MI);
return DotDebugLocEntry(FLabel, SLabel, MLoc, Var);
}
if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) {
if (MI->getOperand(0).isReg()) {
MachineLocation MLoc;
// TODO: Currently an offset of 0 in a DBG_VALUE means
// we need to generate a direct register value.
// There is no way to specify an indirect value with offset 0.
if (MI->getOperand(1).getImm() == 0)
// If the second operand is an immediate, this is a
// register-indirect address.
if (!MI->getOperand(1).isImm())
MLoc.set(MI->getOperand(0).getReg());
else
MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
Expand Down
33 changes: 22 additions & 11 deletions lib/CodeGen/LiveDebugVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class LDVImpl;
class UserValue {
const MDNode *variable; ///< The debug info variable we are part of.
unsigned offset; ///< Byte offset into variable.
bool Indirect; ///< true if this is a register-indirect+offset value.
DebugLoc dl; ///< The debug location for the variable. This is
///< used by dwarf writer to find lexical scope.
UserValue *leader; ///< Equivalence class leader.
Expand All @@ -134,9 +135,10 @@ class UserValue {

public:
/// UserValue - Create a new UserValue.
UserValue(const MDNode *var, unsigned o, DebugLoc L,
UserValue(const MDNode *var, unsigned o, bool i, DebugLoc L,
LocMap::Allocator &alloc)
: variable(var), offset(o), dl(L), leader(this), next(0), locInts(alloc)
: variable(var), offset(o), Indirect(i), dl(L), leader(this),
next(0), locInts(alloc)
{}

/// getLeader - Get the leader of this value's equivalence class.
Expand Down Expand Up @@ -299,7 +301,8 @@ class LDVImpl {
UVMap userVarMap;

/// getUserValue - Find or create a UserValue.
UserValue *getUserValue(const MDNode *Var, unsigned Offset, DebugLoc DL);
UserValue *getUserValue(const MDNode *Var, unsigned Offset,
bool Indirect, DebugLoc DL);

/// lookupVirtReg - Find the EC leader for VirtReg or null.
UserValue *lookupVirtReg(unsigned VirtReg);
Expand Down Expand Up @@ -414,7 +417,7 @@ void UserValue::mapVirtRegs(LDVImpl *LDV) {
}

UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset,
DebugLoc DL) {
bool Indirect, DebugLoc DL) {
UserValue *&Leader = userVarMap[Var];
if (Leader) {
UserValue *UV = Leader->getLeader();
Expand All @@ -424,7 +427,7 @@ UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset,
return UV;
}

UserValue *UV = new UserValue(Var, Offset, DL, allocator);
UserValue *UV = new UserValue(Var, Offset, Indirect, DL, allocator);
userValues.push_back(UV);
Leader = UserValue::merge(Leader, UV);
return UV;
Expand All @@ -445,15 +448,17 @@ UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) {
bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) {
// DBG_VALUE loc, offset, variable
if (MI->getNumOperands() != 3 ||
!MI->getOperand(1).isImm() || !MI->getOperand(2).isMetadata()) {
!(MI->getOperand(1).isReg() || MI->getOperand(1).isImm()) ||
!MI->getOperand(2).isMetadata()) {
DEBUG(dbgs() << "Can't handle " << *MI);
return false;
}

// Get or create the UserValue for (variable,offset).
unsigned Offset = MI->getOperand(1).getImm();
bool Indirect = MI->getOperand(1).isImm();
unsigned Offset = Indirect ? MI->getOperand(1).getImm() : 0;
const MDNode *Var = MI->getOperand(2).getMetadata();
UserValue *UV = getUserValue(Var, Offset, MI->getDebugLoc());
UserValue *UV = getUserValue(Var, Offset, Indirect, MI->getDebugLoc());
UV->addDef(Idx, MI->getOperand(0));
return true;
}
Expand Down Expand Up @@ -924,16 +929,22 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
// Frame index locations may require a target callback.
if (Loc.isFI()) {
MachineInstr *MI = TII.emitFrameIndexDebugValue(*MBB->getParent(),
Loc.getIndex(), offset, variable,
Loc.getIndex(),
offset, variable,
findDebugLoc());
if (MI) {
MBB->insert(I, MI);
return;
}
}
// This is not a frame index, or the target is happy with a standard FI.
BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
.addOperand(Loc).addImm(offset).addMetadata(variable);

if (Loc.isReg())
BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE),
Indirect, Loc.getReg(), offset, variable);
else
BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
.addOperand(Loc).addImm(offset).addMetadata(variable);
}

void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
Expand Down
15 changes: 7 additions & 8 deletions lib/CodeGen/SelectionDAG/FastISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,11 +641,11 @@ bool FastISel::SelectCall(const User *I) {
Reg = FuncInfo.InitializeRegForValue(Address);

if (Reg)
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(TargetOpcode::DBG_VALUE))
.addReg(Reg, RegState::Debug).addImm(Offset)
.addMetadata(DI->getVariable());
else
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(TargetOpcode::DBG_VALUE),
DI->getAddress()->getType()->isPointerTy(),
Reg, Offset, DI->getVariable());
else
// We can't yet handle anything else here because it would require
// generating code, thus altering codegen because of debug info.
DEBUG(dbgs() << "Dropping debug info for " << DI);
Expand Down Expand Up @@ -676,9 +676,8 @@ bool FastISel::SelectCall(const User *I) {
.addFPImm(CF).addImm(DI->getOffset())
.addMetadata(DI->getVariable());
} else if (unsigned Reg = lookUpRegForValue(V)) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
.addReg(Reg, RegState::Debug).addImm(DI->getOffset())
.addMetadata(DI->getVariable());
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, DI->getOffset() != 0,
Reg, DI->getOffset(), DI->getVariable());
} else {
// We can't yet handle anything else here because it would require
// generating code, thus altering codegen because of debug info.
Expand Down
8 changes: 7 additions & 1 deletion lib/CodeGen/SelectionDAG/InstrEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,13 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
MIB.addReg(0U);
}

MIB.addImm(Offset).addMetadata(MDPtr);
if (Offset != 0) // Indirect addressing.
MIB.addImm(Offset);
else
MIB.addReg(0U, RegState::Debug);

MIB.addMetadata(MDPtr);

return &*MIB;
}

Expand Down
5 changes: 3 additions & 2 deletions lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4413,8 +4413,9 @@ SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
return false;

MachineInstrBuilder MIB = BuildMI(MF, getCurDebugLoc(),
TII->get(TargetOpcode::DBG_VALUE))
.addReg(Reg, RegState::Debug).addImm(Offset).addMetadata(Variable);
TII->get(TargetOpcode::DBG_VALUE),
Offset != 0,
Reg, Offset, Variable);
FuncInfo.ArgDbgValues.push_back(&*MIB);
return true;
}
Expand Down
17 changes: 10 additions & 7 deletions lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,14 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
MachineBasicBlock::iterator InsertPos = Def;
const MDNode *Variable =
MI->getOperand(MI->getNumOperands()-1).getMetadata();
unsigned Offset = MI->getOperand(1).getImm();
unsigned Offset = 0;
if (MI->getOperand(1).isImm())
Offset = MI->getOperand(1).getImm();
// Def is never a terminator here, so it is ok to increment InsertPos.
BuildMI(*EntryMBB, ++InsertPos, MI->getDebugLoc(),
TII.get(TargetOpcode::DBG_VALUE))
.addReg(LDI->second, RegState::Debug)
.addImm(Offset).addMetadata(Variable);
TII.get(TargetOpcode::DBG_VALUE),
MI->getOperand(1).isReg(),
LDI->second, Offset, Variable);

// If this vreg is directly copied into an exported register then
// that COPY instructions also need DBG_VALUE, if it is the only
Expand All @@ -442,9 +444,10 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
if (CopyUseMI) {
MachineInstr *NewMI =
BuildMI(*MF, CopyUseMI->getDebugLoc(),
TII.get(TargetOpcode::DBG_VALUE))
.addReg(CopyUseMI->getOperand(0).getReg(), RegState::Debug)
.addImm(Offset).addMetadata(Variable);
TII.get(TargetOpcode::DBG_VALUE),
Offset!=0,
CopyUseMI->getOperand(0).getReg(),
Offset, Variable);
MachineBasicBlock::iterator Pos = CopyUseMI;
EntryMBB->insertAfter(Pos, NewMI);
}
Expand Down
4 changes: 2 additions & 2 deletions test/CodeGen/ARM/debug-info-branch-folding.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ target triple = "thumbv7-apple-macosx10.6.7"
;CHECK: vadd.f32 q4, q8, q8
;CHECK-NEXT: LBB0_1

;CHECK:@DEBUG_VALUE: x <- Q4+0
;CHECK-NEXT:@DEBUG_VALUE: y <- Q4+0
;CHECK:@DEBUG_VALUE: x <- Q4
;CHECK-NEXT:@DEBUG_VALUE: y <- Q4


@.str = external constant [13 x i8]
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/X86/2010-06-01-DeadArg-DbgInfo.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ target triple = "x86_64-apple-darwin10.2"
@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 (%struct.foo*, i32)* @_ZN3foo3bazEi to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]

define i32 @_ZN3foo3bazEi(%struct.foo* nocapture %this, i32 %x) nounwind readnone optsize noinline ssp align 2 {
;CHECK: DEBUG_VALUE: baz:this <- RDI+0
;CHECK: DEBUG_VALUE: baz:this <- RDI
entry:
tail call void @llvm.dbg.value(metadata !{%struct.foo* %this}, i64 0, metadata !15)
tail call void @llvm.dbg.value(metadata !{i32 %x}, i64 0, metadata !16)
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/X86/dbg-value-dag-combine.ll
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ entry:
call void @llvm.dbg.value(metadata !12, i64 0, metadata !13), !dbg !14
%tmp2 = load i32 addrspace(1)* %ip, align 4, !dbg !15
%tmp3 = add i32 0, %tmp2, !dbg !15
; CHECK: ##DEBUG_VALUE: idx <- EAX+0
; CHECK: ##DEBUG_VALUE: idx <- EAX
call void @llvm.dbg.value(metadata !{i32 %tmp3}, i64 0, metadata !13), !dbg
!15
%arrayidx = getelementptr i32 addrspace(1)* %ip, i32 %1, !dbg !16
Expand Down
4 changes: 2 additions & 2 deletions test/CodeGen/X86/dbg-value-range.ll
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
!21 = metadata !{metadata !6, metadata !11}
!22 = metadata !{metadata !"bar.c", metadata !"/private/tmp"}

; Check that variable bar:b value range is appropriately trucated in debug info.
; Check that variable bar:b value range is appropriately truncated in debug info.
; The variable is in %rdi which is clobbered by 'movl %ebx, %edi'
; Here Ltmp7 is the end of the location range.

Expand All @@ -54,7 +54,7 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
;CHECK-NEXT: Lset{{.*}} = Ltmp{{.*}}-Ltmp{{.*}}
;CHECK-NEXT: .short Lset
;CHECK-NEXT: Ltmp
;CHECK-NEXT: .byte 85
;CHECK-NEXT: .byte 85 ## DW_OP_reg
;CHECK-NEXT: Ltmp
;CHECK-NEXT: .quad 0
;CHECK-NEXT: .quad 0
12 changes: 9 additions & 3 deletions test/DebugInfo/X86/op_deref.ll
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o %t -filetype=obj
; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s
; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s -check-prefix=DW-CHECK

; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000067] = "vla")
; DW-CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000067] = "vla")
; FIXME: The location here needs to be fixed, but llvm-dwarfdump doesn't handle
; DW_AT_location lists yet.
; CHECK: DW_AT_location [DW_FORM_data4] (0x00000000)
; DW-CHECK: DW_AT_location [DW_FORM_data4] (0x00000000)

; Unfortunately llvm-dwarfdump can't unparse a list of DW_AT_locations
; right now, so we check the asm output:
; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - -filetype=asm | FileCheck %s -check-prefix=ASM-CHECK
; vla should have a register-indirect address at one point.
; ASM-CHECK: DEBUG_VALUE: vla <- RCX+0

define void @testVLAwithSize(i32 %s) nounwind uwtable ssp {
entry:
Expand Down
Loading

0 comments on commit a2b5669

Please sign in to comment.