llvm.org GIT mirror llvm / 478b3a9
Removing the pool allocator from the main CVS tree. Use the poolalloc module in CVS from now on. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7810 91177308-0d34-0410-b5e6-96231b3b80d8 John Criswell 17 years ago
5 changed file(s) with 0 addition(s) and 3584 deletion(s). Raw diff Collapse all Expand all
+0
-156
include/llvm/Transforms/PoolAllocate.h less more
None //===-- PoolAllocate.h - Pool allocation pass -------------------*- C++ -*-===//
1 //
2 // This transform changes programs so that disjoint data structures are
3 // allocated out of different pools of memory, increasing locality. This header
4 // file exposes information about the pool allocation itself so that follow-on
5 // passes may extend or use the pool allocation for analysis.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TRANSFORMS_POOLALLOCATE_H
10 #define LLVM_TRANSFORMS_POOLALLOCATE_H
11
12 #include "llvm/Pass.h"
13 #include "Support/hash_set"
14 #include "Support/EquivalenceClasses.h"
15 class BUDataStructures;
16 class TDDataStructures;
17 class DSNode;
18 class DSGraph;
19 class CallInst;
20
21 namespace PA {
22 /// FuncInfo - Represent the pool allocation information for one function in
23 /// the program. Note that many functions must actually be cloned in order
24 /// for pool allocation to add arguments to the function signature. In this
25 /// case, the Clone and NewToOldValueMap information identify how the clone
26 /// maps to the original function...
27 ///
28 struct FuncInfo {
29 /// MarkedNodes - The set of nodes which are not locally pool allocatable in
30 /// the current function.
31 ///
32 hash_set MarkedNodes;
33
34 /// Clone - The cloned version of the function, if applicable.
35 Function *Clone;
36
37 /// ArgNodes - The list of DSNodes which have pools passed in as arguments.
38 ///
39 std::vector ArgNodes;
40
41 /// In order to handle indirect functions, the start and end of the
42 /// arguments that are useful to this function.
43 /// The pool arguments useful to this function are PoolArgFirst to
44 /// PoolArgLast not inclusive.
45 int PoolArgFirst, PoolArgLast;
46
47 /// PoolDescriptors - The Value* (either an argument or an alloca) which
48 /// defines the pool descriptor for this DSNode. Pools are mapped one to
49 /// one with nodes in the DSGraph, so this contains a pointer to the node it
50 /// corresponds to. In addition, the pool is initialized by calling the
51 /// "poolinit" library function with a chunk of memory allocated with an
52 /// alloca instruction. This entry contains a pointer to that alloca if the
53 /// pool is locally allocated or the argument it is passed in through if
54 /// not.
55 /// Note: Does not include pool arguments that are passed in because of
56 /// indirect function calls that are not used in the function.
57 std::map PoolDescriptors;
58
59 /// NewToOldValueMap - When and if a function needs to be cloned, this map
60 /// contains a mapping from all of the values in the new function back to
61 /// the values they correspond to in the old function.
62 ///
63 std::map NewToOldValueMap;
64 };
65 }
66
67 /// PoolAllocate - The main pool allocation pass
68 ///
69 class PoolAllocate : public Pass {
70 Module *CurModule;
71 BUDataStructures *BU;
72
73 TDDataStructures *TDDS;
74
75 hash_set InlinedFuncs;
76
77 std::map FunctionInfo;
78
79 void buildIndirectFunctionSets(Module &M);
80
81 void FindFunctionPoolArgs(Function &F);
82
83 // Debug function to print the FuncECs
84 void printFuncECs();
85
86 public:
87 Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolAllocArray, *PoolFree;
88
89 // Equivalence class where functions that can potentially be called via
90 // the same function pointer are in the same class.
91 EquivalenceClasses FuncECs;
92
93 // Map from an Indirect CallInst to the set of Functions that it can point to
94 std::multimap CallInstTargets;
95
96 // This maps an equivalence class to the last pool argument number for that
97 // class. This is used because the pool arguments for all functions within
98 // an equivalence class is passed to all the functions in that class.
99 // If an equivalence class does not require pool arguments, it is not
100 // on this map.
101 std::map EqClass2LastPoolArg;
102
103 // Exception flags
104 // CollapseFlag set if all data structures are not pool allocated, due to
105 // collapsing of nodes in the DS graph
106 unsigned CollapseFlag;
107
108 public:
109 bool run(Module &M);
110
111 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
112
113 BUDataStructures &getBUDataStructures() const { return *BU; }
114
115 PA::FuncInfo *getFuncInfo(Function &F) {
116 std::map::iterator I = FunctionInfo.find(&F);
117 return I != FunctionInfo.end() ? &I->second : 0;
118 }
119
120 Module *getCurModule() { return CurModule; }
121
122 private:
123
124 /// AddPoolPrototypes - Add prototypes for the pool functions to the
125 /// specified module and update the Pool* instance variables to point to
126 /// them.
127 ///
128 void AddPoolPrototypes();
129
130 /// MakeFunctionClone - If the specified function needs to be modified for
131 /// pool allocation support, make a clone of it, adding additional arguments
132 /// as neccesary, and return it. If not, just return null.
133 ///
134 Function *MakeFunctionClone(Function &F);
135
136 /// ProcessFunctionBody - Rewrite the body of a transformed function to use
137 /// pool allocation where appropriate.
138 ///
139 void ProcessFunctionBody(Function &Old, Function &New);
140
141 /// CreatePools - This creates the pool initialization and destruction code
142 /// for the DSNodes specified by the NodesToPA list. This adds an entry to
143 /// the PoolDescriptors map for each DSNode.
144 ///
145 void CreatePools(Function &F, const std::vector &NodesToPA,
146 std::map &PoolDescriptors);
147
148 void TransformFunctionBody(Function &F, Function &OldF,
149 DSGraph &G, PA::FuncInfo &FI);
150
151 void InlineIndirectCalls(Function &F, DSGraph &G,
152 hash_set &visited);
153 };
154
155 #endif
+0
-1759
lib/Transforms/IPO/OldPoolAllocate.cpp less more
None //===-- PoolAllocate.cpp - Pool Allocation Pass ---------------------------===//
1 //
2 // This transform changes programs so that disjoint data structures are
3 // allocated out of different pools of memory, increasing locality and shrinking
4 // pointer size.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #if 0
9 #include "llvm/Transforms/IPO.h"
10 #include "llvm/Transforms/Utils/Cloning.h"
11 #include "llvm/Analysis/DataStructure.h"
12 #include "llvm/Module.h"
13 #include "llvm/iMemory.h"
14 #include "llvm/iTerminators.h"
15 #include "llvm/iPHINode.h"
16 #include "llvm/iOther.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Constants.h"
19 #include "llvm/Target/TargetData.h"
20 #include "llvm/Support/InstVisitor.h"
21 #include "Support/DepthFirstIterator.h"
22 #include "Support/STLExtras.h"
23 #include
24 using std::vector;
25 using std::cerr;
26 using std::map;
27 using std::string;
28 using std::set;
29
30 // DEBUG_CREATE_POOLS - Enable this to turn on debug output for the pool
31 // creation phase in the top level function of a transformed data structure.
32 //
33 //#define DEBUG_CREATE_POOLS 1
34
35 // DEBUG_TRANSFORM_PROGRESS - Enable this to get lots of debug output on what
36 // the transformation is doing.
37 //
38 //#define DEBUG_TRANSFORM_PROGRESS 1
39
40 // DEBUG_POOLBASE_LOAD_ELIMINATOR - Turn this on to get statistics about how
41 // many static loads were eliminated from a function...
42 //
43 #define DEBUG_POOLBASE_LOAD_ELIMINATOR 1
44
45 #include "Support/CommandLine.h"
46 enum PtrSize {
47 Ptr8bits, Ptr16bits, Ptr32bits
48 };
49
50 static cl::opt
51 ReqPointerSize("poolalloc-ptr-size",
52 cl::desc("Set pointer size for -poolalloc pass"),
53 cl::values(
54 clEnumValN(Ptr32bits, "32", "Use 32 bit indices for pointers"),
55 clEnumValN(Ptr16bits, "16", "Use 16 bit indices for pointers"),
56 clEnumValN(Ptr8bits , "8", "Use 8 bit indices for pointers"),
57 0));
58
59 static cl::opt
60 DisableRLE("no-pool-load-elim", cl::Hidden,
61 cl::desc("Disable pool load elimination after poolalloc pass"));
62
63 const Type *POINTERTYPE;
64
65 // FIXME: This is dependant on the sparc backend layout conventions!!
66 static TargetData TargetData("test");
67
68 static const Type *getPointerTransformedType(const Type *Ty) {
69 if (const PointerType *PT = dyn_cast(Ty)) {
70 return POINTERTYPE;
71 } else if (const StructType *STy = dyn_cast(Ty)) {
72 vector NewElTypes;
73 NewElTypes.reserve(STy->getElementTypes().size());
74 for (StructType::ElementTypes::const_iterator
75 I = STy->getElementTypes().begin(),
76 E = STy->getElementTypes().end(); I != E; ++I)
77 NewElTypes.push_back(getPointerTransformedType(*I));
78 return StructType::get(NewElTypes);
79 } else if (const ArrayType *ATy = dyn_cast(Ty)) {
80 return ArrayType::get(getPointerTransformedType(ATy->getElementType()),
81 ATy->getNumElements());
82 } else {
83 assert(Ty->isPrimitiveType() && "Unknown derived type!");
84 return Ty;
85 }
86 }
87
88 namespace {
89 struct PoolInfo {
90 DSNode *Node; // The node this pool allocation represents
91 Value *Handle; // LLVM value of the pool in the current context
92 const Type *NewType; // The transformed type of the memory objects
93 const Type *PoolType; // The type of the pool
94
95 const Type *getOldType() const { return Node->getType(); }
96
97 PoolInfo() { // Define a default ctor for map::operator[]
98 cerr << "Map subscript used to get element that doesn't exist!\n";
99 abort(); // Invalid
100 }
101
102 PoolInfo(DSNode *N, Value *H, const Type *NT, const Type *PT)
103 : Node(N), Handle(H), NewType(NT), PoolType(PT) {
104 // Handle can be null...
105 assert(N && NT && PT && "Pool info null!");
106 }
107
108 PoolInfo(DSNode *N) : Node(N), Handle(0), NewType(0), PoolType(0) {
109 assert(N && "Invalid pool info!");
110
111 // The new type of the memory object is the same as the old type, except
112 // that all of the pointer values are replaced with POINTERTYPE values.
113 NewType = getPointerTransformedType(getOldType());
114 }
115 };
116
117 // ScalarInfo - Information about an LLVM value that we know points to some
118 // datastructure we are processing.
119 //
120 struct ScalarInfo {
121 Value *Val; // Scalar value in Current Function
122 PoolInfo Pool; // The pool the scalar points into
123
124 ScalarInfo(Value *V, const PoolInfo &PI) : Val(V), Pool(PI) {
125 assert(V && "Null value passed to ScalarInfo ctor!");
126 }
127 };
128
129 // CallArgInfo - Information on one operand for a call that got expanded.
130 struct CallArgInfo {
131 int ArgNo; // Call argument number this corresponds to
132 DSNode *Node; // The graph node for the pool
133 Value *PoolHandle; // The LLVM value that is the pool pointer
134
135 CallArgInfo(int Arg, DSNode *N, Value *PH)
136 : ArgNo(Arg), Node(N), PoolHandle(PH) {
137 assert(Arg >= -1 && N && PH && "Illegal values to CallArgInfo ctor!");
138 }
139
140 // operator< when sorting, sort by argument number.
141 bool operator<(const CallArgInfo &CAI) const {
142 return ArgNo < CAI.ArgNo;
143 }
144 };
145
146 // TransformFunctionInfo - Information about how a function eeds to be
147 // transformed.
148 //
149 struct TransformFunctionInfo {
150 // ArgInfo - Maintain information about the arguments that need to be
151 // processed. Each CallArgInfo corresponds to an argument that needs to
152 // have a pool pointer passed into the transformed function with it.
153 //
154 // As a special case, "argument" number -1 corresponds to the return value.
155 //
156 vector ArgInfo;
157
158 // Func - The function to be transformed...
159 Function *Func;
160
161 // The call instruction that is used to map CallArgInfo PoolHandle values
162 // into the new function values.
163 CallInst *Call;
164
165 // default ctor...
166 TransformFunctionInfo() : Func(0), Call(0) {}
167
168 bool operator<(const TransformFunctionInfo &TFI) const {
169 if (Func < TFI.Func) return true;
170 if (Func > TFI.Func) return false;
171 if (ArgInfo.size() < TFI.ArgInfo.size()) return true;
172 if (ArgInfo.size() > TFI.ArgInfo.size()) return false;
173 return ArgInfo < TFI.ArgInfo;
174 }
175
176 void finalizeConstruction() {
177 // Sort the vector so that the return value is first, followed by the
178 // argument records, in order. Note that this must be a stable sort so
179 // that the entries with the same sorting criteria (ie they are multiple
180 // pool entries for the same argument) are kept in depth first order.
181 std::stable_sort(ArgInfo.begin(), ArgInfo.end());
182 }
183
184 // addCallInfo - For a specified function call CI, figure out which pool
185 // descriptors need to be passed in as arguments, and which arguments need
186 // to be transformed into indices. If Arg != -1, the specified call
187 // argument is passed in as a pointer to a data structure.
188 //
189 void addCallInfo(DataStructure *DS, CallInst *CI, int Arg,
190 DSNode *GraphNode, map &PoolDescs);
191
192 // Make sure that all dependant arguments are added to this transformation
193 // info. For example, if we call foo(null, P) and foo treats it's first and
194 // second arguments as belonging to the same data structure, the we MUST add
195 // entries to know that the null needs to be transformed into an index as
196 // well.
197 //
198 void ensureDependantArgumentsIncluded(DataStructure *DS,
199 map &PoolDescs);
200 };
201
202
203 // Define the pass class that we implement...
204 struct PoolAllocate : public Pass {
205 PoolAllocate() {
206 switch (ReqPointerSize) {
207 case Ptr32bits: POINTERTYPE = Type::UIntTy; break;
208 case Ptr16bits: POINTERTYPE = Type::UShortTy; break;
209 case Ptr8bits: POINTERTYPE = Type::UByteTy; break;
210 }
211
212 CurModule = 0; DS = 0;
213 PoolInit = PoolDestroy = PoolAlloc = PoolFree = 0;
214 }
215
216 // getPoolType - Get the type used by the backend for a pool of a particular
217 // type. This pool record is used to allocate nodes of type NodeType.
218 //
219 // Here, PoolTy = { NodeType*, sbyte*, uint }*
220 //
221 const StructType *getPoolType(const Type *NodeType) {
222 vector PoolElements;
223 PoolElements.push_back(PointerType::get(NodeType));
224 PoolElements.push_back(PointerType::get(Type::SByteTy));
225 PoolElements.push_back(Type::UIntTy);
226 StructType *Result = StructType::get(PoolElements);
227
228 // Add a name to the symbol table to correspond to the backend
229 // representation of this pool...
230 assert(CurModule && "No current module!?");
231 string Name = CurModule->getTypeName(NodeType);
232 if (Name.empty()) Name = CurModule->getTypeName(PoolElements[0]);
233 CurModule->addTypeName(Name+"oolbe", Result);
234
235 return Result;
236 }
237
238 bool run(Module &M);
239
240 // getAnalysisUsage - This function requires data structure information
241 // to be able to see what is pool allocatable.
242 //
243 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
244 AU.addRequired();
245 }
246
247 public:
248 // CurModule - The module being processed.
249 Module *CurModule;
250
251 // DS - The data structure graph for the module being processed.
252 DataStructure *DS;
253
254 // Prototypes that we add to support pool allocation...
255 Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolAllocArray, *PoolFree;
256
257 // The map of already transformed functions... note that the keys of this
258 // map do not have meaningful values for 'Call' or the 'PoolHandle' elements
259 // of the ArgInfo elements.
260 //
261 map TransformedFunctions;
262
263 // getTransformedFunction - Get a transformed function, or return null if
264 // the function specified hasn't been transformed yet.
265 //
266 Function *getTransformedFunction(TransformFunctionInfo &TFI) const {
267 map::const_iterator I =
268 TransformedFunctions.find(TFI);
269 if (I != TransformedFunctions.end()) return I->second;
270 return 0;
271 }
272
273
274 // addPoolPrototypes - Add prototypes for the pool functions to the
275 // specified module and update the Pool* instance variables to point to
276 // them.
277 //
278 void addPoolPrototypes(Module &M);
279
280
281 // CreatePools - Insert instructions into the function we are processing to
282 // create all of the memory pool objects themselves. This also inserts
283 // destruction code. Add an alloca for each pool that is allocated to the
284 // PoolDescs map.
285 //
286 void CreatePools(Function *F, const vector &Allocs,
287 map &PoolDescs);
288
289 // processFunction - Convert a function to use pool allocation where
290 // available.
291 //
292 bool processFunction(Function *F);
293
294 // transformFunctionBody - This transforms the instruction in 'F' to use the
295 // pools specified in PoolDescs when modifying data structure nodes
296 // specified in the PoolDescs map. IPFGraph is the closed data structure
297 // graph for F, of which the PoolDescriptor nodes come from.
298 //
299 void transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
300 map &PoolDescs);
301
302 // transformFunction - Transform the specified function the specified way.
303 // It we have already transformed that function that way, don't do anything.
304 // The nodes in the TransformFunctionInfo come out of callers data structure
305 // graph, and the PoolDescs passed in are the caller's.
306 //
307 void transformFunction(TransformFunctionInfo &TFI,
308 FunctionDSGraph &CallerIPGraph,
309 map &PoolDescs);
310
311 };
312
313 RegisterOpt X("poolalloc",
314 "Pool allocate disjoint datastructures");
315 }
316
317 // isNotPoolableAlloc - This is a predicate that returns true if the specified
318 // allocation node in a data structure graph is eligable for pool allocation.
319 //
320 static bool isNotPoolableAlloc(const AllocDSNode *DS) {
321 if (DS->isAllocaNode()) return true; // Do not pool allocate alloca's.
322 return false;
323 }
324
325 // processFunction - Convert a function to use pool allocation where
326 // available.
327 //
328 bool PoolAllocate::processFunction(Function *F) {
329 // Get the closed datastructure graph for the current function... if there are
330 // any allocations in this graph that are not escaping, we need to pool
331 // allocate them here!
332 //
333 FunctionDSGraph &IPGraph = DS->getClosedDSGraph(F);
334
335 // Get all of the allocations that do not escape the current function. Since
336 // they are still live (they exist in the graph at all), this means we must
337 // have scalar references to these nodes, but the scalars are never returned.
338 //
339 vector Allocs;
340 IPGraph.getNonEscapingAllocations(Allocs);
341
342 // Filter out allocations that we cannot handle. Currently, this includes
343 // variable sized array allocations and alloca's (which we do not want to
344 // pool allocate)
345 //
346 Allocs.erase(std::remove_if(Allocs.begin(), Allocs.end(), isNotPoolableAlloc),
347 Allocs.end());
348
349
350 if (Allocs.empty()) return false; // Nothing to do.
351
352 #ifdef DEBUG_TRANSFORM_PROGRESS
353 cerr << "Transforming Function: " << F->getName() << "\n";
354 #endif
355
356 // Insert instructions into the function we are processing to create all of
357 // the memory pool objects themselves. This also inserts destruction code.
358 // This fills in the PoolDescs map to associate the alloc node with the
359 // allocation of the memory pool corresponding to it.
360 //
361 map PoolDescs;
362 CreatePools(F, Allocs, PoolDescs);
363
364 #ifdef DEBUG_TRANSFORM_PROGRESS
365 cerr << "Transformed Entry Function: \n" << F;
366 #endif
367
368 // Now we need to figure out what called functions we need to transform, and
369 // how. To do this, we look at all of the scalars, seeing which functions are
370 // either used as a scalar value (so they return a data structure), or are
371 // passed one of our scalar values.
372 //
373 transformFunctionBody(F, IPGraph, PoolDescs);
374
375 return true;
376 }
377
378
379 //===----------------------------------------------------------------------===//
380 //
381 // NewInstructionCreator - This class is used to traverse the function being
382 // modified, changing each instruction visit'ed to use and provide pointer
383 // indexes instead of real pointers. This is what changes the body of a
384 // function to use pool allocation.
385 //
386 class NewInstructionCreator : public InstVisitor {
387 PoolAllocate &PoolAllocator;
388 vector &Scalars;
389 map &CallMap;
390 map &XFormMap; // Map old pointers to new indexes
391
392 struct RefToUpdate {
393 Instruction *I; // Instruction to update
394 unsigned OpNum; // Operand number to update
395 Value *OldVal; // The old value it had
396
397 RefToUpdate(Instruction *i, unsigned o, Value *ov)
398 : I(i), OpNum(o), OldVal(ov) {}
399 };
400 vector ReferencesToUpdate;
401
402 const ScalarInfo &getScalarRef(const Value *V) {
403 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
404 if (Scalars[i].Val == V) return Scalars[i];
405
406 cerr << "Could not find scalar " << V << " in scalar map!\n";
407 assert(0 && "Scalar not found in getScalar!");
408 abort();
409 return Scalars[0];
410 }
411
412 const ScalarInfo *getScalar(const Value *V) {
413 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
414 if (Scalars[i].Val == V) return &Scalars[i];
415 return 0;
416 }
417
418 BasicBlock::iterator ReplaceInstWith(Instruction &I, Instruction *New) {
419 BasicBlock *BB = I.getParent();
420 BasicBlock::iterator RI = &I;
421 BB->getInstList().remove(RI);
422 BB->getInstList().insert(RI, New);
423 XFormMap[&I] = New;
424 return New;
425 }
426
427 Instruction *createPoolBaseInstruction(Value *PtrVal) {
428 const ScalarInfo &SC = getScalarRef(PtrVal);
429 vector Args(3);
430 Args[0] = ConstantUInt::get(Type::UIntTy, 0); // No pointer offset
431 Args[1] = ConstantUInt::get(Type::UByteTy, 0); // Field #0 of pool descriptr
432 Args[2] = ConstantUInt::get(Type::UByteTy, 0); // Field #0 of poolalloc val
433 return new LoadInst(SC.Pool.Handle, Args, PtrVal->getName()+".poolbase");
434 }
435
436
437 public:
438 NewInstructionCreator(PoolAllocate &PA, vector &S,
439 map &C,
440 map &X)
441 : PoolAllocator(PA), Scalars(S), CallMap(C), XFormMap(X) {}
442
443
444 // updateReferences - The NewInstructionCreator is responsible for creating
445 // new instructions to replace the old ones in the function, and then link up
446 // references to values to their new values. For it to do this, however, it
447 // keeps track of information about the value mapping of old values to new
448 // values that need to be patched up. Given this value map and a set of
449 // instruction operands to patch, updateReferences performs the updates.
450 //
451 void updateReferences() {
452 for (unsigned i = 0, e = ReferencesToUpdate.size(); i != e; ++i) {
453 RefToUpdate &Ref = ReferencesToUpdate[i];
454 Value *NewVal = XFormMap[Ref.OldVal];
455
456 if (NewVal == 0) {
457 if (isa(Ref.OldVal) && // Refering to a null ptr?
458 cast(Ref.OldVal)->isNullValue()) {
459 // Transform the null pointer into a null index... caching in XFormMap
460 XFormMap[Ref.OldVal] = NewVal = Constant::getNullValue(POINTERTYPE);
461 //} else if (isa(Ref.OldVal)) {
462 } else {
463 cerr << "Unknown reference to: " << Ref.OldVal << "\n";
464 assert(XFormMap[Ref.OldVal] &&
465 "Reference to value that was not updated found!");
466 }
467 }
468
469 Ref.I->setOperand(Ref.OpNum, NewVal);
470 }
471 ReferencesToUpdate.clear();
472 }
473
474 //===--------------------------------------------------------------------===//
475 // Transformation methods:
476 // These methods specify how each type of instruction is transformed by the
477 // NewInstructionCreator instance...
478 //===--------------------------------------------------------------------===//
479
480 void visitGetElementPtrInst(GetElementPtrInst &I) {
481 assert(0 && "Cannot transform get element ptr instructions yet!");
482 }
483
484 // Replace the load instruction with a new one.
485 void visitLoadInst(LoadInst &I) {
486 vector BeforeInsts;
487
488 // Cast our index to be a UIntTy so we can use it to index into the pool...
489 CastInst *Index = new CastInst(Constant::getNullValue(POINTERTYPE),
490 Type::UIntTy, I.getOperand(0)->getName());
491 BeforeInsts.push_back(Index);
492 ReferencesToUpdate.push_back(RefToUpdate(Index, 0, I.getOperand(0)));
493
494 // Include the pool base instruction...
495 Instruction *PoolBase = createPoolBaseInstruction(I.getOperand(0));
496 BeforeInsts.push_back(PoolBase);
497
498 Instruction *IdxInst =
499 BinaryOperator::create(Instruction::Add, *I.idx_begin(), Index,
500 I.getName()+".idx");
501 BeforeInsts.push_back(IdxInst);
502
503 vector Indices(I.idx_begin(), I.idx_end());
504 Indices[0] = IdxInst;
505 Instruction *Address = new GetElementPtrInst(PoolBase, Indices,
506 I.getName()+".addr");
507 BeforeInsts.push_back(Address);
508
509 Instruction *NewLoad = new LoadInst(Address, I.getName());
510
511 // Replace the load instruction with the new load instruction...
512 BasicBlock::iterator II = ReplaceInstWith(I, NewLoad);
513
514 // Add all of the instructions before the load...
515 NewLoad->getParent()->getInstList().insert(II, BeforeInsts.begin(),
516 BeforeInsts.end());
517
518 // If not yielding a pool allocated pointer, use the new load value as the
519 // value in the program instead of the old load value...
520 //
521 if (!getScalar(&I))
522 I.replaceAllUsesWith(NewLoad);
523 }
524
525 // Replace the store instruction with a new one. In the store instruction,
526 // the value stored could be a pointer type, meaning that the new store may
527 // have to change one or both of it's operands.
528 //
529 void visitStoreInst(StoreInst &I) {
530 assert(getScalar(I.getOperand(1)) &&
531 "Store inst found only storing pool allocated pointer. "
532 "Not imp yet!");
533
534 Value *Val = I.getOperand(0); // The value to store...
535
536 // Check to see if the value we are storing is a data structure pointer...
537 //if (const ScalarInfo *ValScalar = getScalar(I.getOperand(0)))
538 if (isa(I.getOperand(0)->getType()))
539 Val = Constant::getNullValue(POINTERTYPE); // Yes, store a dummy
540
541 Instruction *PoolBase = createPoolBaseInstruction(I.getOperand(1));
542
543 // Cast our index to be a UIntTy so we can use it to index into the pool...
544 CastInst *Index = new CastInst(Constant::getNullValue(POINTERTYPE),
545 Type::UIntTy, I.getOperand(1)->getName());
546 ReferencesToUpdate.push_back(RefToUpdate(Index, 0, I.getOperand(1)));
547
548 // Instructions to add after the Index...
549 vector AfterInsts;
550
551 Instruction *IdxInst =
552 BinaryOperator::create(Instruction::Add, *I.idx_begin(), Index, "idx");
553 AfterInsts.push_back(IdxInst);
554
555 vector Indices(I.idx_begin(), I.idx_end());
556 Indices[0] = IdxInst;
557 Instruction *Address = new GetElementPtrInst(PoolBase, Indices,
558 I.getName()+"storeaddr");
559 AfterInsts.push_back(Address);
560
561 Instruction *NewStore = new StoreInst(Val, Address);
562 AfterInsts.push_back(NewStore);
563 if (Val != I.getOperand(0)) // Value stored was a pointer?
564 ReferencesToUpdate.push_back(RefToUpdate(NewStore, 0, I.getOperand(0)));
565
566
567 // Replace the store instruction with the cast instruction...
568 BasicBlock::iterator II = ReplaceInstWith(I, Index);
569
570 // Add the pool base calculator instruction before the index...
571 II = ++Index->getParent()->getInstList().insert(II, PoolBase);
572 ++II;
573
574 // Add the instructions that go after the index...
575 Index->getParent()->getInstList().insert(II, AfterInsts.begin(),
576 AfterInsts.end());
577 }
578
579
580 // Create call to poolalloc for every malloc instruction
581 void visitMallocInst(MallocInst &I) {
582 const ScalarInfo &SCI = getScalarRef(&I);
583 vector Args;
584
585 CallInst *Call;
586 if (!I.isArrayAllocation()) {
587 Args.push_back(SCI.Pool.Handle);
588 Call = new CallInst(PoolAllocator.PoolAlloc, Args, I.getName());
589 } else {
590 Args.push_back(I.getArraySize());
591 Args.push_back(SCI.Pool.Handle);
592 Call = new CallInst(PoolAllocator.PoolAllocArray, Args, I.getName());
593 }
594
595 ReplaceInstWith(I, Call);
596 }
597
598 // Convert a call to poolfree for every free instruction...
599 void visitFreeInst(FreeInst &I) {
600 // Create a new call to poolfree before the free instruction
601 vector Args;
602 Args.push_back(Constant::getNullValue(POINTERTYPE));
603 Args.push_back(getScalarRef(I.getOperand(0)).Pool.Handle);
604 Instruction *NewCall = new CallInst(PoolAllocator.PoolFree, Args);
605 ReplaceInstWith(I, NewCall);
606 ReferencesToUpdate.push_back(RefToUpdate(NewCall, 1, I.getOperand(0)));
607 }
608
609 // visitCallInst - Create a new call instruction with the extra arguments for
610 // all of the memory pools that the call needs.
611 //
612 void visitCallInst(CallInst &I) {
613 TransformFunctionInfo &TI = CallMap[&I];
614
615 // Start with all of the old arguments...
616 vector Args(I.op_begin()+1, I.op_end());
617
618 for (unsigned i = 0, e = TI.ArgInfo.size(); i != e; ++i) {
619 // Replace all of the pointer arguments with our new pointer typed values.
620 if (TI.ArgInfo[i].ArgNo != -1)
621 Args[TI.ArgInfo[i].ArgNo] = Constant::getNullValue(POINTERTYPE);
622
623 // Add all of the pool arguments...
624 Args.push_back(TI.ArgInfo[i].PoolHandle);
625 }
626
627 Function *NF = PoolAllocator.getTransformedFunction(TI);
628 Instruction *NewCall = new CallInst(NF, Args, I.getName());
629 ReplaceInstWith(I, NewCall);
630
631 // Keep track of the mapping of operands so that we can resolve them to real
632 // values later.
633 Value *RetVal = NewCall;
634 for (unsigned i = 0, e = TI.ArgInfo.size(); i != e; ++i)
635 if (TI.ArgInfo[i].ArgNo != -1)
636 ReferencesToUpdate.push_back(RefToUpdate(NewCall, TI.ArgInfo[i].ArgNo+1,
637 I.getOperand(TI.ArgInfo[i].ArgNo+1)));
638 else
639 RetVal = 0; // If returning a pointer, don't change retval...
640
641 // If not returning a pointer, use the new call as the value in the program
642 // instead of the old call...
643 //
644 if (RetVal)
645 I.replaceAllUsesWith(RetVal);
646 }
647
648 // visitPHINode - Create a new PHI node of POINTERTYPE for all of the old Phi
649 // nodes...
650 //
651 void visitPHINode(PHINode &PN) {
652 Value *DummyVal = Constant::getNullValue(POINTERTYPE);
653 PHINode *NewPhi = new PHINode(POINTERTYPE, PN.getName());
654 for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
655 NewPhi->addIncoming(DummyVal, PN.getIncomingBlock(i));
656 ReferencesToUpdate.push_back(RefToUpdate(NewPhi, i*2,
657 PN.getIncomingValue(i)));
658 }
659
660 ReplaceInstWith(PN, NewPhi);
661 }
662
663 // visitReturnInst - Replace ret instruction with a new return...
664 void visitReturnInst(ReturnInst &I) {
665 Instruction *Ret = new ReturnInst(Constant::getNullValue(POINTERTYPE));
666 ReplaceInstWith(I, Ret);
667 ReferencesToUpdate.push_back(RefToUpdate(Ret, 0, I.getOperand(0)));
668 }
669
670 // visitSetCondInst - Replace a conditional test instruction with a new one
671 void visitSetCondInst(SetCondInst &SCI) {
672 BinaryOperator &I = (BinaryOperator&)SCI;
673 Value *DummyVal = Constant::getNullValue(POINTERTYPE);
674 BinaryOperator *New = BinaryOperator::create(I.getOpcode(), DummyVal,
675 DummyVal, I.getName());
676 ReplaceInstWith(I, New);
677
678 ReferencesToUpdate.push_back(RefToUpdate(New, 0, I.getOperand(0)));
679 ReferencesToUpdate.push_back(RefToUpdate(New, 1, I.getOperand(1)));
680
681 // Make sure branches refer to the new condition...
682 I.replaceAllUsesWith(New);
683 }
684
685 void visitInstruction(Instruction &I) {
686 cerr << "Unknown instruction to FunctionBodyTransformer:\n" << I;
687 }
688 };
689
690
691 // PoolBaseLoadEliminator - Every load and store through a pool allocated
692 // pointer causes a load of the real pool base out of the pool descriptor.
693 // Iterate through the function, doing a local elimination pass of duplicate
694 // loads. This attempts to turn the all too common:
695 //
696 // %reg109.poolbase22 = load %root.pool* %root.pool, uint 0, ubyte 0, ubyte 0
697 // %reg207 = load %root.p* %reg109.poolbase22, uint %reg109, ubyte 0, ubyte 0
698 // %reg109.poolbase23 = load %root.pool* %root.pool, uint 0, ubyte 0, ubyte 0
699 // store double %reg207, %root.p* %reg109.poolbase23, uint %reg109, ...
700 //
701 // into:
702 // %reg109.poolbase22 = load %root.pool* %root.pool, uint 0, ubyte 0, ubyte 0
703 // %reg207 = load %root.p* %reg109.poolbase22, uint %reg109, ubyte 0, ubyte 0
704 // store double %reg207, %root.p* %reg109.poolbase22, uint %reg109, ...
705 //
706 //
707 class PoolBaseLoadEliminator : public InstVisitor {
708 // PoolDescValues - Keep track of the values in the current function that are
709 // pool descriptors (loads from which we want to eliminate).
710 //
711 vector PoolDescValues;
712
713 // PoolDescMap - As we are analyzing a BB, keep track of which load to use
714 // when referencing a pool descriptor.
715 //
716 map PoolDescMap;
717
718 // These two fields keep track of statistics of how effective we are, if
719 // debugging is enabled.
720 //
721 unsigned Eliminated, Remaining;
722 public:
723 // Compact the pool descriptor map into a list of the pool descriptors in the
724 // current context that we should know about...
725 //
726 PoolBaseLoadEliminator(const map &PoolDescs) {
727 Eliminated = Remaining = 0;
728 for (map::const_iterator I = PoolDescs.begin(),
729 E = PoolDescs.end(); I != E; ++I)
730 PoolDescValues.push_back(I->second.Handle);
731
732 // Remove duplicates from the list of pool values
733 sort(PoolDescValues.begin(), PoolDescValues.end());
734 PoolDescValues.erase(unique(PoolDescValues.begin(), PoolDescValues.end()),
735 PoolDescValues.end());
736 }
737
738 #ifdef DEBUG_POOLBASE_LOAD_ELIMINATOR
739 void visitFunction(Function &F) {
740 cerr << "Pool Load Elim '" << F.getName() << "'\t";
741 }
742 ~PoolBaseLoadEliminator() {
743 unsigned Total = Eliminated+Remaining;
744 if (Total)
745 cerr << "removed " << Eliminated << "["
746 << Eliminated*100/Total << "%] loads, leaving "
747 << Remaining << ".\n";
748 }
749 #endif
750
751 // Loop over the function, looking for loads to eliminate. Because we are a
752 // local transformation, we reset all of our state when we enter a new basic
753 // block.
754 //
755 void visitBasicBlock(BasicBlock &) {
756 PoolDescMap.clear(); // Forget state.
757 }
758
759 // Starting with an empty basic block, we scan it looking for loads of the
760 // pool descriptor. When we find a load, we add it to the PoolDescMap,
761 // indicating that we have a value available to recycle next time we see the
762 // poolbase of this instruction being loaded.
763 //
764 void visitLoadInst(LoadInst &LI) {
765 Value *LoadAddr = LI.getPointerOperand();
766 map::iterator VIt = PoolDescMap.find(LoadAddr);
767 if (VIt != PoolDescMap.end()) { // We already have a value for this load?
768 LI.replaceAllUsesWith(VIt->second); // Make the current load dead
769 ++Eliminated;
770 } else {
771 // This load might not be a load of a pool pointer, check to see if it is
772 if (LI.getNumOperands() == 4 && // load pool, uint 0, ubyte 0, ubyte 0
773 find(PoolDescValues.begin(), PoolDescValues.end(), LoadAddr) !=
774 PoolDescValues.end()) {
775
776 assert("Make sure it's a load of the pool base, not a chaining field" &&
777 LI.getOperand(1) == Constant::getNullValue(Type::UIntTy) &&
778 LI.getOperand(2) == Constant::getNullValue(Type::UByteTy) &&
779 LI.getOperand(3) == Constant::getNullValue(Type::UByteTy));
780
781 // If it is a load of a pool base, keep track of it for future reference
782 PoolDescMap.insert(std::make_pair(LoadAddr, &LI));
783 ++Remaining;
784 }
785 }
786 }
787
788 // If we run across a function call, forget all state... Calls to
789 // poolalloc/poolfree can invalidate the pool base pointer, so it should be
790 // reloaded the next time it is used. Furthermore, a call to a random
791 // function might call one of these functions, so be conservative. Through
792 // more analysis, this could be improved in the future.
793 //
794 void visitCallInst(CallInst &) {
795 PoolDescMap.clear();
796 }
797 };
798
799 static void addNodeMapping(DSNode *SrcNode, const PointerValSet &PVS,
800 map &NodeMapping) {
801 for (unsigned i = 0, e = PVS.size(); i != e; ++i)
802 if (NodeMapping[SrcNode].add(PVS[i])) { // Not in map yet?
803 assert(PVS[i].Index == 0 && "Node indexing not supported yet!");
804 DSNode *DestNode = PVS[i].Node;
805
806 // Loop over all of the outgoing links in the mapped graph
807 for (unsigned l = 0, le = DestNode->getNumOutgoingLinks(); l != le; ++l) {
808 PointerValSet &SrcSet = SrcNode->getOutgoingLink(l);
809 const PointerValSet &DestSet = DestNode->getOutgoingLink(l);
810
811 // Add all of the node mappings now!
812 for (unsigned si = 0, se = SrcSet.size(); si != se; ++si) {
813 assert(SrcSet[si].Index == 0 && "Can't handle node offset!");
814 addNodeMapping(SrcSet[si].Node, DestSet, NodeMapping);
815 }
816 }
817 }
818 }
819
820 // CalculateNodeMapping - There is a partial isomorphism between the graph
821 // passed in and the graph that is actually used by the function. We need to
822 // figure out what this mapping is so that we can transformFunctionBody the
823 // instructions in the function itself. Note that every node in the graph that
824 // we are interested in must be both in the local graph of the called function,
825 // and in the local graph of the calling function. Because of this, we only
826 // define the mapping for these nodes [conveniently these are the only nodes we
827 // CAN define a mapping for...]
828 //
829 // The roots of the graph that we are transforming is rooted in the arguments
830 // passed into the function from the caller. This is where we start our
831 // mapping calculation.
832 //
833 // The NodeMapping calculated maps from the callers graph to the called graph.
834 //
835 static void CalculateNodeMapping(Function *F, TransformFunctionInfo &TFI,
836 FunctionDSGraph &CallerGraph,
837 FunctionDSGraph &CalledGraph,
838 map &NodeMapping) {
839 int LastArgNo = -2;
840 for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) {
841 // Figure out what nodes in the called graph the TFI.ArgInfo[i].Node node
842 // corresponds to...
843 //
844 // Only consider first node of sequence. Extra nodes may may be added
845 // to the TFI if the data structure requires more nodes than just the
846 // one the argument points to. We are only interested in the one the
847 // argument points to though.
848 //
849 if (TFI.ArgInfo[i].ArgNo != LastArgNo) {
850 if (TFI.ArgInfo[i].ArgNo == -1) {
851 addNodeMapping(TFI.ArgInfo[i].Node, CalledGraph.getRetNodes(),
852 NodeMapping);
853 } else {
854 // Figure out which node argument # ArgNo points to in the called graph.
855 Function::aiterator AI = F->abegin();
856 std::advance(AI, TFI.ArgInfo[i].ArgNo);
857 addNodeMapping(TFI.ArgInfo[i].Node, CalledGraph.getValueMap()[AI],
858 NodeMapping);
859 }
860 LastArgNo = TFI.ArgInfo[i].ArgNo;
861 }
862 }
863 }
864
865
866
867
868 // addCallInfo - For a specified function call CI, figure out which pool
869 // descriptors need to be passed in as arguments, and which arguments need to be
870 // transformed into indices. If Arg != -1, the specified call argument is
871 // passed in as a pointer to a data structure.
872 //
873 void TransformFunctionInfo::addCallInfo(DataStructure *DS, CallInst *CI,
874 int Arg, DSNode *GraphNode,
875 map &PoolDescs) {
876 assert(CI->getCalledFunction() && "Cannot handle indirect calls yet!");
877 assert(Func == 0 || Func == CI->getCalledFunction() &&
878 "Function call record should always call the same function!");
879 assert(Call == 0 || Call == CI &&
880 "Call element already filled in with different value!");
881 Func = CI->getCalledFunction();
882 Call = CI;
883 //FunctionDSGraph &CalledGraph = DS->getClosedDSGraph(Func);
884
885 // For now, add the entire graph that is pointed to by the call argument.
886 // This graph can and should be pruned to only what the function itself will
887 // use, because often this will be a dramatically smaller subset of what we
888 // are providing.
889 //
890 // FIXME: This should use pool links instead of extra arguments!
891 //
892 for (df_iterator I = df_begin(GraphNode), E = df_end(GraphNode);
893 I != E; ++I)
894 ArgInfo.push_back(CallArgInfo(Arg, *I, PoolDescs[*I].Handle));
895 }
896
897 static void markReachableNodes(const PointerValSet &Vals,
898 set &ReachableNodes) {
899 for (unsigned n = 0, ne = Vals.size(); n != ne; ++n) {
900 DSNode *N = Vals[n].Node;
901 if (ReachableNodes.count(N) == 0) // Haven't already processed node?
902 ReachableNodes.insert(df_begin(N), df_end(N)); // Insert all
903 }
904 }
905
906 // Make sure that all dependant arguments are added to this transformation info.
907 // For example, if we call foo(null, P) and foo treats it's first and second
908 // arguments as belonging to the same data structure, the we MUST add entries to
909 // know that the null needs to be transformed into an index as well.
910 //
911 void TransformFunctionInfo::ensureDependantArgumentsIncluded(DataStructure *DS,
912 map &PoolDescs) {
913 // FIXME: This does not work for indirect function calls!!!
914 if (Func == 0) return; // FIXME!
915
916 // Make sure argument entries are sorted.
917 finalizeConstruction();
918
919 // Loop over the function signature, checking to see if there are any pointer
920 // arguments that we do not convert... if there is something we haven't
921 // converted, set done to false.
922 //
923 unsigned PtrNo = 0;
924 bool Done = true;
925 if (isa(Func->getReturnType())) // Make sure we convert retval
926 if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == -1) {
927 // We DO transform the ret val... skip all possible entries for retval
928 while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == -1)
929 PtrNo++;
930 } else {
931 Done = false;
932 }
933
934 unsigned i = 0;
935 for (Function::aiterator I = Func->abegin(), E = Func->aend(); I!=E; ++I,++i){
936 if (isa(I->getType())) {
937 if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == (int)i) {
938 // We DO transform this arg... skip all possible entries for argument
939 while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == (int)i)
940 PtrNo++;
941 } else {
942 Done = false;
943 break;
944 }
945 }
946 }
947
948 // If we already have entries for all pointer arguments and retvals, there
949 // certainly is no work to do. Bail out early to avoid building relatively
950 // expensive data structures.
951 //
952 if (Done) return;
953
954 #ifdef DEBUG_TRANSFORM_PROGRESS
955 cerr << "Must ensure dependant arguments for: " << Func->getName() << "\n";
956 #endif
957
958 // Otherwise, we MIGHT have to add the arguments/retval if they are part of
959 // the same datastructure graph as some other argument or retval that we ARE
960 // processing.
961 //
962 // Get the data structure graph for the called function.
963 //
964 FunctionDSGraph &CalledDS = DS->getClosedDSGraph(Func);
965
966 // Build a mapping between the nodes in our current graph and the nodes in the
967 // called function's graph. We build it based on our _incomplete_
968 // transformation information, because it contains all of the info that we
969 // should need.
970 //
971 map NodeMapping;
972 CalculateNodeMapping(Func, *this,
973 DS->getClosedDSGraph(Call->getParent()->getParent()),
974 CalledDS, NodeMapping);
975
976 // Build the inverted version of the node mapping, that maps from a node in
977 // the called functions graph to a single node in the caller graph.
978 //
979 map InverseNodeMap;
980 for (map::iterator I = NodeMapping.begin(),
981 E = NodeMapping.end(); I != E; ++I) {
982 PointerValSet &CalledNodes = I->second;
983 for (unsigned i = 0, e = CalledNodes.size(); i != e; ++i)
984 InverseNodeMap[CalledNodes[i].Node] = I->first;
985 }
986 NodeMapping.clear(); // Done with information, free memory
987
988 // Build a set of reachable nodes from the arguments/retval that we ARE
989 // passing in...
990 set ReachableNodes;
991
992 // Loop through all of the arguments, marking all of the reachable data
993 // structure nodes reachable if they are from this pointer...
994 //
995 for (unsigned i = 0, e = ArgInfo.size(); i != e; ++i) {
996 if (ArgInfo[i].ArgNo == -1) {
997 if (i == 0) // Only process retvals once (performance opt)
998 markReachableNodes(CalledDS.getRetNodes(), ReachableNodes);
999 } else { // If it's an argument value...
1000 Function::aiterator AI = Func->abegin();
1001 std::advance(AI, ArgInfo[i].ArgNo);
1002 if (isa(AI->getType()))
1003 markReachableNodes(CalledDS.getValueMap()[AI], ReachableNodes);
1004 }
1005 }
1006
1007 // Now that we know which nodes are already reachable, see if any of the
1008 // arguments that we are not passing values in for can reach one of the
1009 // existing nodes...
1010 //
1011
1012 // IN THEORY, we should allow arbitrary paths from the argument to
1013 // nodes we know about. The problem is that if we do this, then I don't know
1014 // how to get pool pointers for this head list. Since we are completely
1015 // deadline driven, I'll just allow direct accesses to the graph.
1016 //
1017
1018 PtrNo = 0;
1019 if (isa(Func->getReturnType())) // Make sure we convert retval
1020 if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == -1) {
1021 // We DO transform the ret val... skip all possible entries for retval
1022 while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == -1)
1023 PtrNo++;
1024 } else {
1025 // See what the return value points to...
1026
1027 // FIXME: This should generalize to any number of nodes, just see if any
1028 // are reachable.
1029 assert(CalledDS.getRetNodes().size() == 1 &&
1030 "Assumes only one node is returned");
1031 DSNode *N = CalledDS.getRetNodes()[0].Node;
1032
1033 // If the return value is not marked as being passed in, but it NEEDS to
1034 // be transformed, then make it known now.
1035 //
1036 if (ReachableNodes.count(N)) {
1037 #ifdef DEBUG_TRANSFORM_PROGRESS
1038 cerr << "ensure dependant arguments adds return value entry!\n";
1039 #endif
1040 addCallInfo(DS, Call, -1, InverseNodeMap[N], PoolDescs);
1041
1042 // Keep sorted!
1043 finalizeConstruction();
1044 }
1045 }
1046
1047 i = 0;
1048 for (Function::aiterator I = Func->abegin(), E = Func->aend(); I!=E; ++I, ++i)
1049 if (isa(I->getType())) {
1050 if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == (int)i) {
1051 // We DO transform this arg... skip all possible entries for argument
1052 while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == (int)i)
1053 PtrNo++;
1054 } else {
1055 // This should generalize to any number of nodes, just see if any are
1056 // reachable.
1057 assert(CalledDS.getValueMap()[I].size() == 1 &&
1058 "Only handle case where pointing to one node so far!");
1059
1060 // If the arg is not marked as being passed in, but it NEEDS to
1061 // be transformed, then make it known now.
1062 //
1063 DSNode *N = CalledDS.getValueMap()[I][0].Node;
1064 if (ReachableNodes.count(N)) {
1065 #ifdef DEBUG_TRANSFORM_PROGRESS
1066 cerr << "ensure dependant arguments adds for arg #" << i << "\n";
1067 #endif
1068 addCallInfo(DS, Call, i, InverseNodeMap[N], PoolDescs);
1069
1070 // Keep sorted!
1071 finalizeConstruction();
1072 }
1073 }
1074 }
1075 }
1076
1077
1078 // transformFunctionBody - This transforms the instruction in 'F' to use the
1079 // pools specified in PoolDescs when modifying data structure nodes specified in
1080 // the PoolDescs map. Specifically, scalar values specified in the Scalars
1081 // vector must be remapped. IPFGraph is the closed data structure graph for F,
1082 // of which the PoolDescriptor nodes come from.
1083 //
1084 void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
1085 map &PoolDescs) {
1086
1087 // Loop through the value map looking for scalars that refer to nonescaping
1088 // allocations. Add them to the Scalars vector. Note that we may have
1089 // multiple entries in the Scalars vector for each value if it points to more
1090 // than one object.
1091 //
1092 map &ValMap = IPFGraph.getValueMap();
1093 vector Scalars;
1094
1095 #ifdef DEBUG_TRANSFORM_PROGRESS
1096 cerr << "Building scalar map for fn '" << F->getName() << "' body:\n";
1097 #endif
1098
1099 for (map::iterator I = ValMap.begin(),
1100 E = ValMap.end(); I != E; ++I) {
1101 const PointerValSet &PVS = I->second; // Set of things pointed to by scalar
1102
1103 // Check to see if the scalar points to a data structure node...
1104 for (unsigned i = 0, e = PVS.size(); i != e; ++i) {
1105 if (PVS[i].Index) { cerr << "Problem in " << F->getName() << " for " << I->first << "\n"; }
1106 assert(PVS[i].Index == 0 && "Nonzero not handled yet!");
1107
1108 // If the allocation is in the nonescaping set...
1109 map::iterator AI = PoolDescs.find(PVS[i].Node);
1110 if (AI != PoolDescs.end()) { // Add it to the list of scalars
1111 Scalars.push_back(ScalarInfo(I->first, AI->second));
1112 #ifdef DEBUG_TRANSFORM_PROGRESS
1113 cerr << "\nScalar Mapping from:" << I->first
1114 << "Scalar Mapping to: "; PVS.print(cerr);
1115 #endif
1116 }
1117 }
1118 }
1119
1120 #ifdef DEBUG_TRANSFORM_PROGRESS
1121 cerr << "\nIn '" << F->getName()
1122 << "': Found the following values that point to poolable nodes:\n";
1123
1124 for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
1125 cerr << Scalars[i].Val;
1126 cerr << "\n";
1127 #endif
1128
1129 // CallMap - Contain an entry for every call instruction that needs to be
1130 // transformed. Each entry in the map contains information about what we need
1131 // to do to each call site to change it to work.
1132 //
1133 map CallMap;
1134
1135 // Now we need to figure out what called functions we need to transform, and
1136 // how. To do this, we look at all of the scalars, seeing which functions are
1137 // either used as a scalar value (so they return a data structure), or are
1138 // passed one of our scalar values.
1139 //
1140 for (unsigned i = 0, e = Scalars.size(); i != e; ++i) {
1141 Value *ScalarVal = Scalars[i].Val;
1142
1143 // Check to see if the scalar _IS_ a call...
1144 if (CallInst *CI = dyn_cast(ScalarVal))
1145 // If so, add information about the pool it will be returning...
1146 CallMap[CI].addCallInfo(DS, CI, -1, Scalars[i].Pool.Node, PoolDescs);
1147
1148 // Check to see if the scalar is an operand to a call...
1149 for (Value::use_iterator UI = ScalarVal->use_begin(),
1150 UE = ScalarVal->use_end(); UI != UE; ++UI) {
1151 if (CallInst *CI = dyn_cast(*UI)) {
1152 // Find out which operand this is to the call instruction...
1153 User::op_iterator OI = find(CI->op_begin(), CI->op_end(), ScalarVal);
1154 assert(OI != CI->op_end() && "Call on use list but not an operand!?");
1155 assert(OI != CI->op_begin() && "Pointer operand is call destination?");
1156
1157 // FIXME: This is broken if the same pointer is passed to a call more
1158 // than once! It will get multiple entries for the first pointer.
1159
1160 // Add the operand number and pool handle to the call table...
1161 CallMap[CI].addCallInfo(DS, CI, OI-CI->op_begin()-1,
1162 Scalars[i].Pool.Node, PoolDescs);
1163 }
1164 }
1165 }
1166
1167 // Make sure that all dependant arguments are added as well. For example, if
1168 // we call foo(null, P) and foo treats it's first and second arguments as
1169 // belonging to the same data structure, the we MUST set up the CallMap to
1170 // know that the null needs to be transformed into an index as well.
1171 //
1172 for (map::iterator I = CallMap.begin();
1173 I != CallMap.end(); ++I)
1174 I->second.ensureDependantArgumentsIncluded(DS, PoolDescs);
1175
1176 #ifdef DEBUG_TRANSFORM_PROGRESS
1177 // Print out call map...
1178 for (map::iterator I = CallMap.begin();
1179 I != CallMap.end(); ++I) {
1180 cerr << "For call: " << I->first;
1181 cerr << I->second.Func->getName() << " must pass pool pointer for args #";
1182 for (unsigned i = 0; i < I->second.ArgInfo.size(); ++i)
1183 cerr << I->second.ArgInfo[i].ArgNo << ", ";
1184 cerr << "\n\n";
1185 }
1186 #endif
1187
1188 // Loop through all of the call nodes, recursively creating the new functions
1189 // that we want to call... This uses a map to prevent infinite recursion and
1190 // to avoid duplicating functions unneccesarily.
1191 //
1192 for (map::iterator I = CallMap.begin(),
1193 E = CallMap.end(); I != E; ++I) {
1194 // Transform all of the functions we need, or at least ensure there is a
1195 // cached version available.
1196 transformFunction(I->second, IPFGraph, PoolDescs);
1197 }
1198
1199 // Now that all of the functions that we want to call are available, transform
1200 // the local function so that it uses the pools locally and passes them to the
1201 // functions that we just hacked up.
1202 //
1203
1204 // First step, find the instructions to be modified.
1205 vector InstToFix;
1206 for (unsigned i = 0, e = Scalars.size(); i != e; ++i) {
1207 Value *ScalarVal = Scalars[i].Val;
1208
1209 // Check to see if the scalar _IS_ an instruction. If so, it is involved.
1210 if (Instruction *Inst = dyn_cast(ScalarVal))
1211 InstToFix.push_back(Inst);
1212
1213 // All all of the instructions that use the scalar as an operand...
1214 for (Value::use_iterator UI = ScalarVal->use_begin(),
1215 UE = ScalarVal->use_end(); UI != UE; ++UI)
1216 InstToFix.push_back(cast(*UI));
1217 }
1218
1219 // Make sure that we get return instructions that return a null value from the
1220 // function...
1221 //
1222 if (!IPFGraph.getRetNodes().empty()) {
1223 assert(IPFGraph.getRetNodes().size() == 1 && "Can only return one node?");
1224 PointerVal RetNode = IPFGraph.getRetNodes()[0];
1225 assert(RetNode.Index == 0 && "Subindexing not implemented yet!");
1226
1227 // Only process return instructions if the return value of this function is
1228 // part of one of the data structures we are transforming...
1229 //
1230 if (PoolDescs.count(RetNode.Node)) {
1231 // Loop over all of the basic blocks, adding return instructions...
1232 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
1233 if (ReturnInst *RI = dyn_cast(I->getTerminator()))
1234 InstToFix.push_back(RI);
1235 }
1236 }
1237
1238
1239
1240 // Eliminate duplicates by sorting, then removing equal neighbors.
1241 sort(InstToFix.begin(), InstToFix.end());
1242 InstToFix.erase(unique(InstToFix.begin(), InstToFix.end()), InstToFix.end());
1243
1244 // Loop over all of the instructions to transform, creating the new
1245 // replacement instructions for them. This also unlinks them from the
1246 // function so they can be safely deleted later.
1247 //
1248 map XFormMap;
1249 NewInstructionCreator NIC(*this, Scalars, CallMap, XFormMap);
1250
1251 // Visit all instructions... creating the new instructions that we need and
1252 // unlinking the old instructions from the function...
1253 //
1254 #ifdef DEBUG_TRANSFORM_PROGRESS
1255 for (unsigned i = 0, e = InstToFix.size(); i != e; ++i) {
1256 cerr << "Fixing: " << InstToFix[i];
1257 NIC.visit(*InstToFix[i]);
1258 }
1259 #else
1260 NIC.visit(InstToFix.begin(), InstToFix.end());
1261 #endif
1262
1263 // Make all instructions we will delete "let go" of their operands... so that
1264 // we can safely delete Arguments whose types have changed...
1265 //
1266 for_each(InstToFix.begin(), InstToFix.end(),
1267 std::mem_fun(&Instruction::dropAllReferences));
1268
1269 // Loop through all of the pointer arguments coming into the function,
1270 // replacing them with arguments of POINTERTYPE to match the function type of
1271 // the function.
1272 //
1273 FunctionType::ParamTypes::const_iterator TI =
1274 F->getFunctionType()->getParamTypes().begin();
1275 for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I, ++TI) {
1276 if (I->getType() != *TI) {
1277 assert(isa(I->getType()) && *TI == POINTERTYPE);
1278 Argument *NewArg = new Argument(*TI, I->getName());
1279 XFormMap[I] = NewArg; // Map old arg into new arg...
1280
1281 // Replace the old argument and then delete it...
1282 I = F->getArgumentList().erase(I);
1283 I = F->getArgumentList().insert(I, NewArg);
1284 }
1285 }
1286
1287 // Now that all of the new instructions have been created, we can update all
1288 // of the references to dummy values to be references to the actual values
1289 // that are computed.
1290 //
1291 NIC.updateReferences();
1292
1293 #ifdef DEBUG_TRANSFORM_PROGRESS
1294 cerr << "TRANSFORMED FUNCTION:\n" << F;
1295 #endif
1296
1297 // Delete all of the "instructions to fix"
1298 for_each(InstToFix.begin(), InstToFix.end(), deleter);
1299
1300 // Eliminate pool base loads that we can easily prove are redundant
1301 if (!DisableRLE)
1302 PoolBaseLoadEliminator(PoolDescs).visit(F);
1303
1304 // Since we have liberally hacked the function to pieces, we want to inform
1305 // the datastructure pass that its internal representation is out of date.
1306 //
1307 DS->invalidateFunction(F);
1308 }
1309
1310
1311
1312 // transformFunction - Transform the specified function the specified way. It
1313 // we have already transformed that function that way, don't do anything. The
1314 // nodes in the TransformFunctionInfo come out of callers data structure graph.
1315 //
1316 void PoolAllocate::transformFunction(TransformFunctionInfo &TFI,
1317 FunctionDSGraph &CallerIPGraph,
1318 map &CallerPoolDesc) {
1319 if (getTransformedFunction(TFI)) return; // Function xformation already done?
1320
1321 #ifdef DEBUG_TRANSFORM_PROGRESS
1322 cerr << "********** Entering transformFunction for "
1323 << TFI.Func->getName() << ":\n";
1324 for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i)
1325 cerr << " ArgInfo[" << i << "] = " << TFI.ArgInfo[i].ArgNo << "\n";
1326 cerr << "\n";
1327 #endif
1328
1329 const FunctionType *OldFuncType = TFI.Func->getFunctionType();
1330
1331 assert(!OldFuncType->isVarArg() && "Vararg functions not handled yet!");
1332
1333 // Build the type for the new function that we are transforming
1334 vector ArgTys;
1335 ArgTys.reserve(OldFuncType->getNumParams()+TFI.ArgInfo.size());
1336 for (unsigned i = 0, e = OldFuncType->getNumParams(); i != e; ++i)
1337 ArgTys.push_back(OldFuncType->getParamType(i));
1338
1339 const Type *RetType = OldFuncType->getReturnType();
1340
1341 // Add one pool pointer for every argument that needs to be supplemented.
1342 for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) {
1343 if (TFI.ArgInfo[i].ArgNo == -1)
1344 RetType = POINTERTYPE; // Return a pointer
1345 else
1346 ArgTys[TFI.ArgInfo[i].ArgNo] = POINTERTYPE; // Pass a pointer
1347 ArgTys.push_back(PointerType::get(CallerPoolDesc.find(TFI.ArgInfo[i].Node)
1348 ->second.PoolType));
1349 }
1350
1351 // Build the new function type...
1352 const FunctionType *NewFuncType = FunctionType::get(RetType, ArgTys,
1353 OldFuncType->isVarArg());
1354
1355 // The new function is internal, because we know that only we can call it.
1356 // This also helps subsequent IP transformations to eliminate duplicated pool
1357 // pointers (which look like the same value is always passed into a parameter,
1358 // allowing it to be easily eliminated).
1359 //
1360 Function *NewFunc = new Function(NewFuncType, true,
1361 TFI.Func->getName()+".poolxform");
1362 CurModule->getFunctionList().push_back(NewFunc);
1363
1364
1365 #ifdef DEBUG_TRANSFORM_PROGRESS
1366 cerr << "Created function prototype: " << NewFunc << "\n";
1367 #endif
1368
1369 // Add the newly formed function to the TransformedFunctions table so that
1370 // infinite recursion does not occur!
1371 //
1372 TransformedFunctions[TFI] = NewFunc;
1373
1374 // Add arguments to the function... starting with all of the old arguments
1375 vector ArgMap;
1376 for (Function::const_aiterator I = TFI.Func->abegin(), E = TFI.Func->aend();
1377 I != E; ++I) {
1378 Argument *NFA = new Argument(I->getType(), I->getName());
1379 NewFunc->getArgumentList().push_back(NFA);
1380 ArgMap.push_back(NFA); // Keep track of the arguments
1381 }
1382
1383 // Now add all of the arguments corresponding to pools passed in...
1384 for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) {
1385 CallArgInfo &AI = TFI.ArgInfo[i];
1386 string Name;
1387 if (AI.ArgNo == -1)
1388 Name = "ret";
1389 else
1390 Name = ArgMap[AI.ArgNo]->getName(); // Get the arg name
1391 const Type *Ty = PointerType::get(CallerPoolDesc[AI.Node].PoolType);
1392 Argument *NFA = new Argument(Ty, Name+".pool");
1393 NewFunc->getArgumentList().push_back(NFA);
1394 }
1395
1396 // Now clone the body of the old function into the new function...
1397 CloneFunctionInto(NewFunc, TFI.Func, ArgMap);
1398
1399 // Okay, now we have a function that is identical to the old one, except that
1400 // it has extra arguments for the pools coming in. Now we have to get the
1401 // data structure graph for the function we are replacing, and figure out how
1402 // our graph nodes map to the graph nodes in the dest function.
1403 //
1404 FunctionDSGraph &DSGraph = DS->getClosedDSGraph(NewFunc);
1405
1406 // NodeMapping - Multimap from callers graph to called graph. We are
1407 // guaranteed that the called function graph has more nodes than the caller,
1408 // or exactly the same number of nodes. This is because the called function
1409 // might not know that two nodes are merged when considering the callers
1410 // context, but the caller obviously does. Because of this, a single node in
1411 // the calling function's data structure graph can map to multiple nodes in
1412 // the called functions graph.
1413 //
1414 map NodeMapping;
1415
1416 CalculateNodeMapping(NewFunc, TFI, CallerIPGraph, DSGraph,
1417 NodeMapping);
1418
1419 // Print out the node mapping...
1420 #ifdef DEBUG_TRANSFORM_PROGRESS
1421 cerr << "\nNode mapping for call of " << NewFunc->getName() << "\n";
1422 for (map::iterator I = NodeMapping.begin();
1423 I != NodeMapping.end(); ++I) {
1424 cerr << "Map: "; I->first->print(cerr);
1425 cerr << "To: "; I->second.print(cerr);
1426 cerr << "\n";
1427 }
1428 #endif
1429
1430 // Fill in the PoolDescriptor information for the transformed function so that
1431 // it can determine which value holds the pool descriptor for each data
1432 // structure node that it accesses.
1433 //
1434 map PoolDescs;
1435
1436 #ifdef DEBUG_TRANSFORM_PROGRESS
1437 cerr << "\nCalculating the pool descriptor map:\n";
1438 #endif
1439
1440 // Calculate as much of the pool descriptor map as possible. Since we have
1441 // the node mapping between the caller and callee functions, and we have the
1442 // pool descriptor information of the caller, we can calculate a partical pool
1443 // descriptor map for the called function.
1444 //
1445 // The nodes that we do not have complete information for are the ones that
1446 // are accessed by loading pointers derived from arguments passed in, but that
1447 // are not passed in directly. In this case, we have all of the information
1448 // except a pool value. If the called function refers to this pool, the pool
1449 // value will be loaded from the pool graph and added to the map as neccesary.
1450 //
1451 for (map::iterator I = NodeMapping.begin();
1452 I != NodeMapping.end(); ++I) {
1453 DSNode *CallerNode = I->first;
1454 PoolInfo &CallerPI = CallerPoolDesc[CallerNode];
1455
1456 // Check to see if we have a node pointer passed in for this value...
1457 Value *CalleeValue = 0;
1458 for (unsigned a = 0, ae = TFI.ArgInfo.size(); a != ae; ++a)
1459 if (TFI.ArgInfo[a].Node == CallerNode) {
1460 // Calculate the argument number that the pool is to the function
1461 // call... The call instruction should not have the pool operands added
1462 // yet.
1463 unsigned ArgNo = TFI.Call->getNumOperands()-1+a;
1464 #ifdef DEBUG_TRANSFORM_PROGRESS
1465 cerr << "Should be argument #: " << ArgNo << "[i = " << a << "]\n";
1466 #endif
1467 assert(ArgNo < NewFunc->asize() &&
1468 "Call already has pool arguments added??");
1469
1470 // Map the pool argument into the called function...
1471 Function::aiterator AI = NewFunc->abegin();
1472 std::advance(AI, ArgNo);
1473 CalleeValue = AI;
1474 break; // Found value, quit loop
1475 }
1476
1477 // Loop over all of the data structure nodes that this incoming node maps to
1478 // Creating a PoolInfo structure for them.
1479 for (unsigned i = 0, e = I->second.size(); i != e; ++i) {
1480 assert(I->second[i].Index == 0 && "Doesn't handle subindexing yet!");
1481 DSNode *CalleeNode = I->second[i].Node;
1482
1483 // Add the descriptor. We already know everything about it by now, much
1484 // of it is the same as the caller info.
1485 //
1486 PoolDescs.insert(std::make_pair(CalleeNode,
1487 PoolInfo(CalleeNode, CalleeValue,
1488 CallerPI.NewType,
1489 CallerPI.PoolType)));
1490 }
1491 }
1492
1493 // We must destroy the node mapping so that we don't have latent references
1494 // into the data structure graph for the new function. Otherwise we get
1495 // assertion failures when transformFunctionBody tries to invalidate the
1496 // graph.
1497 //
1498 NodeMapping.clear();
1499
1500 // Now that we know everything we need about the function, transform the body
1501 // now!
1502 //
1503 transformFunctionBody(NewFunc, DSGraph, PoolDescs);
1504
1505 #ifdef DEBUG_TRANSFORM_PROGRESS
1506 cerr << "Function after transformation:\n" << NewFunc;
1507 #endif
1508 }
1509
1510 static unsigned countPointerTypes(const Type *Ty) {
1511 if (isa(Ty)) {
1512 return 1;
1513 } else if (const StructType *STy = dyn_cast(Ty)) {
1514 unsigned Num = 0;
1515 for (unsigned i = 0, e = STy->getElementTypes().size(); i != e; ++i)
1516 Num += countPointerTypes(STy->getElementTypes()[i]);
1517 return Num;
1518 } else if (const ArrayType *ATy = dyn_cast(Ty)) {
1519 return countPointerTypes(ATy->getElementType());
1520 } else {
1521 assert(Ty->isPrimitiveType() && "Unknown derived type!");
1522 return 0;
1523 }
1524 }
1525
1526 // CreatePools - Insert instructions into the function we are processing to
1527 // create all of the memory pool objects themselves. This also inserts
1528 // destruction code. Add an alloca for each pool that is allocated to the
1529 // PoolDescs vector.
1530 //
1531 void PoolAllocate::CreatePools(Function *F, const vector &Allocs,
1532 map &PoolDescs) {
1533 // Find all of the return nodes in the function...
1534 vector ReturnNodes;
1535 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
1536 if (isa(I->getTerminator()))
1537 ReturnNodes.push_back(I);
1538
1539 #ifdef DEBUG_CREATE_POOLS
1540 cerr << "Allocs that we are pool allocating:\n";
1541 for (unsigned i = 0, e = Allocs.size(); i != e; ++i)
1542 Allocs[i]->dump();
1543 #endif
1544
1545 map AbsPoolTyMap;
1546
1547 // First pass over the allocations to process...
1548 for (unsigned i = 0, e = Allocs.size(); i != e; ++i) {
1549 // Create the pooldescriptor mapping... with null entries for everything
1550 // except the node & NewType fields.
1551 //
1552 map::iterator PI =
1553 PoolDescs.insert(std::make_pair(Allocs[i], PoolInfo(Allocs[i]))).first;
1554
1555 // Add a symbol table entry for the new type if there was one for the old
1556 // type...
1557 string OldName = CurModule->getTypeName(Allocs[i]->getType());
1558 if (OldName.empty()) OldName = "node";
1559 CurModule->addTypeName(OldName+".p", PI->second.NewType);
1560
1561 // Create the abstract pool types that will need to be resolved in a second
1562 // pass once an abstract type is created for each pool.
1563 //
1564 // Can only handle limited shapes for now...
1565 const Type *OldNodeTy = Allocs[i]->getType();
1566 vector PoolTypes;
1567
1568 // Pool type is the first element of the pool descriptor type...
1569 PoolTypes.push_back(getPoolType(PoolDescs[Allocs[i]].NewType));
1570
1571 unsigned NumPointers = countPointerTypes(OldNodeTy);
1572 while (NumPointers--) // Add a different opaque type for each pointer
1573 PoolTypes.push_back(OpaqueType::get());
1574
1575 assert(Allocs[i]->getNumLinks() == PoolTypes.size()-1 &&
1576 "Node should have same number of pointers as pool!");
1577
1578 StructType *PoolType = StructType::get(PoolTypes);
1579
1580 // Add a symbol table entry for the pooltype if possible...
1581 CurModule->addTypeName(OldName+".pool", PoolType);
1582
1583 // Create the pool type, with opaque values for pointers...
1584 AbsPoolTyMap.insert(std::make_pair(Allocs[i], PoolType));
1585 #ifdef DEBUG_CREATE_POOLS
1586 cerr << "POOL TY: " << AbsPoolTyMap.find(Allocs[i])->second.get() << "\n";
1587 #endif
1588 }
1589
1590 // Now that we have types for all of the pool types, link them all together.
1591 for (unsigned i = 0, e = Allocs.size(); i != e; ++i) {
1592 PATypeHolder &PoolTyH = AbsPoolTyMap.find(Allocs[i])->second;
1593
1594 // Resolve all of the outgoing pointer types of this pool node...
1595 for (unsigned p = 0, pe = Allocs[i]->getNumLinks(); p != pe; ++p) {
1596 PointerValSet &PVS = Allocs[i]->getLink(p);
1597 assert(!PVS.empty() && "Outgoing edge is empty, field unused, can"
1598 " probably just leave the type opaque or something dumb.");
1599 unsigned Out;
1600 for (Out = 0; AbsPoolTyMap.count(PVS[Out].Node) == 0; ++Out)
1601 assert(Out != PVS.size() && "No edge to an outgoing allocation node!?");
1602
1603 assert(PVS[Out].Index == 0 && "Subindexing not implemented yet!");
1604
1605 // The actual struct type could change each time through the loop, so it's
1606 // NOT loop invariant.
1607 const StructType *PoolTy = cast(PoolTyH.get());
1608
1609 // Get the opaque type...
1610 DerivedType *ElTy = (DerivedType*)(PoolTy->getElementTypes()[p+1].get());
1611
1612 #ifdef DEBUG_CREATE_POOLS
1613 cerr << "Refining " << ElTy << " of " << PoolTy << " to "
1614 << AbsPoolTyMap.find(PVS[Out].Node)->second.get() << "\n";
1615 #endif
1616
1617 const Type *RefPoolTy = AbsPoolTyMap.find(PVS[Out].Node)->second.get();
1618 ElTy->refineAbstractTypeTo(PointerType::get(RefPoolTy));
1619
1620 #ifdef DEBUG_CREATE_POOLS
1621 cerr << "Result pool type is: " << PoolTyH.get() << "\n";
1622 #endif
1623 }
1624 }
1625
1626 // Create the code that goes in the entry and exit nodes for the function...
1627 vector EntryNodeInsts;
1628 for (unsigned i = 0, e = Allocs.size(); i != e; ++i) {
1629 PoolInfo &PI = PoolDescs[Allocs[i]];
1630
1631 // Fill in the pool type for this pool...
1632 PI.PoolType = AbsPoolTyMap.find(Allocs[i])->second.get();
1633 assert(!PI.PoolType->isAbstract() &&
1634 "Pool type should not be abstract anymore!");
1635
1636 // Add an allocation and a free for each pool...
1637 AllocaInst *PoolAlloc = new AllocaInst(PI.PoolType, 0,
1638 CurModule->getTypeName(PI.PoolType));
1639 PI.Handle = PoolAlloc;
1640 EntryNodeInsts.push_back(PoolAlloc);
1641 AllocationInst *AI = Allocs[i]->getAllocation();
1642
1643 // Initialize the pool. We need to know how big each allocation is. For
1644 // our purposes here, we assume we are allocating a scalar, or array of
1645 // constant size.
1646 //
1647 unsigned ElSize = TargetData.getTypeSize(PI.NewType);
1648
1649 vector Args;
1650 Args.push_back(ConstantUInt::get(Type::UIntTy, ElSize));
1651 Args.push_back(PoolAlloc); // Pool to initialize
1652 EntryNodeInsts.push_back(new CallInst(PoolInit, Args));
1653
1654 // Add code to destroy the pool in all of the exit nodes of the function...
1655 Args.clear();
1656 Args.push_back(PoolAlloc); // Pool to initialize
1657
1658 for (unsigned EN = 0, ENE = ReturnNodes.size(); EN != ENE; ++EN) {
1659 Instruction *Destroy = new CallInst(PoolDestroy, Args);
1660
1661 // Insert it before the return instruction...
1662 BasicBlock *RetNode = ReturnNodes[EN];
1663 RetNode->getInstList().insert(RetNode->end()--, Destroy);
1664 }
1665 }
1666
1667 // Now that all of the pool descriptors have been created, link them together
1668 // so that called functions can get links as neccesary...
1669 //
1670 for (unsigned i = 0, e = Allocs.size(); i != e; ++i) {
1671 PoolInfo &PI = PoolDescs[Allocs[i]];
1672
1673 // For every pointer in the data structure, initialize a link that
1674 // indicates which pool to access...
1675 //
1676 vector Indices(2);
1677 Indices[0] = ConstantUInt::get(Type::UIntTy, 0);
1678 for (unsigned l = 0, le = PI.Node->getNumLinks(); l != le; ++l)
1679 // Only store an entry for the field if the field is used!
1680 if (!PI.Node->getLink(l).empty()) {
1681 assert(PI.Node->getLink(l).size() == 1 && "Should have only one link!");
1682 PointerVal PV = PI.Node->getLink(l)[0];
1683 assert(PV.Index == 0 && "Subindexing not supported yet!");
1684 PoolInfo &LinkedPool = PoolDescs[PV.Node];
1685 Indices[1] = ConstantUInt::get(Type::UByteTy, 1+l);
1686
1687 EntryNodeInsts.push_back(new StoreInst(LinkedPool.Handle, PI.Handle,
1688 Indices));
1689 }
1690 }
1691
1692 // Insert the entry node code into the entry block...
1693 F->getEntryNode().getInstList().insert(++F->getEntryNode().begin(),
1694 EntryNodeInsts.begin(),
1695 EntryNodeInsts.end());
1696 }
1697
1698
1699 // addPoolPrototypes - Add prototypes for the pool functions to the specified
1700 // module and update the Pool* instance variables to point to them.
1701 //
1702 void PoolAllocate::addPoolPrototypes(Module &M) {
1703 // Get poolinit function...
1704 vector Args;
1705 Args.push_back(Type::UIntTy); // Num bytes per element
1706 FunctionType *PoolInitTy = FunctionType::get(Type::VoidTy, Args, true);
1707 PoolInit = M.getOrInsertFunction("poolinit", PoolInitTy);
1708
1709 // Get pooldestroy function...
1710 Args.pop_back(); // Only takes a pool...
1711 FunctionType *PoolDestroyTy = FunctionType::get(Type::VoidTy, Args, true);
1712 PoolDestroy = M.getOrInsertFunction("pooldestroy", PoolDestroyTy);
1713
1714 // Get the poolalloc function...
1715 FunctionType *PoolAllocTy = FunctionType::get(POINTERTYPE, Args, true);
1716 PoolAlloc = M.getOrInsertFunction("poolalloc", PoolAllocTy);
1717
1718 // Get the poolfree function...
1719 Args.push_back(POINTERTYPE); // Pointer to free
1720 FunctionType *PoolFreeTy = FunctionType::get(Type::VoidTy, Args, true);
1721 PoolFree = M.getOrInsertFunction("poolfree", PoolFreeTy);
1722
1723 Args[0] = Type::UIntTy; // Number of slots to allocate
1724 FunctionType *PoolAllocArrayTy = FunctionType::get(POINTERTYPE, Args, true);
1725 PoolAllocArray = M.getOrInsertFunction("poolallocarray", PoolAllocArrayTy);
1726 }
1727
1728
1729 bool PoolAllocate::run(Module &M) {
1730 addPoolPrototypes(M);
1731 CurModule = &M;
1732
1733 DS = &getAnalysis();
1734 bool Changed = false;
1735
1736 for (Module::iterator I = M.begin(); I != M.end(); ++I)
1737 if (!I->isExternal()) {
1738 Changed |= processFunction(I);
1739 if (Changed) {
1740 cerr << "Only processing one function\n";
1741 break;
1742 }
1743 }
1744
1745 CurModule = 0;
1746 DS = 0;
1747 return false;
1748 }
1749
1750 // createPoolAllocatePass - Global function to access the functionality of this
1751 // pass...
1752 //
1753 Pass *createPoolAllocatePass() {
1754 assert(0 && "Pool allocator disabled!");
1755 return 0;
1756 //return new PoolAllocate();
1757 }
1758 #endif
+0
-1204
lib/Transforms/IPO/PoolAllocate.cpp less more
None //===-- PoolAllocate.cpp - Pool Allocation Pass ---------------------------===//
1 //
2 // This transform changes programs so that disjoint data structures are
3 // allocated out of different pools of memory, increasing locality.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #define DEBUG_TYPE "PoolAllocation"
8 #include "llvm/Transforms/PoolAllocate.h"
9 #include "llvm/Transforms/Utils/Cloning.h"
10 #include "llvm/Analysis/DataStructure.h"
11 #include "llvm/Analysis/DSGraph.h"
12 #include "llvm/Module.h"
13 #include "llvm/DerivedTypes.h"
14 #include "llvm/Constants.h"
15 #include "llvm/Instructions.h"
16 #include "llvm/Target/TargetData.h"
17 #include "llvm/Support/InstVisitor.h"
18 #include "Support/Debug.h"
19 #include "Support/VectorExtras.h"
20 using namespace PA;
21
22 namespace {
23 const Type *VoidPtrTy = PointerType::get(Type::SByteTy);
24
25 // The type to allocate for a pool descriptor: { sbyte*, uint, uint }
26 // void *Data (the data)
27 // unsigned NodeSize (size of an allocated node)
28 // unsigned FreeablePool (are slabs in the pool freeable upon calls to
29 // poolfree?)
30 const Type *PoolDescType =
31 StructType::get(make_vector(VoidPtrTy, Type::UIntTy,
32 Type::UIntTy, 0));
33
34 const PointerType *PoolDescPtr = PointerType::get(PoolDescType);
35
36 RegisterOpt
37 X("poolalloc", "Pool allocate disjoint data structures");
38 }
39
40 void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
41 AU.addRequired();
42 AU.addRequired();
43 AU.addRequired();
44 }
45
46 // Prints out the functions mapped to the leader of the equivalence class they
47 // belong to.
48 void PoolAllocate::printFuncECs() {
49 std::map &leaderMap = FuncECs.getLeaderMap();
50 std::cerr << "Indirect Function Map \n";
51 for (std::map::iterator LI = leaderMap.begin(),
52 LE = leaderMap.end(); LI != LE; ++LI) {
53 std::cerr << LI->first->getName() << ": leader is "
54 << LI->second->getName() << "\n";
55 }
56 }
57
58 static void printNTOMap(std::map &NTOM) {
59 std::cerr << "NTOM MAP\n";
60 for (std::map::iterator I = NTOM.begin(),
61 E = NTOM.end(); I != E; ++I) {
62 if (!isa(I->first) && !isa(I->first))
63 std::cerr << *I->first << " to " << *I->second << "\n";
64 }
65 }
66
67 void PoolAllocate::buildIndirectFunctionSets(Module &M) {
68 // Iterate over the module looking for indirect calls to functions
69
70 // Get top down DSGraph for the functions
71 TDDS = &getAnalysis();
72
73 for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
74
75 DEBUG(std::cerr << "Processing indirect calls function:" << MI->getName() << "\n");
76
77 if (MI->isExternal())
78 continue;
79
80 DSGraph &TDG = TDDS->getDSGraph(*MI);
81
82 std::vector callSites = TDG.getFunctionCalls();
83
84 // For each call site in the function
85 // All the functions that can be called at the call site are put in the
86 // same equivalence class.
87 for (std::vector::iterator CSI = callSites.begin(),
88 CSE = callSites.end(); CSI != CSE ; ++CSI) {
89 if (CSI->isIndirectCall()) {
90 DSNode *DSN = CSI->getCalleeNode();
91 if (DSN->isIncomplete())
92 std::cerr << "Incomplete node " << CSI->getCallInst();
93 // assert(DSN->isGlobalNode());
94 const std::vector &Callees = DSN->getGlobals();
95 if (Callees.size() > 0) {
96 Function *firstCalledF = dyn_cast(*Callees.begin());
97 FuncECs.addElement(firstCalledF);
98 CallInstTargets.insert(std::pair
99 (&CSI->getCallInst(),
100 firstCalledF));
101 if (Callees.size() > 1) {
102 for (std::vector::const_iterator CalleesI =
103 Callees.begin()+1, CalleesE = Callees.end();
104 CalleesI != CalleesE; ++CalleesI) {
105 Function *calledF = dyn_cast(*CalleesI);
106 FuncECs.unionSetsWith(firstCalledF, calledF);
107 CallInstTargets.insert(std::pair
108 (&CSI->getCallInst(), calledF));
109 }
110 }
111 } else {
112 std::cerr << "No targets " << CSI->getCallInst();
113 }
114 }
115 }
116 }
117
118 // Print the equivalence classes
119 DEBUG(printFuncECs());
120 }
121
122 bool PoolAllocate::run(Module &M) {
123 if (M.begin() == M.end()) return false;
124 CurModule = &M;
125
126 AddPoolPrototypes();
127 BU = &getAnalysis();
128
129 buildIndirectFunctionSets(M);
130
131 std::map FuncMap;
132
133 // Loop over the functions in the original program finding the pool desc.
134 // arguments necessary for each function that is indirectly callable.
135 // For each equivalence class, make a list of pool arguments and update
136 // the PoolArgFirst and PoolArgLast values for each function.
137 Module::iterator LastOrigFunction = --M.end();
138 for (Module::iterator I = M.begin(); ; ++I) {
139 if (!I->isExternal())
140 FindFunctionPoolArgs(*I);
141 if (I == LastOrigFunction) break;
142 }
143
144 // Now clone a function using the pool arg list obtained in the previous
145 // pass over the modules.
146 // Loop over only the function initially in the program, don't traverse newly
147 // added ones. If the function uses memory, make its clone.
148 for (Module::iterator I = M.begin(); ; ++I) {
149 if (!I->isExternal())
150 if (Function *R = MakeFunctionClone(*I))
151 FuncMap[I] = R;
152 if (I == LastOrigFunction) break;
153 }
154
155 ++LastOrigFunction;
156
157 // Now that all call targets are available, rewrite the function bodies of the
158 // clones.
159 for (Module::iterator I = M.begin(); I != LastOrigFunction; ++I)
160 if (!I->isExternal()) {
161 std::map::iterator FI = FuncMap.find(I);
162 ProcessFunctionBody(*I, FI != FuncMap.end() ? *FI->second : *I);
163 }
164
165 if (CollapseFlag)
166 std::cerr << "Pool Allocation successful! However all data structures may not be pool allocated\n";
167
168 return true;
169 }
170
171
172 // AddPoolPrototypes - Add prototypes for the pool functions to the specified
173 // module and update the Pool* instance variables to point to them.
174 //
175 void PoolAllocate::AddPoolPrototypes() {
176 CurModule->addTypeName("PoolDescriptor", PoolDescType);
177
178 // Get poolinit function...
179 FunctionType *PoolInitTy =
180 FunctionType::get(Type::VoidTy,
181 make_vector(PoolDescPtr, Type::UIntTy, 0),
182 false);
183 PoolInit = CurModule->getOrInsertFunction("poolinit", PoolInitTy);
184
185 // Get pooldestroy function...
186 std::vector PDArgs(1, PoolDescPtr);
187 FunctionType *PoolDestroyTy =
188 FunctionType::get(Type::VoidTy, PDArgs, false);
189 PoolDestroy = CurModule->getOrInsertFunction("pooldestroy", PoolDestroyTy);
190
191 // Get the poolalloc function...
192 FunctionType *PoolAllocTy = FunctionType::get(VoidPtrTy, PDArgs, false);
193 PoolAlloc = CurModule->getOrInsertFunction("poolalloc", PoolAllocTy);
194
195 // Get the poolfree function...
196 PDArgs.push_back(VoidPtrTy); // Pointer to free
197 FunctionType *PoolFreeTy = FunctionType::get(Type::VoidTy, PDArgs, false);
198 PoolFree = CurModule->getOrInsertFunction("poolfree", PoolFreeTy);
199
200 // The poolallocarray function
201 FunctionType *PoolAllocArrayTy =
202 FunctionType::get(VoidPtrTy,
203 make_vector(PoolDescPtr, Type::UIntTy, 0),
204 false);
205 PoolAllocArray = CurModule->getOrInsertFunction("poolallocarray",
206 PoolAllocArrayTy);
207
208 }
209
210 // Inline the DSGraphs of functions corresponding to the potential targets at
211 // indirect call sites into the DS Graph of the callee.
212 // This is required to know what pools to create/pass at the call site in the
213 // caller
214 //
215 void PoolAllocate::InlineIndirectCalls(Function &F, DSGraph &G,
216 hash_set &visited) {
217 std::vector callSites = G.getFunctionCalls();
218
219 visited.insert(&F);
220
221 // For each indirect call site in the function, inline all the potential
222 // targets
223 for (std::vector::iterator CSI = callSites.begin(),
224 CSE = callSites.end(); CSI != CSE; ++CSI) {
225 if (CSI->isIndirectCall()) {
226 CallInst &CI = CSI->getCallInst();
227 std::pair::iterator,
228 std::multimap::iterator> Targets =
229 CallInstTargets.equal_range(&CI);
230 for (std::multimap::iterator TFI = Targets.first,
231 TFE = Targets.second; TFI != TFE; ++TFI) {
232 DSGraph &TargetG = BU->getDSGraph(*TFI->second);
233 // Call the function recursively if the callee is not yet inlined
234 // and if it hasn't been visited in this sequence of calls
235 // The latter is dependent on the fact that the graphs of all functions
236 // in an SCC are actually the same
237 if (InlinedFuncs.find(TFI->second) == InlinedFuncs.end() &&
238 visited.find(TFI->second) == visited.end()) {
239 InlineIndirectCalls(*TFI->second, TargetG, visited);
240 }
241 G.mergeInGraph(*CSI, *TFI->second, TargetG, DSGraph::KeepModRefBits |
242 DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes |
243 DSGraph::DontCloneAuxCallNodes);
244 }
245 }
246 }
247
248 // Mark this function as one whose graph is inlined with its indirect
249 // function targets' DS Graphs. This ensures that every function is inlined
250 // exactly once
251 InlinedFuncs.insert(&F);
252 }
253
254 void PoolAllocate::FindFunctionPoolArgs(Function &F) {
255
256 DSGraph &G = BU->getDSGraph(F);
257
258 // Inline the potential targets of indirect calls
259 hash_set visitedFuncs;
260 InlineIndirectCalls(F, G, visitedFuncs);
261
262 // The DSGraph is merged with the globals graph.
263 G.mergeInGlobalsGraph();
264
265 // The nodes reachable from globals need to be recognized as potential
266 // arguments. This is required because, upon merging in the globals graph,
267 // the nodes pointed to by globals that are not live are not marked
268 // incomplete.
269 hash_set NodesFromGlobals;
270 for (DSGraph::ScalarMapTy::iterator I = G.getScalarMap().begin(),
271 E = G.getScalarMap().end(); I != E; ++I)
272 if (isa(I->first)) { // Found a global
273 DSNodeHandle &GH = I->second;
274 GH.getNode()->markReachableNodes(NodesFromGlobals);
275 }
276
277 // At this point the DS Graphs have been modified in place including
278 // information about globals as well as indirect calls, making it useful
279 // for pool allocation
280 std::vector &Nodes = G.getNodes();
281 if (Nodes.empty()) return ; // No memory activity, nothing is required
282
283 FuncInfo &FI = FunctionInfo[&F]; // Create a new entry for F
284
285 FI.Clone = 0;
286
287 // Initialize the PoolArgFirst and PoolArgLast for the function depending
288 // on whether there have been other functions in the equivalence class
289 // that have pool arguments so far in the analysis.
290 if (!FuncECs.findClass(&F)) {
291 FI.PoolArgFirst = FI.PoolArgLast = 0;
292 } else {
293 if (EqClass2LastPoolArg.find(FuncECs.findClass(&F)) !=
294 EqClass2LastPoolArg.end())
295 FI.PoolArgFirst = FI.PoolArgLast =
296 EqClass2LastPoolArg[FuncECs.findClass(&F)] + 1;
297 else
298 FI.PoolArgFirst = FI.PoolArgLast = 0;
299 }
300
301 // Find DataStructure nodes which are allocated in pools non-local to the
302 // current function. This set will contain all of the DSNodes which require
303 // pools to be passed in from outside of the function.
304 hash_set &MarkedNodes = FI.MarkedNodes;
305
306 // Mark globals and incomplete nodes as live... (this handles arguments)
307 if (F.getName() != "main")
308 for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
309 if (Nodes[i]->isGlobalNode() && !Nodes[i]->isIncomplete())
310 DEBUG(std::cerr << "Global node is not Incomplete\n");
311 if ((Nodes[i]->isIncomplete() || Nodes[i]->isGlobalNode() ||
312 NodesFromGlobals.count(Nodes[i])) && Nodes[i]->isHeapNode())
313 Nodes[i]->markReachableNodes(MarkedNodes);
314 }
315
316 // Marked the returned node as alive...
317 if (DSNode *RetNode = G.getReturnNodeFor(F).getNode())
318 if (RetNode->isHeapNode())
319 RetNode->markReachableNodes(MarkedNodes);
320
321 if (MarkedNodes.empty()) // We don't need to clone the function if there
322 return; // are no incoming arguments to be added.
323
324 // Erase any marked node that is not a heap node
325
326 for (hash_set::iterator I = MarkedNodes.begin(),
327 E = MarkedNodes.end(); I != E; ) {
328 // erase invalidates hash_set iterators if the iterator points to the
329 // element being erased
330 if (!(*I)->isHeapNode())
331 MarkedNodes.erase(I++);
332 else
333 ++I;
334 }
335
336 FI.PoolArgLast += MarkedNodes.size();
337
338
339 if (FuncECs.findClass(&F)) {
340 // Update the equivalence class last pool argument information
341 // only if there actually were pool arguments to the function.
342 // Also, there is no entry for the Eq. class in EqClass2LastPoolArg
343 // if there are no functions in the equivalence class with pool arguments.
344 if (FI.PoolArgLast != FI.PoolArgFirst)
345 EqClass2LastPoolArg[FuncECs.findClass(&F)] = FI.PoolArgLast - 1;
346 }
347
348 }
349
350 // MakeFunctionClone - If the specified function needs to be modified for pool
351 // allocation support, make a clone of it, adding additional arguments as
352 // neccesary, and return it. If not, just return null.
353 //
354 Function *PoolAllocate::MakeFunctionClone(Function &F) {
355
356 DSGraph &G = BU->getDSGraph(F);
357
358 std::vector &Nodes = G.getNodes();
359 if (Nodes.empty())
360 return 0;
361
362 FuncInfo &FI = FunctionInfo[&F];
363
364 hash_set &MarkedNodes = FI.MarkedNodes;
365
366 if (!FuncECs.findClass(&F)) {
367 // Not in any equivalence class
368 if (MarkedNodes.empty())
369 return 0;
370 } else {
371 // No need to clone if there are no pool arguments in any function in the
372 // equivalence class
373 if (!EqClass2LastPoolArg.count(FuncECs.findClass(&F)))
374 return 0;
375 }
376
377 // Figure out what the arguments are to be for the new version of the function
378 const FunctionType *OldFuncTy = F.getFunctionType();
379 std::vector ArgTys;
380 if (!FuncECs.findClass(&F)) {
381 ArgTys.reserve(OldFuncTy->getParamTypes().size() + MarkedNodes.size());
382 FI.ArgNodes.reserve(MarkedNodes.size());
383 for (hash_set::iterator I = MarkedNodes.begin(),
384 E = MarkedNodes.end(); I != E; ++I) {
385 ArgTys.push_back(PoolDescPtr); // Add the appropriate # of pool descs
386 FI.ArgNodes.push_back(*I);
387 }
388 if (FI.ArgNodes.empty()) return 0; // No nodes to be pool allocated!
389
390 }
391 else {
392 // This function is a member of an equivalence class and needs to be cloned
393 ArgTys.reserve(OldFuncTy->getParamTypes().size() +
394 EqClass2LastPoolArg[FuncECs.findClass(&F)] + 1);
395 FI.ArgNodes.reserve(EqClass2LastPoolArg[FuncECs.findClass(&F)] + 1);
396
397 for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i) {
398 ArgTys.push_back(PoolDescPtr); // Add the appropriate # of pool
399 // descs
400 }
401
402 for (hash_set::iterator I = MarkedNodes.begin(),
403 E = MarkedNodes.end(); I != E; ++I) {
404 FI.ArgNodes.push_back(*I);
405 }
406
407 assert ((FI.ArgNodes.size() == (unsigned) (FI.PoolArgLast -
408 FI.PoolArgFirst)) &&
409 "Number of ArgNodes equal to the number of pool arguments used by this function");
410
411 if (FI.ArgNodes.empty()) return 0;
412 }
413
414
415 ArgTys.insert(ArgTys.end(), OldFuncTy->getParamTypes().begin(),
416 OldFuncTy->getParamTypes().end());
417
418
419 // Create the new function prototype
420 FunctionType *FuncTy = FunctionType::get(OldFuncTy->getReturnType(), ArgTys,
421 OldFuncTy->isVarArg());
422 // Create the new function...
423 Function *New = new Function(FuncTy, GlobalValue::InternalLinkage,
424 F.getName(), F.getParent());
425
426 // Set the rest of the new arguments names to be PDa and add entries to the
427 // pool descriptors map
428 std::map &PoolDescriptors = FI.PoolDescriptors;
429 Function::aiterator NI = New->abegin();
430
431 if (FuncECs.findClass(&F)) {
432 // If the function belongs to an equivalence class
433 for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i,
434 ++NI)
435 NI->setName("PDa");
436
437 NI = New->abegin();
438 if (FI.PoolArgFirst > 0)
439 for (int i = 0; i < FI.PoolArgFirst; ++NI, ++i)
440 ;
441
442 for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI)
443 PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI));
444
445 NI = New->abegin();
446 if (EqClass2LastPoolArg.count(FuncECs.findClass(&F)))
447 for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i, ++NI)
448 ;
449 } else {
450 // If the function does not belong to an equivalence class
451 if (FI.ArgNodes.size())
452 for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) {
453 NI->setName("PDa"); // Add pd entry
454 PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI));
455 }
456 NI = New->abegin();
457 if (FI.ArgNodes.size())
458 for (unsigned i = 0; i < FI.ArgNodes.size(); ++NI, ++i)
459 ;
460 }
461
462 // Map the existing arguments of the old function to the corresponding
463 // arguments of the new function.
464 std::map ValueMap;
465 if (NI != New->aend())
466 for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++NI) {
467 ValueMap[I] = NI;
468 NI->setName(I->getName());
469 }
470
471 // Populate the value map with all of the globals in the program.
472 // FIXME: This should be unneccesary!
473 Module &M = *F.getParent();
474 for (Module::iterator I = M.begin(), E=M.end(); I!=E; ++I) ValueMap[I] = I;
475 for (Module::giterator I = M.gbegin(), E=M.gend(); I!=E; ++I) ValueMap[I] = I;
476
477 // Perform the cloning.
478 std::vector Returns;
479 CloneFunctionInto(New, &F, ValueMap, Returns);
480
481 // Invert the ValueMap into the NewToOldValueMap
482 std::map &NewToOldValueMap = FI.NewToOldValueMap;
483 for (std::map::iterator I = ValueMap.begin(),
484 E = ValueMap.end(); I != E; ++I)
485 NewToOldValueMap.insert(std::make_pair(I->second, I->first));
486
487 return FI.Clone = New;
488 }
489
490
491 // processFunction - Pool allocate any data structures which are contained in
492 // the specified function...
493 //
494 void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) {
495 DSGraph &G = BU->getDSGraph(F);
496
497 std::vector &Nodes = G.getNodes();
498 if (Nodes.empty()) return; // Quick exit if nothing to do...
499
500 FuncInfo &FI = FunctionInfo[&F]; // Get FuncInfo for F
501 hash_set &MarkedNodes = FI.MarkedNodes;
502
503 DEBUG(std::cerr << "[" << F.getName() << "] Pool Allocate: ");
504
505 // Loop over all of the nodes which are non-escaping, adding pool-allocatable
506 // ones to the NodesToPA vector.
507 std::vector NodesToPA;
508 for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
509 if (Nodes[i]->isHeapNode() && // Pick nodes with heap elems
510 !MarkedNodes.count(Nodes[i])) // Can't be marked
511 NodesToPA.push_back(Nodes[i]);
512
513 DEBUG(std::cerr << NodesToPA.size() << " nodes to pool allocate\n");
514 if (!NodesToPA.empty()) {
515 // Create pool construction/destruction code
516 std::map &PoolDescriptors = FI.PoolDescriptors;
517 CreatePools(NewF, NodesToPA, PoolDescriptors);
518 }
519
520 // Transform the body of the function now...
521 TransformFunctionBody(NewF, F, G, FI);
522 }
523
524
525 // CreatePools - This creates the pool initialization and destruction code for
526 // the DSNodes specified by the NodesToPA list. This adds an entry to the
527 // PoolDescriptors map for each DSNode.
528 //
529 void PoolAllocate::CreatePools(Function &F,
530 const std::vector &NodesToPA,
531 std::map &PoolDescriptors) {
532 // Find all of the return nodes in the CFG...
533 std::vector ReturnNodes;
534 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
535 if (isa(I->getTerminator()))
536 ReturnNodes.push_back(I);
537
538 TargetData &TD = getAnalysis();
539
540 // Loop over all of the pools, inserting code into the entry block of the
541 // function for the initialization and code in the exit blocks for
542 // destruction.
543 //
544 Instruction *InsertPoint = F.front().begin();
545 for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) {
546 DSNode *Node = NodesToPA[i];
547
548 // Create a new alloca instruction for the pool...
549 Value *AI = new AllocaInst(PoolDescType, 0, "PD", InsertPoint);
550
551 Value *ElSize;
552
553 // Void types in DS graph are never used
554 if (Node->getType() != Type::VoidTy)
555 ElSize = ConstantUInt::get(Type::UIntTy, TD.getTypeSize(Node->getType()));
556 else {
557 DEBUG(std::cerr << "Potential node collapsing in " << F.getName()
558 << ". All Data Structures may not be pool allocated\n");
559 ElSize = ConstantUInt::get(Type::UIntTy, 0);
560 }
561
562 // Insert the call to initialize the pool...
563 new CallInst(PoolInit, make_vector(AI, ElSize, 0), "", InsertPoint);
564
565 // Update the PoolDescriptors map
566 PoolDescriptors.insert(std::make_pair(Node, AI));
567
568 // Insert a call to pool destroy before each return inst in the function
569 for (unsigned r = 0, e = ReturnNodes.size(); r != e; ++r)
570 new CallInst(PoolDestroy, make_vector(AI, 0), "",
571 ReturnNodes[r]->getTerminator());
572 }
573 }
574
575
576 namespace {
577 /// FuncTransform - This class implements transformation required of pool
578 /// allocated functions.
579 struct FuncTransform : public InstVisitor {
580 PoolAllocate &PAInfo;
581 DSGraph &G; // The Bottom-up DS Graph
582 DSGraph &TDG; // The Top-down DS Graph
583 FuncInfo &FI;
584
585 FuncTransform(PoolAllocate &P, DSGraph &g, DSGraph &tdg, FuncInfo &fi)
586 : PAInfo(P), G(g), TDG(tdg), FI(fi) {
587 }
588
589 void visitMallocInst(MallocInst &MI);
590 void visitFreeInst(FreeInst &FI);
591 void visitCallInst(CallInst &CI);
592
593 // The following instructions are never modified by pool allocation
594 void visitBranchInst(BranchInst &I) { }
595 void visitBinaryOperator(Instruction &I) { }
596 void visitShiftInst (ShiftInst &I) { }
597 void visitSwitchInst (SwitchInst &I) { }
598 void visitCastInst (CastInst &I) { }
599 void visitAllocaInst(AllocaInst &I) { }
600 void visitLoadInst(LoadInst &I) { }
601 void visitGetElementPtrInst (GetElementPtrInst &I) { }
602
603 void visitReturnInst(ReturnInst &I);
604 void visitStoreInst (StoreInst &I);
605 void visitPHINode(PHINode &I);
606
607 void visitInstruction(Instruction &I) {
608 std::cerr << "PoolAllocate does not recognize this instruction\n";
609 abort();
610 }
611
612 private:
613 DSNodeHandle& getDSNodeHFor(Value *V) {
614 // if (isa(V))
615 // return DSNodeHandle();
616
617 if (!FI.NewToOldValueMap.empty()) {
618 // If the NewToOldValueMap is in effect, use it.
619 std::map::iterator I = FI.NewToOldValueMap.find(V);
620 if (I != FI.NewToOldValueMap.end())
621 V = (Value*)I->second;
622 }
623
624 return G.getScalarMap()[V];
625 }
626
627 DSNodeHandle& getTDDSNodeHFor(Value *V) {
628 if (!FI.NewToOldValueMap.empty()) {
629 // If the NewToOldValueMap is in effect, use it.
630 std::map::iterator I = FI.NewToOldValueMap.find(V);
631 if (I != FI.NewToOldValueMap.end())
632 V = (Value*)I->second;
633 }
634
635 return TDG.getScalarMap()[V];
636 }
637
638 Value *getPoolHandle(Value *V) {
639 DSNode *Node = getDSNodeHFor(V).getNode();
640 // Get the pool handle for this DSNode...
641 std::map::iterator I = FI.PoolDescriptors.find(Node);
642
643 if (I != FI.PoolDescriptors.end()) {
644 // Check that the node pointed to by V in the TD DS graph is not
645 // collapsed
646 DSNode *TDNode = getTDDSNodeHFor(V).getNode();
647 if (TDNode->getType() != Type::VoidTy)
648 return I->second;
649 else {
650 PAInfo.CollapseFlag = 1;
651 return 0;
652 }
653 }
654 else
655 return 0;
656
657 }
658
659 bool isFuncPtr(Value *V);
660
661 Function* getFuncClass(Value *V);
662
663 Value* retCloneIfFunc(Value *V);
664 };
665 }
666
667 void PoolAllocate::TransformFunctionBody(Function &F, Function &OldF,
668 DSGraph &G, FuncInfo &FI) {
669 FuncTransform(*this, G, TDDS->getDSGraph(OldF), FI).visit(F);
670 }
671
672 // Returns true if V is a function pointer
673 bool FuncTransform::isFuncPtr(Value *V) {
674 if (const PointerType *PTy = dyn_cast(V->getType()))
675 return isa(PTy->getElementType());
676 return false;
677 }
678
679 // Given a function pointer, return the function eq. class if one exists
680 Function* FuncTransform::getFuncClass(Value *V) {
681 // Look at DSGraph and see if the set of of functions it could point to
682 // are pool allocated.
683
684 if (!isFuncPtr(V))
685 return 0;
686
687 // Two cases:
688 // if V is a constant
689 if (Function *theFunc = dyn_cast(V)) {
690 if (!PAInfo.FuncECs.findClass(theFunc))
691 // If this function does not belong to any equivalence class
692 return 0;
693 if (PAInfo.EqClass2LastPoolArg.count(PAInfo.FuncECs.findClass(theFunc)))
694 return PAInfo.FuncECs.findClass(theFunc);
695 else
696 return 0;
697 }
698
699 // if V is not a constant
700 DSNode *DSN = TDG.getNodeForValue(V).getNode();
701 if (!DSN) {
702 return 0;
703 }
704 const std::vector &Callees = DSN->getGlobals();
705 if (Callees.size() > 0) {
706 Function *calledF = dyn_cast(*Callees.begin());
707 assert(PAInfo.FuncECs.findClass(calledF) && "should exist in some eq. class");
708 if (PAInfo.EqClass2LastPoolArg.count(PAInfo.FuncECs.findClass(calledF)))
709 return PAInfo.FuncECs.findClass(calledF);
710 }
711
712 return 0;
713 }
714
715 // Returns the clone if V is a static function (not a pointer) and belongs
716 // to an equivalence class i.e. is pool allocated
717 Value* FuncTransform::retCloneIfFunc(Value *V) {
718 if (Function *fixedFunc = dyn_cast(V))
719 if (getFuncClass(V))
720 return PAInfo.getFuncInfo(*fixedFunc)->Clone;
721
722 return 0;
723 }
724
725 void FuncTransform::visitReturnInst (ReturnInst &RI) {
726 if (RI.getNumOperands())
727 if (Value *clonedFunc = retCloneIfFunc(RI.getOperand(0))) {
728 // Cast the clone of RI.getOperand(0) to the non-pool-allocated type
729 CastInst *CastI = new CastInst(clonedFunc, RI.getOperand(0)->getType(),
730 "tmp", &RI);
731 // Insert return instruction that returns the casted value
732 ReturnInst *RetI = new ReturnInst(CastI, &RI);
733
734 // Remove original return instruction
735 RI.getParent()->getInstList().erase(&RI);
736
737 if (!FI.NewToOldValueMap.empty()) {
738 std::map::iterator II =
739 FI.NewToOldValueMap.find(&RI);
740 assert(II != FI.NewToOldValueMap.end() &&
741 "RI not found in clone?");
742 FI.NewToOldValueMap.insert(std::make_pair(RetI, II->second));
743 FI.NewToOldValueMap.erase(II);
744 }
745 }
746 }
747
748 void FuncTransform::visitStoreInst (StoreInst &SI) {
749 // Check if a constant function is being stored
750 if (Value *clonedFunc = retCloneIfFunc(SI.getOperand(0))) {
751 CastInst *CastI = new CastInst(clonedFunc, SI.getOperand(0)->getType(),
752 "tmp", &SI);
753 StoreInst *StoreI = new StoreInst(CastI, SI.getOperand(1), &SI);
754 SI.getParent()->getInstList().erase(&SI);
755
756 // Update the NewToOldValueMap if this is a clone
757 if (!FI.NewToOldValueMap.empty()) {
758 std::map::iterator II =
759 FI.NewToOldValueMap.find(&SI);
760 assert(II != FI.NewToOldValueMap.end() &&
761 "SI not found in clone?");
762 FI.NewToOldValueMap.insert(std::make_pair(StoreI, II->second));
763 FI.NewToOldValueMap.erase(II);
764 }
765 }
766 }
767
768 void FuncTransform::visitPHINode(PHINode &PI) {
769 // If any of the operands of the PHI node is a constant function pointer
770 // that is cloned, the cast instruction has to be inserted at the end of the
771 // previous basic block
772
773 if (isFuncPtr(&PI)) {
774 PHINode *V = new PHINode(PI.getType(), PI.getName(), &PI);
775 for (unsigned i = 0 ; i < PI.getNumIncomingValues(); ++i) {
776 if (Value *clonedFunc = retCloneIfFunc(PI.getIncomingValue(i))) {
777 // Insert CastInst at the end of PI.getIncomingBlock(i)
778 BasicBlock::iterator BBI = --PI.getIncomingBlock(i)->end();
779 // BBI now points to the terminator instruction of the basic block.
780 CastInst *CastI = new CastInst(clonedFunc, PI.getType(), "tmp", BBI);
781 V->addIncoming(CastI, PI.getIncomingBlock(i));
782 } else {
783 V->addIncoming(PI.getIncomingValue(i), PI.getIncomingBlock(i));
784 }
785
786 }
787 PI.replaceAllUsesWith(V);
788 PI.getParent()->getInstList().erase(&PI);
789
790 DSGraph::ScalarMapTy &SM = G.getScalarMap();
791 DSGraph::ScalarMapTy::iterator PII = SM.find(&PI);
792
793 // Update Scalar map of DSGraph if this is one of the original functions
794 // Otherwise update the NewToOldValueMap
795 if (PII != SM.end()) {
796 SM.insert(std::make_pair(V, PII->second));
797 SM.erase(PII); // Destroy the PHINode
798 } else {
799 std::map::iterator II =
800 FI.NewToOldValueMap.find(&PI);
801 assert(II != FI.NewToOldValueMap.end() &&
802 "PhiI not found in clone?");
803 FI.NewToOldValueMap.insert(std::make_pair(V, II->second));
804 FI.NewToOldValueMap.erase(II);
805 }
806 }
807 }
808
809 void FuncTransform::visitMallocInst(MallocInst &MI) {
810 // Get the pool handle for the node that this contributes to...
811 Value *PH = getPoolHandle(&MI);
812
813 // NB: PH is zero even if the node is collapsed
814 if (PH == 0) return;
815
816 // Insert a call to poolalloc
817 Value *V;
818 if (MI.isArrayAllocation())
819 V = new CallInst(PAInfo.PoolAllocArray,
820 make_vector(PH, MI.getOperand(0), 0),
821 MI.getName(), &MI);
822 else
823 V = new CallInst(PAInfo.PoolAlloc, make_vector(PH, 0),
824 MI.getName(), &MI);
825
826 MI.setName(""); // Nuke MIs name
827
828 Value *Casted = V;
829
830 // Cast to the appropriate type if necessary
831 if (V->getType() != MI.getType()) {
832 Casted = new CastInst(V, MI.getType(), V->getName(), &MI);
833 }
834
835 // Update def-use info
836 MI.replaceAllUsesWith(Casted);
837
838 // Remove old malloc instruction
839 MI.getParent()->getInstList().erase(&MI);
840
841 DSGraph::ScalarMapTy &SM = G.getScalarMap();
842 DSGraph::ScalarMapTy::iterator MII = SM.find(&MI);
843
844 // If we are modifying the original function, update the DSGraph...
845 if (MII != SM.end()) {
846 // V and Casted now point to whatever the original malloc did...
847 SM.insert(std::make_pair(V, MII->second));
848 if (V != Casted)
849 SM.insert(std::make_pair(Casted, MII->second));
850 SM.erase(MII); // The malloc is now destroyed
851 } else { // Otherwise, update the NewToOldValueMap
852 std::map::iterator MII =
853 FI.NewToOldValueMap.find(&MI);
854 assert(MII != FI.NewToOldValueMap.end() && "MI not found in clone?");
855 FI.NewToOldValueMap.insert(std::make_pair(V, MII->second));
856 if (V != Casted)
857 FI.NewToOldValueMap.insert(std::make_pair(Casted, MII->second));
858 FI.NewToOldValueMap.erase(MII);
859 }
860 }
861
862 void FuncTransform::visitFreeInst(FreeInst &FrI) {
863 Value *Arg = FrI.getOperand(0);
864 Value *PH = getPoolHandle(Arg); // Get the pool handle for this DSNode...
865 if (PH == 0) return;
866 // Insert a cast and a call to poolfree...
867 Value *Casted = Arg;
868 if (Arg->getType() != PointerType::get(Type::SByteTy))
869 Casted = new CastInst(Arg, PointerType::get(Type::SByteTy),
870 Arg->getName()+".casted", &FrI);
871
872 CallInst *FreeI = new CallInst(PAInfo.PoolFree, make_vector(PH, Casted, 0),
873 "", &FrI);
874 // Delete the now obsolete free instruction...
875 FrI.getParent()->getInstList().erase(&FrI);
876
877 // Update the NewToOldValueMap if this is a clone
878 if (!FI.NewToOldValueMap.empty()) {
879 std::map::iterator II =
880 FI.NewToOldValueMap.find(&FrI);
881 assert(II != FI.NewToOldValueMap.end() &&
882 "FrI not found in clone?");
883 FI.NewToOldValueMap.insert(std::make_pair(FreeI, II->second));
884 FI.NewToOldValueMap.erase(II);
885 }
886 }
887
888 static void CalcNodeMapping(DSNodeHandle& Caller, DSNodeHandle& Callee,
889 std::map &NodeMapping) {
890 DSNode *CalleeNode = Callee.getNode();
891 DSNode *CallerNode = Caller.getNode();
892
893 unsigned CalleeOffset = Callee.getOffset();
894 unsigned CallerOffset = Caller.getOffset();
895
896 if (CalleeNode == 0) return;
897
898 // If callee has a node and caller doesn't, then a constant argument was
899 // passed by the caller
900 if (CallerNode == 0) {
901 NodeMapping.insert(NodeMapping.end(), std::make_pair(CalleeNode,
902 (DSNode *) 0));
903 }
904
905 // Map the callee node to the caller node.
906 // NB: The callee node could be of a different type. Eg. if it points to the
907 // field of a struct that the caller points to
908 std::map::iterator I = NodeMapping.find(CalleeNode);
909 if (I != NodeMapping.end()) { // Node already in map...
910 assert(I->second == CallerNode &&
911 "Node maps to different nodes on paths?");
912 } else {
913 NodeMapping.insert(I, std::make_pair(CalleeNode, CallerNode));
914
915 if (CalleeNode->getType() != CallerNode->getType() && CallerOffset == 0)
916 DEBUG(std::cerr << "NB: Mapping of nodes between different types\n");
917
918 // Recursively map the callee links to the caller links starting from the
919 // offset in the node into which they are mapped.
920 // Being a BU Graph, the callee ought to have smaller number of links unless
921 // there is collapsing in the caller
922 unsigned numCallerLinks = CallerNode->getNumLinks() - CallerOffset;
923 unsigned numCalleeLinks = CalleeNode->getNumLinks() - CalleeOffset;
924
925 if (numCallerLinks > 0) {
926 if (numCallerLinks < numCalleeLinks) {
927 DEBUG(std::cerr << "Potential node collapsing in caller\n");
928 for (unsigned i = 0, e = numCalleeLinks; i != e; ++i)
929 CalcNodeMapping(CallerNode->getLink(((i%numCallerLinks) << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping);
930 } else {
931 for (unsigned i = 0, e = numCalleeLinks; i != e; ++i)
932 CalcNodeMapping(CallerNode->getLink((i << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping);
933 }
934 } else if (numCalleeLinks > 0) {
935 DEBUG(std::cerr <<
936 "Caller has unexpanded node, due to indirect call perhaps!\n");
937 }
938 }
939 }
940
941 void FuncTransform::visitCallInst(CallInst &CI) {
942 Function *CF = CI.getCalledFunction();
943
944 // optimization for function pointers that are basically gotten from a cast
945 // with only one use and constant expressions with casts in them
946 if (!CF) {
947 if (CastInst* CastI = dyn_cast(CI.getCalledValue())) {
948 if (isa(CastI->getOperand(0)) &&
949 CastI->getOperand(0)->getType() == CastI->getType())
950 CF = dyn_cast(CastI->getOperand(0));
951 } else if (ConstantExpr *CE = dyn_cast(CI.getOperand(0))) {
952 if (CE->getOpcode() == Instruction::Cast) {
953 if (isa(CE->getOperand(0)))
954 return;
955 else
956 assert(0 && "Function pointer cast not handled as called function\n");
957 }
958 }
959
960 }
961
962 DSGraph &CallerG = G;
963
964 std::vector Args;
965 if (!CF) { // Indirect call
966 DEBUG(std::cerr << " Handling call: " << CI);
967
968 std::map PoolArgs;
969 Function *FuncClass;
970
971 std::pair::iterator,
972 std::multimap::iterator> Targets =
973 PAInfo.CallInstTargets.equal_range(&CI);
974 for (std::multimap::iterator TFI = Targets.first,
975 TFE = Targets.second; TFI != TFE; ++TFI) {
976 if (TFI == Targets.first) {
977 FuncClass = PAInfo.FuncECs.findClass(TFI->second);
978 // Nothing to transform if there are no pool arguments in this
979 // equivalence class of functions.
980 if (!PAInfo.EqClass2LastPoolArg.count(FuncClass))
981 return;
982 }
983
984 FuncInfo *CFI = PAInfo.getFuncInfo(*TFI->second);
985
986 if (!CFI->ArgNodes.size()) continue; // Nothing to transform...
987
988 DSGraph &CG = PAInfo.getBUDataStructures().getDSGraph(*TFI->second);
989 std::map NodeMapping;
990
991 Function::aiterator AI = TFI->second->abegin(), AE = TFI->second->aend();
992 unsigned OpNum = 1;
993 for ( ; AI != AE; ++AI, ++OpNum) {
994 if (!isa(CI.getOperand(OpNum)))
995 CalcNodeMapping(getDSNodeHFor(CI.getOperand(OpNum)),
996 CG.getScalarMap()[AI], NodeMapping);
997 }
998 assert(OpNum == CI.getNumOperands() && "Varargs calls not handled yet!");
999
1000 if (CI.getType() != Type::VoidTy)
1001 CalcNodeMapping(getDSNodeHFor(&CI),
1002 CG.getReturnNodeFor(*TFI->second), NodeMapping);
1003
1004 // Map the nodes that are pointed to by globals.
1005 // For all globals map getDSNodeForGlobal(g)->CG.getDSNodeForGlobal(g)
1006 for (DSGraph::ScalarMapTy::iterator SMI = G.getScalarMap().begin(),
1007 SME = G.getScalarMap().end(); SMI != SME; ++SMI)
1008 if (isa(SMI->first)) {
1009 CalcNodeMapping(SMI->second,
1010 CG.getScalarMap()[SMI->first], NodeMapping);
1011 }
1012
1013 unsigned idx = CFI->PoolArgFirst;
1014
1015 // The following loop determines the pool pointers corresponding to
1016 // CFI.
1017 for (unsigned i = 0, e = CFI->ArgNodes.size(); i != e; ++i, ++idx) {
1018 if (NodeMapping.count(CFI->ArgNodes[i])) {
1019 assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!");
1020 DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second;
1021 if (LocalNode) {
1022 assert(FI.PoolDescriptors.count(LocalNode) &&
1023 "Node not pool allocated?");
1024 PoolArgs[idx] = FI.PoolDescriptors.find(LocalNode)->second;
1025 }
1026 else
1027 // LocalNode is null when a constant is passed in as a parameter
1028 PoolArgs[idx] = Constant::getNullValue(PoolDescPtr);
1029 } else {
1030 PoolArgs[idx] = Constant::getNullValue(PoolDescPtr);
1031 }
1032 }
1033 }
1034
1035 // Push the pool arguments into Args.
1036 if (PAInfo.EqClass2LastPoolArg.count(FuncClass)) {
1037 for (int i = 0; i <= PAInfo.EqClass2LastPoolArg[FuncClass]; ++i) {
1038 if (PoolArgs.find(i) != PoolArgs.end())
1039 Args.push_back(PoolArgs[i]);
1040 else
1041 Args.push_back(Constant::getNullValue(PoolDescPtr));
1042 }
1043
1044 assert(Args.size()== (unsigned) PAInfo.EqClass2LastPoolArg[FuncClass] + 1
1045 && "Call has same number of pool args as the called function");
1046 }
1047
1048 // Add the rest of the arguments (the original arguments of the function)...
1049 Args.insert(Args.end(), CI.op_begin()+1, CI.op_end());
1050
1051 std::string Name = CI.getName();
1052
1053 Value *NewCall;
1054 if (Args.size() > CI.getNumOperands() - 1) {
1055 // If there are any pool arguments
1056 CastInst *CastI =
1057 new CastInst(CI.getOperand(0),
1058 PAInfo.getFuncInfo(*FuncClass)->Clone->getType(), "tmp",
1059 &CI);
1060 NewCall = new CallInst(CastI, Args, Name, &CI);
1061 } else {
1062 NewCall = new CallInst(CI.getOperand(0), Args, Name, &CI);
1063 }
1064
1065 CI.replaceAllUsesWith(NewCall);
1066 DEBUG(std::cerr << " Result Call: " << *NewCall);
1067
1068 if (CI.getType() != Type::VoidTy) {
1069 // If we are modifying the original function, update the DSGraph...
1070 DSGraph::ScalarMapTy &SM = G.getScalarMap();
1071 DSGraph::ScalarMapTy::iterator CII = SM.find(&CI);
1072 if (CII != SM.end()) {
1073 SM.insert(std::make_pair(NewCall, CII->second));
1074 SM.erase(CII); // Destroy the CallInst
1075 } else {
1076 // Otherwise update the NewToOldValueMap with the new CI return value
1077 std::map::iterator CII =
1078 FI.NewToOldValueMap.find(&CI);
1079 assert(CII != FI.NewToOldValueMap.end() && "CI not found in clone?");
1080 FI.NewToOldValueMap.insert(std::make_pair(NewCall, CII->second));
1081 FI.NewToOldValueMap.erase(CII);
1082 }
1083 } else if (!FI.NewToOldValueMap.empty()) {
1084 std::map::iterator II =
1085 FI.NewToOldValueMap.find(&CI);
1086 assert(II != FI.NewToOldValueMap.end() &&
1087 "CI not found in clone?");
1088 FI.NewToOldValueMap.insert(std::make_pair(NewCall, II->second));
1089 FI.NewToOldValueMap.erase(II);
1090 }
1091 }
1092 else {
1093
1094 FuncInfo *CFI = PAInfo.getFuncInfo(*CF);
1095
1096 if (CFI == 0 || CFI->Clone == 0) return; // Nothing to transform...
1097
1098 DEBUG(std::cerr << " Handling call: " << CI);
1099
1100 DSGraph &CG = PAInfo.getBUDataStructures().getDSGraph(*CF); // Callee graph
1101
1102 // We need to figure out which local pool descriptors correspond to the pool
1103 // descriptor arguments passed into the function call. Calculate a mapping
1104 // from callee DSNodes to caller DSNodes. We construct a partial isomophism
1105 // between the graphs to figure out which pool descriptors need to be passed
1106 // in. The roots of this mapping is found from arguments and return values.
1107 //
1108 std::map NodeMapping;
1109
1110 Function::aiterator AI = CF->abegin(), AE = CF->aend();
1111 unsigned OpNum = 1;
1112 for (; AI != AE; ++AI, ++OpNum) {
1113 Value *callOp = CI.getOperand(OpNum);
1114 if (!isa(callOp))
1115 CalcNodeMapping(getDSNodeHFor(callOp), CG.getScalarMap()[AI],
1116 NodeMapping);
1117 }
1118 assert(OpNum == CI.getNumOperands() && "Varargs calls not handled yet!");
1119
1120 // Map the return value as well...
1121 if (CI.getType() != Type::VoidTy)
1122 CalcNodeMapping(getDSNodeHFor(&CI), CG.getReturnNodeFor(*CF),
1123 NodeMapping);
1124
1125 // Map the nodes that are pointed to by globals.
1126 // For all globals map getDSNodeForGlobal(g)->CG.getDSNodeForGlobal(g)
1127 for (DSGraph::ScalarMapTy::iterator SMI = G.getScalarMap().begin(),
1128 SME = G.getScalarMap().end(); SMI != SME; ++SMI)
1129 if (isa(SMI->first)) {
1130 CalcNodeMapping(SMI->second,
1131 CG.getScalarMap()[SMI->first], NodeMapping);
1132 }
1133
1134 // Okay, now that we have established our mapping, we can figure out which
1135 // pool descriptors to pass in...
1136
1137 // Add an argument for each pool which must be passed in...
1138 if (CFI->PoolArgFirst != 0) {
1139 for (int i = 0; i < CFI->PoolArgFirst; ++i)
1140 Args.push_back(Constant::getNullValue(PoolDescPtr));
1141 }
1142
1143 for (unsigned i = 0, e = CFI->ArgNodes.size(); i != e; ++i) {
1144 if (NodeMapping.count(CFI->ArgNodes[i])) {
1145
1146 DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second;
1147 if (LocalNode) {
1148 assert(FI.PoolDescriptors.count(LocalNode) &&
1149 "Node not pool allocated?");
1150 Args.push_back(FI.PoolDescriptors.find(LocalNode)->second);
1151 } else
1152 Args.push_back(Constant::getNullValue(PoolDescPtr));
1153 } else {
1154 Args.push_back(Constant::getNullValue(PoolDescPtr));
1155 }
1156 }
1157
1158 Function *FuncClass = PAInfo.FuncECs.findClass(CF);
1159
1160 if (PAInfo.EqClass2LastPoolArg.count(FuncClass))
1161 for (int i = CFI->PoolArgLast;
1162 i <= PAInfo.EqClass2LastPoolArg[FuncClass]; ++i)
1163 Args.push_back(Constant::getNullValue(PoolDescPtr));
1164
1165 // Add the rest of the arguments...
1166 Args.insert(Args.end(), CI.op_begin()+1, CI.op_end());
1167
1168 std::string Name = CI.getName();
1169
1170 std::map::iterator CNewII;
1171
1172 Value *NewCall = new CallInst(CFI->Clone, Args, Name, &CI);
1173
1174 CI.replaceAllUsesWith(NewCall);
1175 DEBUG(std::cerr << " Result Call: " << *NewCall);
1176
1177 if (CI.getType() != Type::VoidTy) {
1178 // If we are modifying the original function, update the DSGraph...
1179 DSGraph::ScalarMapTy &SM = G.getScalarMap();
1180 DSGraph::ScalarMapTy::iterator CII = SM.find(&CI);
1181 if (CII != SM.end()) {
1182 SM.insert(std::make_pair(NewCall, CII->second));
1183 SM.erase(CII); // Destroy the CallInst
1184 } else {
1185 // Otherwise update the NewToOldValueMap with the new CI return value
1186 std::map::iterator CNII =
1187 FI.NewToOldValueMap.find(&CI);
1188 assert(CNII != FI.NewToOldValueMap.end() && CNII->second &&
1189 "CI not found in clone?");
1190 FI.NewToOldValueMap.insert(std::make_pair(NewCall, CNII->second));
1191 FI.NewToOldValueMap.erase(CNII);
1192 }
1193 } else if (!FI.NewToOldValueMap.empty()) {
1194 std::map::iterator II =
1195 FI.NewToOldValueMap.find(&CI);
1196 assert(II != FI.NewToOldValueMap.end() && "CI not found in clone?");
1197 FI.NewToOldValueMap.insert(std::make_pair(NewCall, II->second));
1198 FI.NewToOldValueMap.erase(II);
1199 }
1200 }
1201
1202 CI.getParent()->getInstList().erase(&CI);
1203 }
+0
-4
runtime/GCCLibraries/libpoolalloc/Makefile less more
None LEVEL = ../../..
1 LIBNAME = poolalloc
2 include ../Makefile.libs
3
+0
-461
runtime/GCCLibraries/libpoolalloc/PoolAllocatorChained.c less more
None #include
1 #include
2 #include
3
4 #undef assert
5 #define assert(X)
6
7
8 /* In the current implementation, each slab in the pool has NODES_PER_SLAB
9 * nodes unless the isSingleArray flag is set in which case it contains a
10 * single array of size ArraySize. Small arrays (size <= NODES_PER_SLAB) are
11 * still allocated in the slabs of size NODES_PER_SLAB
12 */
13 #define NODES_PER_SLAB 512
14
15 typedef struct PoolTy {
16 void *Data;
17 unsigned NodeSize;
18 unsigned FreeablePool; /* Set to false if the memory from this pool cannot be
19 freed before destroy*/
20
21 } PoolTy;
22
23 /* PoolSlab Structure - Hold NODES_PER_SLAB objects of the current node type.
24 * Invariants: FirstUnused <= LastUsed+1
25 */
26 typedef struct PoolSlab {
27 unsigned FirstUnused; /* First empty node in slab */
28 int LastUsed; /* Last allocated node in slab */
29 struct PoolSlab *Next;
30 unsigned char AllocatedBitVector[NODES_PER_SLAB/8];
31 unsigned char StartOfAllocation[NODES_PER_SLAB/8];
32
33 unsigned isSingleArray; /* If this slab is used for exactly one array */
34 /* The array is allocated from the start to the end of the slab */
35 unsigned ArraySize; /* The size of the array allocated */
36
37 char Data[1]; /* Buffer to hold data in this slab... variable sized */
38
39 } PoolSlab;
40
41 #define NODE_ALLOCATED(POOLSLAB, NODENUM) \
42 ((POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] & (1 << ((NODENUM) & 7)))
43 #define MARK_NODE_ALLOCATED(POOLSLAB, NODENUM) \
44 (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7)
45 #define MARK_NODE_FREE(POOLSLAB, NODENUM) \
46 (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7))
47 #define ALLOCATION_BEGINS(POOLSLAB, NODENUM) \
48 ((POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] & (1 << ((NODENUM) & 7)))
49 #define SET_START_BIT(POOLSLAB, NODENUM) \
50 (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7)
51 #define CLEAR_START_BIT(POOLSLAB, NODENUM) \
52 (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7))
53
54
55 /* poolinit - Initialize a pool descriptor to empty
56 */
57 void poolinit(PoolTy *Pool, unsigned NodeSize) {
58 if (!Pool) {
59 printf("Null pool pointer passed into poolinit!\n");
60 exit(1);
61 }
62
63 Pool->NodeSize = NodeSize;
64 Pool->Data = 0;
65
66 Pool->FreeablePool = 1;
67
68 }
69
70 void poolmakeunfreeable(PoolTy *Pool) {
71 if (!Pool) {
72 printf("Null pool pointer passed in to poolmakeunfreeable!\n");
73 exit(1);
74 }
75
76 Pool->FreeablePool = 0;
77 }
78
79 /* pooldestroy - Release all memory allocated for a pool
80 */
81 void pooldestroy(PoolTy *Pool) {
82 PoolSlab *PS;
83 if (!Pool) {
84 printf("Null pool pointer passed in to pooldestroy!\n");
85 exit(1);
86 }
87
88 PS = (PoolSlab*)Pool->Data;
89 while (PS) {
90 PoolSlab *Next = PS->Next;
91 free(PS);
92 PS = Next;
93 }
94 }
95
96 static void *FindSlabEntry(PoolSlab *PS, unsigned NodeSize) {
97 /* Loop through all of the slabs looking for one with an opening */
98 for (; PS; PS = PS->Next) {
99
100 /* If the slab is a single array, go on to the next slab */
101 /* Don't allocate single nodes in a SingleArray slab */
102 if (PS->isSingleArray)
103 continue;
104
105 /* Check to see if there are empty entries at the end of the slab... */
106 if (PS->LastUsed < NODES_PER_SLAB-1) {
107 /* Mark the returned entry used */
108 MARK_NODE_ALLOCATED(PS, PS->LastUsed+1);
109 SET_START_BIT(PS, PS->LastUsed+1);
110
111 /* If we are allocating out the first unused field, bump its index also */
112 if (PS->FirstUnused == PS->LastUsed+1)
113 PS->FirstUnused++;
114
115 /* Return the entry, increment LastUsed field. */
116 return &PS->Data[0] + ++PS->LastUsed * NodeSize;
117 }
118
119 /* If not, check to see if this node has a declared "FirstUnused" value that
120 * is less than the number of nodes allocated...
121 */
122 if (PS->FirstUnused < NODES_PER_SLAB) {
123 /* Successfully allocate out the first unused node */
124 unsigned Idx = PS->FirstUnused;
125
126 MARK_NODE_ALLOCATED(PS, Idx);
127 SET_START_BIT(PS, Idx);
128
129 /* Increment FirstUnused to point to the new first unused value... */
130 do {
131 ++PS->FirstUnused;
132 } while (PS->FirstUnused < NODES_PER_SLAB &&
133 NODE_ALLOCATED(PS, PS->FirstUnused));
134
135 return &PS->Data[0] + Idx*NodeSize;
136 }
137 }
138
139 /* No empty nodes available, must grow # slabs! */
140 return 0;
141 }
142
143 char *poolalloc(PoolTy *Pool) {
144 unsigned NodeSize;
145 PoolSlab *PS;
146 void *Result;
147
148 if (!Pool) {
149 printf("Null pool pointer passed in to poolalloc!\n");
150 exit(1);
151 }
152
153 NodeSize = Pool->NodeSize;
154 // Return if this pool has size 0
155 if (NodeSize == 0)
156 return 0;
157
158 PS = (PoolSlab*)Pool->Data;
159
160 if ((Result = FindSlabEntry(PS, NodeSize)))
161 return Result;
162
163 /* Otherwise we must allocate a new slab and add it to the list */
164 PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1);
165
166 if (!PS) {
167 printf("poolalloc: Could not allocate memory!");
168 exit(1);
169 }
170
171 /* Initialize the slab to indicate that the first element is allocated */
172 PS->FirstUnused = 1;
173 PS->LastUsed = 0;
174 /* This is not a single array */
175 PS->isSingleArray = 0;
176 PS->ArraySize = 0;
177
178 MARK_NODE_ALLOCATED(PS, 0);
179 SET_START_BIT(PS, 0);
180
181 /* Add the slab to the list... */
182 PS->Next = (PoolSlab*)Pool->Data;
183 Pool->Data = PS;
184 return &PS->Data[0];
185 }
186
187 void poolfree(PoolTy *Pool, char *Node) {
188 unsigned NodeSize, Idx;
189 PoolSlab *PS;
190 PoolSlab **PPS;
191 unsigned idxiter;
192
193 if (!Pool) {
194 printf("Null pool pointer passed in to poolfree!\n");
195 exit(1);
196 }
197
198 NodeSize = Pool->NodeSize;
199
200 // Return if this pool has size 0
201 if (NodeSize == 0)
202 return;
203
204 PS = (PoolSlab*)Pool->Data;
205 PPS = (PoolSlab**)&Pool->Data;
206
207 /* Search for the slab that contains this node... */
208 while (&PS->Data[0] > Node || &PS->Data[NodeSize*NODES_PER_SLAB-1] < Node) {
209 if (!PS) {
210 printf("poolfree: node being free'd not found in allocation pool specified!\n");
211 exit(1);
212 }
213
214 PPS = &PS->Next;
215 PS = PS->Next;
216 }
217
218 /* PS now points to the slab where Node is */
219
220 Idx = (Node-&PS->Data[0])/NodeSize;
221 assert(Idx < NODES_PER_SLAB && "Pool slab searching loop broken!");
222
223 if (PS->isSingleArray) {
224
225 /* If this slab is a SingleArray */
226
227 if (Idx != 0) {
228 printf("poolfree: Attempt to free middle of allocated array\n");
229 exit(1);
230 }
231 if (!NODE_ALLOCATED(PS,0)) {
232 printf("poolfree: Attempt to free node that is already freed\n");
233 exit(1);
234 }
235 /* Mark this SingleArray slab as being free by just marking the first
236 entry as free*/
237 MARK_NODE_FREE(PS, 0);
238 } else {
239
240 /* If this slab is not a SingleArray */
241
242 if (!ALLOCATION_BEGINS(PS, Idx)) {
243 printf("poolfree: Attempt to free middle of allocated array\n");
244 exit(1);
245 }
246
247 /* Free the first node */
248 if (!NODE_ALLOCATED(PS, Idx)) {
249 printf("poolfree: Attempt to free node that is already freed\n");
250 exit(1);
251 }
252 CLEAR_START_BIT(PS, Idx);
253 MARK_NODE_FREE(PS, Idx);
254
255 // Free all nodes
256 idxiter = Idx + 1;
257 while (idxiter < NODES_PER_SLAB && (!ALLOCATION_BEGINS(PS,idxiter)) &&
258 (NODE_ALLOCATED(PS, idxiter))) {
259 MARK_NODE_FREE(PS, idxiter);
260 ++idxiter;
261 }
262
263 /* Update the first free field if this node is below the free node line */
264 if (Idx < PS->FirstUnused) PS->FirstUnused = Idx;
265
266 /* If we are not freeing the last element in a slab... */
267 if (idxiter - 1 != PS->LastUsed) {
268 return;
269 }
270
271 /* Otherwise we are freeing the last element in a slab... shrink the
272 * LastUsed marker down to last used node.
273 */
274 PS->LastUsed = Idx;
275 do {
276 --PS->LastUsed;
277 /* Fixme, this should scan the allocated array an entire byte at a time
278 * for performance!
279 */
280 } while (PS->LastUsed >= 0 && (!NODE_ALLOCATED(PS, PS->LastUsed)));
281
282 assert(PS->FirstUnused <= PS->LastUsed+1 &&
283 "FirstUnused field was out of date!");
284 }
285
286 /* Ok, if this slab is empty, we unlink it from the of slabs and either move
287 * it to the head of the list, or free it, depending on whether or not there
288 * is already an empty slab at the head of the list.
289 */
290 /* Do this only if the pool is freeable */
291 if (Pool->FreeablePool) {
292 if (PS->isSingleArray) {
293 /* If it is a SingleArray, just free it */
294 *PPS = PS->Next;
295 free(PS);
296 } else if (PS->LastUsed == -1) { /* Empty slab? */
297 PoolSlab *HeadSlab;
298 *PPS = PS->Next; /* Unlink from the list of slabs... */
299
300 HeadSlab = (PoolSlab*)Pool->Data;
301 if (HeadSlab && HeadSlab->LastUsed == -1){/*List already has empty slab?*/
302 free(PS); /*Free memory for slab */
303 } else {
304 PS->Next = HeadSlab; /*No empty slab yet, add this*/
305 Pool->Data = PS; /*one to the head of the list */
306 }
307 }
308 } else {
309 /* Pool is not freeable for safety reasons */
310 /* Leave it in the list of PoolSlabs as an empty PoolSlab */
311 if (!PS->isSingleArray)
312 if (PS->LastUsed == -1) {
313 PS->FirstUnused = 0;
314
315 /* Do not free the pool, but move it to the head of the list if there is
316 no empty slab there already */
317 PoolSlab *HeadSlab;
318 HeadSlab = (PoolSlab*)Pool->Data;
319 if (HeadSlab && HeadSlab->LastUsed != -1) {
320 PS->Next = HeadSlab;
321 Pool->Data = PS;
322 }
323 }
324 }
325 }
326
327 /* The poolallocarray version of FindSlabEntry */
328 static void *FindSlabEntryArray(PoolSlab *PS, unsigned NodeSize,
329 unsigned Size) {
330 unsigned i;
331
332 /* Loop through all of the slabs looking for one with an opening */
333 for (; PS; PS = PS->Next) {
334
335 /* For large array allocation */
336 if (Size > NODES_PER_SLAB) {
337 /* If this slab is a SingleArray that is free with size > Size, use it */
338 if (PS->isSingleArray && !NODE_ALLOCATED(PS,0) && PS->ArraySize >= Size) {
339 /* Allocate the array in this slab */
340 MARK_NODE_ALLOCATED(PS,0); /* In a single array, only the first node
341 needs to be marked */
342 return &PS->Data[0];
343 } else
344 continue;
345 } else if (PS->isSingleArray)
346 continue; /* Do not allocate small arrays in SingleArray slabs */
347
348 /* For small array allocation */
349 /* Check to see if there are empty entries at the end of the slab... */
350 if (PS->LastUsed < NODES_PER_SLAB-Size) {
351 /* Mark the returned entry used and set the start bit*/
352 SET_START_BIT(PS, PS->LastUsed + 1);
353 for (i = PS->LastUsed + 1; i <= PS->LastUsed + Size; ++i)
354 MARK_NODE_ALLOCATED(PS, i);
355
356 /* If we are allocating out the first unused field, bump its index also */
357 if (PS->FirstUnused == PS->LastUsed+1)
358 PS->FirstUnused += Size;
359
360 /* Increment LastUsed */
361 PS->LastUsed += Size;
362
363 /* Return the entry */
364 return &PS->Data[0] + (PS->LastUsed - Size + 1) * NodeSize;
365 }
366
367 /* If not, check to see if this node has a declared "FirstUnused" value
368 * starting which Size nodes can be allocated
369 */
370 if (PS->FirstUnused < NODES_PER_SLAB - Size + 1 &&
371 (PS->LastUsed < PS->FirstUnused ||
372 PS->LastUsed - PS->FirstUnused >= Size)) {
373 unsigned Idx = PS->FirstUnused, foundArray;
374
375 /* Check if there is a continuous array of Size nodes starting
376 FirstUnused */
377 foundArray = 1;
378 for (i = Idx; (i < Idx + Size) && foundArray; ++i)
379 if (NODE_ALLOCATED(PS, i))
380 foundArray = 0;
381
382 if (foundArray) {
383 /* Successfully allocate starting from the first unused node */
384 SET_START_BIT(PS, Idx);
385 for (i = Idx; i < Idx + Size; ++i)
386 MARK_NODE_ALLOCATED(PS, i);
387
388 PS->FirstUnused += Size;
389 while (PS->FirstUnused < NODES_PER_SLAB &&
390 NODE_ALLOCATED(PS, PS->FirstUnused)) {
391 ++PS->FirstUnused;
392 }
393 return &PS->Data[0] + Idx*NodeSize;
394 }
395
396 }
397 }
398
399 /* No empty nodes available, must grow # slabs! */
400 return 0;
401 }
402
403 char* poolallocarray(PoolTy* Pool, unsigned Size) {
404 unsigned NodeSize;
405 PoolSlab *PS;
406 void *Result;
407 unsigned i;
408
409 if (!Pool) {
410 printf("Null pool pointer passed to poolallocarray!\n");
411 exit(1);
412 }
413
414 NodeSize = Pool->NodeSize;
415
416 // Return if this pool has size 0
417 if (NodeSize == 0)
418 return 0;
419
420 PS = (PoolSlab*)Pool->Data;
421
422 if ((Result = FindSlabEntryArray(PS, NodeSize,Size)))
423 return Result;
424
425 /* Otherwise we must allocate a new slab and add it to the list */
426 if (Size > NODES_PER_SLAB) {
427 /* Allocate a new slab of size Size */
428 PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*Size-1);
429 if (!PS) {
430 printf("poolallocarray: Could not allocate memory!\n");
431 exit(1);
432 }
433 PS->isSingleArray = 1;
434 PS->ArraySize = Size;
435 MARK_NODE_ALLOCATED(PS, 0);
436 } else {
437 PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1);
438 if (!PS) {
439 printf("poolallocarray: Could not allocate memory!\n");
440 exit(1);
441 }
442
443 /* Initialize the slab to indicate that the first element is allocated */
444 PS->FirstUnused = Size;
445 PS->LastUsed = Size - 1;
446
447 PS->isSingleArray = 0;
448 PS->ArraySize = 0;
449
450 SET_START_BIT(PS, 0);
451 for (i = 0; i < Size; ++i) {
452 MARK_NODE_ALLOCATED(PS, i);
453 }
454 }
455
456 /* Add the slab to the list... */
457 PS->Next = (PoolSlab*)Pool->Data;
458 Pool->Data = PS;
459 return &PS->Data[0];
460 }