From: Chris Lattner Date: Fri, 29 Mar 2002 05:50:20 +0000 (+0000) Subject: Implement the first step of pool allocation - Creating, initialization, and X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=54ce13f983c44134014d06b03bdf8eab82d9e8a2;p=oota-llvm.git Implement the first step of pool allocation - Creating, initialization, and destruction of the pools. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2039 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/IPO/OldPoolAllocate.cpp b/lib/Transforms/IPO/OldPoolAllocate.cpp index c116ed1c66b..64616cd8fb6 100644 --- a/lib/Transforms/IPO/OldPoolAllocate.cpp +++ b/lib/Transforms/IPO/OldPoolAllocate.cpp @@ -12,8 +12,16 @@ #include "llvm/Module.h" #include "llvm/Function.h" #include "llvm/iMemory.h" +#include "llvm/iTerminators.h" +#include "llvm/iOther.h" +#include "llvm/ConstantVals.h" +#include "llvm/Target/TargetData.h" +#include "Support/STLExtras.h" #include +// FIXME: This is dependant on the sparc backend layout conventions!! +static TargetData TargetData("test"); + // Define the pass class that we implement... namespace { class PoolAllocate : public Pass { @@ -71,13 +79,13 @@ namespace { // allocation node in a data structure graph is eligable for pool allocation. // static bool isNotPoolableAlloc(const AllocDSNode *DS) { - if (DS->isAllocaNode()) return false; // Do not pool allocate alloca's. + if (DS->isAllocaNode()) return true; // Do not pool allocate alloca's. MallocInst *MI = cast(DS->getAllocation()); if (MI->isArrayAllocation() && !isa(MI->getArraySize())) - return false; // Do not allow variable size allocations... + return true; // Do not allow variable size allocations... - return true; + return false; } @@ -134,19 +142,85 @@ bool PoolAllocate::processFunction(Function *F) { for (unsigned i = 0, e = Scalars.size(); i != e; ++i) Scalars[i].first->dump(); + + // FIXME: This should use an IP version of the UnifyAllExits pass! + vector ReturnNodes; + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) + if (isa((*I)->getTerminator())) + ReturnNodes.push_back(*I); + + + // Create the code that goes in the entry and exit nodes for the method... + vector EntryNodeInsts; + for (unsigned i = 0, e = Allocs.size(); i != e; ++i) { + // Add an allocation and a free for each pool... + AllocaInst *PoolAlloc = new AllocaInst(PoolTy, 0, "pool"); + EntryNodeInsts.push_back(PoolAlloc); + + AllocationInst *AI = Allocs[i]->getAllocation(); + + // Initialize the pool. We need to know how big each allocation is. For + // our purposes here, we assume we are allocating a scalar, or array of + // constant size. + // + unsigned ElSize = TargetData.getTypeSize(AI->getAllocatedType()); + ElSize *= cast(AI->getArraySize())->getValue(); + + vector Args; + Args.push_back(PoolAlloc); // Pool to initialize + Args.push_back(ConstantUInt::get(Type::UIntTy, ElSize)); + EntryNodeInsts.push_back(new CallInst(PoolInit, Args)); + + // Destroy the pool... + Args.pop_back(); + + for (unsigned EN = 0, ENE = ReturnNodes.size(); EN != ENE; ++EN) { + Instruction *Destroy = new CallInst(PoolDestroy, Args); + + // Insert it before the return instruction... + BasicBlock *RetNode = ReturnNodes[EN]; + RetNode->getInstList().insert(RetNode->end()-1, Destroy); + } + } + + // Insert the entry node code into the entry block... + F->getEntryNode()->getInstList().insert(F->getEntryNode()->begin()+1, + EntryNodeInsts.begin(), + EntryNodeInsts.end()); + return false; } -// Prototypes that we add to support pool allocation... -Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree; - // addPoolPrototypes - Add prototypes for the pool methods to the specified // module and update the Pool* instance variables to point to them. // void PoolAllocate::addPoolPrototypes(Module *M) { - //M->getOrCreate... - + // Get PoolInit function... + vector Args; + Args.push_back(PoolTy); // Pool to initialize + Args.push_back(Type::UIntTy); // Num bytes per element + FunctionType *PoolInitTy = FunctionType::get(Type::VoidTy, Args, false); + PoolInit = M->getOrInsertFunction("poolinit", PoolInitTy); + + // Get pooldestroy function... + Args.pop_back(); // Only takes a pool... + FunctionType *PoolDestroyTy = FunctionType::get(Type::VoidTy, Args, false); + PoolDestroy = M->getOrInsertFunction("pooldestroy", PoolDestroyTy); + + const Type *PtrVoid = PointerType::get(Type::SByteTy); + + // Get the poolalloc function... + FunctionType *PoolAllocTy = FunctionType::get(PtrVoid, Args, false); + PoolAlloc = M->getOrInsertFunction("poolalloc", PoolAllocTy); + + // Get the poolfree function... + Args.push_back(PtrVoid); + FunctionType *PoolFreeTy = FunctionType::get(Type::VoidTy, Args, false); + PoolFree = M->getOrInsertFunction("poolfree", PoolFreeTy); + + // Add the %PoolTy type to the symbol table of the module... + M->addTypeName("PoolTy", PoolTy->getElementType()); }