[llvm-commits] [poolalloc] r116417 - in /poolalloc/trunk: include/poolalloc/PoolAllocate.h lib/PoolAllocate/PoolAllocate.cpp

John Criswell criswell at uiuc.edu
Wed Oct 13 11:53:01 PDT 2010


Author: criswell
Date: Wed Oct 13 13:53:00 2010
New Revision: 116417

URL: http://llvm.org/viewvc/llvm-project?rev=116417&view=rev
Log:
Initialize global pools in a global constructor (ctor) function instead of
at the beginning of main().  This fixes SAFECode with Automatic Pool Allocation
on 164.gzip, and it should allow Automatic Pool Allocation to work on C++
programs that use global constructor methods.

Modified:
    poolalloc/trunk/include/poolalloc/PoolAllocate.h
    poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp

Modified: poolalloc/trunk/include/poolalloc/PoolAllocate.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/PoolAllocate.h?rev=116417&r1=116416&r2=116417&view=diff
==============================================================================
--- poolalloc/trunk/include/poolalloc/PoolAllocate.h (original)
+++ poolalloc/trunk/include/poolalloc/PoolAllocate.h Wed Oct 13 13:53:00 2010
@@ -215,6 +215,9 @@
   Constant *PoolFree;
   Constant *PoolCalloc;
   Constant *PoolStrdup;
+
+  // Function which will initialize global pools
+  Function * GlobalPoolCtor;
   
   static const Type *PoolDescPtrTy;
 

Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=116417&r1=116416&r2=116417&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Wed Oct 13 13:53:00 2010
@@ -105,6 +105,87 @@
   return;
 }
 
+//
+// Function: createGlobalPoolCtor()
+//
+// Description:
+//  This function creates an empty function which will be a global constructor
+//  (i.e., global ctor).  Pool Allocation will eventually add code to it to
+//  initialize all of the global pools.
+//
+static Function *
+createGlobalPoolCtor (Module & M) {
+  //
+  // Create the global pool ctor function.
+  //
+  LLVMContext & Context = M.getContext();
+  const Type * VoidType = Type::getVoidTy (Context);
+  FunctionType * FTy = FunctionType::get(VoidType,
+                                         std::vector<const Type*>(),
+                                         false);
+  Function *InitFunc = Function::Create (FTy,
+                                         GlobalValue::ExternalLinkage,
+                                         "poolalloc_global_ctor",
+                                         &M);
+
+  //
+  // Add an entry basic block that just returns.
+  //
+  BasicBlock * BB = BasicBlock::Create (Context, "entry", InitFunc);
+  ReturnInst::Create(Context, BB);
+
+  //
+  // Insert the run-time ctor into the ctor list.
+  //
+  const Type * Int32Type = IntegerType::getInt32Ty(Context);
+  std::vector<Constant *> CtorInits;
+  CtorInits.push_back (ConstantInt::get (Int32Type, 65535));
+  CtorInits.push_back (InitFunc);
+  Constant * RuntimeCtorInit = ConstantStruct::get(Context, CtorInits, false);
+
+  //
+  // Get the current set of static global constructors and add the new ctor
+  // to the end of the list (the list seems to be initialized in reverse
+  // order).
+  //
+  std::vector<Constant *> CurrentCtors;
+  GlobalVariable * GVCtor = M.getNamedGlobal ("llvm.global_ctors");
+  if (GVCtor) {
+    if (Constant * C = GVCtor->getInitializer()) {
+      for (unsigned index = 0; index < C->getNumOperands(); ++index) {
+        CurrentCtors.push_back (cast<Constant>(C->getOperand (index)));
+      }
+    }
+
+    //
+    // Rename the global variable so that we can name our global
+    // llvm.global_ctors.
+    //
+    GVCtor->setName ("removed");
+  }
+  CurrentCtors.push_back (RuntimeCtorInit);
+
+  //
+  // Create a new initializer.
+  //
+  const ArrayType * AT = ArrayType::get (RuntimeCtorInit-> getType(),
+                                         CurrentCtors.size());
+  Constant * NewInit=ConstantArray::get (AT, CurrentCtors);
+
+  //
+  // Create the new llvm.global_ctors global variable and replace all uses of
+  // the old global variable with the new one.
+  //
+  new GlobalVariable (M,
+                      NewInit->getType(),
+                      false,
+                      GlobalValue::AppendingLinkage,
+                      NewInit,
+                      "llvm.global_ctors");
+
+  return InitFunc;
+}
+
 void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
   // We will need the heuristic pass to tell us what to do and how to do it
   AU.addRequired<Heuristic>();
@@ -163,6 +244,9 @@
   // Add the pool* prototypes to the module
   AddPoolPrototypes(&M);
 
+  // Create the global ctor function for initializing the global pools.
+  GlobalPoolCtor = createGlobalPoolCtor (M);
+
   // Create the pools for memory objects reachable by global variables.
   if (SetupGlobalPools(M))
     return true;
@@ -853,9 +937,6 @@
 //
 // FIXME: Update comment
 //
-// FIXME: Global pools should probably be initialized by a global ctor instead
-//        of by main().
-//
 // SetupGlobalPools - Create global pools for all DSNodes in the globals graph
 // which contain heap objects.  If a global variable points to a piece of memory
 // allocated from the heap, this pool gets a global lifetime.  This is
@@ -875,21 +956,13 @@
   std::vector<const DSNode*> NodesToPA;
   CurHeuristic->getGlobalPoolNodes (NodesToPA);
 
-  // Otherwise get the main function to insert the poolinit calls.
-  Function *MainFunc = M.getFunction("main");
-  if (MainFunc == 0 || MainFunc->isDeclaration()) {
-    errs() << "Cannot pool allocate this program: it has global "
-              << "pools but no 'main' function yet!\n";
-    return true;
-  }
-
   errs() << "Pool allocating " << NodesToPA.size() << " global nodes!\n";
 
   DSGraph* GG = Graphs->getGlobalsGraph();
   std::vector<Heuristic::OnePool> ResultPools;
   CurHeuristic->AssignToPools(NodesToPA, 0, GG, ResultPools);
 
-  BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin();
+  BasicBlock::iterator InsertPt = GlobalPoolCtor->getEntryBlock().begin();
 
   //
   // Create a set of the DSNodes globally reachable from memory.  We'll assign
@@ -939,14 +1012,11 @@
   DSNode *GNode = Graphs->getGlobalsGraph()->addObjectToGraph(GV);
   GNode->setModifiedMarker()->setReadMarker();
 
-  Function *MainFunc = CurModule->getFunction("main");
-  assert(MainFunc && "No main in program??");
-
   BasicBlock::iterator InsertPt;
   if (IPHint)
     InsertPt = IPHint;
   else {
-    InsertPt = MainFunc->getEntryBlock().begin();
+    InsertPt = GlobalPoolCtor->getEntryBlock().begin();
     while (isa<AllocaInst>(InsertPt)) ++InsertPt;
   }
 





More information about the llvm-commits mailing list