[cfe-commits] r124704 - in /cfe/trunk: include/clang/Sema/CodeCompleteConsumer.h lib/Sema/CodeCompleteConsumer.cpp

Douglas Gregor dgregor at apple.com
Tue Feb 1 15:59:42 PST 2011


Author: dgregor
Date: Tue Feb  1 17:59:42 2011
New Revision: 124704

URL: http://llvm.org/viewvc/llvm-project?rev=124704&view=rev
Log:
Unique code-completion strings. On Cocoa.h, this costs us about 4% in
speed but saves us about 25% of the memory usage for strings.

Modified:
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=124704&r1=124703&r2=124704&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Tue Feb  1 17:59:42 2011
@@ -15,7 +15,9 @@
 
 #include "clang/AST/Type.h"
 #include "clang/AST/CanonicalType.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
 #include "clang-c/Index.h"
@@ -421,11 +423,47 @@
   std::string getAsString() const;   
 };
 
+/// \brief \c DenseMap information object for StringRefs.
+struct DenseMapStringRefInfo {
+  static inline llvm::StringRef getEmptyKey() {
+    return llvm::StringRef(reinterpret_cast<const char*>((intptr_t)-1), 0);
+  }
+  static inline llvm::StringRef getTombstoneKey() {
+    return llvm::StringRef(reinterpret_cast<const char *>((intptr_t)-2), 0);
+  }
+  static unsigned getHashValue(llvm::StringRef Str) {
+    return llvm::HashString(Str);
+  }
+  static bool isEqual(llvm::StringRef LHS, llvm::StringRef RHS) { 
+    if (LHS.size() == 0 && RHS.size() == 0) {
+      intptr_t LHSVal = reinterpret_cast<intptr_t>(LHS.data());
+      intptr_t RHSVal = reinterpret_cast<intptr_t>(RHS.data());
+      if (LHSVal == -1 || LHSVal == -2 || RHSVal == -1 || RHSVal == -2)
+        return LHSVal == RHSVal;
+      
+      return true;
+    }
+    
+    return LHS == RHS;
+  }
+};
+
 /// \brief An allocator used specifically for the purpose of code completion.
 class CodeCompletionAllocator : public llvm::BumpPtrAllocator { 
+  llvm::DenseSet<llvm::StringRef, DenseMapStringRefInfo> UniqueStrings;
+  unsigned StringBytesAllocated;
+  unsigned StringBytesUniqued;
+  unsigned StringsAllocated;
+  unsigned StringsUniqued;
+  
 public:
+  CodeCompletionAllocator();
+  ~CodeCompletionAllocator();
+  
   /// \brief Copy the given string into this allocator.
   const char *CopyString(llvm::StringRef String);
+  
+  void PrintStats();
 };
   
 /// \brief A builder class used to construct new code-completion strings.

Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=124704&r1=124703&r2=124704&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Tue Feb  1 17:59:42 2011
@@ -220,10 +220,41 @@
   return 0;
 }
 
+CodeCompletionAllocator::CodeCompletionAllocator()
+  : llvm::BumpPtrAllocator(), StringBytesAllocated(0), StringBytesUniqued(0), 
+    StringsAllocated(0), StringsUniqued(0)
+{
+}
+
+CodeCompletionAllocator::~CodeCompletionAllocator() { }
+
+void CodeCompletionAllocator::PrintStats() {
+  llvm::errs() << "---Code completion memory allocation---\n" 
+    << "String bytes uniqued: " << StringBytesUniqued << "/"
+    << StringBytesAllocated << " (" 
+    << ((float)StringBytesUniqued*100/StringBytesAllocated)
+    << ")\nStrings uniqued: " << StringsUniqued << "/" << StringsAllocated
+    << " (" << ((float)StringsUniqued*100/StringsAllocated)
+  << ")\n";
+  
+  llvm::BumpPtrAllocator::PrintStats();
+}
+
 const char *CodeCompletionAllocator::CopyString(llvm::StringRef String) {
+  llvm::DenseSet<llvm::StringRef, DenseMapStringRefInfo>::iterator Uniqued
+    = UniqueStrings.find(String);
+  ++StringsAllocated;
+  StringBytesAllocated += String.size() + 1;
+  if (Uniqued != UniqueStrings.end()) {
+    StringBytesUniqued += String.size() + 1;
+    ++StringsUniqued;
+    return Uniqued->data();
+  }
+  
   char *Mem = (char *)Allocate(String.size() + 1, 1);
   std::copy(String.begin(), String.end(), Mem);
   Mem[String.size()] = 0;
+  UniqueStrings.insert(llvm::StringRef(Mem, String.size()));
   return Mem;
 }
 





More information about the cfe-commits mailing list