diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 464f475098ec5..1fb8f8f779322 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -688,6 +688,8 @@ enum FunctionCodes { FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE = 64, // [DILocation, DILocalVariable, DIExpression, Value] FUNC_CODE_DEBUG_RECORD_LABEL = 65, // [DILocation, DILabel] + FUNC_CODE_DEBUG_RECORD_DECLARE_VALUE = + 66, // [DILocation, DILocalVariable, DIExpression, ValueAsMetadata] }; enum UseListCodes { diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index f3839c9694f34..e56c74c20a029 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -1151,6 +1151,18 @@ namespace llvm { DIExpression *Expr, const DILocation *DL, InsertPosition InsertPt); + /// Insert a new llvm.dbg.declare_value intrinsic call. + /// \param Storage llvm::Value of the variable + /// \param VarInfo Variable's debug info descriptor. + /// \param Expr A complex location expression. + /// \param DL Debug info location. + /// \param InsertPt Location for the new intrinsic. + LLVM_ABI DbgInstPtr insertDeclareValue(llvm::Value *Storage, + DILocalVariable *VarInfo, + DIExpression *Expr, + const DILocation *DL, + InsertPosition InsertPt); + /// Insert a new llvm.dbg.label intrinsic call. /// \param LabelInfo Label's debug info descriptor. /// \param DL Debug info location. diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h index 220e4c1cad4f7..d75820add7254 100644 --- a/llvm/include/llvm/IR/DebugInfo.h +++ b/llvm/include/llvm/IR/DebugInfo.h @@ -44,6 +44,8 @@ class Module; LLVM_ABI TinyPtrVector findDVRDeclares(Value *V); /// As above, for DVRValues. LLVM_ABI TinyPtrVector findDVRValues(Value *V); +/// As above, for DVRCoroFrameEntrys. +LLVM_ABI TinyPtrVector findDVRDeclareValues(Value *V); /// Finds the debug info records describing a value. LLVM_ABI void diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index 457c60e3bc929..186e8f312c4c9 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -282,6 +282,7 @@ class DbgVariableRecord : public DbgRecord, protected DebugValueUser { Declare, Value, Assign, + DeclareValue, End, ///< Marks the end of the concrete types. Any, ///< To indicate all LocationTypes in searches. @@ -364,6 +365,13 @@ class DbgVariableRecord : public DbgRecord, protected DebugValueUser { createDVRDeclare(Value *Address, DILocalVariable *DV, DIExpression *Expr, const DILocation *DI, DbgVariableRecord &InsertBefore); + LLVM_ABI static DbgVariableRecord * + createDVRDeclareValue(Value *Address, DILocalVariable *DV, DIExpression *Expr, + const DILocation *DI); + LLVM_ABI static DbgVariableRecord * + createDVRDeclareValue(Value *Address, DILocalVariable *DV, DIExpression *Expr, + const DILocation *DI, DbgVariableRecord &InsertBefore); + /// Iterator for ValueAsMetadata that internally uses direct pointer iteration /// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the /// ValueAsMetadata . @@ -414,6 +422,7 @@ class DbgVariableRecord : public DbgRecord, protected DebugValueUser { bool isDbgDeclare() const { return Type == LocationType::Declare; } bool isDbgValue() const { return Type == LocationType::Value; } + bool isDbgDeclareValue() const { return Type == LocationType::DeclareValue; } /// Get the locations corresponding to the variable referenced by the debug /// info intrinsic. Depending on the intrinsic, this could be the diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index 0622bfae2c845..589e2a65a6908 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -428,6 +428,7 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: case Intrinsic::dbg_assign: + case Intrinsic::dbg_declare_value: return true; default: return false; @@ -464,6 +465,26 @@ class DbgDeclareInst : public DbgVariableIntrinsic { /// @} }; +/// This represents the llvm.dbg.declare_value instruction. +class DbgDeclareValueInst : public DbgVariableIntrinsic { +public: + Value *getAddress() const { + assert(getNumVariableLocationOps() == 1 && + "dbg.declare_value must have exactly 1 location operand."); + return getVariableLocationOp(0); + } + + /// \name Casting methods + /// @{ + static bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::dbg_declare_value; + } + static bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + /// @} +}; + /// This represents the llvm.dbg.value instruction. class DbgValueInst : public DbgVariableIntrinsic { public: diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 4d59ee8676b9e..ca43df41b8ecc 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1447,6 +1447,10 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in { llvm_metadata_ty]>; def int_dbg_label : DefaultAttrsIntrinsic<[], [llvm_metadata_ty]>; + def int_dbg_declare_value : DefaultAttrsIntrinsic<[], + [llvm_metadata_ty, + llvm_metadata_ty, + llvm_metadata_ty]>; } //===------------------ Exception Handling Intrinsics----------------------===// diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 7a6c19ece92ac..940f7b53c8243 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -1005,6 +1005,7 @@ lltok::Kind LLLexer::LexIdentifier() { DBGRECORDTYPEKEYWORD(declare); DBGRECORDTYPEKEYWORD(assign); DBGRECORDTYPEKEYWORD(label); + DBGRECORDTYPEKEYWORD(declare_value); #undef DBGRECORDTYPEKEYWORD if (Keyword.starts_with("DIFlag")) { diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 5164cec33e6f5..64cda950c7858 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -7148,7 +7148,8 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { .Case("declare", RecordKind::ValueKind) .Case("value", RecordKind::ValueKind) .Case("assign", RecordKind::ValueKind) - .Case("label", RecordKind::LabelKind); + .Case("label", RecordKind::LabelKind) + .Case("declare_value", RecordKind::ValueKind); // Parsing labels is trivial; parse here and early exit, otherwise go into the // full DbgVariableRecord processing stage. @@ -7173,7 +7174,8 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { LocType ValueType = StringSwitch(Lex.getStrVal()) .Case("declare", LocType::Declare) .Case("value", LocType::Value) - .Case("assign", LocType::Assign); + .Case("assign", LocType::Assign) + .Case("declare_value", LocType::DeclareValue); Lex.Lex(); if (parseToken(lltok::lparen, "Expected '(' here")) diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp index fe9e0ddca7091..911ec7501eb8b 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp @@ -272,6 +272,7 @@ GetCodeName(unsigned CodeID, unsigned BlockID, STRINGIFY_CODE(FUNC_CODE, INST_CALLBR) STRINGIFY_CODE(FUNC_CODE, BLOCKADDR_USERS) STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_DECLARE) + STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_DECLARE_VALUE) STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_VALUE) STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_ASSIGN) STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_VALUE_SIMPLE) diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 466dcb02696f4..5a2bc86d80a55 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -6653,6 +6653,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE: case bitc::FUNC_CODE_DEBUG_RECORD_VALUE: case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE: + case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE_VALUE: case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: { // DbgVariableRecords are placed after the Instructions that they are // attached to. @@ -6669,6 +6670,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // ..., Value // dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE) // ..., LocationMetadata + // dbg_declare_value (FUNC_CODE_DEBUG_RECORD_DECLARE_VALUE) + // ..., LocationMetadata // dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN) // ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata unsigned Slot = 0; @@ -6710,6 +6713,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) { DVR = new DbgVariableRecord(RawLocation, Var, Expr, DIL, DbgVariableRecord::LocationType::Declare); break; + case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE_VALUE: + DVR = new DbgVariableRecord( + RawLocation, Var, Expr, DIL, + DbgVariableRecord::LocationType::DeclareValue); + break; case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: { DIAssignID *ID = cast(getFnMetadataByID(Record[Slot++])); DIExpression *AddrExpr = diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 61aa7c2f5af53..c71fd7ad11dde 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3841,6 +3841,9 @@ void ModuleBitcodeWriter::writeFunction( } else if (DVR.isDbgDeclare()) { Vals.push_back(VE.getMetadataID(DVR.getRawLocation())); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_DECLARE, Vals); + } else if (DVR.isDbgDeclareValue()) { + Vals.push_back(VE.getMetadataID(DVR.getRawLocation())); + Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_DECLARE_VALUE, Vals); } else { assert(DVR.isDbgAssign() && "Unexpected DbgRecord kind"); Vals.push_back(VE.getMetadataID(DVR.getRawLocation())); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 488b078ab6caf..eb89b663da084 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -4841,6 +4841,9 @@ void AssemblyWriter::printDbgVariableRecord(const DbgVariableRecord &DVR) { case DbgVariableRecord::LocationType::Declare: Out << "declare"; break; + case DbgVariableRecord::LocationType::DeclareValue: + Out << "declare_value"; + break; case DbgVariableRecord::LocationType::Assign: Out << "assign"; break; diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index b838e36c8824f..513baeee13443 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -4623,6 +4623,11 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) { DbgVariableRecord::LocationType::Declare, unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, 1), unwrapMAVOp(CI, 2), nullptr, nullptr, nullptr, getDebugLocSafe(CI)); + } else if (Name == "declare_value") { + DR = DbgVariableRecord::createUnresolvedDbgVariableRecord( + DbgVariableRecord::LocationType::DeclareValue, + unwrapMAVMetadataOp(CI, 0), unwrapMAVOp(CI, 1), unwrapMAVOp(CI, 2), + nullptr, nullptr, nullptr, getDebugLocSafe(CI)); } else if (Name == "addr") { // Upgrade dbg.addr to dbg.value with DW_OP_deref. MDNode *ExprNode = unwrapMAVOp(CI, 2); diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 07a870f0630a5..fdce3aaf35342 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -1145,6 +1145,24 @@ DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo, return DVR; } +DbgInstPtr DIBuilder::insertDeclareValue(Value *Storage, + DILocalVariable *VarInfo, + DIExpression *Expr, + const DILocation *DL, + InsertPosition InsertPt) { + assert(VarInfo && + "empty or invalid DILocalVariable* passed to dbg.declare_value"); + assert(DL && "Expected debug loc"); + assert(DL->getScope()->getSubprogram() == + VarInfo->getScope()->getSubprogram() && + "Expected matching subprograms"); + + DbgVariableRecord *DVR = + DbgVariableRecord::createDVRDeclareValue(Storage, VarInfo, Expr, DL); + insertDbgVariableRecord(DVR, InsertPt); + return DVR; +} + void DIBuilder::insertDbgVariableRecord(DbgVariableRecord *DVR, InsertPosition InsertPt) { assert(InsertPt.isValid()); diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 58836068a4929..abf18be60a9bb 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -63,6 +63,23 @@ TinyPtrVector llvm::findDVRDeclares(Value *V) { return Declares; } +TinyPtrVector llvm::findDVRDeclareValues(Value *V) { + // This function is hot. Check whether the value has any metadata to avoid a + // DenseMap lookup. This check is a bitfield datamember lookup. + if (!V->isUsedByMetadata()) + return {}; + auto *L = ValueAsMetadata::getIfExists(V); + if (!L) + return {}; + + TinyPtrVector Coros; + for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) + if (DVR->getType() == DbgVariableRecord::LocationType::DeclareValue) + Coros.push_back(DVR); + + return Coros; +} + TinyPtrVector llvm::findDVRValues(Value *V) { // This function is hot. Check whether the value has any metadata to avoid a // DenseMap lookup. This check is a bitfield datamember lookup. diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index 2b9b0f958a171..0ab526b263911 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -41,6 +41,9 @@ DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI) case Intrinsic::dbg_declare: Type = LocationType::Declare; break; + case Intrinsic::dbg_declare_value: + Type = LocationType::DeclareValue; + break; case Intrinsic::dbg_assign: { Type = LocationType::Assign; const DbgAssignIntrinsic *Assign = @@ -209,6 +212,22 @@ DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV, return NewDVRDeclare; } +DbgVariableRecord * +DbgVariableRecord::createDVRDeclareValue(Value *Address, DILocalVariable *DV, + DIExpression *Expr, + const DILocation *DI) { + return new DbgVariableRecord(ValueAsMetadata::get(Address), DV, Expr, DI, + LocationType::DeclareValue); +} + +DbgVariableRecord *DbgVariableRecord::createDVRDeclareValue( + Value *Address, DILocalVariable *DV, DIExpression *Expr, + const DILocation *DI, DbgVariableRecord &InsertBefore) { + auto *NewDVRCoro = createDVRDeclareValue(Address, DV, Expr, DI); + NewDVRCoro->insertBefore(&InsertBefore); + return NewDVRCoro; +} + DbgVariableRecord *DbgVariableRecord::createDVRAssign( Value *Val, DILocalVariable *Variable, DIExpression *Expression, DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression, @@ -416,6 +435,10 @@ DbgVariableRecord::createDebugIntrinsic(Module *M, case DbgVariableRecord::LocationType::Declare: IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_declare); break; + case DbgVariableRecord::LocationType::DeclareValue: + IntrinsicFn = + Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_declare_value); + break; case DbgVariableRecord::LocationType::Value: IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_value); break; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 7917712846990..604e7613f0532 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -192,6 +192,9 @@ struct VerifierSupport { case DbgVariableRecord::LocationType::Declare: *OS << "declare"; break; + case DbgVariableRecord::LocationType::DeclareValue: + *OS << "declare_value"; + break; case DbgVariableRecord::LocationType::Assign: *OS << "assign"; break; @@ -7024,6 +7027,7 @@ void Verifier::visit(DbgVariableRecord &DVR) { CheckDI(DVR.getType() == DbgVariableRecord::LocationType::Value || DVR.getType() == DbgVariableRecord::LocationType::Declare || + DVR.getType() == DbgVariableRecord::LocationType::DeclareValue || DVR.getType() == DbgVariableRecord::LocationType::Assign, "invalid #dbg record type", &DVR, DVR.getType(), BB, F); diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index c89af688a69ca..b07fa644baa10 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -554,6 +554,7 @@ static void cacheDIVar(FrameDataInfo &FrameData, DIVarCache.insert({V, (*I)->getVariable()}); }; CacheIt(findDVRDeclares(V)); + CacheIt(findDVRDeclareValues(V)); } } @@ -1142,6 +1143,47 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { for_each(DVRs, SalvageOne); } + TinyPtrVector DVRDeclareValues = + findDVRDeclareValues(Def); + // Try best to find dbg.declare_value. If the spill is a temp, there may + // not be a direct dbg.declare_value. Walk up the load chain to find one + // from an alias. + if (F->getSubprogram()) { + auto *CurDef = Def; + while (DVRDeclareValues.empty() && isa(CurDef)) { + auto *LdInst = cast(CurDef); + // Only consider ptr to ptr same type load. + if (LdInst->getPointerOperandType() != LdInst->getType()) + break; + CurDef = LdInst->getPointerOperand(); + if (!isa(CurDef)) + break; + DVRDeclareValues = findDVRDeclareValues(CurDef); + } + } + + auto SalvageOneCoro = [&](auto *DDI) { + // This dbg.declare_value is preserved for all coro-split function + // fragments. It will be unreachable in the main function, and + // processed by coro::salvageDebugInfo() by the Cloner. However, convert + // it to a dbg.declare to make sure future passes don't have to deal + // with a dbg.declare_value. + auto *VAM = ValueAsMetadata::get(CurrentReload); + Type *Ty = VAM->getValue()->getType(); + // If the metadata type is not a pointer, emit a dbg.value instead. + DbgVariableRecord *NewDVR = new DbgVariableRecord( + ValueAsMetadata::get(CurrentReload), DDI->getVariable(), + DDI->getExpression(), DDI->getDebugLoc(), + Ty->isPointerTy() ? DbgVariableRecord::LocationType::Declare + : DbgVariableRecord::LocationType::Value); + Builder.GetInsertPoint()->getParent()->insertDbgRecordBefore( + NewDVR, Builder.GetInsertPoint()); + // This dbg.declare_value is for the main function entry point. It + // will be deleted in all coro-split functions. + coro::salvageDebugInfo(ArgToAllocaMap, *DDI, false /*UseEntryValue*/); + }; + for_each(DVRDeclareValues, SalvageOneCoro); + // If we have a single edge PHINode, remove it and replace it with a // reload from the coroutine frame. (We already took care of multi edge // PHINodes by normalizing them in the rewritePHIs function). @@ -1925,7 +1967,7 @@ void coro::salvageDebugInfo( Function *F = DVR.getFunction(); // Follow the pointer arithmetic all the way to the incoming // function argument and convert into a DIExpression. - bool SkipOutermostLoad = DVR.isDbgDeclare(); + bool SkipOutermostLoad = DVR.isDbgDeclare() || DVR.isDbgDeclareValue(); Value *OriginalStorage = DVR.getVariableLocationOp(0); auto SalvagedInfo = @@ -1939,10 +1981,11 @@ void coro::salvageDebugInfo( DVR.replaceVariableLocationOp(OriginalStorage, Storage); DVR.setExpression(Expr); - // We only hoist dbg.declare today since it doesn't make sense to hoist - // dbg.value since it does not have the same function wide guarantees that - // dbg.declare does. - if (DVR.getType() == DbgVariableRecord::LocationType::Declare) { + // We only hoist dbg.declare and dbg.declare_value today since it doesn't make + // sense to hoist dbg.value since it does not have the same function wide + // guarantees that dbg.declare does. + if (DVR.getType() == DbgVariableRecord::LocationType::Declare || + DVR.getType() == DbgVariableRecord::LocationType::DeclareValue) { std::optional InsertPt; if (auto *I = dyn_cast(Storage)) { InsertPt = I->getInsertionPointAfterDef(); @@ -1957,6 +2000,19 @@ void coro::salvageDebugInfo( InsertPt = F->getEntryBlock().begin(); if (InsertPt) { DVR.removeFromParent(); + // If there is a dbg.declare_value being reinserted, insert it as a + // dbg.declare instead, so that subsequent passes don't have to deal with + // a dbg.declare_value. + if (DVR.getType() == DbgVariableRecord::LocationType::DeclareValue) { + auto *MD = DVR.getRawLocation(); + if (auto *VAM = dyn_cast(MD)) { + Type *Ty = VAM->getValue()->getType(); + if (Ty->isPointerTy()) + DVR.Type = DbgVariableRecord::LocationType::Declare; + else + DVR.Type = DbgVariableRecord::LocationType::Value; + } + } (*InsertPt)->getParent()->insertDbgRecordBefore(&DVR, *InsertPt); } }