[llvm-commits] [llvm] r99957 - in /llvm/trunk: include/llvm/Instruction.h include/llvm/LLVMContext.h include/llvm/Support/ValueHandle.h lib/VMCore/Instruction.cpp lib/VMCore/LLVMContext.cpp lib/VMCore/Metadata.cpp

Chris Lattner sabre at nondot.org
Tue Mar 30 16:03:27 PDT 2010


Author: lattner
Date: Tue Mar 30 18:03:27 2010
New Revision: 99957

URL: http://llvm.org/viewvc/llvm-project?rev=99957&view=rev
Log:
Fix a major source of compile-time slowness at -O0 -g by optimizing
the storage of !dbg metadata kinds in the instruction themselves.
The on-the-side hash table works great for metadata that not-all
instructions get, or for metadata that only exists when optimizing.
But when compile-time is everything, it isn't great.

I'm not super thrilled with the fact that this plops a TrackingVH in
Instruction, because it grows it by 3 words.  I'm investigating 
alternatives, but this should be a step in the right direction in any
case.

Modified:
    llvm/trunk/include/llvm/Instruction.h
    llvm/trunk/include/llvm/LLVMContext.h
    llvm/trunk/include/llvm/Support/ValueHandle.h
    llvm/trunk/lib/VMCore/Instruction.cpp
    llvm/trunk/lib/VMCore/LLVMContext.cpp
    llvm/trunk/lib/VMCore/Metadata.cpp

Modified: llvm/trunk/include/llvm/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.h?rev=99957&r1=99956&r2=99957&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instruction.h (original)
+++ llvm/trunk/include/llvm/Instruction.h Tue Mar 30 18:03:27 2010
@@ -17,6 +17,7 @@
 
 #include "llvm/User.h"
 #include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
 
@@ -31,6 +32,7 @@
   Instruction(const Instruction &);        // Do not implement
 
   BasicBlock *Parent;
+  TrackingVH<MDNode> DbgInfo;         // 'dbg' Metadata cache.
   
   enum {
     /// HasMetadataBit - This is a bit stored in the SubClassData field which
@@ -123,7 +125,7 @@
   /// hasMetadata() - Return true if this instruction has any metadata attached
   /// to it.
   bool hasMetadata() const {
-    return (getSubclassDataFromValue() & HasMetadataBit) != 0;
+    return DbgInfo != 0 || hasMetadataHashEntry();
   }
   
   /// getMetadata - Get the metadata of given kind attached to this Instruction.
@@ -155,6 +157,12 @@
   void setMetadata(const char *Kind, MDNode *Node);
 
 private:
+  /// hasMetadataHashEntry - Return true if we have an entry in the on-the-side
+  /// metadata hash.
+  bool hasMetadataHashEntry() const {
+    return (getSubclassDataFromValue() & HasMetadataBit) != 0;
+  }
+  
   // These are all implemented in Metadata.cpp.
   MDNode *getMetadataImpl(unsigned KindID) const;
   MDNode *getMetadataImpl(const char *Kind) const;
@@ -315,7 +323,7 @@
     return Value::getSubclassDataFromValue();
   }
   
-  void setHasMetadata(bool V) {
+  void setHasMetadataHashEntry(bool V) {
     setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
                          (V ? HasMetadataBit : 0));
   }

Modified: llvm/trunk/include/llvm/LLVMContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LLVMContext.h?rev=99957&r1=99956&r2=99957&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LLVMContext.h (original)
+++ llvm/trunk/include/llvm/LLVMContext.h Tue Mar 30 18:03:27 2010
@@ -36,6 +36,12 @@
   LLVMContext();
   ~LLVMContext();
   
+  // Pinned metadata names, which always have the same value.  This is a
+  // compile-time performance optimization, not a correctness optimization.
+  enum {
+    MD_dbg = 1   // "dbg" -> 1.
+  };
+  
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
   /// This ID is uniqued across modules in the current LLVMContext.
   unsigned getMDKindID(StringRef Name) const;

Modified: llvm/trunk/include/llvm/Support/ValueHandle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ValueHandle.h?rev=99957&r1=99956&r2=99957&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ValueHandle.h (original)
+++ llvm/trunk/include/llvm/Support/ValueHandle.h Tue Mar 30 18:03:27 2010
@@ -302,7 +302,7 @@
 
   ValueTy *getValPtr() const {
     CheckValidity();
-    return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
+    return (ValueTy*)ValueHandleBase::getValPtr();
   }
   void setValPtr(ValueTy *P) {
     CheckValidity();

Modified: llvm/trunk/lib/VMCore/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=99957&r1=99956&r2=99957&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Instruction.cpp (original)
+++ llvm/trunk/lib/VMCore/Instruction.cpp Tue Mar 30 18:03:27 2010
@@ -22,7 +22,7 @@
 
 Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
                          Instruction *InsertBefore)
