mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-04 09:37:20 +00:00
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:
parent
4ab6aefe44
commit
f9c81670d7
@ -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();
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user