blob: 17ce3dd8521e6ce4017e17c07cf93a796c7c85e6 [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"
Chris Lattner291a1b12002-03-29 19:05:48 +000010#include "llvm/Transforms/CloneFunction.h"
Chris Lattner64fd9352002-03-28 18:08:31 +000011#include "llvm/Analysis/DataStructure.h"
Chris Lattner396d5d72002-03-30 04:02:31 +000012#include "llvm/Analysis/DataStructureGraph.h"
Chris Lattner64fd9352002-03-28 18:08:31 +000013#include "llvm/Pass.h"
Chris Lattner175f37c2002-03-29 03:40:59 +000014#include "llvm/Module.h"
15#include "llvm/Function.h"
16#include "llvm/iMemory.h"
Chris Lattnere0618ca2002-03-29 05:50:20 +000017#include "llvm/iTerminators.h"
18#include "llvm/iOther.h"
19#include "llvm/ConstantVals.h"
20#include "llvm/Target/TargetData.h"
Chris Lattnerf32d65d2002-03-29 21:25:19 +000021#include "llvm/Support/InstVisitor.h"
Chris Lattner396d5d72002-03-30 04:02:31 +000022#include "Support/DepthFirstIterator.h"
Chris Lattnere0618ca2002-03-29 05:50:20 +000023#include "Support/STLExtras.h"
Chris Lattner175f37c2002-03-29 03:40:59 +000024#include <algorithm>
Chris Lattner64fd9352002-03-28 18:08:31 +000025
Chris Lattner692ad5d2002-03-29 17:13:46 +000026
Chris Lattnere0618ca2002-03-29 05:50:20 +000027// FIXME: This is dependant on the sparc backend layout conventions!!
28static TargetData TargetData("test");
29
Chris Lattner64fd9352002-03-28 18:08:31 +000030namespace {
Chris Lattner692ad5d2002-03-29 17:13:46 +000031 // ScalarInfo - Information about an LLVM value that we know points to some
32 // datastructure we are processing.
33 //
34 struct ScalarInfo {
35 Value *Val; // Scalar value in Current Function
36 AllocDSNode *AllocNode; // Allocation node it points to
37 Value *PoolHandle; // PoolTy* LLVM value
38
39 ScalarInfo(Value *V, AllocDSNode *AN, Value *PH)
40 : Val(V), AllocNode(AN), PoolHandle(PH) {}
41 };
42
Chris Lattner396d5d72002-03-30 04:02:31 +000043 // CallArgInfo - Information on one operand for a call that got expanded.
44 struct CallArgInfo {
45 int ArgNo; // Call argument number this corresponds to
46 AllocDSNode *AllocNode; // The allocation graph node for the pool
47 Value *PoolHandle; // The LLVM value that is the pool pointer
48
49 CallArgInfo(int Arg, AllocDSNode *AN, Value *PH)
50 : ArgNo(Arg), AllocNode(AN), PoolHandle(PH) {
51 }
52
53 bool operator<(const CallArgInfo &CAI) const {
54 return ArgNo < CAI.ArgNo;
55 }
56 };
57
Chris Lattner692ad5d2002-03-29 17:13:46 +000058 // TransformFunctionInfo - Information about how a function eeds to be
59 // transformed.
60 //
61 struct TransformFunctionInfo {
62 // ArgInfo - Maintain information about the arguments that need to be
63 // processed. Each pair corresponds to an argument (whose number is the
64 // first element) that needs to have a pool pointer (the second element)
65 // passed into the transformed function with it.
66 //
67 // As a special case, "argument" number -1 corresponds to the return value.
68 //
Chris Lattner396d5d72002-03-30 04:02:31 +000069 vector<CallArgInfo> ArgInfo;
Chris Lattner692ad5d2002-03-29 17:13:46 +000070
71 // Func - The function to be transformed...
72 Function *Func;
73
74 // default ctor...
75 TransformFunctionInfo() : Func(0) {}
76
Chris Lattner396d5d72002-03-30 04:02:31 +000077 bool operator<(const TransformFunctionInfo &TFI) const {
Chris Lattner291a1b12002-03-29 19:05:48 +000078 if (Func < TFI.Func) return true;
79 if (Func > TFI.Func) return false;
Chris Lattner291a1b12002-03-29 19:05:48 +000080 if (ArgInfo.size() < TFI.ArgInfo.size()) return true;
81 if (ArgInfo.size() > TFI.ArgInfo.size()) return false;
Chris Lattner396d5d72002-03-30 04:02:31 +000082 return ArgInfo < TFI.ArgInfo;
Chris Lattner692ad5d2002-03-29 17:13:46 +000083 }
84
85 void finalizeConstruction() {
86 // Sort the vector so that the return value is first, followed by the
87 // argument records, in order.
88 sort(ArgInfo.begin(), ArgInfo.end());
89 }
90 };
91
92
93 // Define the pass class that we implement...
Chris Lattner175f37c2002-03-29 03:40:59 +000094 class PoolAllocate : public Pass {
95 // PoolTy - The type of a scalar value that contains a pool pointer.
96 PointerType *PoolTy;
97 public:
98
99 PoolAllocate() {
100 // Initialize the PoolTy instance variable, since the type never changes.
101 vector<const Type*> PoolElements;
102 PoolElements.push_back(PointerType::get(Type::SByteTy));
103 PoolElements.push_back(Type::UIntTy);
104 PoolTy = PointerType::get(StructType::get(PoolElements));
105 // PoolTy = { sbyte*, uint }*
106
107 CurModule = 0; DS = 0;
108 PoolInit = PoolDestroy = PoolAlloc = PoolFree = 0;
Chris Lattner64fd9352002-03-28 18:08:31 +0000109 }
110
Chris Lattner175f37c2002-03-29 03:40:59 +0000111 bool run(Module *M);
112
113 // getAnalysisUsageInfo - This function requires data structure information
114 // to be able to see what is pool allocatable.
Chris Lattner64fd9352002-03-28 18:08:31 +0000115 //
116 virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Chris Lattner175f37c2002-03-29 03:40:59 +0000117 Pass::AnalysisSet &,Pass::AnalysisSet &) {
Chris Lattner64fd9352002-03-28 18:08:31 +0000118 Required.push_back(DataStructure::ID);
119 }
Chris Lattner175f37c2002-03-29 03:40:59 +0000120
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000121 public:
Chris Lattner175f37c2002-03-29 03:40:59 +0000122 // CurModule - The module being processed.
123 Module *CurModule;
124
125 // DS - The data structure graph for the module being processed.
126 DataStructure *DS;
127
128 // Prototypes that we add to support pool allocation...
129 Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree;
130
Chris Lattner692ad5d2002-03-29 17:13:46 +0000131 // The map of already transformed functions...
132 map<TransformFunctionInfo, Function*> TransformedFunctions;
133
134 // getTransformedFunction - Get a transformed function, or return null if
135 // the function specified hasn't been transformed yet.
136 //
137 Function *getTransformedFunction(TransformFunctionInfo &TFI) const {
138 map<TransformFunctionInfo, Function*>::const_iterator I =
139 TransformedFunctions.find(TFI);
140 if (I != TransformedFunctions.end()) return I->second;
141 return 0;
142 }
143
144
Chris Lattner175f37c2002-03-29 03:40:59 +0000145 // addPoolPrototypes - Add prototypes for the pool methods to the specified
146 // module and update the Pool* instance variables to point to them.
147 //
148 void addPoolPrototypes(Module *M);
149
Chris Lattner66df97d2002-03-29 06:21:38 +0000150
151 // CreatePools - Insert instructions into the function we are processing to
152 // create all of the memory pool objects themselves. This also inserts
153 // destruction code. Add an alloca for each pool that is allocated to the
154 // PoolDescriptors vector.
155 //
156 void CreatePools(Function *F, const vector<AllocDSNode*> &Allocs,
Chris Lattner396d5d72002-03-30 04:02:31 +0000157 map<AllocDSNode*, AllocaInst*> &PoolDescriptors);
Chris Lattner66df97d2002-03-29 06:21:38 +0000158
Chris Lattner175f37c2002-03-29 03:40:59 +0000159 // processFunction - Convert a function to use pool allocation where
160 // available.
161 //
162 bool processFunction(Function *F);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000163
164
Chris Lattner396d5d72002-03-30 04:02:31 +0000165 void transformFunctionBody(Function *F, vector<ScalarInfo> &Scalars,
166 map<AllocDSNode*, AllocaInst*> &PoolDescriptors);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000167
168 // transformFunction - Transform the specified function the specified way.
169 // It we have already transformed that function that way, don't do anything.
170 //
171 void transformFunction(TransformFunctionInfo &TFI);
172
Chris Lattner64fd9352002-03-28 18:08:31 +0000173 };
174}
175
Chris Lattner175f37c2002-03-29 03:40:59 +0000176
177
Chris Lattner692ad5d2002-03-29 17:13:46 +0000178// isNotPoolableAlloc - This is a predicate that returns true if the specified
Chris Lattner175f37c2002-03-29 03:40:59 +0000179// allocation node in a data structure graph is eligable for pool allocation.
180//
181static bool isNotPoolableAlloc(const AllocDSNode *DS) {
Chris Lattnere0618ca2002-03-29 05:50:20 +0000182 if (DS->isAllocaNode()) return true; // Do not pool allocate alloca's.
Chris Lattner175f37c2002-03-29 03:40:59 +0000183
184 MallocInst *MI = cast<MallocInst>(DS->getAllocation());
185 if (MI->isArrayAllocation() && !isa<Constant>(MI->getArraySize()))
Chris Lattnere0618ca2002-03-29 05:50:20 +0000186 return true; // Do not allow variable size allocations...
Chris Lattner175f37c2002-03-29 03:40:59 +0000187
Chris Lattnere0618ca2002-03-29 05:50:20 +0000188 return false;
Chris Lattner175f37c2002-03-29 03:40:59 +0000189}
190
Chris Lattner175f37c2002-03-29 03:40:59 +0000191// processFunction - Convert a function to use pool allocation where
192// available.
193//
194bool PoolAllocate::processFunction(Function *F) {
195 // Get the closed datastructure graph for the current function... if there are
196 // any allocations in this graph that are not escaping, we need to pool
197 // allocate them here!
198 //
199 FunctionDSGraph &IPGraph = DS->getClosedDSGraph(F);
200
201 // Get all of the allocations that do not escape the current function. Since
202 // they are still live (they exist in the graph at all), this means we must
203 // have scalar references to these nodes, but the scalars are never returned.
204 //
Chris Lattner692ad5d2002-03-29 17:13:46 +0000205 vector<AllocDSNode*> Allocs;
Chris Lattner175f37c2002-03-29 03:40:59 +0000206 IPGraph.getNonEscapingAllocations(Allocs);
207
208 // Filter out allocations that we cannot handle. Currently, this includes
209 // variable sized array allocations and alloca's (which we do not want to
210 // pool allocate)
211 //
212 Allocs.erase(remove_if(Allocs.begin(), Allocs.end(), isNotPoolableAlloc),
213 Allocs.end());
214
215
216 if (Allocs.empty()) return false; // Nothing to do.
217
Chris Lattner692ad5d2002-03-29 17:13:46 +0000218 // Insert instructions into the function we are processing to create all of
219 // the memory pool objects themselves. This also inserts destruction code.
Chris Lattner396d5d72002-03-30 04:02:31 +0000220 // This fills in the PoolDescriptors map to associate the alloc node with the
221 // allocation of the memory pool corresponding to it.
Chris Lattner692ad5d2002-03-29 17:13:46 +0000222 //
Chris Lattner396d5d72002-03-30 04:02:31 +0000223 map<AllocDSNode*, AllocaInst*> PoolDescriptors;
Chris Lattner692ad5d2002-03-29 17:13:46 +0000224 CreatePools(F, Allocs, PoolDescriptors);
225
226
Chris Lattner175f37c2002-03-29 03:40:59 +0000227 // Loop through the value map looking for scalars that refer to nonescaping
Chris Lattner692ad5d2002-03-29 17:13:46 +0000228 // allocations. Add them to the Scalars vector. Note that we may have
229 // multiple entries in the Scalars vector for each value if it points to more
230 // than one object.
Chris Lattner175f37c2002-03-29 03:40:59 +0000231 //
232 map<Value*, PointerValSet> &ValMap = IPGraph.getValueMap();
Chris Lattner692ad5d2002-03-29 17:13:46 +0000233 vector<ScalarInfo> Scalars;
Chris Lattner175f37c2002-03-29 03:40:59 +0000234
235 for (map<Value*, PointerValSet>::iterator I = ValMap.begin(),
236 E = ValMap.end(); I != E; ++I) {
237 const PointerValSet &PVS = I->second; // Set of things pointed to by scalar
Chris Lattner692ad5d2002-03-29 17:13:46 +0000238
239 assert(PVS.size() == 1 &&
240 "Only handle scalars that point to one thing so far!");
241
Chris Lattner175f37c2002-03-29 03:40:59 +0000242 // Check to see if the scalar points to anything that is an allocation...
243 for (unsigned i = 0, e = PVS.size(); i != e; ++i)
244 if (AllocDSNode *Alloc = dyn_cast<AllocDSNode>(PVS[i].Node)) {
245 assert(PVS[i].Index == 0 && "Nonzero not handled yet!");
246
247 // If the allocation is in the nonescaping set...
Chris Lattner396d5d72002-03-30 04:02:31 +0000248 map<AllocDSNode*, AllocaInst*>::iterator AI=PoolDescriptors.find(Alloc);
249 if (AI != PoolDescriptors.end()) // Add it to the list of scalars
250 Scalars.push_back(ScalarInfo(I->first, Alloc, AI->second));
Chris Lattner175f37c2002-03-29 03:40:59 +0000251 }
252 }
253
Chris Lattner692ad5d2002-03-29 17:13:46 +0000254 // Now we need to figure out what called methods we need to transform, and
255 // how. To do this, we look at all of the scalars, seeing which functions are
256 // either used as a scalar value (so they return a data structure), or are
257 // passed one of our scalar values.
258 //
Chris Lattner396d5d72002-03-30 04:02:31 +0000259 transformFunctionBody(F, Scalars, PoolDescriptors);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000260
261 return true;
262}
263
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000264
265class FunctionBodyTransformer : public InstVisitor<FunctionBodyTransformer> {
266 PoolAllocate &PoolAllocator;
267 vector<ScalarInfo> &Scalars;
268 map<CallInst*, TransformFunctionInfo> &CallMap;
269
270 const ScalarInfo &getScalar(const Value *V) {
271 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
272 if (Scalars[i].Val == V) return Scalars[i];
273 assert(0 && "Scalar not found in getScalar!");
274 abort();
275 return Scalars[0];
276 }
277
278 // updateScalars - Map the scalars array entries that look like 'From' to look
279 // like 'To'.
280 //
281 void updateScalars(Value *From, Value *To) {
282 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
283 if (Scalars[i].Val == From) Scalars[i].Val = To;
284 }
285
286public:
287 FunctionBodyTransformer(PoolAllocate &PA, vector<ScalarInfo> &S,
288 map<CallInst*, TransformFunctionInfo> &C)
289 : PoolAllocator(PA), Scalars(S), CallMap(C) {}
290
291 void visitMemAccessInst(MemAccessInst *MAI) {
292 // Don't do anything to load, store, or GEP yet...
293 }
294
295 // Convert a malloc instruction into a call to poolalloc
296 void visitMallocInst(MallocInst *I) {
297 const ScalarInfo &SC = getScalar(I);
298 BasicBlock *BB = I->getParent();
299 BasicBlock::iterator MI = find(BB->begin(), BB->end(), I);
300 BB->getInstList().remove(MI); // Remove the Malloc instruction from the BB
301
302 // Create a new call to poolalloc before the malloc instruction
303 vector<Value*> Args;
304 Args.push_back(SC.PoolHandle);
305 CallInst *Call = new CallInst(PoolAllocator.PoolAlloc, Args, I->getName());
306 MI = BB->getInstList().insert(MI, Call)+1;
307
308 // If the type desired is not void*, cast it now...
309 Value *Ptr = Call;
310 if (Call->getType() != I->getType()) {
311 CastInst *CI = new CastInst(Ptr, I->getType(), I->getName());
312 BB->getInstList().insert(MI, CI);
313 Ptr = CI;
314 }
315
316 // Change everything that used the malloc to now use the pool alloc...
317 I->replaceAllUsesWith(Ptr);
318
319 // Update the scalars array...
320 updateScalars(I, Ptr);
321
322 // Delete the instruction now.
323 delete I;
324 }
325
326 // Convert the free instruction into a call to poolfree
327 void visitFreeInst(FreeInst *I) {
328 Value *Ptr = I->getOperand(0);
329 const ScalarInfo &SC = getScalar(Ptr);
330 BasicBlock *BB = I->getParent();
331 BasicBlock::iterator FI = find(BB->begin(), BB->end(), I);
332
333 // If the value is not an sbyte*, convert it now!
334 if (Ptr->getType() != PointerType::get(Type::SByteTy)) {
335 CastInst *CI = new CastInst(Ptr, PointerType::get(Type::SByteTy),
336 Ptr->getName());
337 FI = BB->getInstList().insert(FI, CI)+1;
338 Ptr = CI;
339 }
340
341 // Create a new call to poolfree before the free instruction
342 vector<Value*> Args;
343 Args.push_back(SC.PoolHandle);
344 Args.push_back(Ptr);
345 CallInst *Call = new CallInst(PoolAllocator.PoolFree, Args);
346 FI = BB->getInstList().insert(FI, Call)+1;
347
348 // Remove the old free instruction...
349 delete BB->getInstList().remove(FI);
350 }
351
352 // visitCallInst - Create a new call instruction with the extra arguments for
353 // all of the memory pools that the call needs.
354 //
355 void visitCallInst(CallInst *I) {
356 TransformFunctionInfo &TI = CallMap[I];
357 BasicBlock *BB = I->getParent();
358 BasicBlock::iterator CI = find(BB->begin(), BB->end(), I);
359 BB->getInstList().remove(CI); // Remove the old call instruction
360
361 // Start with all of the old arguments...
362 vector<Value*> Args(I->op_begin()+1, I->op_end());
363
364 // Add all of the pool arguments...
365 for (unsigned i = 0, e = TI.ArgInfo.size(); i != e; ++i)
Chris Lattner396d5d72002-03-30 04:02:31 +0000366 Args.push_back(TI.ArgInfo[i].PoolHandle);
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000367
368 Function *NF = PoolAllocator.getTransformedFunction(TI);
369 CallInst *NewCall = new CallInst(NF, Args, I->getName());
370 BB->getInstList().insert(CI, NewCall);
371
372 // Change everything that used the malloc to now use the pool alloc...
373 if (I->getType() != Type::VoidTy) {
374 I->replaceAllUsesWith(NewCall);
375
376 // Update the scalars array...
377 updateScalars(I, NewCall);
378 }
379
380 delete I; // Delete the old call instruction now...
381 }
382
Chris Lattner396d5d72002-03-30 04:02:31 +0000383 void visitPHINode(PHINode *PN) {
384 // Handle PHI Node
385 }
386
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000387 void visitInstruction(Instruction *I) {
388 cerr << "Unknown instruction to FunctionBodyTransformer:\n";
389 I->dump();
390 }
391
392};
393
394
Chris Lattner396d5d72002-03-30 04:02:31 +0000395static void addCallInfo(TransformFunctionInfo &TFI, CallInst *CI, int Arg,
396 DSNode *AllocNode,
397 map<AllocDSNode*, AllocaInst*> &PoolDescriptors) {
398
399 // For now, add the entire graph that is pointed to by the call argument.
400 // This graph can and should be pruned to only what the function itself will
401 // use, because often this will be a dramatically smaller subset of what we
402 // are providing.
403 //
404 for (df_iterator<DSNode*> I = df_begin(AllocNode), E = df_end(AllocNode);
405 I != E; ++I) {
406 if (AllocDSNode *AN = dyn_cast<AllocDSNode>(*I))
407 TFI.ArgInfo.push_back(CallArgInfo(Arg, AN, PoolDescriptors[AN]));
408 }
409
410 assert(CI->getCalledFunction() && "Cannot handle indirect calls yet!");
411 assert(TFI.Func == 0 || TFI.Func == CI->getCalledFunction() &&
412 "Function call record should always call the same function!");
413 TFI.Func = CI->getCalledFunction();
414}
415
Chris Lattner692ad5d2002-03-29 17:13:46 +0000416void PoolAllocate::transformFunctionBody(Function *F,
Chris Lattner396d5d72002-03-30 04:02:31 +0000417 vector<ScalarInfo> &Scalars,
418 map<AllocDSNode*, AllocaInst*> &PoolDescriptors) {
Chris Lattner175f37c2002-03-29 03:40:59 +0000419 cerr << "In '" << F->getName()
420 << "': Found the following values that point to poolable nodes:\n";
421
422 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
Chris Lattner692ad5d2002-03-29 17:13:46 +0000423 Scalars[i].Val->dump();
Chris Lattnere0618ca2002-03-29 05:50:20 +0000424
Chris Lattner692ad5d2002-03-29 17:13:46 +0000425 // CallMap - Contain an entry for every call instruction that needs to be
426 // transformed. Each entry in the map contains information about what we need
427 // to do to each call site to change it to work.
428 //
429 map<CallInst*, TransformFunctionInfo> CallMap;
Chris Lattner66df97d2002-03-29 06:21:38 +0000430
Chris Lattner692ad5d2002-03-29 17:13:46 +0000431 // Now we need to figure out what called methods we need to transform, and
432 // how. To do this, we look at all of the scalars, seeing which functions are
433 // either used as a scalar value (so they return a data structure), or are
434 // passed one of our scalar values.
435 //
436 for (unsigned i = 0, e = Scalars.size(); i != e; ++i) {
437 Value *ScalarVal = Scalars[i].Val;
438
439 // Check to see if the scalar _IS_ a call...
440 if (CallInst *CI = dyn_cast<CallInst>(ScalarVal))
441 // If so, add information about the pool it will be returning...
Chris Lattner396d5d72002-03-30 04:02:31 +0000442 addCallInfo(CallMap[CI], CI, -1, Scalars[i].AllocNode, PoolDescriptors);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000443
444 // Check to see if the scalar is an operand to a call...
445 for (Value::use_iterator UI = ScalarVal->use_begin(),
446 UE = ScalarVal->use_end(); UI != UE; ++UI) {
447 if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
448 // Find out which operand this is to the call instruction...
449 User::op_iterator OI = find(CI->op_begin(), CI->op_end(), ScalarVal);
450 assert(OI != CI->op_end() && "Call on use list but not an operand!?");
451 assert(OI != CI->op_begin() && "Pointer operand is call destination?");
452
453 // FIXME: This is broken if the same pointer is passed to a call more
454 // than once! It will get multiple entries for the first pointer.
455
456 // Add the operand number and pool handle to the call table...
Chris Lattner396d5d72002-03-30 04:02:31 +0000457 addCallInfo(CallMap[CI], CI, OI-CI->op_begin()-1, Scalars[i].AllocNode,
458 PoolDescriptors);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000459 }
460 }
461 }
462
463 // Print out call map...
464 for (map<CallInst*, TransformFunctionInfo>::iterator I = CallMap.begin();
465 I != CallMap.end(); ++I) {
466 cerr << "\nFor call: ";
467 I->first->dump();
468 I->second.finalizeConstruction();
Chris Lattner291a1b12002-03-29 19:05:48 +0000469 cerr << I->second.Func->getName() << " must pass pool pointer for arg #";
Chris Lattner692ad5d2002-03-29 17:13:46 +0000470 for (unsigned i = 0; i < I->second.ArgInfo.size(); ++i)
Chris Lattner396d5d72002-03-30 04:02:31 +0000471 cerr << I->second.ArgInfo[i].ArgNo << " ";
Chris Lattner692ad5d2002-03-29 17:13:46 +0000472 cerr << "\n";
473 }
474
475 // Loop through all of the call nodes, recursively creating the new functions
476 // that we want to call... This uses a map to prevent infinite recursion and
477 // to avoid duplicating functions unneccesarily.
478 //
479 for (map<CallInst*, TransformFunctionInfo>::iterator I = CallMap.begin(),
480 E = CallMap.end(); I != E; ++I) {
481 // Make sure the entries are sorted.
482 I->second.finalizeConstruction();
483 transformFunction(I->second);
484 }
485
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000486 // Now that all of the functions that we want to call are available, transform
487 // the local method so that it uses the pools locally and passes them to the
488 // functions that we just hacked up.
489 //
490
491 // First step, find the instructions to be modified.
492 vector<Instruction*> InstToFix;
493 for (unsigned i = 0, e = Scalars.size(); i != e; ++i) {
494 Value *ScalarVal = Scalars[i].Val;
495
496 // Check to see if the scalar _IS_ an instruction. If so, it is involved.
497 if (Instruction *Inst = dyn_cast<Instruction>(ScalarVal))
498 InstToFix.push_back(Inst);
499
500 // All all of the instructions that use the scalar as an operand...
501 for (Value::use_iterator UI = ScalarVal->use_begin(),
502 UE = ScalarVal->use_end(); UI != UE; ++UI)
503 InstToFix.push_back(dyn_cast<Instruction>(*UI));
504 }
505
506 // Eliminate duplicates by sorting, then removing equal neighbors.
507 sort(InstToFix.begin(), InstToFix.end());
508 InstToFix.erase(unique(InstToFix.begin(), InstToFix.end()), InstToFix.end());
509
510 // Use a FunctionBodyTransformer to transform all of the involved instructions
511 FunctionBodyTransformer FBT(*this, Scalars, CallMap);
512 for (unsigned i = 0, e = InstToFix.size(); i != e; ++i)
513 FBT.visit(InstToFix[i]);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000514
515
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000516 // Since we have liberally hacked the function to pieces, we want to inform
517 // the datastructure pass that its internal representation is out of date.
518 //
519 DS->invalidateFunction(F);
Chris Lattner692ad5d2002-03-29 17:13:46 +0000520}
521
522
523// transformFunction - Transform the specified function the specified way.
524// It we have already transformed that function that way, don't do anything.
525//
526void PoolAllocate::transformFunction(TransformFunctionInfo &TFI) {
527 if (getTransformedFunction(TFI)) return; // Function xformation already done?
528
Chris Lattner291a1b12002-03-29 19:05:48 +0000529 Function *FuncToXForm = TFI.Func;
530 const FunctionType *OldFuncType = FuncToXForm->getFunctionType();
Chris Lattner692ad5d2002-03-29 17:13:46 +0000531
Chris Lattner291a1b12002-03-29 19:05:48 +0000532 assert(!OldFuncType->isVarArg() && "Vararg functions not handled yet!");
Chris Lattner692ad5d2002-03-29 17:13:46 +0000533
Chris Lattner291a1b12002-03-29 19:05:48 +0000534 // Build the type for the new function that we are transforming
535 vector<const Type*> ArgTys;
536 for (unsigned i = 0, e = OldFuncType->getNumParams(); i != e; ++i)
537 ArgTys.push_back(OldFuncType->getParamType(i));
538
539 // Add one pool pointer for every argument that needs to be supplemented.
540 ArgTys.insert(ArgTys.end(), TFI.ArgInfo.size(), PoolTy);
541
542 // Build the new function type...
543 const // FIXME when types are not const
544 FunctionType *NewFuncType = FunctionType::get(OldFuncType->getReturnType(),
545 ArgTys,OldFuncType->isVarArg());
546
547 // The new function is internal, because we know that only we can call it.
548 // This also helps subsequent IP transformations to eliminate duplicated pool
549 // pointers. [in the future when they are implemented].
550 //
551 Function *NewFunc = new Function(NewFuncType, true,
552 FuncToXForm->getName()+".poolxform");
553 CurModule->getFunctionList().push_back(NewFunc);
554
555 // Add the newly formed function to the TransformedFunctions table so that
556 // infinite recursion does not occur!
557 //
558 TransformedFunctions[TFI] = NewFunc;
559
560 // Add arguments to the function... starting with all of the old arguments
561 vector<Value*> ArgMap;
562 for (unsigned i = 0, e = FuncToXForm->getArgumentList().size(); i != e; ++i) {
563 const FunctionArgument *OFA = FuncToXForm->getArgumentList()[i];
564 FunctionArgument *NFA = new FunctionArgument(OFA->getType(),OFA->getName());
565 NewFunc->getArgumentList().push_back(NFA);
566 ArgMap.push_back(NFA); // Keep track of the arguments
567 }
568
569 // Now add all of the arguments corresponding to pools passed in...
570 for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) {
571 string Name;
Chris Lattner396d5d72002-03-30 04:02:31 +0000572 if (TFI.ArgInfo[i].ArgNo == -1)
Chris Lattner291a1b12002-03-29 19:05:48 +0000573 Name = "retpool";
574 else
Chris Lattner396d5d72002-03-30 04:02:31 +0000575 Name = ArgMap[TFI.ArgInfo[i].ArgNo]->getName(); // Get the arg name
Chris Lattner291a1b12002-03-29 19:05:48 +0000576 FunctionArgument *NFA = new FunctionArgument(PoolTy, Name+".pool");
577 NewFunc->getArgumentList().push_back(NFA);
578 }
579
580 // Now clone the body of the old function into the new function...
581 CloneFunctionInto(NewFunc, FuncToXForm, ArgMap);
582
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000583 // Okay, now we have a function that is identical to the old one, except that
584 // it has extra arguments for the pools coming in.
585
586
Chris Lattner66df97d2002-03-29 06:21:38 +0000587}
588
589
590// CreatePools - Insert instructions into the function we are processing to
591// create all of the memory pool objects themselves. This also inserts
592// destruction code. Add an alloca for each pool that is allocated to the
593// PoolDescriptors vector.
594//
595void PoolAllocate::CreatePools(Function *F, const vector<AllocDSNode*> &Allocs,
Chris Lattner396d5d72002-03-30 04:02:31 +0000596 map<AllocDSNode*, AllocaInst*> &PoolDescriptors){
Chris Lattnere0618ca2002-03-29 05:50:20 +0000597 // FIXME: This should use an IP version of the UnifyAllExits pass!
598 vector<BasicBlock*> ReturnNodes;
599 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
600 if (isa<ReturnInst>((*I)->getTerminator()))
601 ReturnNodes.push_back(*I);
602
603
604 // Create the code that goes in the entry and exit nodes for the method...
605 vector<Instruction*> EntryNodeInsts;
606 for (unsigned i = 0, e = Allocs.size(); i != e; ++i) {
607 // Add an allocation and a free for each pool...
608 AllocaInst *PoolAlloc = new AllocaInst(PoolTy, 0, "pool");
609 EntryNodeInsts.push_back(PoolAlloc);
Chris Lattner396d5d72002-03-30 04:02:31 +0000610 PoolDescriptors[Allocs[i]] = PoolAlloc; // Keep track of pool allocas
Chris Lattnere0618ca2002-03-29 05:50:20 +0000611 AllocationInst *AI = Allocs[i]->getAllocation();
612
613 // Initialize the pool. We need to know how big each allocation is. For
614 // our purposes here, we assume we are allocating a scalar, or array of
615 // constant size.
616 //
617 unsigned ElSize = TargetData.getTypeSize(AI->getAllocatedType());
618 ElSize *= cast<ConstantUInt>(AI->getArraySize())->getValue();
619
620 vector<Value*> Args;
621 Args.push_back(PoolAlloc); // Pool to initialize
622 Args.push_back(ConstantUInt::get(Type::UIntTy, ElSize));
623 EntryNodeInsts.push_back(new CallInst(PoolInit, Args));
624
625 // Destroy the pool...
626 Args.pop_back();
627
628 for (unsigned EN = 0, ENE = ReturnNodes.size(); EN != ENE; ++EN) {
629 Instruction *Destroy = new CallInst(PoolDestroy, Args);
630
631 // Insert it before the return instruction...
632 BasicBlock *RetNode = ReturnNodes[EN];
633 RetNode->getInstList().insert(RetNode->end()-1, Destroy);
634 }
635 }
636
637 // Insert the entry node code into the entry block...
638 F->getEntryNode()->getInstList().insert(F->getEntryNode()->begin()+1,
639 EntryNodeInsts.begin(),
640 EntryNodeInsts.end());
Chris Lattner175f37c2002-03-29 03:40:59 +0000641}
642
643
Chris Lattner175f37c2002-03-29 03:40:59 +0000644// addPoolPrototypes - Add prototypes for the pool methods to the specified
645// module and update the Pool* instance variables to point to them.
646//
647void PoolAllocate::addPoolPrototypes(Module *M) {
Chris Lattnere0618ca2002-03-29 05:50:20 +0000648 // Get PoolInit function...
649 vector<const Type*> Args;
650 Args.push_back(PoolTy); // Pool to initialize
651 Args.push_back(Type::UIntTy); // Num bytes per element
652 FunctionType *PoolInitTy = FunctionType::get(Type::VoidTy, Args, false);
653 PoolInit = M->getOrInsertFunction("poolinit", PoolInitTy);
Chris Lattner175f37c2002-03-29 03:40:59 +0000654
Chris Lattnere0618ca2002-03-29 05:50:20 +0000655 // Get pooldestroy function...
656 Args.pop_back(); // Only takes a pool...
657 FunctionType *PoolDestroyTy = FunctionType::get(Type::VoidTy, Args, false);
658 PoolDestroy = M->getOrInsertFunction("pooldestroy", PoolDestroyTy);
659
660 const Type *PtrVoid = PointerType::get(Type::SByteTy);
661
662 // Get the poolalloc function...
663 FunctionType *PoolAllocTy = FunctionType::get(PtrVoid, Args, false);
664 PoolAlloc = M->getOrInsertFunction("poolalloc", PoolAllocTy);
665
666 // Get the poolfree function...
667 Args.push_back(PtrVoid);
668 FunctionType *PoolFreeTy = FunctionType::get(Type::VoidTy, Args, false);
669 PoolFree = M->getOrInsertFunction("poolfree", PoolFreeTy);
670
671 // Add the %PoolTy type to the symbol table of the module...
672 M->addTypeName("PoolTy", PoolTy->getElementType());
Chris Lattner175f37c2002-03-29 03:40:59 +0000673}
674
675
676bool PoolAllocate::run(Module *M) {
677 addPoolPrototypes(M);
678 CurModule = M;
679
680 DS = &getAnalysis<DataStructure>();
681 bool Changed = false;
Chris Lattner291a1b12002-03-29 19:05:48 +0000682
683 // We cannot use an iterator here because it will get invalidated when we add
684 // functions to the module later...
685 for (unsigned i = 0; i != M->size(); ++i)
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000686 if (!M->getFunctionList()[i]->isExternal()) {
Chris Lattner291a1b12002-03-29 19:05:48 +0000687 Changed |= processFunction(M->getFunctionList()[i]);
Chris Lattnerf32d65d2002-03-29 21:25:19 +0000688 if (Changed) {
689 cerr << "Only processing one function\n";
690 break;
691 }
692 }
Chris Lattner175f37c2002-03-29 03:40:59 +0000693
694 CurModule = 0;
695 DS = 0;
696 return false;
697}
698
699
700// createPoolAllocatePass - Global function to access the functionality of this
701// pass...
702//
Chris Lattner64fd9352002-03-28 18:08:31 +0000703Pass *createPoolAllocatePass() { return new PoolAllocate(); }