diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -17,6 +17,7 @@ #include "llvm-c/Types.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/BasicBlock.h" @@ -24,6 +25,7 @@ #include "llvm/IR/ConstantFolder.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" @@ -91,7 +93,28 @@ /// Common base class shared among various IRBuilders. class IRBuilderBase { - DebugLoc CurDbgLocation; + /// Pairs of (metadata kind, MDNode *) that should be added to all newly + /// created instructions, like !dbg metadata. + SmallVector, 2> MetadataToCopy; + + /// Add or update the an entry (Kind, MD) to MetadataToCopy, if \p MD is not + /// null. If \p MD is null, remove the entry with \p Kind. + void AddOrRemoveMetadataToCopy(unsigned Kind, MDNode *MD) { + if (!MD) { + erase_if(MetadataToCopy, [Kind](const std::pair &KV) { + return KV.first == Kind; + }); + return; + } + + for (auto &KV : MetadataToCopy) + if (KV.first == Kind) { + KV.second = MD; + return; + } + + MetadataToCopy.emplace_back(Kind, MD); + } protected: BasicBlock *BB; @@ -125,7 +148,7 @@ template InstTy *Insert(InstTy *I, const Twine &Name = "") const { Inserter.InsertHelper(I, Name, BB, InsertPt); - SetInstDebugLocation(I); + AddMetadataToInst(I); return I; } @@ -182,16 +205,42 @@ } /// Set location information used by debugging information. - void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); } + void SetCurrentDebugLocation(DebugLoc L) { + AddOrRemoveMetadataToCopy(LLVMContext::MD_dbg, L.getAsMDNode()); + } + + /// Collect metadata with IDs \p MetadataKinds from \p Src which should be + /// added to all created instructions. Entries present in MedataDataToCopy but + /// not on \p Src will be dropped from MetadataToCopy. + void CollectMetadataToCopy(Instruction *Src, + ArrayRef MetadataKinds) { + for (unsigned K : MetadataKinds) + AddOrRemoveMetadataToCopy(K, Src->getMetadata(K)); + } /// Get location information used by debugging information. - const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } + DebugLoc getCurrentDebugLocation() const { + for (auto &KV : MetadataToCopy) + if (KV.first == LLVMContext::MD_dbg) + return {cast(KV.second)}; + + return {}; + } /// If this builder has a current debug location, set it on the /// specified instruction. void SetInstDebugLocation(Instruction *I) const { - if (CurDbgLocation) - I->setDebugLoc(CurDbgLocation); + for (const auto &KV : MetadataToCopy) + if (KV.first == LLVMContext::MD_dbg) { + I->setDebugLoc(DebugLoc(KV.second)); + return; + } + } + + /// Add all entries in MetadataToCopy to \p I. + void AddMetadataToInst(Instruction *I) const { + for (auto &KV : MetadataToCopy) + I->setMetadata(KV.first, KV.second); } /// Get the return type of the current function that we're emitting diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h --- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h +++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h @@ -352,7 +352,7 @@ } /// Get location information used by debugging information. - const DebugLoc &getCurrentDebugLocation() const { + DebugLoc getCurrentDebugLocation() const { return Builder.getCurrentDebugLocation(); } diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3678,7 +3678,7 @@ // Now that we have an instruction, try combining it to simplify it. Builder.SetInsertPoint(I); - Builder.SetCurrentDebugLocation(I->getDebugLoc()); + Builder.CollectMetadataToCopy(I, {LLVMContext::MD_dbg}); #ifndef NDEBUG std::string OrigI;