mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-10 02:25:47 +00:00
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
This commit is contained in:
@@ -12,8 +12,16 @@
|
|||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/iMemory.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 <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
// FIXME: This is dependant on the sparc backend layout conventions!!
|
||||||
|
static TargetData TargetData("test");
|
||||||
|
|
||||||
// Define the pass class that we implement...
|
// Define the pass class that we implement...
|
||||||
namespace {
|
namespace {
|
||||||
class PoolAllocate : public Pass {
|
class PoolAllocate : public Pass {
|
||||||
@@ -71,13 +79,13 @@ namespace {
|
|||||||
// allocation node in a data structure graph is eligable for pool allocation.
|
// allocation node in a data structure graph is eligable for pool allocation.
|
||||||
//
|
//
|
||||||
static bool isNotPoolableAlloc(const AllocDSNode *DS) {
|
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<MallocInst>(DS->getAllocation());
|
MallocInst *MI = cast<MallocInst>(DS->getAllocation());
|
||||||
if (MI->isArrayAllocation() && !isa<Constant>(MI->getArraySize()))
|
if (MI->isArrayAllocation() && !isa<Constant>(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)
|
for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
|
||||||
Scalars[i].first->dump();
|
Scalars[i].first->dump();
|
||||||
|
|
||||||
|
// FIXME: This should use an IP version of the UnifyAllExits pass!
|
||||||
|
vector<BasicBlock*> ReturnNodes;
|
||||||
|
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
|
||||||
|
if (isa<ReturnInst>((*I)->getTerminator()))
|
||||||
|
ReturnNodes.push_back(*I);
|
||||||
|
|
||||||
|
|
||||||
|
// Create the code that goes in the entry and exit nodes for the method...
|
||||||
|
vector<Instruction*> 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<ConstantUInt>(AI->getArraySize())->getValue();
|
||||||
|
|
||||||
|
vector<Value*> 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;
|
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
|
// addPoolPrototypes - Add prototypes for the pool methods to the specified
|
||||||
// module and update the Pool* instance variables to point to them.
|
// module and update the Pool* instance variables to point to them.
|
||||||
//
|
//
|
||||||
void PoolAllocate::addPoolPrototypes(Module *M) {
|
void PoolAllocate::addPoolPrototypes(Module *M) {
|
||||||
//M->getOrCreate...
|
// Get PoolInit function...
|
||||||
|
vector<const Type*> 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user