diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -50,6 +50,9 @@ class TargetPassConfig; class User; class Value; +#ifndef NDEBUG +class DILocationVerifier; +#endif // Technically the pass should run on an hypothetical MachineModule, // since it should translate Global into some sort of MachineGlobal. @@ -169,6 +172,22 @@ SwiftErrorValueTracking SwiftError; +#ifndef NDEBUG + DILocationVerifier *Verifier = nullptr; + + class RAIIVerifierInstaller { + IRTranslator *IRT; + + public: + RAIIVerifierInstaller(IRTranslator *IRT, DILocationVerifier *Verifier) + : IRT(IRT) { + IRT->Verifier = Verifier; + } + + ~RAIIVerifierInstaller() { IRT->Verifier = nullptr; } + }; +#endif + /// \name Methods for translating form LLVM IR to MachineInstr. /// \see ::translate for general information on the translate methods. /// @{ diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -125,11 +125,12 @@ : MachineFunctionPass(ID), OptLevel(optlevel) {} #ifndef NDEBUG -namespace { +namespace llvm { /// Verify that every instruction created has the same DILocation as the /// instruction being translated. class DILocationVerifier : public GISelChangeObserver { const Instruction *CurrInst = nullptr; + unsigned constantBlockCounter = 0; public: DILocationVerifier() = default; @@ -150,15 +151,34 @@ LLVM_DEBUG(dbgs() << "Checking DILocation from " << *CurrInst << " was copied to " << MI); #endif - // We allow insts in the entry block to have a debug loc line of 0 because + // We allow insts in the entry block to have no debug loc because // they could have originated from constants, and we don't want a jumpy // debug experience. assert((CurrInst->getDebugLoc() == MI.getDebugLoc() || - MI.getDebugLoc().getLine() == 0) && + (constantBlockCounter > 0 && MI.getParent()->isEntryBlock() && + !MI.getDebugLoc())) && "Line info was not transferred to all instructions"); } + + void enterConstantBlock() { ++constantBlockCounter; } + + void leaveConstantBlock() { + assert(constantBlockCounter > 0 && "Hasn't entered constant block"); + --constantBlockCounter; + } + + class ConstantBlock { + DILocationVerifier *Verifier; + + public: + ConstantBlock(DILocationVerifier *Verifier) : Verifier(Verifier) { + Verifier->enterConstantBlock(); + } + + ~ConstantBlock() { Verifier->leaveConstantBlock(); } + }; }; -} // namespace +} // namespace llvm #endif // ifndef NDEBUG @@ -2922,6 +2942,7 @@ DILocationVerifier Verifier; GISelObserverWrapper WrapperObserver(&Verifier); RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver); + RAIIVerifierInstaller VerifierInstaller(this, &Verifier); #endif // ifndef NDEBUG for (auto &Phi : PendingPHIs) { const PHINode *PI = Phi.first; @@ -2969,11 +2990,13 @@ bool IRTranslator::translate(const Constant &C, Register Reg) { // We only emit constants into the entry block from here. To prevent jumpy - // debug behaviour set the line to 0. + // debug behaviour remove debug line. if (auto CurrInstDL = CurBuilder->getDL()) - EntryBuilder->setDebugLoc(DILocation::get(C.getContext(), 0, 0, - CurrInstDL.getScope(), - CurrInstDL.getInlinedAt())); + EntryBuilder->setDebugLoc(DebugLoc()); + +#ifndef NDEBUG + DILocationVerifier::ConstantBlock ConstantBlock(Verifier); +#endif if (auto CI = dyn_cast(&C)) EntryBuilder->buildConstant(Reg, *CI); @@ -3436,6 +3459,7 @@ #ifndef NDEBUG DILocationVerifier Verifier; WrapperObserver.addObserver(&Verifier); + RAIIVerifierInstaller VerifierInstaller(this, &Verifier); #endif // ifndef NDEBUG RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver); RAIIMFObserverInstaller ObsInstall(*MF, WrapperObserver); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-of-shifted-dbg-value-fallback.ll b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-of-shifted-dbg-value-fallback.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-of-shifted-dbg-value-fallback.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-of-shifted-dbg-value-fallback.ll @@ -54,12 +54,10 @@ ; CHECK-NEXT: //DEBUG_VALUE: baz:3 <- undef ; CHECK-NEXT: .loc 1 4 1 prologue_end // tmp.ll:4:1 ; CHECK-NEXT: lsl x8, x0, #4 -; CHECK-NEXT: .loc 1 0 0 is_stmt 0 // tmp.ll:0:0 ; CHECK-NEXT: adrp x9, global+202752 ; CHECK-NEXT: add x9, x9, :lo12:global+202752 -; CHECK-NEXT: .loc 1 4 1 // tmp.ll:4:1 ; CHECK-NEXT: and x8, x8, #0x1ff0 -; CHECK-NEXT: .loc 1 5 1 is_stmt 1 // tmp.ll:5:1 +; CHECK-NEXT: .loc 1 5 1 // tmp.ll:5:1 ; CHECK-NEXT: str xzr, [x9, x8] ; CHECK-NEXT: .loc 1 6 1 // tmp.ll:6:1 ; CHECK-NEXT: ret diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/constant-dbg-loc.ll b/llvm/test/CodeGen/AArch64/GlobalISel/constant-dbg-loc.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/constant-dbg-loc.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/constant-dbg-loc.ll @@ -6,16 +6,16 @@ @var1 = common global i32 0, align 4, !dbg !0 @var2 = common global i32 0, align 4, !dbg !6 -; We check here that the G_GLOBAL_VALUE has a debug loc with line 0. +; We check here that the G_GLOBAL_VALUE has no debug loc. define i32 @main() #0 !dbg !14 { ; CHECK-LABEL: name: main ; CHECK: bb.1.entry: ; CHECK: successors: %bb.2(0x40000000), %bb.3(0x40000000) ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 - ; CHECK: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var1, debug-location !DILocation(line: 0, scope: !18) + ; CHECK: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var1 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 - ; CHECK: [[GV1:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var2, debug-location !DILocation(line: 0, scope: !22) + ; CHECK: [[GV1:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var2 ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.retval ; CHECK: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store (s32) into %ir.retval) ; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0), debug-location !17 :: (dereferenceable load (s32) from @var1)