Split public interface out into header file

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5472 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2003-02-03 19:08:18 +00:00
parent 4ab6aefe44
commit f9c81670d7

View File

@ -5,7 +5,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO.h" #include "llvm/Transforms/PoolAllocate.h"
#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DSGraph.h" #include "llvm/Analysis/DSGraph.h"
@ -18,6 +18,8 @@
#include "Support/Statistic.h" #include "Support/Statistic.h"
#include "Support/VectorExtras.h" #include "Support/VectorExtras.h"
using namespace PA;
namespace { namespace {
const Type *VoidPtrTy = PointerType::get(Type::SByteTy); const Type *VoidPtrTy = PointerType::get(Type::SByteTy);
// The type to allocate for a pool descriptor: { sbyte*, uint } // The type to allocate for a pool descriptor: { sbyte*, uint }
@ -25,100 +27,16 @@ namespace {
StructType::get(make_vector<const Type*>(VoidPtrTy, Type::UIntTy, 0)); StructType::get(make_vector<const Type*>(VoidPtrTy, Type::UIntTy, 0));
const PointerType *PoolDescPtr = PointerType::get(PoolDescType); const PointerType *PoolDescPtr = PointerType::get(PoolDescType);
RegisterOpt<PoolAllocate>
X("poolalloc", "Pool allocate disjoint data structures");
}
/// PoolInfo - This struct represents a single pool in the context of a void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
/// function. Pools are mapped one to one with nodes in the DSGraph, so this
/// contains a pointer to the node it corresponds to. In addition, the pool
/// is initialized by calling the "poolinit" library function with a chunk of
/// memory allocated with an alloca instruction. This entry contains a
/// pointer to that alloca if the pool is locally allocated or the argument it
/// is passed in through if not.
///
struct PoolInfo {
Value *PoolHandle; // Pool Handle, an alloca or incoming argument.
PoolInfo(Value *PH) : PoolHandle(PH) {}
};
struct FuncInfo {
/// MarkedNodes - The set of nodes which are not locally pool allocatable in
/// the current function.
///
hash_set<DSNode*> MarkedNodes;
/// Clone - The cloned version of the function, if applicable.
Function *Clone;
/// ArgNodes - The list of DSNodes which have pools passed in as arguments.
///
std::vector<DSNode*> ArgNodes;
/// PoolDescriptors - A PoolInfo object for each relevant DSNode in the
/// current graph.
std::map<DSNode*, PoolInfo> PoolDescriptors;
/// NewToOldValueMap - When and if a function needs to be cloned, this map
/// contains a mapping from all of the values in the new function back to
/// the values they correspond to in the old function.
///
std::map<Value*, const Value*> NewToOldValueMap;
};
/// PA - The main pool allocation pass
///
class PA : public Pass {
Module *CurModule;
BUDataStructures *BU;
std::map<Function*, FuncInfo> FunctionInfo;
public:
Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree;
public:
bool run(Module &M);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<BUDataStructures>(); AU.addRequired<BUDataStructures>();
AU.addRequired<TargetData>(); AU.addRequired<TargetData>();
} }
BUDataStructures &getBUDataStructures() const { return *BU; } bool PoolAllocate::run(Module &M) {
FuncInfo *getFuncInfo(Function &F) {
std::map<Function*, FuncInfo>::iterator I = FunctionInfo.find(&F);
return I != FunctionInfo.end() ? &I->second : 0;
}
private:
/// AddPoolPrototypes - Add prototypes for the pool functions to the
/// specified module and update the Pool* instance variables to point to
/// them.
///
void AddPoolPrototypes();
/// MakeFunctionClone - If the specified function needs to be modified for
/// pool allocation support, make a clone of it, adding additional arguments
/// as neccesary, and return it. If not, just return null.
///
Function *MakeFunctionClone(Function &F);
/// ProcessFunctionBody - Rewrite the body of a transformed function to use
/// pool allocation where appropriate.
///
void ProcessFunctionBody(Function &Old, Function &New);
/// CreatePools - This creates the pool initialization and destruction code
/// for the DSNodes specified by the NodesToPA list. This adds an entry to
/// the PoolDescriptors map for each DSNode.
///
void CreatePools(Function &F, const std::vector<DSNode*> &NodesToPA,
std::map<DSNode*, PoolInfo> &PoolDescriptors);
void TransformFunctionBody(Function &F, DSGraph &G, FuncInfo &FI);
};
RegisterOpt<PA> X("poolalloc", "Pool allocate disjoint data structures");
}
bool PA::run(Module &M) {
if (M.begin() == M.end()) return false; if (M.begin() == M.end()) return false;
CurModule = &M; CurModule = &M;
@ -155,7 +73,7 @@ bool PA::run(Module &M) {
// AddPoolPrototypes - Add prototypes for the pool functions to the specified // AddPoolPrototypes - Add prototypes for the pool functions 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 PA::AddPoolPrototypes() { void PoolAllocate::AddPoolPrototypes() {
CurModule->addTypeName("PoolDescriptor", PoolDescType); CurModule->addTypeName("PoolDescriptor", PoolDescType);
// Get poolinit function... // Get poolinit function...
@ -193,7 +111,7 @@ void PA::AddPoolPrototypes() {
// allocation support, make a clone of it, adding additional arguments as // allocation support, make a clone of it, adding additional arguments as
// neccesary, and return it. If not, just return null. // neccesary, and return it. If not, just return null.
// //
Function *PA::MakeFunctionClone(Function &F) { Function *PoolAllocate::MakeFunctionClone(Function &F) {
DSGraph &G = BU->getDSGraph(F); DSGraph &G = BU->getDSGraph(F);
std::vector<DSNode*> &Nodes = G.getNodes(); std::vector<DSNode*> &Nodes = G.getNodes();
if (Nodes.empty()) return 0; // No memory activity, nothing is required if (Nodes.empty()) return 0; // No memory activity, nothing is required
@ -245,11 +163,11 @@ Function *PA::MakeFunctionClone(Function &F) {
// Set the rest of the new arguments names to be PDa<n> and add entries to the // Set the rest of the new arguments names to be PDa<n> and add entries to the
// pool descriptors map // pool descriptors map
std::map<DSNode*, PoolInfo> &PoolDescriptors = FI.PoolDescriptors; std::map<DSNode*, Value*> &PoolDescriptors = FI.PoolDescriptors;
Function::aiterator NI = New->abegin(); Function::aiterator NI = New->abegin();
for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) { for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) {
NI->setName("PDa"); // Add pd entry NI->setName("PDa"); // Add pd entry
PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], PoolInfo(NI))); PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI));
} }
// Map the existing arguments of the old function to the corresponding // Map the existing arguments of the old function to the corresponding
@ -283,7 +201,7 @@ Function *PA::MakeFunctionClone(Function &F) {
// processFunction - Pool allocate any data structures which are contained in // processFunction - Pool allocate any data structures which are contained in
// the specified function... // the specified function...
// //
void PA::ProcessFunctionBody(Function &F, Function &NewF) { void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) {
DSGraph &G = BU->getDSGraph(F); DSGraph &G = BU->getDSGraph(F);
std::vector<DSNode*> &Nodes = G.getNodes(); std::vector<DSNode*> &Nodes = G.getNodes();
if (Nodes.empty()) return; // Quick exit if nothing to do... if (Nodes.empty()) return; // Quick exit if nothing to do...
@ -305,7 +223,7 @@ void PA::ProcessFunctionBody(Function &F, Function &NewF) {
DEBUG(std::cerr << NodesToPA.size() << " nodes to pool allocate\n"); DEBUG(std::cerr << NodesToPA.size() << " nodes to pool allocate\n");
if (!NodesToPA.empty()) { if (!NodesToPA.empty()) {
// Create pool construction/destruction code // Create pool construction/destruction code
std::map<DSNode*, PoolInfo> &PoolDescriptors = FI.PoolDescriptors; std::map<DSNode*, Value*> &PoolDescriptors = FI.PoolDescriptors;
CreatePools(NewF, NodesToPA, PoolDescriptors); CreatePools(NewF, NodesToPA, PoolDescriptors);
} }
@ -318,8 +236,9 @@ void PA::ProcessFunctionBody(Function &F, Function &NewF) {
// the DSNodes specified by the NodesToPA list. This adds an entry to the // the DSNodes specified by the NodesToPA list. This adds an entry to the
// PoolDescriptors map for each DSNode. // PoolDescriptors map for each DSNode.
// //
void PA::CreatePools(Function &F, const std::vector<DSNode*> &NodesToPA, void PoolAllocate::CreatePools(Function &F,
std::map<DSNode*, PoolInfo> &PoolDescriptors) { const std::vector<DSNode*> &NodesToPA,
std::map<DSNode*, Value*> &PoolDescriptors) {
// Find all of the return nodes in the CFG... // Find all of the return nodes in the CFG...
std::vector<BasicBlock*> ReturnNodes; std::vector<BasicBlock*> ReturnNodes;
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
@ -346,7 +265,7 @@ void PA::CreatePools(Function &F, const std::vector<DSNode*> &NodesToPA,
new CallInst(PoolInit, make_vector(AI, ElSize, 0), "", InsertPoint); new CallInst(PoolInit, make_vector(AI, ElSize, 0), "", InsertPoint);
// Update the PoolDescriptors map // Update the PoolDescriptors map
PoolDescriptors.insert(std::make_pair(Node, PoolInfo(AI))); PoolDescriptors.insert(std::make_pair(Node, AI));
// Insert a call to pool destroy before each return inst in the function // Insert a call to pool destroy before each return inst in the function
for (unsigned r = 0, e = ReturnNodes.size(); r != e; ++r) for (unsigned r = 0, e = ReturnNodes.size(); r != e; ++r)
@ -360,11 +279,12 @@ namespace {
/// FuncTransform - This class implements transformation required of pool /// FuncTransform - This class implements transformation required of pool
/// allocated functions. /// allocated functions.
struct FuncTransform : public InstVisitor<FuncTransform> { struct FuncTransform : public InstVisitor<FuncTransform> {
PA &PAInfo; PoolAllocate &PAInfo;
DSGraph &G; DSGraph &G;
FuncInfo &FI; FuncInfo &FI;
FuncTransform(PA &P, DSGraph &g, FuncInfo &fi) : PAInfo(P), G(g), FI(fi) {} FuncTransform(PoolAllocate &P, DSGraph &g, FuncInfo &fi)
: PAInfo(P), G(g), FI(fi) {}
void visitMallocInst(MallocInst &MI); void visitMallocInst(MallocInst &MI);
void visitFreeInst(FreeInst &FI); void visitFreeInst(FreeInst &FI);
@ -384,13 +304,13 @@ namespace {
Value *getPoolHandle(Value *V) { Value *getPoolHandle(Value *V) {
DSNode *Node = getDSNodeFor(V); DSNode *Node = getDSNodeFor(V);
// Get the pool handle for this DSNode... // Get the pool handle for this DSNode...
std::map<DSNode*, PoolInfo>::iterator I = FI.PoolDescriptors.find(Node); std::map<DSNode*, Value*>::iterator I = FI.PoolDescriptors.find(Node);
return I != FI.PoolDescriptors.end() ? I->second.PoolHandle : 0; return I != FI.PoolDescriptors.end() ? I->second : 0;
} }
}; };
} }
void PA::TransformFunctionBody(Function &F, DSGraph &G, FuncInfo &FI) { void PoolAllocate::TransformFunctionBody(Function &F, DSGraph &G, FuncInfo &FI){
FuncTransform(*this, G, FI).visit(F); FuncTransform(*this, G, FI).visit(F);
} }
@ -505,7 +425,7 @@ void FuncTransform::visitCallInst(CallInst &CI) {
assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!"); assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!");
DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second; DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second;
assert(FI.PoolDescriptors.count(LocalNode) && "Node not pool allocated?"); assert(FI.PoolDescriptors.count(LocalNode) && "Node not pool allocated?");
Args.push_back(FI.PoolDescriptors.find(LocalNode)->second.PoolHandle); Args.push_back(FI.PoolDescriptors.find(LocalNode)->second);
} else { } else {
Args.push_back(Constant::getNullValue(PoolDescPtr)); Args.push_back(Constant::getNullValue(PoolDescPtr));
} }
@ -521,11 +441,3 @@ void FuncTransform::visitCallInst(CallInst &CI) {
DEBUG(std::cerr << " Result Call: " << *NewCall); DEBUG(std::cerr << " Result Call: " << *NewCall);
CI.getParent()->getInstList().erase(&CI); CI.getParent()->getInstList().erase(&CI);
} }
// createPoolAllocatePass - Global function to access the functionality of this
// pass...
//
Pass *createPoolAllocatePass() {
return new PA();
}