[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