diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -3576,13 +3576,11 @@ void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc); /** - * Attempts to set the debug location for the given instruction using the - * current debug location for the given builder. If the builder has no current - * debug location, this function is a no-op. + * Adds all metadata entries registered in the builder to \p Inst * - * @see llvm::IRBuilder::SetInstDebugLocation() + * @see llvm::IRBuilder::AddInstMetadata() */ -void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst); +void LLVMAddInstMetadata(LLVMBuilderRef Builder, LLVMValueRef Inst); /** * Get the dafult floating-point math metadata for a given builder. 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); + AddInstMetadata(I); return I; } @@ -182,16 +205,32 @@ } /// 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); + /// Add all entries in MetadataToCopy to \p I. + void AddInstMetadata(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/IR/Core.cpp b/llvm/lib/IR/Core.cpp --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -3091,8 +3091,8 @@ Context, unwrap(Builder)->getCurrentDebugLocation().getAsMDNode())); } -void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) { - unwrap(Builder)->SetInstDebugLocation(unwrap(Inst)); +void LLVMAddInstMetadata(LLVMBuilderRef Builder, LLVMValueRef Inst) { + unwrap(Builder)->AddInstMetadata(unwrap(Inst)); } void LLVMBuilderSetDefaultFPMathTag(LLVMBuilderRef Builder, 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; diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -850,7 +850,7 @@ LLVMSetMetadata(Dst, Kind, LLVMMetadataAsValue(Ctx, MD)); } LLVMDisposeValueMetadataEntries(AllMetadata); - LLVMSetInstDebugLocation(Builder, Dst); + LLVMAddInstMetadata(Builder, Dst); check_value_kind(Dst, LLVMInstructionValueKind); return VMap[Src] = Dst;