Reuse a technique (pioneered for BasicBlocks) of superposing ilist with
authorGabor Greif <ggreif@gmail.com>
Sun, 1 Mar 2009 16:38:10 +0000 (16:38 +0000)
committerGabor Greif <ggreif@gmail.com>
Sun, 1 Mar 2009 16:38:10 +0000 (16:38 +0000)
its sentinel. This is quite a win when a function really has a basic block.
When the function is just a declaration (and stays so) the old way did not
allocate a sentinel. So this change is most beneficial when the ratio of
function definition to declaration is high. I.e. linkers etc. Incidentally
these are the most resource demanding applications, so I expect that the
reduced malloc traffic, locality and space savings outweigh the cost of
addition of two pointers to Function.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65776 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Function.h
lib/VMCore/Function.cpp

index ee53252b954b8306eed801dd8c571f05d2c792d4..bdae9cd02f5a32f9066b9f6fa02a066b2157cec2 100644 (file)
@@ -32,12 +32,17 @@ class FunctionType;
 template<> struct ilist_traits<BasicBlock>
   : public SymbolTableListTraits<BasicBlock, Function> {
 
-  // createSentinel is used to create a node that marks the end of the list...
-  static BasicBlock *createSentinel();
-  static void destroySentinel(BasicBlock *BB) { delete BB; }
+  // createSentinel is used to get hold of the node that marks the end of the
+  // list... (same trick used here as in ilist_traits<Instruction>)
+  BasicBlock *createSentinel() const {
+    return const_cast<BasicBlock*>(static_cast<const BasicBlock*>(&Sentinel));
+  }
+  static void destroySentinel(BasicBlock*) {}
   static iplist<BasicBlock> &getList(Function *F);
   static ValueSymbolTable *getSymTab(Function *ItemParent);
   static int getListOffset();
+private:
+  ilist_node<BasicBlock> Sentinel;
 };
 
 template<> struct ilist_traits<Argument>
index cff4457a41804559cc234545082c87896f011424..fefe082cb4e44d2635bd37c20b8fad240526077a 100644 (file)
 #include "llvm/ADT/StringExtras.h"
 using namespace llvm;
 
-BasicBlock *ilist_traits<BasicBlock>::createSentinel() {
-  BasicBlock *Ret = BasicBlock::Create();
-  // This should not be garbage monitored.
-  LeakDetector::removeGarbageObject(Ret);
-  return Ret;
-}
-
 iplist<BasicBlock> &ilist_traits<BasicBlock>::getList(Function *F) {
   return F->getBasicBlockList();
 }