Skip to content

Commit 99c3317

Browse files
committed
[globalisel][irtranslator] Verify that DILocations aren't lost in translation
Summary: Also fix a couple bugs where DILocations are lost. EntryBuilder wasn't passing on debug locations for PHI's, constants, GLOBAL_VALUE, etc. Reviewers: aprantl, vsk, bogner, aditya_nandakumar, volkan, rtereshin, aemerson Reviewed By: aemerson Subscribers: aemerson, rovka, kristof.beyls, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D53740 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@345743 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 08b668a commit 99c3317

File tree

2 files changed

+120
-23
lines changed

2 files changed

+120
-23
lines changed

lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,36 @@ IRTranslator::IRTranslator() : MachineFunctionPass(ID) {
104104
initializeIRTranslatorPass(*PassRegistry::getPassRegistry());
105105
}
106106

107+
#ifndef NDEBUG
108+
/// Verify that every instruction created has the same DILocation as the
109+
/// instruction being translated.
110+
class DILocationVerifier : MachineFunction::Delegate {
111+
MachineFunction &MF;
112+
const Instruction *CurrInst = nullptr;
113+
114+
public:
115+
DILocationVerifier(MachineFunction &MF) : MF(MF) { MF.setDelegate(this); }
116+
~DILocationVerifier() { MF.resetDelegate(this); }
117+
118+
const Instruction *getCurrentInst() const { return CurrInst; }
119+
void setCurrentInst(const Instruction *Inst) { CurrInst = Inst; }
120+
121+
void MF_HandleInsertion(const MachineInstr &MI) override {
122+
assert(getCurrentInst() && "Inserted instruction without a current MI");
123+
124+
// Only print the check message if we're actually checking it.
125+
#ifndef NDEBUG
126+
LLVM_DEBUG(dbgs() << "Checking DILocation from " << *CurrInst
127+
<< " was copied to " << MI);
128+
#endif
129+
assert(CurrInst->getDebugLoc() == MI.getDebugLoc() &&
130+
"Line info was not transferred to all instructions");
131+
}
132+
void MF_HandleRemoval(const MachineInstr &MI) override {}
133+
};
134+
#endif // ifndef NDEBUG
135+
136+
107137
void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
108138
AU.addRequired<StackProtector>();
109139
AU.addRequired<TargetPassConfig>();
@@ -1468,9 +1498,16 @@ bool IRTranslator::translateAtomicRMW(const User &U,
14681498
}
14691499

