Index: llvm/include/llvm/IR/DebugInfo.h =================================================================== --- llvm/include/llvm/IR/DebugInfo.h +++ llvm/include/llvm/IR/DebugInfo.h @@ -16,6 +16,7 @@ #ifndef LLVM_IR_DEBUGINFO_H #define LLVM_IR_DEBUGINFO_H +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" @@ -25,6 +26,7 @@ class DbgDeclareInst; class DbgValueInst; +class Instruction; class Module; /// Find subprogram that is enclosing this scope. @@ -50,6 +52,13 @@ /// All debug type metadata nodes are unreachable and garbage collected. bool stripNonLineTableDebugInfo(Module &M); +/// Update the debug locations contained within the MD_loop metadata attached +/// to the instruction \p I, if one exists. \p Updater is applied to each debug +/// location in the MD_loop metadata: the returned value is included in the +/// updated loop metadata node if it is non-null. +void updateLoopMetadataDebugLocations( + Instruction &I, function_ref Updater); + /// Return Debug Info Metadata Version by checking module flags. unsigned getDebugMetadataVersionFromModule(const Module &M); Index: llvm/lib/IR/DebugInfo.cpp =================================================================== --- llvm/lib/IR/DebugInfo.cpp +++ llvm/lib/IR/DebugInfo.cpp @@ -278,6 +278,41 @@ return true; } +static MDNode *updateLoopMetadataDebugLocationsImpl( + MDNode *OrigLoopID, + function_ref Updater) { + assert(OrigLoopID && OrigLoopID->getNumOperands() > 0 && + "Loop ID needs at least one operand"); + assert(OrigLoopID && OrigLoopID->getOperand(0).get() == OrigLoopID && + "Loop ID should refer to itself"); + + // Save space for the self-referential LoopID. + SmallVector MDs = {nullptr}; + + for (unsigned i = 1; i < OrigLoopID->getNumOperands(); ++i) { + Metadata *MD = OrigLoopID->getOperand(i); + if (DILocation *DL = dyn_cast(MD)) { + if (DILocation *NewDL = Updater(*DL)) + MDs.push_back(NewDL); + } else + MDs.push_back(MD); + } + + MDNode *NewLoopID = MDNode::getDistinct(OrigLoopID->getContext(), MDs); + // Insert the self-referential LoopID. + NewLoopID->replaceOperandWith(0, NewLoopID); + return NewLoopID; +} + +void llvm::updateLoopMetadataDebugLocations( + Instruction &I, function_ref Updater) { + MDNode *OrigLoopID = I.getMetadata(LLVMContext::MD_loop); + if (!OrigLoopID) + return; + MDNode *NewLoopID = updateLoopMetadataDebugLocationsImpl(OrigLoopID, Updater); + I.setMetadata(LLVMContext::MD_loop, NewLoopID); +} + static MDNode *stripDebugLocFromLoopID(MDNode *N) { assert(!N->operands().empty() && "Missing self reference?"); @@ -294,20 +329,10 @@ })) return nullptr; - SmallVector Args; - // Reserve operand 0 for loop id self reference. - auto TempNode = MDNode::getTemporary(N->getContext(), None); - Args.push_back(TempNode.get()); - // Add all non-debug location operands back. - for (auto Op = N->op_begin() + 1; Op != N->op_end(); Op++) { - if (!isa(*Op)) - Args.push_back(*Op); - } - - // Set the first operand to itself. - MDNode *LoopID = MDNode::get(N->getContext(), Args); - LoopID->replaceOperandWith(0, LoopID); - return LoopID; + auto dropDebugLoc = [](const DILocation &) -> DILocation * { + return nullptr; + }; + return updateLoopMetadataDebugLocationsImpl(N, dropDebugLoc); } bool llvm::stripDebugInfo(Function &F) { Index: llvm/lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- llvm/lib/Transforms/Utils/InlineFunction.cpp +++ llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1356,34 +1356,6 @@ IA); } -/// Returns the LoopID for a loop which has has been cloned from another -/// function for inlining with the new inlined-at start and end locs. -static MDNode *inlineLoopID(const MDNode *OrigLoopId, DILocation *InlinedAt, - LLVMContext &Ctx, - DenseMap &IANodes) { - assert(OrigLoopId && OrigLoopId->getNumOperands() > 0 && - "Loop ID needs at least one operand"); - assert(OrigLoopId && OrigLoopId->getOperand(0).get() == OrigLoopId && - "Loop ID should refer to itself"); - - // Save space for the self-referential LoopID. - SmallVector MDs = {nullptr}; - - for (unsigned i = 1; i < OrigLoopId->getNumOperands(); ++i) { - Metadata *MD = OrigLoopId->getOperand(i); - // Update the DILocations to encode the inlined-at metadata. - if (DILocation *DL = dyn_cast(MD)) - MDs.push_back(inlineDebugLoc(DL, InlinedAt, Ctx, IANodes)); - else - MDs.push_back(MD); - } - - MDNode *NewLoopID = MDNode::getDistinct(Ctx, MDs); - // Insert the self-referential LoopID. - NewLoopID->replaceOperandWith(0, NewLoopID); - return NewLoopID; -} - /// Update inlined instructions' line numbers to /// to encode location where these instructions are inlined. static void fixupLineNumbers(Function *Fn, Function::iterator FI, @@ -1415,11 +1387,11 @@ BI != BE; ++BI) { // Loop metadata needs to be updated so that the start and end locs // reference inlined-at locations. - if (MDNode *LoopID = BI->getMetadata(LLVMContext::MD_loop)) { - MDNode *NewLoopID = - inlineLoopID(LoopID, InlinedAtNode, BI->getContext(), IANodes); - BI->setMetadata(LLVMContext::MD_loop, NewLoopID); - } + auto updateLoopInfoLoc = [&Ctx, &InlinedAtNode, &IANodes]( + const DILocation &Loc) -> DILocation * { + return inlineDebugLoc(&Loc, InlinedAtNode, Ctx, IANodes).get(); + }; + updateLoopMetadataDebugLocations(*BI, updateLoopInfoLoc); if (!NoInlineLineTables) if (DebugLoc DL = BI->getDebugLoc()) {