diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index aab0d5c5a348b..748837fc26d6c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1148,12 +1148,7 @@ SDValue SelectionDAGBuilder::getControlRoot() { return updateRoot(PendingExports); } -void SelectionDAGBuilder::visit(const Instruction &I) { - // Set up outgoing PHI node register values before emitting the terminator. - if (I.isTerminator()) { - HandlePHINodesInSuccessorBlocks(I.getParent()); - } - +void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) { // Add SDDbgValue nodes for any var locs here. Do so before updating // SDNodeOrder, as this mapping is {Inst -> Locs BEFORE Inst}. if (FunctionVarLocs const *FnVarLocs = DAG.getFunctionVarLocs()) { @@ -1169,10 +1164,56 @@ void SelectionDAGBuilder::visit(const Instruction &I) { } SmallVector Values(It->Values.location_ops()); if (!handleDebugValue(Values, Var, It->Expr, It->DL, SDNodeOrder, - It->Values.hasArgList())) - addDanglingDebugInfo(It, SDNodeOrder); + It->Values.hasArgList())) { + SmallVector Vals; + for (Value *V : It->Values.location_ops()) + Vals.push_back(V); + addDanglingDebugInfo(Vals, + FnVarLocs->getDILocalVariable(It->VariableID), + It->Expr, Vals.size() > 1, It->DL, SDNodeOrder); + } + } + } + + // Is there is any debug-info attached to this instruction, in the form of + // DPValue non-instruction debug-info records. + for (DPValue &DPV : I.getDbgValueRange()) { + DILocalVariable *Variable = DPV.getVariable(); + DIExpression *Expression = DPV.getExpression(); + dropDanglingDebugInfo(Variable, Expression); + + // A DPValue with no locations is a kill location. + SmallVector Values(DPV.location_ops()); + if (Values.empty()) { + handleKillDebugValue(Variable, Expression, DPV.getDebugLoc(), + SDNodeOrder); + continue; + } + + // A DPValue with an undef or absent location is also a kill location. + if (llvm::any_of(Values, + [](Value *V) { return !V || isa(V); })) { + handleKillDebugValue(Variable, Expression, DPV.getDebugLoc(), + SDNodeOrder); + continue; + } + + bool IsVariadic = DPV.hasArgList(); + if (!handleDebugValue(Values, Variable, Expression, DPV.getDebugLoc(), + SDNodeOrder, IsVariadic)) { + addDanglingDebugInfo(Values, Variable, Expression, IsVariadic, + DPV.getDebugLoc(), SDNodeOrder); } } +} + +void SelectionDAGBuilder::visit(const Instruction &I) { + visitDbgInfo(I); + + // Set up outgoing PHI node register values before emitting the terminator. + if (I.isTerminator()) { + HandlePHINodesInSuccessorBlocks(I.getParent()); + } // Increase the SDNodeOrder if dealing with a non-debug instruction. if (!isa(I)) @@ -1232,14 +1273,12 @@ void SelectionDAGBuilder::visit(unsigned Opcode, const User &I) { static bool handleDanglingVariadicDebugInfo(SelectionDAG &DAG, DILocalVariable *Variable, DebugLoc DL, unsigned Order, - RawLocationWrapper Values, + SmallVectorImpl &Values, DIExpression *Expression) { - if (!Values.hasArgList()) - return false; // For variadic dbg_values we will now insert an undef. // FIXME: We can potentially recover these! SmallVector Locs; - for (const Value *V : Values.location_ops()) { + for (const Value *V : Values) { auto *Undef = UndefValue::get(V->getType()); Locs.push_back(SDDbgOperand::fromConst(Undef)); } @@ -1250,44 +1289,31 @@ static bool handleDanglingVariadicDebugInfo(SelectionDAG &DAG, return true; } -void SelectionDAGBuilder::addDanglingDebugInfo(const VarLocInfo *VarLoc, - unsigned Order) { - if (!handleDanglingVariadicDebugInfo( - DAG, - const_cast(DAG.getFunctionVarLocs() - ->getVariable(VarLoc->VariableID) - .getVariable()), - VarLoc->DL, Order, VarLoc->Values, VarLoc->Expr)) { - DanglingDebugInfoMap[VarLoc->Values.getVariableLocationOp(0)].emplace_back( - VarLoc, Order); - } -} - -void SelectionDAGBuilder::addDanglingDebugInfo(const DbgValueInst *DI, +void SelectionDAGBuilder::addDanglingDebugInfo(SmallVectorImpl &Values, + DILocalVariable *Var, + DIExpression *Expr, + bool IsVariadic, DebugLoc DL, unsigned Order) { - // We treat variadic dbg_values differently at this stage. - if (!handleDanglingVariadicDebugInfo( - DAG, DI->getVariable(), DI->getDebugLoc(), Order, - DI->getWrappedLocation(), DI->getExpression())) { - // TODO: Dangling debug info will eventually either be resolved or produce - // an Undef DBG_VALUE. However in the resolution case, a gap may appear - // between the original dbg.value location and its resolved DBG_VALUE, - // which we should ideally fill with an extra Undef DBG_VALUE. - assert(DI->getNumVariableLocationOps() == 1 && - "DbgValueInst without an ArgList should have a single location " - "operand."); - DanglingDebugInfoMap[DI->getValue(0)].emplace_back(DI, Order); + if (IsVariadic) { + handleDanglingVariadicDebugInfo(DAG, Var, DL, Order, Values, Expr); + return; } + // TODO: Dangling debug info will eventually either be resolved or produce + // an Undef DBG_VALUE. However in the resolution case, a gap may appear + // between the original dbg.value location and its resolved DBG_VALUE, + // which we should ideally fill with an extra Undef DBG_VALUE. + assert(Values.size() == 1); + DanglingDebugInfoMap[Values[0]].emplace_back(Var, Expr, DL, Order); } void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable, const DIExpression *Expr) { auto isMatchingDbgValue = [&](DanglingDebugInfo &DDI) { - DIVariable *DanglingVariable = DDI.getVariable(DAG.getFunctionVarLocs()); + DIVariable *DanglingVariable = DDI.getVariable(); DIExpression *DanglingExpr = DDI.getExpression(); if (DanglingVariable == Variable && Expr->fragmentsOverlap(DanglingExpr)) { - LLVM_DEBUG(dbgs() << "Dropping dangling debug info for " << printDDI(DDI) - << "\n"); + LLVM_DEBUG(dbgs() << "Dropping dangling debug info for " + << printDDI(nullptr, DDI) << "\n"); return true; } return false; @@ -1300,7 +1326,7 @@ void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable, // whether it can be salvaged. for (auto &DDI : DDIV) if (isMatchingDbgValue(DDI)) - salvageUnresolvedDbgValue(DDI); + salvageUnresolvedDbgValue(DDIMI.first, DDI); erase_if(DDIV, isMatchingDbgValue); } @@ -1319,7 +1345,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, DebugLoc DL = DDI.getDebugLoc(); unsigned ValSDNodeOrder = Val.getNode()->getIROrder(); unsigned DbgSDNodeOrder = DDI.getSDNodeOrder(); - DILocalVariable *Variable = DDI.getVariable(DAG.getFunctionVarLocs()); + DILocalVariable *Variable = DDI.getVariable(); DIExpression *Expr = DDI.getExpression(); assert(Variable->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); @@ -1333,8 +1359,8 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, // calling EmitFuncArgumentDbgValue here. if (!EmitFuncArgumentDbgValue(V, Variable, Expr, DL, FuncArgumentDbgValueKind::Value, Val)) { - LLVM_DEBUG(dbgs() << "Resolve dangling debug info for " << printDDI(DDI) - << "\n"); + LLVM_DEBUG(dbgs() << "Resolve dangling debug info for " + << printDDI(V, DDI) << "\n"); LLVM_DEBUG(dbgs() << " By mapping to:\n "; Val.dump()); // Increase the SDNodeOrder for the DbgValue here to make sure it is // inserted after the definition of Val when emitting the instructions @@ -1348,9 +1374,11 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, DAG.AddDbgValue(SDV, false); } else LLVM_DEBUG(dbgs() << "Resolved dangling debug info for " - << printDDI(DDI) << " in EmitFuncArgumentDbgValue\n"); + << printDDI(V, DDI) + << " in EmitFuncArgumentDbgValue\n"); } else { - LLVM_DEBUG(dbgs() << "Dropping debug info for " << printDDI(DDI) << "\n"); + LLVM_DEBUG(dbgs() << "Dropping debug info for " << printDDI(V, DDI) + << "\n"); auto Undef = UndefValue::get(V->getType()); auto SDV = DAG.getConstantDbgValue(Variable, Expr, Undef, DL, DbgSDNodeOrder); @@ -1360,14 +1388,14 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, DDIV.clear(); } -void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) { +void SelectionDAGBuilder::salvageUnresolvedDbgValue(const Value *V, + DanglingDebugInfo &DDI) { // TODO: For the variadic implementation, instead of only checking the fail // state of `handleDebugValue`, we need know specifically which values were // invalid, so that we attempt to salvage only those values when processing // a DIArgList. - Value *V = DDI.getVariableLocationOp(0); - Value *OrigV = V; - DILocalVariable *Var = DDI.getVariable(DAG.getFunctionVarLocs()); + const Value *OrigV = V; + DILocalVariable *Var = DDI.getVariable(); DIExpression *Expr = DDI.getExpression(); DebugLoc DL = DDI.getDebugLoc(); unsigned SDOrder = DDI.getSDNodeOrder(); @@ -1384,11 +1412,12 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) { // a non-instruction is seen, such as a constant expression or global // variable. FIXME: Further work could recover those too. while (isa(V)) { - Instruction &VAsInst = *cast(V); + const Instruction &VAsInst = *cast(V); // Temporary "0", awaiting real implementation. SmallVector Ops; SmallVector AdditionalValues; - V = salvageDebugInfoImpl(VAsInst, Expr->getNumLocationOperands(), Ops, + V = salvageDebugInfoImpl(const_cast(VAsInst), + Expr->getNumLocationOperands(), Ops, AdditionalValues); // If we cannot salvage any further, and haven't yet found a suitable debug // expression, bail out. @@ -1421,8 +1450,8 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) { auto *Undef = UndefValue::get(OrigV->getType()); auto *SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder); DAG.AddDbgValue(SDV, false); - LLVM_DEBUG(dbgs() << "Dropping debug value info for:\n " << printDDI(DDI) - << "\n"); + LLVM_DEBUG(dbgs() << "Dropping debug value info for:\n " + << printDDI(OrigV, DDI) << "\n"); } void SelectionDAGBuilder::handleKillDebugValue(DILocalVariable *Var, @@ -1572,7 +1601,7 @@ void SelectionDAGBuilder::resolveOrClearDbgInfo() { // Try to fixup any remaining dangling debug info -- and drop it if we can't. for (auto &Pair : DanglingDebugInfoMap) for (auto &DDI : Pair.second) - salvageUnresolvedDbgValue(DDI); + salvageUnresolvedDbgValue(const_cast(Pair.first), DDI); clearDanglingDebugInfo(); } @@ -6313,7 +6342,8 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, bool IsVariadic = DI.hasArgList(); if (!handleDebugValue(Values, Variable, Expression, DI.getDebugLoc(), SDNodeOrder, IsVariadic)) - addDanglingDebugInfo(&DI, SDNodeOrder); + addDanglingDebugInfo(Values, Variable, Expression, IsVariadic, + DI.getDebugLoc(), SDNodeOrder); return; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index a97884f0efb9a..5b55c3461b0b6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -106,54 +106,39 @@ class SelectionDAGBuilder { /// Helper type for DanglingDebugInfoMap. class DanglingDebugInfo { - using DbgValTy = const DbgValueInst *; - using VarLocTy = const VarLocInfo *; - PointerUnion Info; unsigned SDNodeOrder = 0; public: + DILocalVariable *Variable; + DIExpression *Expression; + DebugLoc dl; DanglingDebugInfo() = default; - DanglingDebugInfo(const DbgValueInst *DI, unsigned SDNO) - : Info(DI), SDNodeOrder(SDNO) {} - DanglingDebugInfo(const VarLocInfo *VarLoc, unsigned SDNO) - : Info(VarLoc), SDNodeOrder(SDNO) {} - - DILocalVariable *getVariable(const FunctionVarLocs *Locs) const { - if (isa(Info)) - return Locs->getDILocalVariable(cast(Info)->VariableID); - return cast(Info)->getVariable(); - } - DIExpression *getExpression() const { - if (isa(Info)) - return cast(Info)->Expr; - return cast(Info)->getExpression(); - } - Value *getVariableLocationOp(unsigned Idx) const { - assert(Idx == 0 && "Dangling variadic debug values not supported yet"); - if (isa(Info)) - return cast(Info)->Values.getVariableLocationOp(Idx); - return cast(Info)->getVariableLocationOp(Idx); - } - DebugLoc getDebugLoc() const { - if (isa(Info)) - return cast(Info)->DL; - return cast(Info)->getDebugLoc(); - } + DanglingDebugInfo(DILocalVariable *Var, DIExpression *Expr, DebugLoc DL, + unsigned SDNO) + : SDNodeOrder(SDNO), Variable(Var), Expression(Expr), + dl(std::move(DL)) {} + + DILocalVariable *getVariable() const { return Variable; } + DIExpression *getExpression() const { return Expression; } + DebugLoc getDebugLoc() const { return dl; } unsigned getSDNodeOrder() const { return SDNodeOrder; } /// Helper for printing DanglingDebugInfo. This hoop-jumping is to - /// accommodate the fact that an argument is required for getVariable. + /// store a Value pointer, so that we can print a whole DDI as one object. /// Call SelectionDAGBuilder::printDDI instead of using directly. struct Print { - Print(const DanglingDebugInfo &DDI, const FunctionVarLocs *VarLocs) - : DDI(DDI), VarLocs(VarLocs) {} + Print(const Value *V, const DanglingDebugInfo &DDI) : V(V), DDI(DDI) {} + const Value *V; const DanglingDebugInfo &DDI; - const FunctionVarLocs *VarLocs; friend raw_ostream &operator<<(raw_ostream &OS, const DanglingDebugInfo::Print &P) { - OS << "DDI(var=" << *P.DDI.getVariable(P.VarLocs) - << ", val= " << *P.DDI.getVariableLocationOp(0) - << ", expr=" << *P.DDI.getExpression() + OS << "DDI(var=" << *P.DDI.getVariable(); + if (P.V) + OS << ", val=" << *P.V; + else + OS << ", val=nullptr"; + + OS << ", expr=" << *P.DDI.getExpression() << ", order=" << P.DDI.getSDNodeOrder() << ", loc=" << P.DDI.getDebugLoc() << ")"; return OS; @@ -164,8 +149,9 @@ class SelectionDAGBuilder { /// Returns an object that defines `raw_ostream &operator<<` for printing. /// Usage example: //// errs() << printDDI(MyDanglingInfo) << " is dangling\n"; - DanglingDebugInfo::Print printDDI(const DanglingDebugInfo &DDI) { - return DanglingDebugInfo::Print(DDI, DAG.getFunctionVarLocs()); + DanglingDebugInfo::Print printDDI(const Value *V, + const DanglingDebugInfo &DDI) { + return DanglingDebugInfo::Print(V, DDI); } /// Helper type for DanglingDebugInfoMap. @@ -344,6 +330,7 @@ class SelectionDAGBuilder { ISD::NodeType ExtendType = ISD::ANY_EXTEND); void visit(const Instruction &I); + void visitDbgInfo(const Instruction &I); void visit(unsigned Opcode, const User &I); @@ -352,8 +339,9 @@ class SelectionDAGBuilder { SDValue getCopyFromRegs(const Value *V, Type *Ty); /// Register a dbg_value which relies on a Value which we have not yet seen. - void addDanglingDebugInfo(const DbgValueInst *DI, unsigned Order); - void addDanglingDebugInfo(const VarLocInfo *VarLoc, unsigned Order); + void addDanglingDebugInfo(SmallVectorImpl &Values, + DILocalVariable *Var, DIExpression *Expr, + bool IsVariadic, DebugLoc DL, unsigned Order); /// If we have dangling debug info that describes \p Variable, or an /// overlapping part of variable considering the \p Expr, then this method @@ -368,7 +356,7 @@ class SelectionDAGBuilder { /// For the given dangling debuginfo record, perform last-ditch efforts to /// resolve the debuginfo to something that is represented in this DAG. If /// this cannot be done, produce an Undef debug value record. - void salvageUnresolvedDbgValue(DanglingDebugInfo &DDI); + void salvageUnresolvedDbgValue(const Value *V, DanglingDebugInfo &DDI); /// For a given list of Values, attempt to create and record a SDDbgValue in /// the SelectionDAG. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 0cc426254806d..bf6298c7520a7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -685,10 +685,13 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin, CurDAG->NewNodesMustHaveLegalTypes = false; // Lower the instructions. If a call is emitted as a tail call, cease emitting - // nodes for this block. + // nodes for this block. If an instruction is elided, don't emit it, but do + // handle any debug-info attached to it. for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) { if (!ElidedArgCopyInstrs.count(&*I)) SDB->visit(*I); + else + SDB->visitDbgInfo(*I); } // Make sure the root of the DAG is up-to-date. diff --git a/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll b/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll index 828cebfd0728d..798bbb6d37908 100644 --- a/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll +++ b/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll @@ -5,6 +5,9 @@ ; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations=false -stop-before=finalize-isel -o - | FileCheck %s ; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations -stop-before=finalize-isel -o - | FileCheck %s +; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations=false -stop-before=finalize-isel -o - --try-experimental-debuginfo-iterators | FileCheck %s +; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations -stop-before=finalize-isel -o - --try-experimental-debuginfo-iterators | FileCheck %s + ;; Check that unused argument values are handled the same way for variadic ;; dbg_values as non-variadics. diff --git a/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll b/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll index adeaa0fd318a4..b98e99c53dfe6 100644 --- a/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll +++ b/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll @@ -1,5 +1,7 @@ ; RUN: llc %s -stop-after=finalize-isel -o - \ ; RUN: | FileCheck %s --implicit-check-not=DBG --check-prefixes=AT-DISABLED,BOTH +; RUN: llc %s -stop-after=finalize-isel -o - --try-experimental-debuginfo-iterators \ +; RUN: | FileCheck %s --implicit-check-not=DBG --check-prefixes=AT-DISABLED,BOTH ;; Check that dbg.values with empty metadata are treated as kills (i.e. become ;; DBG_VALUE $noreg, ...). dbg.declares with empty metadata location operands ;; should be ignored. diff --git a/llvm/test/DebugInfo/X86/dbg-val-list-dangling.ll b/llvm/test/DebugInfo/X86/dbg-val-list-dangling.ll index 5292197a1caac..d902b13252278 100644 --- a/llvm/test/DebugInfo/X86/dbg-val-list-dangling.ll +++ b/llvm/test/DebugInfo/X86/dbg-val-list-dangling.ll @@ -6,6 +6,7 @@ ;; able to recover the value in some cases. ; RUN: llc %s -start-after=codegenprepare -stop-before=finalize-isel -o - -experimental-debug-variable-locations=false | FileCheck %s +; RUN: llc %s -start-after=codegenprepare -stop-before=finalize-isel -o - -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators | FileCheck %s ;; Check that dangling debug info in the SelectionDAG build phase is handled ;; in the same way for variadic dbg_value ndoes as non-variadics. diff --git a/llvm/test/DebugInfo/X86/dbg-val-list-undef.ll b/llvm/test/DebugInfo/X86/dbg-val-list-undef.ll index 4b58d631dcba3..42c796938438c 100644 --- a/llvm/test/DebugInfo/X86/dbg-val-list-undef.ll +++ b/llvm/test/DebugInfo/X86/dbg-val-list-undef.ll @@ -1,6 +1,9 @@ ; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations=false -stop-before=finalize-isel -o - | FileCheck %s ; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations -stop-before=finalize-isel -o - | FileCheck %s +; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations=false -stop-before=finalize-isel -o - --try-experimental-debuginfo-iterators | FileCheck %s +; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations -stop-before=finalize-isel -o - --try-experimental-debuginfo-iterators | FileCheck %s + ;; %y is unused and cannot (FIXME: currently) be salvaged. Ensure that the ;; variadic dbg_value using %y becomes undef. diff --git a/llvm/test/DebugInfo/X86/dbg-value-arg-movement.ll b/llvm/test/DebugInfo/X86/dbg-value-arg-movement.ll index 89c3e44a1dfb3..4c47cb046deb0 100644 --- a/llvm/test/DebugInfo/X86/dbg-value-arg-movement.ll +++ b/llvm/test/DebugInfo/X86/dbg-value-arg-movement.ll @@ -1,6 +1,9 @@ ; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare -stop-before=finalize-isel %s -o - -experimental-debug-variable-locations=false | FileCheck %s --check-prefixes=COMMON,CHECK ; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare -stop-before=finalize-isel %s -o - -experimental-debug-variable-locations=true | FileCheck %s --check-prefixes=COMMON,INSTRREF +; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare -stop-before=finalize-isel %s -o - -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=COMMON,CHECK +; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare -stop-before=finalize-isel %s -o - -experimental-debug-variable-locations=true --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=COMMON,INSTRREF + ; Test the movement of dbg.values of arguments. SelectionDAG tries to be ; helpful and places DBG_VALUEs of Arguments at the start of functions. ; Unfortunately, this doesn't necessarily make sense, as one can specify an diff --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll index 9d87f7b03c7df..97b156773b911 100644 --- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll +++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll @@ -5,6 +5,10 @@ ; RUN: -experimental-debug-variable-locations=true \ ; RUN: | FileCheck %s --check-prefixes=CHECK,INSTRREF +; RUN: llc -start-after=codegenprepare -stop-before finalize-isel -o - %s \ +; RUN: -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators \ +; RUN: | FileCheck %s --check-prefixes=CHECK,DBGVALUE + ; This test case was generated from the following debug.c program, ; using: clang debug.c -g -O1 -S -o dbg_value_phi_isel1.ll -emit-llvm ; -------------------------------------- diff --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll index 0047e816855bc..6ff5f3f82a332 100644 --- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll +++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll @@ -5,6 +5,10 @@ ; RUN: -experimental-debug-variable-locations=true \ ; RUN: | FileCheck %s --check-prefixes=CHECK,INSTRREF +; RUN: llc -start-after=codegenprepare -stop-before finalize-isel -o - %s \ +; RUN: -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators \ +; RUN: | FileCheck %s --check-prefixes=CHECK,DBGVALUE + ; This test case is a modified version of dbg_value_phi_isel1.ll ; where the llvm.dbg.value nodes in for.body has been moved. diff --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll index 0bba204a408b5..fd0cfc1e96122 100644 --- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll +++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll @@ -5,6 +5,10 @@ ; RUN: -experimental-debug-variable-locations=true \ ; RUN: | FileCheck %s --check-prefixes=CHECK,INSTRREF +; RUN: llc -start-after=codegenprepare -stop-before finalize-isel -o - %s \ +; RUN: -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators \ +; RUN: | FileCheck %s --check-prefixes=CHECK,DBGVALUE + ; This test case was generated from the following phi-split.c program, ; using: clang phi-split.c -g -O1 -S -o - --target=i386 -emit-llvm ; -------------------------------------- diff --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll index bcf646b56e68e..47c8515a537cf 100644 --- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll +++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll @@ -5,6 +5,10 @@ ; RUN: -experimental-debug-variable-locations=true \ ; RUN: | FileCheck %s --check-prefixes=CHECK,INSTRREF +; RUN: llc -start-after=codegenprepare -stop-before finalize-isel -o - %s \ +; RUN: -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators \ +; RUN: | FileCheck %s --check-prefixes=CHECK,DBGVALUE + ; This is a reproducer based on the test case from PR37321. ; We verify that the fragment for the last DBG_VALUE is limited depending diff --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-ssareg.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-ssareg.ll index 6656bf2409e84..c712d8410b7bf 100644 --- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-ssareg.ll +++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-ssareg.ll @@ -5,6 +5,10 @@ ; RUN: -experimental-debug-variable-locations=true \ ; RUN: | FileCheck %s --check-prefixes=CHECK,INSTRREF +; RUN: llc -start-after=codegenprepare -stop-before finalize-isel -o - %s \ +; RUN: -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators \ +; RUN: | FileCheck %s --check-prefixes=CHECK,DBGVALUE + ; Test that dbg.values of an SSA variable that's not used in a basic block, ; is converted to a DBG_VALUE in that same basic block. We know that %1 is ; live from the entry bb to the exit bb, is allocated a vreg because it's diff --git a/llvm/test/DebugInfo/X86/sdag-ir-salvage.ll b/llvm/test/DebugInfo/X86/sdag-ir-salvage.ll index 57da7044c791b..a620b239f14f2 100644 --- a/llvm/test/DebugInfo/X86/sdag-ir-salvage.ll +++ b/llvm/test/DebugInfo/X86/sdag-ir-salvage.ll @@ -7,6 +7,11 @@ ; RUN: -experimental-debug-variable-locations=true \ ; RUN: | FileCheck %s --check-prefixes=CHECK,INSTRREF +; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare \ +; RUN: -stop-before finalize-isel %s -o - \ +; RUN: -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators \ +; RUN: | FileCheck %s --check-prefixes=CHECK,DBGVALUE + ; Test that the dbg.value for %baz, which doesn't exist in the 'next' bb, ; can be salvaged back to the underlying argument vreg. diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index 0b174afc22ddc..d388ff09cbd58 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -186,6 +186,13 @@ static cl::opt RemarksFormat( cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml")); +static cl::opt TryUseNewDbgInfoFormat( + "try-experimental-debuginfo-iterators", + cl::desc("Enable debuginfo iterator positions, if they're built in"), + cl::init(false)); + +extern cl::opt UseNewDbgInfoFormat; + namespace { std::vector &getRunPassNames() { @@ -203,7 +210,7 @@ struct RunPassOption { getRunPassNames().push_back(std::string(PassName)); } }; -} +} // namespace static RunPassOption RunPassOpt; @@ -377,6 +384,17 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); + // RemoveDIs debug-info transition: tests may request that we /try/ to use the + // new debug-info format, if it's built in. +#ifdef EXPERIMENTAL_DEBUGINFO_ITERATORS + if (TryUseNewDbgInfoFormat) { + // If LLVM was built with support for this, turn the new debug-info format + // on. + UseNewDbgInfoFormat = true; + } +#endif + (void)TryUseNewDbgInfoFormat; + if (TimeTrace) timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]); auto TimeTraceScopeExit = make_scope_exit([]() {