mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[DebugInfo] Create merged locations for instructions other than calls
This lifts a restriction on DILocation::getMergedLocation(), allowing it to create merged locations for instructions other than calls. Instruction::applyMergedLocation() now defaults to creating merged locations for all instructions. The default behavior of getMergedLocation() is unchanged: callers which invoke it directly are unaffected. This change will enable a follow-up Mem2Reg fix which improves crash reporting. Differential Revision: https://reviews.llvm.org/D45396 llvm-svn: 329955
This commit is contained in:
parent
433915c6fd
commit
5d0335a194
@ -1497,26 +1497,25 @@ public:
|
||||
/// discriminator.
|
||||
inline const DILocation *cloneWithDuplicationFactor(unsigned DF) const;
|
||||
|
||||
enum { NoGeneratedLocation = false, WithGeneratedLocation = true };
|
||||
|
||||
/// When two instructions are combined into a single instruction we also
|
||||
/// need to combine the original locations into a single location.
|
||||
///
|
||||
/// When the locations are the same we can use either location. When they
|
||||
/// differ, we need a third location which is distinct from either. If
|
||||
/// they have the same file/line but have a different discriminator we
|
||||
/// could create a location with a new discriminator. If they are from
|
||||
/// different files/lines the location is ambiguous and can't be
|
||||
/// represented in a single line entry. In this case, no location
|
||||
/// should be set, unless the merged instruction is a call, which we will
|
||||
/// set the merged debug location as line 0 of the nearest common scope
|
||||
/// where 2 locations are inlined from. This only applies to Instruction;
|
||||
/// for MachineInstruction, as it is post-inline, we will treat the call
|
||||
/// instruction the same way as other instructions.
|
||||
/// differ, we need a third location which is distinct from either. If they
|
||||
/// have the same file/line but have a different discriminator we could
|
||||
/// create a location with a new discriminator. If they are from different
|
||||
/// files/lines the location is ambiguous and can't be represented in a line
|
||||
/// entry. In this case, if \p GenerateLocation is true, we will set the
|
||||
/// merged debug location as line 0 of the nearest common scope where the two
|
||||
/// locations are inlined from.
|
||||
///
|
||||
/// \p ForInst: The Instruction the merged DILocation is for. If the
|
||||
/// Instruction is unavailable or non-existent, use nullptr.
|
||||
/// \p GenerateLocation: Whether the merged location can be generated when
|
||||
/// \p LocA and \p LocB differ.
|
||||
static const DILocation *
|
||||
getMergedLocation(const DILocation *LocA, const DILocation *LocB,
|
||||
const Instruction *ForInst = nullptr);
|
||||
bool GenerateLocation = NoGeneratedLocation);
|
||||
|
||||
/// Returns the base discriminator for a given encoded discriminator \p D.
|
||||
static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
|
||||
|
@ -675,7 +675,8 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
|
||||
|
||||
void Instruction::applyMergedLocation(const DILocation *LocA,
|
||||
const DILocation *LocB) {
|
||||
setDebugLoc(DILocation::getMergedLocation(LocA, LocB, this));
|
||||
setDebugLoc(DILocation::getMergedLocation(LocA, LocB,
|
||||
DILocation::WithGeneratedLocation));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -68,16 +68,16 @@ DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
|
||||
Storage, Context.pImpl->DILocations);
|
||||
}
|
||||
|
||||
const DILocation *
|
||||
DILocation::getMergedLocation(const DILocation *LocA, const DILocation *LocB,
|
||||
const Instruction *ForInst) {
|
||||
const DILocation *DILocation::getMergedLocation(const DILocation *LocA,
|
||||
const DILocation *LocB,
|
||||
bool GenerateLocation) {
|
||||
if (!LocA || !LocB)
|
||||
return nullptr;
|
||||
|
||||
if (LocA == LocB || !LocA->canDiscriminate(*LocB))
|
||||
return LocA;
|
||||
|
||||
if (!dyn_cast_or_null<CallInst>(ForInst))
|
||||
if (!GenerateLocation)
|
||||
return nullptr;
|
||||
|
||||
SmallPtrSet<DILocation *, 5> InlinedLocationsA;
|
||||
|
@ -5,8 +5,8 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; If all the operands to a phi node are of the same operation, instcombine
|
||||
; will try to pull them through the phi node, combining them into a single
|
||||
; operation. Check that when it does this the combined operation does not
|
||||
; have a debug location set.
|
||||
; operation. Check that when it does this the combined operation has a merged
|
||||
; debug location.
|
||||
|
||||
; Test folding of a binary operation. Generated from source:
|
||||
|
||||
@ -24,8 +24,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
; CHECK: define i32 @binop
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
|
||||
; CHECK: sub nsw i32 %b, %[[PHI]]
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: sub nsw i32 %b, %[[PHI]], !dbg [[binopMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i32
|
||||
|
||||
define i32 @binop(i32 %a, i32 %b) !dbg !6 {
|
||||
@ -66,8 +65,7 @@ if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: define i32 @cmp
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
|
||||
; CHECK: icmp slt i32 %[[PHI]], %b
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: icmp slt i32 %[[PHI]], %b, !dbg [[cmpMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i32
|
||||
|
||||
define i32 @cmp(i32 %a, i32 %b) !dbg !15 {
|
||||
@ -108,8 +106,7 @@ if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: define i32* @gep
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i64 [ %call, %if.then ], [ %call1, %if.else ]
|
||||
; CHECK: getelementptr inbounds i32, i32* %b, i64 %[[PHI]]
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: getelementptr inbounds i32, i32* %b, i64 %[[PHI]], !dbg [[gepMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i32*
|
||||
|
||||
define i32* @gep(i32 %a, i32* %b) !dbg !23 {
|
||||
@ -149,8 +146,7 @@ if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: define i32 @load
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32* [ %call, %if.then ], [ %call1, %if.else ]
|
||||
; CHECK: load i32, i32* %[[PHI]]
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: load i32, i32* %[[PHI]],{{.*}} !dbg [[loadMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i32
|
||||
|
||||
define i32 @load(i32 %a) !dbg !31 {
|
||||
@ -190,8 +186,7 @@ if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: define i64 @cast
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
|
||||
; CHECK: sext i32 %[[PHI]] to i64
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: sext i32 %[[PHI]] to i64, !dbg [[castMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i64
|
||||
|
||||
define i64 @cast(i32 %a) !dbg !39 {
|
||||
@ -231,8 +226,7 @@ if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: define i32 @binop_const
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
|
||||
; CHECK: add nsw i32 %[[PHI]], -5
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: add nsw i32 %[[PHI]], -5, !dbg [[binopConstMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i32
|
||||
|
||||
define i32 @binop_const(i32 %a) !dbg !45 {
|
||||
@ -273,8 +267,7 @@ if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: define i32 @cmp_const
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
|
||||
; CHECK: icmp slt i32 %[[PHI]], 10
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: icmp slt i32 %[[PHI]], 10, !dbg [[cmpConstMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i32
|
||||
|
||||
define i32 @cmp_const(i32 %a) !dbg !53 {
|
||||
@ -305,6 +298,14 @@ declare i64 @bar2()
|
||||
declare i32* @foo3()
|
||||
declare i32* @bar3()
|
||||
|
||||
; CHECK: [[binopMergedLoc]] = !DILocation(line: 0
|
||||
; CHECK: [[cmpMergedLoc]] = !DILocation(line: 0
|
||||
; CHECK: [[gepMergedLoc]] = !DILocation(line: 0
|
||||
; CHECK: [[loadMergedLoc]] = !DILocation(line: 0
|
||||
; CHECK: [[castMergedLoc]] = !DILocation(line: 0
|
||||
; CHECK: [[binopConstMergedLoc]] = !DILocation(line: 0
|
||||
; CHECK: [[cmpConstMergedLoc]] = !DILocation(line: 0
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
|
||||
|
@ -6,7 +6,8 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
; Simplify CFG will try to sink the last instruction in a series of basic
|
||||
; blocks, creating a "common" instruction in the successor block. If the
|
||||
; debug locations of the commoned instructions have different file/line
|
||||
; numbers the debug location of the common instruction should not be set.
|
||||
; numbers the debug location of the common instruction should be a merged
|
||||
; location.
|
||||
|
||||
; Generated from source:
|
||||
|
||||
@ -24,8 +25,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
; CHECK: define i32 @test
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32 [ %call1, %if.else ], [ %call, %if.then ]
|
||||
; CHECK: sub nsw i32 %b, %[[PHI]]
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK: sub nsw i32 %b, %[[PHI]], !dbg [[testMergedLoc:![0-9]+]]
|
||||
; CHECK: ret i32
|
||||
|
||||
define i32 @test(i32 %a, i32 %b) !dbg !6 {
|
||||
@ -61,9 +61,8 @@ if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: define i32 @test2
|
||||
; CHECK-LABEL: if.end:
|
||||
; CHECK: %[[PHI:.*]] = phi i32 [ %call1, %if.else ], [ %call, %if.then ]
|
||||
; CHECK: sub nsw i32 %b, %[[PHI]], !dbg ![[DBG:.*]]
|
||||
; CHECK: sub nsw i32 %b, %[[PHI]], !dbg [[test2Loc:![0-9]+]]
|
||||
; CHECK: ret i32
|
||||
; CHECK: ![[DBG]] = !DILocation(line: 17, scope: !{{.*}})
|
||||
|
||||
define i32 @test2(i32 %a, i32 %b) !dbg !15 {
|
||||
entry:
|
||||
@ -85,6 +84,9 @@ if.end: ; preds = %if.else, %if.then
|
||||
ret i32 %b.addr.0, !dbg !17
|
||||
}
|
||||
|
||||
; CHECK: [[testMergedLoc]] = !DILocation(line: 0
|
||||
; CHECK: [[test2Loc]] = !DILocation(line: 17
|
||||
|
||||
declare i32 @foo()
|
||||
declare i32 @bar()
|
||||
|
||||
|
@ -21,8 +21,10 @@
|
||||
; CHECK: define {{.*}}@foo
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: %storemerge = phi
|
||||
; This final check is the "real" test, verify no !dbg on the store.
|
||||
; CHECK-NEXT: store i32 %storemerge{{.*}}, align 4{{$}}
|
||||
;
|
||||
; The debug location on the store should be a line-0 location.
|
||||
; CHECK-NEXT: store i32 %storemerge{{.*}}, align 4, !dbg [[storeLoc:![0-9]+]]
|
||||
; CHECK: [[storeLoc]] = !DILocation(line: 0
|
||||
;
|
||||
; ModuleID = 'test1.ll'
|
||||
source_filename = "test.c"
|
||||
|
@ -1,6 +1,7 @@
|
||||
; RUN: opt < %s -simplifycfg -S | FileCheck %s
|
||||
|
||||
; Check if the debug info for hoisted store for "ret = 0" is removed
|
||||
; Check that the debug location for the hoisted store for "ret = 0" is a
|
||||
; line-0 location.
|
||||
;
|
||||
; int foo(int x) {
|
||||
; int ret = 1;
|
||||
@ -12,12 +13,11 @@
|
||||
; CHECK: store i32 1,{{.+}}!dbg ![[DLOC1:[0-9]+]]
|
||||
; CHECK: icmp ne {{.+}}!dbg ![[DLOC2:[0-9]+]]
|
||||
; CHECK: [[VREG:%[^ ]+]] = select
|
||||
; CHECK: store i32 [[VREG]]
|
||||
; CHECK-NOT: !dbg
|
||||
; CHECK-SAME: {{$}}
|
||||
; CHECK: store i32 [[VREG]],{{.*}} !dbg [[storeLoc:![0-9]+]]
|
||||
; CHECK: ret {{.+}}!dbg ![[DLOC3:[0-9]+]]
|
||||
; CHECK: ![[DLOC1]] = !DILocation(line: 2
|
||||
; CHECK: ![[DLOC2]] = !DILocation(line: 3
|
||||
; CHECK: [[storeLoc]] = !DILocation(line: 0
|
||||
; CHECK: ![[DLOC3]] = !DILocation(line: 5
|
||||
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
@ -26,9 +26,9 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Function Attrs: uwtable
|
||||
define void @_Z3fooi(i32) #0 !dbg !6 {
|
||||
; CHECK: load i32, i32* %2, align 4, !tbaa
|
||||
; CHECK: store i32 %5, i32* @x, align 4, !tbaa
|
||||
; CHECK: call void @_Z3barv(), !dbg ![[BAR:[0-9]+]]
|
||||
; CHECK: load i32, i32* %2, align 4, !dbg ![[LOAD:[0-9]+]], !tbaa
|
||||
; CHECK: store i32 %5, i32* @x, align 4, !dbg ![[BAR:[0-9]+]], !tbaa
|
||||
; CHECK: call void @_Z3barv(), !dbg ![[BAR]]
|
||||
; CHECK: call void @_Z3bazv(), !dbg ![[BAZ:[0-9]+]]
|
||||
%2 = alloca i32, align 4
|
||||
store i32 %0, i32* %2, align 4, !tbaa !8
|
||||
@ -60,6 +60,7 @@ declare void @_Z3bazv() #1
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
|
||||
; CHECK: ![[LOAD]] = !DILocation(line: 6, column: 7
|
||||
; CHECK: ![[BAR]] = !DILocation(line: 0
|
||||
; CHECK: ![[BAZ]] = !DILocation(line: 12, column: 5
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1)
|
||||
|
Loading…
Reference in New Issue
Block a user