Skip to content

Commit

Permalink
Improve virtual register handling when computing debug information
Browse files Browse the repository at this point in the history
Summary: Some backends, like WebAssembly, use virtual registers instead of physical registers. This crashes the DbgValueHistoryCalculator pass, which assumes that all registers are physical. Instead, skip virtual registers when iterating aliases, and assume that they are clobbered.

Reviewers: dexonsmith, dschuff, aprantl

Subscribers: yurydelendik, llvm-commits, jfb, sunfish

Differential Revision: https://reviews.llvm.org/D22590

llvm-svn: 278371
  • Loading branch information
ddcc committed Aug 11, 2016
1 parent e36d771 commit 6ba1965
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 7 deletions.
23 changes: 16 additions & 7 deletions llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
Expand Up @@ -31,7 +31,7 @@ static unsigned isDescribedByReg(const MachineInstr &MI) {
assert(MI.isDebugValue());
assert(MI.getNumOperands() == 4);
// If location of variable is described using a register (directly or
// indirecltly), this register is always a first operand.
// indirectly), this register is always a first operand.
return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
}

Expand Down Expand Up @@ -164,7 +164,9 @@ static void collectChangingRegs(const MachineFunction *MF,
// Look for register defs and register masks. Register masks are
// typically on calls and they clobber everything not in the mask.
for (const MachineOperand &MO : MI.operands()) {
if (MO.isReg() && MO.isDef() && MO.getReg()) {
// Skip virtual registers since they are handled by the parent.
if (MO.isReg() && MO.isDef() && MO.getReg() &&
!TRI->isVirtualRegister(MO.getReg())) {
for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
++AI)
Regs.set(*AI);
Expand Down Expand Up @@ -192,12 +194,18 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF,
// some variables.
for (const MachineOperand &MO : MI.operands()) {
if (MO.isReg() && MO.isDef() && MO.getReg()) {
// If this is a virtual register, only clobber it since it doesn't
// have aliases.
if (TRI->isVirtualRegister(MO.getReg()))
clobberRegisterUses(RegVars, MO.getReg(), Result, MI);
// If this is a register def operand, it may end a debug value
// range.
for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
++AI)
if (ChangingRegs.test(*AI))
clobberRegisterUses(RegVars, *AI, Result, MI);
else {
for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
++AI)
if (ChangingRegs.test(*AI))
clobberRegisterUses(RegVars, *AI, Result, MI);
}
} else if (MO.isRegMask()) {
// If this is a register mask operand, clobber all debug values in
// non-CSRs.
Expand Down Expand Up @@ -238,7 +246,8 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF,
if (!MBB.empty() && &MBB != &MF->back()) {
for (auto I = RegVars.begin(), E = RegVars.end(); I != E;) {
auto CurElem = I++; // CurElem can be erased below.
if (ChangingRegs.test(CurElem->first))
if (TRI->isVirtualRegister(CurElem->first) ||
ChangingRegs.test(CurElem->first))
clobberRegisterUses(RegVars, CurElem, Result, MBB.back());
}
}
Expand Down
69 changes: 69 additions & 0 deletions llvm/test/CodeGen/WebAssembly/dbgvalue.ll
@@ -0,0 +1,69 @@
; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=wasm32-unknown-unknown | FileCheck %s
; CHECK: BB#0
; CHECK: #DEBUG_VALUE: usage:self <- %vreg4
; CHECK: BB#1
; CHECK: DW_TAG_variable
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"

%0 = type opaque

@key = external local_unnamed_addr global [15 x i8], align 1
@.str = external unnamed_addr constant [33 x i8], align 1

; Function Attrs: nounwind
define internal i32 @0(i8*) local_unnamed_addr !dbg !14 !type !22 {
tail call void @llvm.dbg.value(metadata i8* %0, i64 0, metadata !21, metadata !23), !dbg !24
%2 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i32 0, i32 0), i8* %0), !dbg !25
br i1 1, label %a, label %b
a:
%3 = add i32 %2, %2
br label %c

b:
%4 = sub i32 %2, %2
br label %c

c:
%5 = phi i32 [ %3, %a ], [ %4, %b ]
%6 = add i32 ptrtoint (i32 (i8*)* @0 to i32), %5
ret i32 %6, !dbg !26
}

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr

; Function Attrs: nounwind readnone
declare void @llvm.dbg.value(metadata, i64, metadata, metadata)

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!11, !12}
!llvm.ident = !{!13}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 273884) (llvm/trunk 273897)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3)
!1 = !DIFile(filename: "crash.c", directory: "wasm/tests")
!2 = !{}
!3 = !{!4}
!4 = distinct !DIGlobalVariable(name: "key", scope: !0, file: !1, line: 7, type: !5, isLocal: false, isDefinition: true, variable: [15 x i8]* @key)
!5 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 120, align: 8, elements: !9)
!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint8_t", file: !7, line: 185, baseType: !8)
!7 = !DIFile(filename: "wasm/emscripten/system/include/libc/bits/alltypes.h", directory: "wasm/tests")
!8 = !DIBasicType(name: "unsigned char", size: 8, align: 8, encoding: DW_ATE_unsigned_char)
!9 = !{!10}
!10 = !DISubrange(count: 15)
!11 = !{i32 2, !"Dwarf Version", i32 4}
!12 = !{i32 2, !"Debug Info Version", i32 3}
!13 = !{!"clang version 3.9.0 (trunk 273884) (llvm/trunk 273897)"}
!14 = distinct !DISubprogram(name: "usage", scope: !1, file: !1, line: 15, type: !15, isLocal: false, isDefinition: true, scopeLine: 15, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !20)
!15 = !DISubroutineType(types: !16)
!16 = !{!17, !18}
!17 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 32, align: 32)
!19 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
!20 = !{!21}
!21 = !DILocalVariable(name: "self", arg: 1, scope: !14, file: !1, line: 15, type: !18)
!22 = !{i64 0, !"_ZTSFiPcE"}
!23 = !DIExpression()
!24 = !DILocation(line: 15, column: 17, scope: !14)
!25 = !DILocation(line: 16, column: 3, scope: !14)
!26 = !DILocation(line: 17, column: 3, scope: !14)

0 comments on commit 6ba1965

Please sign in to comment.