14701500
void IRTranslator::finishPendingPhis() {
1501+
#ifndef NDEBUG
1502+
DILocationVerifier Verifier(*MF);
1503+
#endif // ifndef NDEBUG
14711504
for (auto &Phi : PendingPHIs) {
14721505
const PHINode *PI = Phi.first;
14731506
ArrayRef<MachineInstr *> ComponentPHIs = Phi.second;
1507+
EntryBuilder.setDebugLoc(PI->getDebugLoc());
1508+
#ifndef NDEBUG
1509+
Verifier.setCurrentInst(PI);
1510+
#endif // ifndef NDEBUG
14741511

14751512
// All MachineBasicBlocks exist, add them to the PHI. We assume IRTranslator
14761513
// won't create extra control flow here, otherwise we need to find the
@@ -1509,6 +1546,7 @@ bool IRTranslator::valueIsSplit(const Value &V,
15091546

15101547
bool IRTranslator::translate(const Instruction &Inst) {
15111548
CurBuilder.setDebugLoc(Inst.getDebugLoc());
1549+
EntryBuilder.setDebugLoc(Inst.getDebugLoc());
15121550
switch(Inst.getOpcode()) {
15131551
#define HANDLE_INST(NUM, OPCODE, CLASS) \
15141552
case Instruction::OPCODE: return translate##OPCODE(Inst, CurBuilder);
@@ -1684,31 +1722,39 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
16841722
}
16851723

16861724
// Need to visit defs before uses when translating instructions.
1687-
ReversePostOrderTraversal<const Function *> RPOT(&F);
1688-
for (const BasicBlock *BB : RPOT) {
1689-
MachineBasicBlock &MBB = getMBB(*BB);
1690-
// Set the insertion point of all the following translations to
1691-
// the end of this basic block.
1692-
CurBuilder.setMBB(MBB);
1693-
1694-
for (const Instruction &Inst : *BB) {
1695-
if (translate(Inst))
1696-
continue;
1697-
1698-
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
1699-
Inst.getDebugLoc(), BB);
1700-
R << "unable to translate instruction: " << ore::NV("Opcode", &Inst);
1701-
1702-
if (ORE->allowExtraAnalysis("gisel-irtranslator")) {
1703-
std::string InstStrStorage;
1704-
raw_string_ostream InstStr(InstStrStorage);
1705-
InstStr << Inst;
1725+
{
1726+
ReversePostOrderTraversal<const Function *> RPOT(&F);
1727+
#ifndef NDEBUG
1728+
DILocationVerifier Verifier(*MF);
1729+
#endif // ifndef NDEBUG
1730+
for (const BasicBlock *BB : RPOT) {
1731+
MachineBasicBlock &MBB = getMBB(*BB);
1732+
// Set the insertion point of all the following translations to
1733+
// the end of this basic block.
1734+
CurBuilder.setMBB(MBB);
1735+
1736+
for (const Instruction &Inst : *BB) {
1737+
#ifndef NDEBUG
1738+
Verifier.setCurrentInst(&Inst);
1739+
#endif // ifndef NDEBUG
1740+
if (translate(Inst))
1741+
continue;
1742+
1743+
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
1744+
Inst.getDebugLoc(), BB);
1745+
R << "unable to translate instruction: " << ore::NV("Opcode", &Inst);
1746+
1747+
if (ORE->allowExtraAnalysis("gisel-irtranslator")) {
1748+
std::string InstStrStorage;
1749+
raw_string_ostream InstStr(InstStrStorage);
1750+
InstStr << Inst;
1751+
1752+
R << ": '" << InstStr.str() << "'";
1753+
}
17061754

1707-
R << ": '" << InstStr.str() << "'";
1755+
reportTranslationError(*MF, *TPC, *ORE, R);
1756+
return false;
17081757
}
1709-
1710-
reportTranslationError(*MF, *TPC, *ORE, R);
1711-
return false;
17121758
}
17131759
}
17141760

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
; RUN: llc -O0 -mtriple=aarch64-apple-ios -global-isel -debug-only=irtranslator \
2+
; RUN: -stop-after=irtranslator %s -o - 2>&1 | FileCheck %s
3+
4+
; CHECK: Checking DILocation from %retval = alloca i32, align 4 was copied to G_FRAME_INDEX
5+
; CHECK: Checking DILocation from %rv = alloca i32, align 4 was copied to G_FRAME_INDEX
6+
; CHECK: Checking DILocation from store i32 0, i32* %retval, align 4 was copied to G_CONSTANT
7+
; CHECK: Checking DILocation from store i32 0, i32* %retval, align 4 was copied to G_STORE
8+
; CHECK: Checking DILocation from store i32 0, i32* %rv, align 4, !dbg !12 was copied to G_STORE debug-location !12; t.cpp:2:5
9+
; CHECK: Checking DILocation from %0 = load i32, i32* %rv, align 4, !dbg !13 was copied to G_LOAD debug-location !13; t.cpp:3:8
10+
; CHECK: Checking DILocation from ret i32 %0, !dbg !14 was copied to COPY debug-location !14; t.cpp:3:1
11+
; CHECK: Checking DILocation from ret i32 %0, !dbg !14 was copied to RET_ReallyLR implicit $w0, debug-location !14; t.cpp:3:1
12+
13+
source_filename = "t.cpp"
14+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
15+
target triple = "arm64-unknown-linux-gnu"
16+
17+
; Function Attrs: noinline norecurse nounwind optnone
18+
define dso_local i32 @main() !dbg !7 {
19+
entry:
20+
%retval = alloca i32, align 4
21+
%rv = alloca i32, align 4
22+
store i32 0, i32* %retval, align 4
23+
call void @llvm.dbg.declare(metadata i32* %rv, metadata !11, metadata !DIExpression()), !dbg !12
24+
store i32 0, i32* %rv, align 4, !dbg !12
25+
%0 = load i32, i32* %rv, align 4, !dbg !13
26+
ret i32 %0, !dbg !14
27+
}
28+
29+
; Function Attrs: nounwind readnone speculatable
30+
declare void @llvm.dbg.declare(metadata, metadata, metadata)
31+
32+
!llvm.dbg.cu = !{!0}
33+
!llvm.module.flags = !{!3, !4, !5}
34+
!llvm.ident = !{!6}
35+
36+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 (trunk) (llvm/trunk 344296)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
37+
!1 = !DIFile(filename: "t.cpp", directory: "/Volumes/Data/llvm.org/svn/build")
38+
!2 = !{}
39+
!3 = !{i32 2, !"Dwarf Version", i32 4}
40+
!4 = !{i32 2, !"Debug Info Version", i32 3}
41+
!5 = !{i32 1, !"wchar_size", i32 4}
42+
!6 = !{!"clang version 8.0.0 (trunk) (llvm/trunk 344296)"}
43+
!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
44+
!8 = !DISubroutineType(types: !9)
45+
!9 = !{!10}
46+
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
47+
!11 = !DILocalVariable(name: "rv", scope: !7, file: !1, line: 2, type: !10)
48+
!12 = !DILocation(line: 2, column: 5, scope: !7)
49+
!13 = !DILocation(line: 3, column: 8, scope: !7)
50+
!14 = !DILocation(line: 3, column: 1, scope: !7)
51+

0 commit comments

Comments
 (0)