1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[Instruction] Add updateLocationAfterHoist helper

Introduce a helper on Instruction which can be used to update the debug
location after hoisting.

Use this in GVN and LICM, where we were mistakenly introducing new line
0 locations after hoisting (the docs recommend dropping the location in
this case).

For more context, see the discussion in https://reviews.llvm.org/D60913.

Differential Revision: https://reviews.llvm.org/D85670
This commit is contained in:
Vedant Kumar 2020-08-10 10:44:13 -07:00
parent 6985687166
commit 62d3804379
8 changed files with 76 additions and 14 deletions

View File

@ -492,6 +492,10 @@ public:
/// merged DebugLoc.
void applyMergedLocation(const DILocation *LocA, const DILocation *LocB);
/// Updates the debug location given that the instruction has been hoisted
/// from a block to a predecessor of that block.
void updateLocationAfterHoist();
private:
/// Return true if we have an entry in the on-the-side metadata hash.
bool hasMetadataHashEntry() const {

View File

@ -696,6 +696,24 @@ void Instruction::applyMergedLocation(const DILocation *LocA,
setDebugLoc(DILocation::getMergedLocation(LocA, LocB));
}
void Instruction::updateLocationAfterHoist() {
const DebugLoc &DL = getDebugLoc();
if (!DL)
return;
// If we didn't hoist a call, drop the location to allow a location from a
// preceding instruction to propagate.
if (!isa<CallBase>(this)) {
setDebugLoc(DebugLoc());
return;
}
// Set a line 0 location for (potentially inlinable) calls. Set the scope to
// the parent function's scope if it's available, and drop any inlinedAt info
// to avoid making it look like the inlined callee was reached early.
setDebugLoc(DebugLoc::get(0, 0, DL.getScope()));
}
//===----------------------------------------------------------------------===//
// LLVM C API implementations.
//===----------------------------------------------------------------------===//

View File

@ -46,7 +46,6 @@
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
@ -1314,8 +1313,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
// Instructions that have been inserted in predecessor(s) to materialize
// the load address do not retain their original debug locations. Doing
// so could lead to confusing (but correct) source attributions.
if (const DebugLoc &DL = I->getDebugLoc())
I->setDebugLoc(DebugLoc::get(0, 0, DL.getScope(), DL.getInlinedAt()));
I->updateLocationAfterHoist();
// FIXME: We really _ought_ to insert these value numbers into their
// parent's availability map. However, in doing so, we risk getting into

View File

@ -1658,10 +1658,7 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
// Move the new node to the destination block, before its terminator.
moveInstructionBefore(I, *Dest->getTerminator(), *SafetyInfo, MSSAU, SE);
// Apply line 0 debug locations when we are moving instructions to different
// basic blocks because we want to avoid jumpy line tables.
if (const DebugLoc &DL = I.getDebugLoc())
I.setDebugLoc(DebugLoc::get(0, 0, DL.getScope(), DL.getInlinedAt()));
I.updateLocationAfterHoist();
if (isa<LoadInst>(I))
++NumMovedLoads;

View File

@ -18,9 +18,8 @@
; We make sure that the instruction that is hoisted into the preheader
; does not have a debug location.
; CHECK: for.body.lr.ph:
; CHECK: getelementptr{{.*}}%p.addr, i64 4{{.*}} !dbg [[zero:![0-9]+]]
; CHECK: getelementptr{{.*}}%p.addr, i64 4{{$}}
; CHECK: for.body:
; CHECK: [[zero]] = !DILocation(line: 0
;
; ModuleID = 't.ll'
source_filename = "test.c"

View File

@ -4,8 +4,8 @@ target datalayout = "e-p:64:64:64"
; CHECK-LABEL: @foo(
; CHECK: entry.end_crit_edge:
; CHECK: %[[INDEX:[a-z0-9.]+]] = sext i32 %x to i64{{.*}} !dbg [[ZERO_LOC:![0-9]+]]
; CHECK: %[[ADDRESS:[a-z0-9.]+]] = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %[[INDEX]]{{.*}} !dbg [[ZERO_LOC]]
; CHECK: %[[INDEX:[a-z0-9.]+]] = sext i32 %x to i64{{$}}
; CHECK: %[[ADDRESS:[a-z0-9.]+]] = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %[[INDEX]]{{$}}
; CHECK: %n.pre = load i32, i32* %[[ADDRESS]], align 4, !dbg [[N_LOC:![0-9]+]]
; CHECK: br label %end
; CHECK: then:
@ -14,8 +14,7 @@ target datalayout = "e-p:64:64:64"
; CHECK: %n = phi i32 [ %n.pre, %entry.end_crit_edge ], [ %z, %then ], !dbg [[N_LOC]]
; CHECK: ret i32 %n
; CHECK-DAG: [[N_LOC]] = !DILocation(line: 47, column: 1, scope: !{{.*}})
; CHECK-DAG: [[ZERO_LOC]] = !DILocation(line: 0
; CHECK: [[N_LOC]] = !DILocation(line: 47, column: 1, scope: !{{.*}})
@G = external global [100 x i32]
define i32 @foo(i32 %x, i32 %z) !dbg !6 {

View File

@ -1,6 +1,6 @@
; RUN: opt -S -licm < %s | FileCheck %s
; CHECK: %arrayidx4.promoted = load i32, i32* %arrayidx4, align 1, !tbaa !59
; CHECK: %arrayidx4.promoted = load i32, i32* %arrayidx4, align 1, !tbaa !{{[0-9]+$}}
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

View File

@ -1304,5 +1304,52 @@ TEST(InstructionsTest, UnaryOperator) {
I->deleteValue();
}
TEST(InstructionsTest, UpdateLocationAfterHoist) {
LLVMContext C;
std::unique_ptr<Module> M = parseIR(C,
R"(
declare void @callee()
define void @f() {
call void @callee() ; Inst with no location.
call void @callee(), !dbg !11 ; Call with location.
ret void, !dbg !11 ; Non-call inst with location.
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "t2.c", directory: "foo")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
!9 = !DISubroutineType(types: !10)
!10 = !{null}
!11 = !DILocation(line: 2, column: 7, scope: !8)
)");
ASSERT_TRUE(M);
Function *F = cast<Function>(M->getNamedValue("f"));
BasicBlock &BB = F->front();
auto *I1 = BB.getFirstNonPHI();
auto *I2 = I1->getNextNode();
auto *I3 = BB.getTerminator();
EXPECT_FALSE(bool(I1->getDebugLoc()));
I1->updateLocationAfterHoist();
EXPECT_FALSE(bool(I1->getDebugLoc()));
const MDNode *Scope = I2->getDebugLoc().getScope();
EXPECT_EQ(I2->getDebugLoc().getLine(), 2U);
I2->updateLocationAfterHoist();
EXPECT_EQ(I2->getDebugLoc().getLine(), 0U);
EXPECT_EQ(I2->getDebugLoc().getScope(), Scope);
EXPECT_EQ(I3->getDebugLoc().getLine(), 2U);
I3->updateLocationAfterHoist();
EXPECT_FALSE(bool(I3->getDebugLoc()));
}
} // end anonymous namespace
} // end namespace llvm