blob: 7e9f15556aacab337c8cb89ebef5639bbd51f203 [file] [log] [blame]
Chris Lattner64fd9352002-03-28 18:08:31 +00001//===-- PoolAllocate.cpp - Pool Allocation Pass ---------------------------===//
2//
3// This transform changes programs so that disjoint data structures are
4// allocated out of different pools of memory, increasing locality and shrinking
5// pointer size.
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/Transforms/IPO/PoolAllocate.h"
10#include "llvm/Analysis/DataStructure.h"
11#include "llvm/Pass.h"
Chris Lattner175f37c2002-03-29 03:40:59 +000012#include "llvm/Module.h"
13#include "llvm/Function.h"
14#include "llvm/iMemory.h"
Chris Lattnere0618ca2002-03-29 05:50:20 +000015#include "llvm/iTerminators.h"
16#include "llvm/iOther.h"
17#include "llvm/ConstantVals.h"
18#include "llvm/Target/TargetData.h"
19#include "Support/STLExtras.h"
Chris Lattner175f37c2002-03-29 03:40:59 +000020#include <algorithm>
Chris Lattner64fd9352002-03-28 18:08:31 +000021
Chris Lattner692ad5d2002-03-29 17:13:46 +000022
Chris Lattnere0618ca2002-03-29 05:50:20 +000023// FIXME: This is dependant on the sparc backend layout conventions!!
24static TargetData TargetData("test");
25
Chris Lattner64fd9352002-03-28 18:08:31 +000026namespace {
Chris Lattner692ad5d2002-03-29 17:13:46 +000027 // ScalarInfo - Information about an LLVM value that we know points to some
28 // datastructure we are processing.
29 //
30 struct ScalarInfo {
31 Value *Val; // Scalar value in Current Function
32 AllocDSNode *AllocNode; // Allocation node it points to
33 Value *PoolHandle; // PoolTy* LLVM value
34
35 ScalarInfo(Value *V, AllocDSNode *AN, Value *PH)
36 : Val(V), AllocNode(AN), PoolHandle(PH) {}
37 };
38
39 // TransformFunctionInfo - Information about how a function eeds to be
40 // transformed.
41 //
42 struct TransformFunctionInfo {
43 // ArgInfo - Maintain information about the arguments that need to be
44 // processed. Each pair corresponds to an argument (whose number is the
45 // first element) that needs to have a pool pointer (the second element)
46 // passed into the transformed function with it.
47 //
48 // As a special case, "argument" number -1 corresponds to the return value.
49 //
50 vector<pair<int, Value*> > ArgInfo;
51
52 // Func - The function to be transformed...
53 Function *Func;
54
55 // default ctor...
56 TransformFunctionInfo() : Func(0) {}
57
58 inline bool operator<(const TransformFunctionInfo &TFI) const {
59 return Func < TFI.Func || (Func == TFI.Func && ArgInfo < TFI.ArgInfo);
60 }
61
62 void finalizeConstruction() {
63 // Sort the vector so that the return value is first, followed by the
64 // argument records, in order.
65 sort(ArgInfo.begin(), ArgInfo.end());
66 }
67 };
68
69
70 // Define the pass class that we implement...
Chris Lattner175f37c2002-03-29 03:40:59 +000071 class PoolAllocate : public Pass {
72 // PoolTy - The type of a scalar value that contains a pool pointer.
73 PointerType *PoolTy;
74 public:
75
76 PoolAllocate() {
77 // Initialize the PoolTy instance variable, since the type never changes.
78 vector<const Type*> PoolElements;
79 PoolElements.push_back(PointerType::get(Type::SByteTy));
80 PoolElements.push_back(Type::UIntTy);
81 PoolTy = PointerType::get(StructType::get(PoolElements));
82 // PoolTy = { sbyte*, uint }*
83
84 CurModule = 0; DS = 0;
85 PoolInit = PoolDestroy = PoolAlloc = PoolFree = 0;
Chris Lattner64fd9352002-03-28 18:08:31 +000086 }
87
Chris Lattner175f37c2002-03-29 03:40:59 +000088 bool run(Module *M);
89
90 // getAnalysisUsageInfo - This function requires data structure information
91 // to be able to see what is pool allocatable.
Chris Lattner64fd9352002-03-28 18:08:31 +000092 //
93 virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Chris Lattner175f37c2002-03-29 03:40:59 +000094 Pass::AnalysisSet &,Pass::AnalysisSet &) {
Chris Lattner64fd9352002-03-28 18:08:31 +000095 Required.push_back(DataStructure::ID);
96 }
Chris Lattner175f37c2002-03-29 03:40:59 +000097
98 private:
99 // CurModule - The module being processed.
100 Module *CurModule;
101
102 // DS - The data structure graph for the module being processed.
103 DataStructure *DS;
104
105 // Prototypes that we add to support pool allocation...
106 Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree;
107
Chris Lattner692ad5d2002-03-29 17:13:46 +0000108 // The map of already transformed functions...
109 map<TransformFunctionInfo, Function*> TransformedFunctions;
110
111 // getTransformedFunction - Get a transformed function, or return null if
112 // the function specified hasn't been transformed yet.
113 //
114 Function *getTransformedFunction(TransformFunctionInfo &TFI) const {
115 map<TransformFunctionInfo, Function*>::const_iterator I =
116 TransformedFunctions.find(TFI);
117 if (I != TransformedFunctions.end()) return I->second;
118 return 0;
119 }
120
121
Chris Lattner175f37c2002-03-29 03:40:59 +0000122 // addPoolPrototypes - Add prototypes for the pool methods to the specified
123 // module and update the Pool* instance variables to point to them.
124 //
125 void addPoolPrototypes(Module *M);
126
Chris Lattner66df97d2002-03-29 06:21:38 +0000127
128 // CreatePools - Insert instructions into the function we are processing to
129 // create all of the memory pool objects themselves. This also inserts
130 // destruction code. Add an alloca for each pool that is allocated to the
131 // PoolDescriptors vector.
132 //
133 void CreatePools(Function *F, const vector<AllocDSNode*> &Allocs,
134 vector<AllocaInst*> &PoolDescriptors);
135
Chris Lattner175f37c2002-03-29 03:40:59 +0000136 // processFunction - Convert a function to use pool allocation where
137 // available.
138 //
139 bool processFunction(Function *F);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000140
141
142 void transformFunctionBody(Function *F, vector<ScalarInfo> &Scalars);
143
144 // transformFunction - Transform the specified function the specified way.
145 // It we have already transformed that function that way, don't do anything.
146 //
147 void transformFunction(TransformFunctionInfo &TFI);
148
Chris Lattner64fd9352002-03-28 18:08:31 +0000149 };
150}
151
Chris Lattner175f37c2002-03-29 03:40:59 +0000152
153
Chris Lattner692ad5d2002-03-29 17:13:46 +0000154// isNotPoolableAlloc - This is a predicate that returns true if the specified
Chris Lattner175f37c2002-03-29 03:40:59 +0000155// allocation node in a data structure graph is eligable for pool allocation.
156//
157static bool isNotPoolableAlloc(const AllocDSNode *DS) {
Chris Lattnere0618ca2002-03-29 05:50:20 +0000158 if (DS->isAllocaNode()) return true; // Do not pool allocate alloca's.
Chris Lattner175f37c2002-03-29 03:40:59 +0000159
160 MallocInst *MI = cast<MallocInst>(DS->getAllocation());
161 if (MI->isArrayAllocation() && !isa<Constant>(MI->getArraySize()))
Chris Lattnere0618ca2002-03-29 05:50:20 +0000162 return true; // Do not allow variable size allocations...
Chris Lattner175f37c2002-03-29 03:40:59 +0000163
Chris Lattnere0618ca2002-03-29 05:50:20 +0000164 return false;
Chris Lattner175f37c2002-03-29 03:40:59 +0000165}
166
Chris Lattner175f37c2002-03-29 03:40:59 +0000167// processFunction - Convert a function to use pool allocation where
168// available.
169//
170bool PoolAllocate::processFunction(Function *F) {
171 // Get the closed datastructure graph for the current function... if there are
172 // any allocations in this graph that are not escaping, we need to pool
173 // allocate them here!
174 //
175 FunctionDSGraph &IPGraph = DS->getClosedDSGraph(F);
176
177 // Get all of the allocations that do not escape the current function. Since
178 // they are still live (they exist in the graph at all), this means we must
179 // have scalar references to these nodes, but the scalars are never returned.
180 //
Chris Lattner692ad5d2002-03-29 17:13:46 +0000181 vector<AllocDSNode*> Allocs;
Chris Lattner175f37c2002-03-29 03:40:59 +0000182 IPGraph.getNonEscapingAllocations(Allocs);
183
184 // Filter out allocations that we cannot handle. Currently, this includes
185 // variable sized array allocations and alloca's (which we do not want to
186 // pool allocate)
187 //
188 Allocs.erase(remove_if(Allocs.begin(), Allocs.end(), isNotPoolableAlloc),
189 Allocs.end());
190
191
192 if (Allocs.empty()) return false; // Nothing to do.
193
Chris Lattner692ad5d2002-03-29 17:13:46 +0000194 // Insert instructions into the function we are processing to create all of
195 // the memory pool objects themselves. This also inserts destruction code.
196 // This fills in the PoolDescriptors vector to be a array parallel with
197 // Allocs, but containing the alloca instructions that allocate the pool ptr.
198 //
199 vector<AllocaInst*> PoolDescriptors;
200 CreatePools(F, Allocs, PoolDescriptors);
201
202
Chris Lattner175f37c2002-03-29 03:40:59 +0000203 // Loop through the value map looking for scalars that refer to nonescaping
Chris Lattner692ad5d2002-03-29 17:13:46 +0000204 // allocations. Add them to the Scalars vector. Note that we may have
205 // multiple entries in the Scalars vector for each value if it points to more
206 // than one object.
Chris Lattner175f37c2002-03-29 03:40:59 +0000207 //
208 map<Value*, PointerValSet> &ValMap = IPGraph.getValueMap();
Chris Lattner692ad5d2002-03-29 17:13:46 +0000209 vector<ScalarInfo> Scalars;
Chris Lattner175f37c2002-03-29 03:40:59 +0000210
211 for (map<Value*, PointerValSet>::iterator I = ValMap.begin(),
212 E = ValMap.end(); I != E; ++I) {
213 const PointerValSet &PVS = I->second; // Set of things pointed to by scalar
Chris Lattner692ad5d2002-03-29 17:13:46 +0000214
215 assert(PVS.size() == 1 &&
216 "Only handle scalars that point to one thing so far!");
217
Chris Lattner175f37c2002-03-29 03:40:59 +0000218 // Check to see if the scalar points to anything that is an allocation...
219 for (unsigned i = 0, e = PVS.size(); i != e; ++i)
220 if (AllocDSNode *Alloc = dyn_cast<AllocDSNode>(PVS[i].Node)) {
221 assert(PVS[i].Index == 0 && "Nonzero not handled yet!");
222
223 // If the allocation is in the nonescaping set...
Chris Lattner692ad5d2002-03-29 17:13:46 +0000224 vector<AllocDSNode*>::iterator AI =
225 find(Allocs.begin(), Allocs.end(), Alloc);
226 if (AI != Allocs.end()) {
227 unsigned IDX = AI-Allocs.begin();
Chris Lattner175f37c2002-03-29 03:40:59 +0000228 // Add it to the list of scalars we have
Chris Lattner692ad5d2002-03-29 17:13:46 +0000229 Scalars.push_back(ScalarInfo(I->first, Alloc, PoolDescriptors[IDX]));
230 }
Chris Lattner175f37c2002-03-29 03:40:59 +0000231 }
232 }
233
Chris Lattner692ad5d2002-03-29 17:13:46 +0000234 // Now we need to figure out what called methods we need to transform, and
235 // how. To do this, we look at all of the scalars, seeing which functions are
236 // either used as a scalar value (so they return a data structure), or are
237 // passed one of our scalar values.
238 //
239 transformFunctionBody(F, Scalars);
240
241 return true;
242}
243
244static void addCallInfo(TransformFunctionInfo &TFI, CallInst *CI, int Arg,
245 Value *PoolHandle) {
246 assert(CI->getCalledFunction() && "Cannot handle indirect calls yet!");
247 TFI.ArgInfo.push_back(make_pair(Arg, PoolHandle));
248
249 assert(TFI.Func == 0 || TFI.Func == CI->getCalledFunction() &&
250 "Function call record should always call the same function!");
251 TFI.Func = CI->getCalledFunction();
252}
253
254void PoolAllocate::transformFunctionBody(Function *F,
255 vector<ScalarInfo> &Scalars) {
Chris Lattner175f37c2002-03-29 03:40:59 +0000256 cerr << "In '" << F->getName()
257 << "': Found the following values that point to poolable nodes:\n";
258
259 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
Chris Lattner692ad5d2002-03-29 17:13:46 +0000260 Scalars[i].Val->dump();
Chris Lattnere0618ca2002-03-29 05:50:20 +0000261
Chris Lattner692ad5d2002-03-29 17:13:46 +0000262 // CallMap - Contain an entry for every call instruction that needs to be
263 // transformed. Each entry in the map contains information about what we need
264 // to do to each call site to change it to work.
265 //
266 map<CallInst*, TransformFunctionInfo> CallMap;
Chris Lattner66df97d2002-03-29 06:21:38 +0000267
Chris Lattner692ad5d2002-03-29 17:13:46 +0000268 // Now we need to figure out what called methods we need to transform, and
269 // how. To do this, we look at all of the scalars, seeing which functions are
270 // either used as a scalar value (so they return a data structure), or are
271 // passed one of our scalar values.
272 //
273 for (unsigned i = 0, e = Scalars.size(); i != e; ++i) {
274 Value *ScalarVal = Scalars[i].Val;
275
276 // Check to see if the scalar _IS_ a call...
277 if (CallInst *CI = dyn_cast<CallInst>(ScalarVal))
278 // If so, add information about the pool it will be returning...
279 addCallInfo(CallMap[CI], CI, -1, Scalars[i].PoolHandle);
280
281 // Check to see if the scalar is an operand to a call...
282 for (Value::use_iterator UI = ScalarVal->use_begin(),
283 UE = ScalarVal->use_end(); UI != UE; ++UI) {
284 if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
285 // Find out which operand this is to the call instruction...
286 User::op_iterator OI = find(CI->op_begin(), CI->op_end(), ScalarVal);
287 assert(OI != CI->op_end() && "Call on use list but not an operand!?");
288 assert(OI != CI->op_begin() && "Pointer operand is call destination?");
289
290 // FIXME: This is broken if the same pointer is passed to a call more
291 // than once! It will get multiple entries for the first pointer.
292
293 // Add the operand number and pool handle to the call table...
294 addCallInfo(CallMap[CI], CI, OI-CI->op_begin(), Scalars[i].PoolHandle);
295 }
296 }
297 }
298
299 // Print out call map...
300 for (map<CallInst*, TransformFunctionInfo>::iterator I = CallMap.begin();
301 I != CallMap.end(); ++I) {
302 cerr << "\nFor call: ";
303 I->first->dump();
304 I->second.finalizeConstruction();
305 cerr << " must pass pool pointer for arg #";
306 for (unsigned i = 0; i < I->second.ArgInfo.size(); ++i)
307 cerr << I->second.ArgInfo[i].first << " ";
308 cerr << "\n";
309 }
310
311 // Loop through all of the call nodes, recursively creating the new functions
312 // that we want to call... This uses a map to prevent infinite recursion and
313 // to avoid duplicating functions unneccesarily.
314 //
315 for (map<CallInst*, TransformFunctionInfo>::iterator I = CallMap.begin(),
316 E = CallMap.end(); I != E; ++I) {
317 // Make sure the entries are sorted.
318 I->second.finalizeConstruction();
319 transformFunction(I->second);
320 }
321
322
323
324}
325
326
327// transformFunction - Transform the specified function the specified way.
328// It we have already transformed that function that way, don't do anything.
329//
330void PoolAllocate::transformFunction(TransformFunctionInfo &TFI) {
331 if (getTransformedFunction(TFI)) return; // Function xformation already done?
332
333
334
Chris Lattner66df97d2002-03-29 06:21:38 +0000335}
336
337
338// CreatePools - Insert instructions into the function we are processing to
339// create all of the memory pool objects themselves. This also inserts
340// destruction code. Add an alloca for each pool that is allocated to the
341// PoolDescriptors vector.
342//
343void PoolAllocate::CreatePools(Function *F, const vector<AllocDSNode*> &Allocs,
344 vector<AllocaInst*> &PoolDescriptors) {
Chris Lattnere0618ca2002-03-29 05:50:20 +0000345 // FIXME: This should use an IP version of the UnifyAllExits pass!
346 vector<BasicBlock*> ReturnNodes;
347 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
348 if (isa<ReturnInst>((*I)->getTerminator()))
349 ReturnNodes.push_back(*I);
350
351
352 // Create the code that goes in the entry and exit nodes for the method...
353 vector<Instruction*> EntryNodeInsts;
354 for (unsigned i = 0, e = Allocs.size(); i != e; ++i) {
355 // Add an allocation and a free for each pool...
356 AllocaInst *PoolAlloc = new AllocaInst(PoolTy, 0, "pool");
357 EntryNodeInsts.push_back(PoolAlloc);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000358 PoolDescriptors.push_back(PoolAlloc); // Keep track of pool allocas
Chris Lattnere0618ca2002-03-29 05:50:20 +0000359 AllocationInst *AI = Allocs[i]->getAllocation();
360
361 // Initialize the pool. We need to know how big each allocation is. For
362 // our purposes here, we assume we are allocating a scalar, or array of
363 // constant size.
364 //
365 unsigned ElSize = TargetData.getTypeSize(AI->getAllocatedType());
366 ElSize *= cast<ConstantUInt>(AI->getArraySize())->getValue();
367
368 vector<Value*> Args;
369 Args.push_back(PoolAlloc); // Pool to initialize
370 Args.push_back(ConstantUInt::get(Type::UIntTy, ElSize));
371 EntryNodeInsts.push_back(new CallInst(PoolInit, Args));
372
373 // Destroy the pool...
374 Args.pop_back();
375
376 for (unsigned EN = 0, ENE = ReturnNodes.size(); EN != ENE; ++EN) {
377 Instruction *Destroy = new CallInst(PoolDestroy, Args);
378
379 // Insert it before the return instruction...
380 BasicBlock *RetNode = ReturnNodes[EN];
381 RetNode->getInstList().insert(RetNode->end()-1, Destroy);
382 }
383 }
384
385 // Insert the entry node code into the entry block...
386 F->getEntryNode()->getInstList().insert(F->getEntryNode()->begin()+1,
387 EntryNodeInsts.begin(),
388 EntryNodeInsts.end());
Chris Lattner175f37c2002-03-29 03:40:59 +0000389}
390
391
Chris Lattner175f37c2002-03-29 03:40:59 +0000392// addPoolPrototypes - Add prototypes for the pool methods to the specified
393// module and update the Pool* instance variables to point to them.
394//
395void PoolAllocate::addPoolPrototypes(Module *M) {
Chris Lattnere0618ca2002-03-29 05:50:20 +0000396 // Get PoolInit function...
397 vector<const Type*> Args;
398 Args.push_back(PoolTy); // Pool to initialize
399 Args.push_back(Type::UIntTy); // Num bytes per element
400 FunctionType *PoolInitTy = FunctionType::get(Type::VoidTy, Args, false);
401 PoolInit = M->getOrInsertFunction("poolinit", PoolInitTy);
Chris Lattner175f37c2002-03-29 03:40:59 +0000402
Chris Lattnere0618ca2002-03-29 05:50:20 +0000403 // Get pooldestroy function...
404 Args.pop_back(); // Only takes a pool...
405 FunctionType *PoolDestroyTy = FunctionType::get(Type::VoidTy, Args, false);
406 PoolDestroy = M->getOrInsertFunction("pooldestroy", PoolDestroyTy);
407
408 const Type *PtrVoid = PointerType::get(Type::SByteTy);
409
410 // Get the poolalloc function...
411 FunctionType *PoolAllocTy = FunctionType::get(PtrVoid, Args, false);
412 PoolAlloc = M->getOrInsertFunction("poolalloc", PoolAllocTy);
413
414 // Get the poolfree function...
415 Args.push_back(PtrVoid);
416 FunctionType *PoolFreeTy = FunctionType::get(Type::VoidTy, Args, false);
417 PoolFree = M->getOrInsertFunction("poolfree", PoolFreeTy);
418
419 // Add the %PoolTy type to the symbol table of the module...
420 M->addTypeName("PoolTy", PoolTy->getElementType());
Chris Lattner175f37c2002-03-29 03:40:59 +0000421}
422
423
424bool PoolAllocate::run(Module *M) {
425 addPoolPrototypes(M);
426 CurModule = M;
427
428 DS = &getAnalysis<DataStructure>();
429 bool Changed = false;
430 for (Module::iterator I = M->begin(); I != M->end(); ++I)
431 if (!(*I)->isExternal())
432 Changed |= processFunction(*I);
433
434 CurModule = 0;
435 DS = 0;
436 return false;
437}
438
439
440// createPoolAllocatePass - Global function to access the functionality of this
441// pass...
442//
Chris Lattner64fd9352002-03-28 18:08:31 +0000443Pass *createPoolAllocatePass() { return new PoolAllocate(); }