Skip to content

Commit 54eb1a2

Browse files
committed
[IRBuilder] Generalize debug loc handling for arbitrary metadata.
This patch extends IRBuilder to allow adding/preserving arbitrary metadata on created instructions. Instead of using references to specific metadata nodes (like DebugLoc), IRbuilder now keeps a vector of (metadata kind, MDNode *) pairs, which are added to each created instruction. The patch itself is a NFC and only moves the existing debug location handling over to the new system. In a follow-up patch it will be used to preserve !annotation metadata besides !dbg. The current approach requires iterating over MetadataToCopy to avoid adding duplicates, but given that the number of metadata kinds to copy/preserve is going to be very small initially (0, 1 (for !dbg) or 2 (!dbg and !annotation)) that should not matter. Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D93400
1 parent 1e15425 commit 54eb1a2

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
#include "llvm-c/Types.h"
1818
#include "llvm/ADT/ArrayRef.h"
1919
#include "llvm/ADT/None.h"
20+
#include "llvm/ADT/STLExtras.h"
2021
#include "llvm/ADT/StringRef.h"
2122
#include "llvm/ADT/Twine.h"
2223
#include "llvm/IR/BasicBlock.h"
2324
#include "llvm/IR/Constant.h"
2425
#include "llvm/IR/ConstantFolder.h"
2526
#include "llvm/IR/Constants.h"
2627
#include "llvm/IR/DataLayout.h"
28+
#include "llvm/IR/DebugInfoMetadata.h"
2729
#include "llvm/IR/DebugLoc.h"
2830
#include "llvm/IR/DerivedTypes.h"
2931
#include "llvm/IR/Function.h"
@@ -91,7 +93,28 @@ class IRBuilderCallbackInserter : public IRBuilderDefaultInserter {
9193

9294
/// Common base class shared among various IRBuilders.
9395
class IRBuilderBase {
94-
DebugLoc CurDbgLocation;
96+
/// Pairs of (metadata kind, MDNode *) that should be added to all newly
97+
/// created instructions, like !dbg metadata.
98+
SmallVector<std::pair<unsigned, MDNode *>, 2> MetadataToCopy;
99+
100+
/// Add or update the an entry (Kind, MD) to MetadataToCopy, if \p MD is not
101+
/// null. If \p MD is null, remove the entry with \p Kind.
102+
void AddOrRemoveMetadataToCopy(unsigned Kind, MDNode *MD) {
103+
if (!MD) {
104+
erase_if(MetadataToCopy, [Kind](const std::pair<unsigned, MDNode *> &KV) {
105+
return KV.first == Kind;
106+
});
107+
return;
108+
}
109+
110+
for (auto &KV : MetadataToCopy)
111+
if (KV.first == Kind) {
112+
KV.second = MD;
113+
return;
114+
}
115+
116+
MetadataToCopy.emplace_back(Kind, MD);
117+
}
95118

96119
protected:
97120
BasicBlock *BB;
@@ -125,7 +148,7 @@ class IRBuilderBase {
125148
template<typename InstTy>
126149
InstTy *Insert(InstTy *I, const Twine &Name = "") const {
127150
Inserter.InsertHelper(I, Name, BB, InsertPt);
128-
SetInstDebugLocation(I);
151+
AddMetadataToInst(I);
129152
return I;
130153
}
131154

@@ -182,16 +205,42 @@ class IRBuilderBase {
182205
}
183206

184207
/// Set location information used by debugging information.
185-
void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); }
208+
void SetCurrentDebugLocation(DebugLoc L) {
209+
AddOrRemoveMetadataToCopy(LLVMContext::MD_dbg, L.getAsMDNode());
210+
}
211+
212+
/// Collect metadata with IDs \p MetadataKinds from \p Src which should be
213+
/// added to all created instructions. Entries present in MedataDataToCopy but
214+
/// not on \p Src will be dropped from MetadataToCopy.
215+
void CollectMetadataToCopy(Instruction *Src,
216+
ArrayRef<unsigned> MetadataKinds) {
217+
for (unsigned K : MetadataKinds)
218+
AddOrRemoveMetadataToCopy(K, Src->getMetadata(K));
219+
}
186220

187221
/// Get location information used by debugging information.
188-
const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; }
222+
DebugLoc getCurrentDebugLocation() const {
223+
for (auto &KV : MetadataToCopy)
224+
if (KV.first == LLVMContext::MD_dbg)
225+
return {cast<DILocation>(KV.second)};
226+
227+
return {};
228+
}
189229

190230
/// If this builder has a current debug location, set it on the
191231
/// specified instruction.
192232
void SetInstDebugLocation(Instruction *I) const {
193-
if (CurDbgLocation)
194-
I->setDebugLoc(CurDbgLocation);
233+
for (const auto &KV : MetadataToCopy)
234+
if (KV.first == LLVMContext::MD_dbg) {
235+
I->setDebugLoc(DebugLoc(KV.second));
236+
return;
237+
}
238+
}
239+
240+
/// Add all entries in MetadataToCopy to \p I.
241+
void AddMetadataToInst(Instruction *I) const {
242+
for (auto &KV : MetadataToCopy)
243+
I->setMetadata(KV.first, KV.second);
195244
}
196245

197246
/// Get the return type of the current function that we're emitting

llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ namespace llvm {
305305
}
306306

307307
/// Get location information used by debugging information.
308-
const DebugLoc &getCurrentDebugLocation() const {
308+
DebugLoc getCurrentDebugLocation() const {
309309
return Builder.getCurrentDebugLocation();
310310
}
311311

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3550,7 +3550,7 @@ bool InstCombiner::run() {
35503550

35513551
// Now that we have an instruction, try combining it to simplify it.
35523552
Builder.SetInsertPoint(I);
3553-
Builder.SetCurrentDebugLocation(I->getDebugLoc());
3553+
Builder.CollectMetadataToCopy(I, {LLVMContext::MD_dbg});
35543554

35553555
#ifndef NDEBUG
35563556
std::string OrigI;

0 commit comments

Comments
 (0)