-  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) {
+  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0), DbgInfo(0) {
   // Make sure that we get added to a basicblock
   LeakDetector::addGarbageObject(this);
 
@@ -36,7 +36,7 @@
 
 Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
                          BasicBlock *InsertAtEnd)
-  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) {
+  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0), DbgInfo(0) {
   // Make sure that we get added to a basicblock
   LeakDetector::addGarbageObject(this);
 

Modified: llvm/trunk/lib/VMCore/LLVMContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContext.cpp?rev=99957&r1=99956&r2=99957&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/LLVMContext.cpp (original)
+++ llvm/trunk/lib/VMCore/LLVMContext.cpp Tue Mar 30 18:03:27 2010
@@ -26,7 +26,11 @@
   return *GlobalContext;
 }
 
-LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { }
+LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
+  // Create the first metadata kind, which is always 'dbg'.
+  unsigned DbgID = getMDKindID("dbg");
+  assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
+}
 LLVMContext::~LLVMContext() { delete pImpl; }
 
 

Modified: llvm/trunk/lib/VMCore/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Metadata.cpp?rev=99957&r1=99956&r2=99957&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Metadata.cpp (original)
+++ llvm/trunk/lib/VMCore/Metadata.cpp Tue Mar 30 18:03:27 2010
@@ -430,12 +430,19 @@
 void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
   if (Node == 0 && !hasMetadata()) return;
 
+  // Handle 'dbg' as a special case since it is not stored in the hash table.
+  if (KindID == LLVMContext::MD_dbg) {
+    DbgInfo = Node;
+    return;
+  }
+  
   // Handle the case when we're adding/updating metadata on an instruction.
   if (Node) {
     LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
-    assert(!Info.empty() == hasMetadata() && "HasMetadata bit is wonked");
+    assert(!Info.empty() == hasMetadataHashEntry() &&
+           "HasMetadata bit is wonked");
     if (Info.empty()) {
-      setHasMetadata(true);
+      setHasMetadataHashEntry(true);
     } else {
       // Handle replacement of an existing value.
       for (unsigned i = 0, e = Info.size(); i != e; ++i)
@@ -451,18 +458,19 @@
   }
 
   // Otherwise, we're removing metadata from an instruction.
-  assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) &&
+  assert(hasMetadataHashEntry() &&
+         getContext().pImpl->MetadataStore.count(this) &&
          "HasMetadata bit out of date!");
   LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
 
   // Common case is removing the only entry.
   if (Info.size() == 1 && Info[0].first == KindID) {
     getContext().pImpl->MetadataStore.erase(this);
-    setHasMetadata(false);
+    setHasMetadataHashEntry(false);
     return;
   }
 
-  // Handle replacement of an existing value.
+  // Handle removal of an existing value.
   for (unsigned i = 0, e = Info.size(); i != e; ++i)
     if (Info[i].first == KindID) {
       Info[i] = Info.back();
@@ -474,8 +482,14 @@
 }
 
 MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
+  // Handle 'dbg' as a special case since it is not stored in the hash table.
+  if (KindID == LLVMContext::MD_dbg)
+    return DbgInfo;
+  
+  if (!hasMetadataHashEntry()) return 0;
+  
   LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
-  assert(hasMetadata() && !Info.empty() && "Shouldn't have called this");
+  assert(!Info.empty() && "bit out of sync with hash table");
 
   for (LLVMContextImpl::MDMapTy::iterator I = Info.begin(), E = Info.end();
        I != E; ++I)
@@ -485,14 +499,22 @@
 }
 
 void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,
-                                       MDNode*> > &Result)const {
-  assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) &&
+                                       MDNode*> > &Result) const {
+  Result.clear();
+  
+  // Handle 'dbg' as a special case since it is not stored in the hash table.
+  if (DbgInfo) {
+    Result.push_back(std::make_pair((unsigned)LLVMContext::MD_dbg, DbgInfo));
+    if (!hasMetadataHashEntry()) return;
+  }
+  
+  assert(hasMetadataHashEntry() &&
+         getContext().pImpl->MetadataStore.count(this) &&
          "Shouldn't have called this");
   const LLVMContextImpl::MDMapTy &Info =
     getContext().pImpl->MetadataStore.find(this)->second;
   assert(!Info.empty() && "Shouldn't have called this");
 
-  Result.clear();
   Result.append(Info.begin(), Info.end());
 
   // Sort the resulting array so it is stable.
@@ -503,7 +525,10 @@
 /// removeAllMetadata - Remove all metadata from this instruction.
 void Instruction::removeAllMetadata() {
   assert(hasMetadata() && "Caller should check");
-  getContext().pImpl->MetadataStore.erase(this);
-  setHasMetadata(false);
+  DbgInfo = 0;
+  if (hasMetadataHashEntry()) {
+    getContext().pImpl->MetadataStore.erase(this);
+    setHasMetadataHashEntry(false);
+  }
 }
 





More information about the llvm-commits mailing list