1 //===-- PoolAllocate.cpp - Pool Allocation Pass ---------------------------===//
3 // This transform changes programs so that disjoint data structures are
4 // allocated out of different pools of memory, increasing locality and shrinking
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/IPO/PoolAllocate.h"
10 #include "llvm/Analysis/DataStructure.h"
11 #include "llvm/Pass.h"
12 #include "llvm/Module.h"
13 #include "llvm/Function.h"
14 #include "llvm/iMemory.h"
17 // Define the pass class that we implement...
19 class PoolAllocate : public Pass {
20 // PoolTy - The type of a scalar value that contains a pool pointer.
25 // Initialize the PoolTy instance variable, since the type never changes.
26 vector<const Type*> PoolElements;
27 PoolElements.push_back(PointerType::get(Type::SByteTy));
28 PoolElements.push_back(Type::UIntTy);
29 PoolTy = PointerType::get(StructType::get(PoolElements));
30 // PoolTy = { sbyte*, uint }*
32 CurModule = 0; DS = 0;
33 PoolInit = PoolDestroy = PoolAlloc = PoolFree = 0;
38 // getAnalysisUsageInfo - This function requires data structure information
39 // to be able to see what is pool allocatable.
41 virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
42 Pass::AnalysisSet &,Pass::AnalysisSet &) {
43 Required.push_back(DataStructure::ID);
47 // CurModule - The module being processed.
50 // DS - The data structure graph for the module being processed.
53 // Prototypes that we add to support pool allocation...
54 Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree;
56 // addPoolPrototypes - Add prototypes for the pool methods to the specified
57 // module and update the Pool* instance variables to point to them.
59 void addPoolPrototypes(Module *M);
61 // processFunction - Convert a function to use pool allocation where
64 bool processFunction(Function *F);
70 // isNotPoolableAlloc - This is a predicate that returns true if the specified
71 // allocation node in a data structure graph is eligable for pool allocation.
73 static bool isNotPoolableAlloc(const AllocDSNode *DS) {
74 if (DS->isAllocaNode()) return false; // Do not pool allocate alloca's.
76 MallocInst *MI = cast<MallocInst>(DS->getAllocation());
77 if (MI->isArrayAllocation() && !isa<Constant>(MI->getArraySize()))
78 return false; // Do not allow variable size allocations...
84 // processFunction - Convert a function to use pool allocation where
87 bool PoolAllocate::processFunction(Function *F) {
88 // Get the closed datastructure graph for the current function... if there are
89 // any allocations in this graph that are not escaping, we need to pool
90 // allocate them here!
92 FunctionDSGraph &IPGraph = DS->getClosedDSGraph(F);
94 // Get all of the allocations that do not escape the current function. Since
95 // they are still live (they exist in the graph at all), this means we must
96 // have scalar references to these nodes, but the scalars are never returned.
98 std::vector<AllocDSNode*> Allocs;
99 IPGraph.getNonEscapingAllocations(Allocs);
101 // Filter out allocations that we cannot handle. Currently, this includes
102 // variable sized array allocations and alloca's (which we do not want to
105 Allocs.erase(remove_if(Allocs.begin(), Allocs.end(), isNotPoolableAlloc),
109 if (Allocs.empty()) return false; // Nothing to do.
111 // Loop through the value map looking for scalars that refer to nonescaping
114 map<Value*, PointerValSet> &ValMap = IPGraph.getValueMap();
115 vector<pair<Value*, AllocDSNode*> > Scalars;
117 for (map<Value*, PointerValSet>::iterator I = ValMap.begin(),
118 E = ValMap.end(); I != E; ++I) {
119 const PointerValSet &PVS = I->second; // Set of things pointed to by scalar
120 // Check to see if the scalar points to anything that is an allocation...
121 for (unsigned i = 0, e = PVS.size(); i != e; ++i)
122 if (AllocDSNode *Alloc = dyn_cast<AllocDSNode>(PVS[i].Node)) {
123 assert(PVS[i].Index == 0 && "Nonzero not handled yet!");
125 // If the allocation is in the nonescaping set...
126 if (find(Allocs.begin(), Allocs.end(), Alloc) != Allocs.end())
127 // Add it to the list of scalars we have
128 Scalars.push_back(make_pair(I->first, Alloc));
132 cerr << "In '" << F->getName()
133 << "': Found the following values that point to poolable nodes:\n";
135 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
136 Scalars[i].first->dump();
141 // Prototypes that we add to support pool allocation...
142 Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree;
144 // addPoolPrototypes - Add prototypes for the pool methods to the specified
145 // module and update the Pool* instance variables to point to them.
147 void PoolAllocate::addPoolPrototypes(Module *M) {
153 bool PoolAllocate::run(Module *M) {
154 addPoolPrototypes(M);
157 DS = &getAnalysis<DataStructure>();
158 bool Changed = false;
159 for (Module::iterator I = M->begin(); I != M->end(); ++I)
160 if (!(*I)->isExternal())
161 Changed |= processFunction(*I);
169 // createPoolAllocatePass - Global function to access the functionality of this
172 Pass *createPoolAllocatePass() { return new PoolAllocate(); }