summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp33
-rw-r--r--llvm/lib/IR/LLVMContextImpl.cpp4
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h43
-rw-r--r--llvm/lib/IR/Metadata.cpp93
4 files changed, 170 insertions, 3 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index ea7e0aa5266..215332b8256 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1272,6 +1272,39 @@ static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
Out << "}";
}
+namespace {
+struct FieldSeparator {
+ bool Skip;
+ FieldSeparator() : Skip(true) {}
+};
+raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
+ if (FS.Skip) {
+ FS.Skip = false;
+ return OS;
+ }
+ return OS << ", ";
+}
+} // end namespace
+
+static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!MDLocation(";
+ FieldSeparator FS;
+ if (DL->getLine())
+ Out << FS << "line: " << DL->getLine();
+ if (DL->getColumn())
+ Out << FS << "column: " << DL->getColumn();
+ Out << FS << "scope: ";
+ WriteAsOperandInternal(Out, DL->getScope(), TypePrinter, Machine, Context);
+ if (DL->getInlinedAt()) {
+ Out << FS << "inlinedAt: ";
+ WriteAsOperandInternal(Out, DL->getInlinedAt(), TypePrinter, Machine,
+ Context);
+ }
+ Out << ")";
+}
+
static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
TypePrinting *TypePrinter,
SlotTracker *Machine,
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index d47a0d332fb..1fa080b8133 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -140,11 +140,15 @@ LLVMContextImpl::~LLVMContextImpl() {
I->dropAllReferences();
for (auto *I : MDTuples)
I->dropAllReferences();
+ for (auto *I : MDLocations)
+ I->dropAllReferences();
for (UniquableMDNode *I : DistinctMDNodes)
I->deleteAsSubclass();
for (MDTuple *I : MDTuples)
delete I;
+ for (MDLocation *I : MDLocations)
+ delete I;
// Destroy MDStrings.
MDStringCache.clear();
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 11b8d38f9af..6ebc567f808 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -215,6 +215,48 @@ struct MDTupleInfo {
}
};
+/// \brief DenseMapInfo for MDLocation.
+struct MDLocationInfo {
+ struct KeyTy {
+ unsigned Line;
+ unsigned Column;
+ Metadata *Scope;
+ Metadata *InlinedAt;
+
+ KeyTy(unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt)
+ : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt) {}
+
+ KeyTy(const MDLocation *L)
+ : Line(L->getLine()), Column(L->getColumn()), Scope(L->getScope()),
+ InlinedAt(L->getInlinedAt()) {}
+
+ bool operator==(const MDLocation *RHS) const {
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey())
+ return false;
+ return Line == RHS->getLine() && Column == RHS->getColumn() &&
+ Scope == RHS->getScope() && InlinedAt == RHS->getInlinedAt();
+ }
+ };
+ static inline MDLocation *getEmptyKey() {
+ return DenseMapInfo<MDLocation *>::getEmptyKey();
+ }
+ static inline MDLocation *getTombstoneKey() {
+ return DenseMapInfo<MDLocation *>::getTombstoneKey();
+ }
+ static unsigned getHashValue(const KeyTy &Key) {
+ return hash_combine(Key.Line, Key.Column, Key.Scope, Key.InlinedAt);
+ }
+ static unsigned getHashValue(const MDLocation *U) {
+ return getHashValue(KeyTy(U));
+ }
+ static bool isEqual(const KeyTy &LHS, const MDLocation *RHS) {
+ return LHS == RHS;
+ }
+ static bool isEqual(const MDLocation *LHS, const MDLocation *RHS) {
+ return LHS == RHS;
+ }
+};
+
class LLVMContextImpl {
public:
/// OwnedModules - The set of modules instantiated in this context, and which
@@ -246,6 +288,7 @@ public:
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
DenseSet<MDTuple *, MDTupleInfo> MDTuples;
+ DenseSet<MDLocation *, MDLocationInfo> MDLocations;
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they
// aren't in the MDNodeSet, but they're still shared between objects, so no
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 852f1dc2041..ab83252bfda 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -640,6 +640,93 @@ MDTuple *MDTuple::uniquifyImpl() {
void MDTuple::eraseFromStoreImpl() { getContext().pImpl->MDTuples.erase(this); }
+MDLocation::MDLocation(LLVMContext &C, unsigned Line, unsigned Column,
+ ArrayRef<Metadata *> MDs, bool AllowRAUW)
+ : UniquableMDNode(C, MDLocationKind, MDs, AllowRAUW) {
+ assert((MDs.size() == 1 || MDs.size() == 2) &&
+ "Expected a scope and optional inlined-at");
+
+ // Set line and column.
+ assert(Line < (1u << 24) && "Expected 24-bit line");
+ assert(Column < (1u << 8) && "Expected 8-bit column");
+
+ MDNodeSubclassData = Line;
+ SubclassData16 = Column;
+}
+
+MDLocation *MDLocation::constructHelper(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt, bool AllowRAUW) {
+ SmallVector<Metadata *, 2> Ops;
+ Ops.push_back(Scope);
+ if (InlinedAt)
+ Ops.push_back(InlinedAt);
+ return new (Ops.size()) MDLocation(Context, Line, Column, Ops, AllowRAUW);
+}
+
+static void adjustLine(unsigned &Line) {
+ // Set to unknown on overflow. Still use 24 bits for now.
+ if (Line >= (1u << 24))
+ Line = 0;
+}
+
+static void adjustColumn(unsigned &Column) {
+ // Set to unknown on overflow. Still use 8 bits for now.
+ if (Column >= (1u << 8))
+ Column = 0;
+}
+
+MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt, bool ShouldCreate) {
+ // Fixup line/column.
+ adjustLine(Line);
+ adjustColumn(Column);
+
+ MDLocationInfo::KeyTy Key(Line, Column, Scope, InlinedAt);
+
+ auto &Store = Context.pImpl->MDLocations;
+ auto I = Store.find_as(Key);
+ if (I != Store.end())
+ return *I;
+ if (!ShouldCreate)
+ return nullptr;
+
+ auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
+ /* AllowRAUW */ true);
+ Store.insert(N);
+ return N;
+}
+
+MDLocation *MDLocation::getDistinct(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt) {
+ // Fixup line/column.
+ adjustLine(Line);
+ adjustColumn(Column);
+
+ auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
+ /* AllowRAUW */ false);
+ N->storeDistinctInContext();
+ return N;
+}
+
+MDLocation *MDLocation::uniquifyImpl() {
+ MDLocationInfo::KeyTy Key(this);
+
+ auto &Store = getContext().pImpl->MDLocations;
+ auto I = Store.find_as(Key);
+ if (I == Store.end()) {
+ Store.insert(this);
+ return this;
+ }
+ return *I;
+}
+
+void MDLocation::eraseFromStoreImpl() {
+ getContext().pImpl->MDLocations.erase(this);
+}
+
MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context,
ArrayRef<Metadata *> MDs) {
return MDNodeFwdDecl::get(Context, MDs);
@@ -650,9 +737,9 @@ void MDNode::deleteTemporary(MDNode *N) { delete cast<MDNodeFwdDecl>(N); }
void UniquableMDNode::storeDistinctInContext() {
assert(!IsDistinctInContext && "Expected newly distinct metadata");
IsDistinctInContext = true;
- auto *T = cast<MDTuple>(this);
- T->setHash(0);
- getContext().pImpl->DistinctMDNodes.insert(T);
+ if (auto *T = dyn_cast<MDTuple>(this))
+ T->setHash(0);
+ getContext().pImpl->DistinctMDNodes.insert(this);
}
void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
OpenPOWER on IntegriCloud