[llvm] r225824 - IR: Add MDLocation class
Duncan P. N. Exon Smith
dexonsmith at apple.com
Tue Jan 13 12:44:56 PST 2015
Author: dexonsmith
Date: Tue Jan 13 14:44:56 2015
New Revision: 225824
URL: http://llvm.org/viewvc/llvm-project?rev=225824&view=rev
Log:
IR: Add MDLocation class
Add a new subclass of `UniquableMDNode`, `MDLocation`. This will be the
IR version of `DebugLoc` and `DILocation`. The goal is to rename this
to `DILocation` once the IR classes supersede the `DI`-prefixed
wrappers.
This isn't used anywhere yet. Part of PR21433.
Modified:
llvm/trunk/include/llvm/IR/Metadata.def
llvm/trunk/include/llvm/IR/Metadata.h
llvm/trunk/lib/IR/AsmWriter.cpp
llvm/trunk/lib/IR/LLVMContextImpl.cpp
llvm/trunk/lib/IR/LLVMContextImpl.h
llvm/trunk/lib/IR/Metadata.cpp
llvm/trunk/unittests/IR/MetadataTest.cpp
Modified: llvm/trunk/include/llvm/IR/Metadata.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.def?rev=225824&r1=225823&r2=225824&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.def (original)
+++ llvm/trunk/include/llvm/IR/Metadata.def Tue Jan 13 14:44:56 2015
@@ -50,6 +50,7 @@ HANDLE_METADATA_BRANCH(MDNode)
HANDLE_METADATA_LEAF(MDNodeFwdDecl)
HANDLE_UNIQUABLE_BRANCH(UniquableMDNode)
HANDLE_UNIQUABLE_LEAF(MDTuple)
+HANDLE_UNIQUABLE_LEAF(MDLocation)
#undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF
Modified: llvm/trunk/include/llvm/IR/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=225824&r1=225823&r2=225824&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.h (original)
+++ llvm/trunk/include/llvm/IR/Metadata.h Tue Jan 13 14:44:56 2015
@@ -57,6 +57,7 @@ protected:
public:
enum MetadataKind {
MDTupleKind,
+ MDLocationKind,
MDNodeFwdDeclKind,
ConstantAsMetadataKind,
LocalAsMetadataKind,
@@ -670,6 +671,7 @@ public:
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind ||
+ MD->getMetadataID() == MDLocationKind ||
MD->getMetadataID() == MDNodeFwdDeclKind;
}
@@ -726,7 +728,8 @@ protected:
public:
static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDTupleKind;
+ return MD->getMetadataID() == MDTupleKind ||
+ MD->getMetadataID() == MDLocationKind;
}
/// \brief Check whether any operands are forward declarations.
@@ -812,6 +815,60 @@ MDNode *MDNode::getDistinct(LLVMContext
return MDTuple::getDistinct(Context, MDs);
}
+/// \brief Debug location.
+///
+/// A debug location in source code, used for debug info and otherwise.
+class MDLocation : public UniquableMDNode {
+ friend class LLVMContextImpl;
+ friend class UniquableMDNode;
+
+ MDLocation(LLVMContext &C, unsigned Line, unsigned Column,
+ ArrayRef<Metadata *> MDs, bool AllowRAUW);
+ ~MDLocation() { dropAllReferences(); }
+
+ static MDLocation *constructHelper(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt, bool AllowRAUW);
+
+ static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt, bool ShouldCreate);
+
+ // Disallow replacing operands.
+ void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
+
+public:
+ static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column,
+ Metadata *Scope, Metadata *InlinedAt = nullptr) {
+ return getImpl(Context, Line, Column, Scope, InlinedAt,
+ /* ShouldCreate */ true);
+ }
+ static MDLocation *getIfExists(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt = nullptr) {
+ return getImpl(Context, Line, Column, Scope, InlinedAt,
+ /* ShouldCreate */ false);
+ }
+ static MDLocation *getDistinct(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt = nullptr);
+
+ unsigned getLine() const { return MDNodeSubclassData; }
+ unsigned getColumn() const { return SubclassData16; }
+ Metadata *getScope() const { return getOperand(0); }
+ Metadata *getInlinedAt() const {
+ return getNumOperands() == 2 ? getOperand(1) : nullptr;
+ }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDLocationKind;
+ }
+
+private:
+ MDLocation *uniquifyImpl();
+ void eraseFromStoreImpl();
+};
+
/// \brief Forward declaration of metadata.
///
/// Forward declaration of metadata, in the form of a basic tuple. Unlike \a
Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=225824&r1=225823&r2=225824&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue Jan 13 14:44:56 2015
@@ -1272,6 +1272,39 @@ static void writeMDTuple(raw_ostream &Ou
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,
Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=225824&r1=225823&r2=225824&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Tue Jan 13 14:44:56 2015
@@ -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();
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=225824&r1=225823&r2=225824&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Tue Jan 13 14:44:56 2015
@@ -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
Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=225824&r1=225823&r2=225824&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Tue Jan 13 14:44:56 2015
@@ -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)
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) {
Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=225824&r1=225823&r2=225824&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
+++ llvm/trunk/unittests/IR/MetadataTest.cpp Tue Jan 13 14:44:56 2015
@@ -387,6 +387,43 @@ TEST_F(MDNodeTest, replaceResolvedOperan
Temp->replaceAllUsesWith(nullptr);
}
+typedef MetadataTest MDLocationTest;
+
+TEST_F(MDLocationTest, Overflow) {
+ MDNode *N = MDNode::get(Context, None);
+ {
+ MDLocation *L = MDLocation::get(Context, 2, 7, N);
+ EXPECT_EQ(2u, L->getLine());
+ EXPECT_EQ(7u, L->getColumn());
+ }
+ unsigned U24 = 1u << 24;
+ unsigned U8 = 1u << 8;
+ {
+ MDLocation *L = MDLocation::get(Context, U24 - 1, U8 - 1, N);
+ EXPECT_EQ(U24 - 1, L->getLine());
+ EXPECT_EQ(U8 - 1, L->getColumn());
+ }
+ {
+ MDLocation *L = MDLocation::get(Context, U24, U8, N);
+ EXPECT_EQ(0u, L->getLine());
+ EXPECT_EQ(0u, L->getColumn());
+ }
+ {
+ MDLocation *L = MDLocation::get(Context, U24 + 1, U8 + 1, N);
+ EXPECT_EQ(0u, L->getLine());
+ EXPECT_EQ(0u, L->getColumn());
+ }
+}
+
+TEST_F(MDLocationTest, getDistinct) {
+ MDNode *N = MDNode::get(Context, None);
+ MDLocation *L0 = MDLocation::getDistinct(Context, 2, 7, N);
+ EXPECT_TRUE(L0->isDistinct());
+ MDLocation *L1 = MDLocation::get(Context, 2, 7, N);
+ EXPECT_FALSE(L1->isDistinct());
+ EXPECT_EQ(L1, MDLocation::get(Context, 2, 7, N));
+}
+
typedef MetadataTest MetadataAsValueTest;
TEST_F(MetadataAsValueTest, MDNode) {
More information about the llvm-commits
mailing list