From 4c7f3dfeaac9c9ca155c00f0eb05ffa90ed317f9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 30 Mar 2002 04:02:31 +0000 Subject: [PATCH] Maintain enough information so that the pools for all of the nodes of the graph can be passed around. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2053 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/OldPoolAllocate.cpp | 110 +++++++++++++++---------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/lib/Transforms/IPO/OldPoolAllocate.cpp b/lib/Transforms/IPO/OldPoolAllocate.cpp index 395fe9e7f36..17ce3dd8521 100644 --- a/lib/Transforms/IPO/OldPoolAllocate.cpp +++ b/lib/Transforms/IPO/OldPoolAllocate.cpp @@ -9,6 +9,7 @@ #include "llvm/Transforms/IPO/PoolAllocate.h" #include "llvm/Transforms/CloneFunction.h" #include "llvm/Analysis/DataStructure.h" +#include "llvm/Analysis/DataStructureGraph.h" #include "llvm/Pass.h" #include "llvm/Module.h" #include "llvm/Function.h" @@ -18,6 +19,7 @@ #include "llvm/ConstantVals.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/InstVisitor.h" +#include "Support/DepthFirstIterator.h" #include "Support/STLExtras.h" #include @@ -38,6 +40,21 @@ namespace { : Val(V), AllocNode(AN), PoolHandle(PH) {} }; + // CallArgInfo - Information on one operand for a call that got expanded. + struct CallArgInfo { + int ArgNo; // Call argument number this corresponds to + AllocDSNode *AllocNode; // The allocation graph node for the pool + Value *PoolHandle; // The LLVM value that is the pool pointer + + CallArgInfo(int Arg, AllocDSNode *AN, Value *PH) + : ArgNo(Arg), AllocNode(AN), PoolHandle(PH) { + } + + bool operator<(const CallArgInfo &CAI) const { + return ArgNo < CAI.ArgNo; + } + }; + // TransformFunctionInfo - Information about how a function eeds to be // transformed. // @@ -49,7 +66,7 @@ namespace { // // As a special case, "argument" number -1 corresponds to the return value. // - vector > ArgInfo; + vector ArgInfo; // Func - The function to be transformed... Function *Func; @@ -57,20 +74,12 @@ namespace { // default ctor... TransformFunctionInfo() : Func(0) {} - inline bool operator<(const TransformFunctionInfo &TFI) const { + bool operator<(const TransformFunctionInfo &TFI) const { if (Func < TFI.Func) return true; if (Func > TFI.Func) return false; - - // Loop over the arguments, checking to see if only the arg _numbers_ are - // less... if (ArgInfo.size() < TFI.ArgInfo.size()) return true; if (ArgInfo.size() > TFI.ArgInfo.size()) return false; - - for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) { - if (ArgInfo[i].first < TFI.ArgInfo[i].first) return true; - if (ArgInfo[i].first > TFI.ArgInfo[i].first) return false; - } - return false; // They must be equal + return ArgInfo < TFI.ArgInfo; } void finalizeConstruction() { @@ -145,7 +154,7 @@ namespace { // PoolDescriptors vector. // void CreatePools(Function *F, const vector &Allocs, - vector &PoolDescriptors); + map &PoolDescriptors); // processFunction - Convert a function to use pool allocation where // available. @@ -153,7 +162,8 @@ namespace { bool processFunction(Function *F); - void transformFunctionBody(Function *F, vector &Scalars); + void transformFunctionBody(Function *F, vector &Scalars, + map &PoolDescriptors); // transformFunction - Transform the specified function the specified way. // It we have already transformed that function that way, don't do anything. @@ -207,10 +217,10 @@ bool PoolAllocate::processFunction(Function *F) { // Insert instructions into the function we are processing to create all of // the memory pool objects themselves. This also inserts destruction code. - // This fills in the PoolDescriptors vector to be a array parallel with - // Allocs, but containing the alloca instructions that allocate the pool ptr. + // This fills in the PoolDescriptors map to associate the alloc node with the + // allocation of the memory pool corresponding to it. // - vector PoolDescriptors; + map PoolDescriptors; CreatePools(F, Allocs, PoolDescriptors); @@ -235,13 +245,9 @@ bool PoolAllocate::processFunction(Function *F) { assert(PVS[i].Index == 0 && "Nonzero not handled yet!"); // If the allocation is in the nonescaping set... - vector::iterator AI = - find(Allocs.begin(), Allocs.end(), Alloc); - if (AI != Allocs.end()) { - unsigned IDX = AI-Allocs.begin(); - // Add it to the list of scalars we have - Scalars.push_back(ScalarInfo(I->first, Alloc, PoolDescriptors[IDX])); - } + map::iterator AI=PoolDescriptors.find(Alloc); + if (AI != PoolDescriptors.end()) // Add it to the list of scalars + Scalars.push_back(ScalarInfo(I->first, Alloc, AI->second)); } } @@ -250,22 +256,11 @@ bool PoolAllocate::processFunction(Function *F) { // either used as a scalar value (so they return a data structure), or are // passed one of our scalar values. // - transformFunctionBody(F, Scalars); + transformFunctionBody(F, Scalars, PoolDescriptors); return true; } -static void addCallInfo(TransformFunctionInfo &TFI, CallInst *CI, int Arg, - Value *PoolHandle) { - assert(CI->getCalledFunction() && "Cannot handle indirect calls yet!"); - TFI.ArgInfo.push_back(make_pair(Arg, PoolHandle)); - - assert(TFI.Func == 0 || TFI.Func == CI->getCalledFunction() && - "Function call record should always call the same function!"); - TFI.Func = CI->getCalledFunction(); -} - - class FunctionBodyTransformer : public InstVisitor { PoolAllocate &PoolAllocator; @@ -368,7 +363,7 @@ public: // Add all of the pool arguments... for (unsigned i = 0, e = TI.ArgInfo.size(); i != e; ++i) - Args.push_back(TI.ArgInfo[i].second); + Args.push_back(TI.ArgInfo[i].PoolHandle); Function *NF = PoolAllocator.getTransformedFunction(TI); CallInst *NewCall = new CallInst(NF, Args, I->getName()); @@ -385,6 +380,10 @@ public: delete I; // Delete the old call instruction now... } + void visitPHINode(PHINode *PN) { + // Handle PHI Node + } + void visitInstruction(Instruction *I) { cerr << "Unknown instruction to FunctionBodyTransformer:\n"; I->dump(); @@ -393,8 +392,30 @@ public: }; +static void addCallInfo(TransformFunctionInfo &TFI, CallInst *CI, int Arg, + DSNode *AllocNode, + map &PoolDescriptors) { + + // For now, add the entire graph that is pointed to by the call argument. + // This graph can and should be pruned to only what the function itself will + // use, because often this will be a dramatically smaller subset of what we + // are providing. + // + for (df_iterator I = df_begin(AllocNode), E = df_end(AllocNode); + I != E; ++I) { + if (AllocDSNode *AN = dyn_cast(*I)) + TFI.ArgInfo.push_back(CallArgInfo(Arg, AN, PoolDescriptors[AN])); + } + + assert(CI->getCalledFunction() && "Cannot handle indirect calls yet!"); + assert(TFI.Func == 0 || TFI.Func == CI->getCalledFunction() && + "Function call record should always call the same function!"); + TFI.Func = CI->getCalledFunction(); +} + void PoolAllocate::transformFunctionBody(Function *F, - vector &Scalars) { + vector &Scalars, + map &PoolDescriptors) { cerr << "In '" << F->getName() << "': Found the following values that point to poolable nodes:\n"; @@ -418,7 +439,7 @@ void PoolAllocate::transformFunctionBody(Function *F, // Check to see if the scalar _IS_ a call... if (CallInst *CI = dyn_cast(ScalarVal)) // If so, add information about the pool it will be returning... - addCallInfo(CallMap[CI], CI, -1, Scalars[i].PoolHandle); + addCallInfo(CallMap[CI], CI, -1, Scalars[i].AllocNode, PoolDescriptors); // Check to see if the scalar is an operand to a call... for (Value::use_iterator UI = ScalarVal->use_begin(), @@ -433,7 +454,8 @@ void PoolAllocate::transformFunctionBody(Function *F, // than once! It will get multiple entries for the first pointer. // Add the operand number and pool handle to the call table... - addCallInfo(CallMap[CI], CI, OI-CI->op_begin()-1,Scalars[i].PoolHandle); + addCallInfo(CallMap[CI], CI, OI-CI->op_begin()-1, Scalars[i].AllocNode, + PoolDescriptors); } } } @@ -446,7 +468,7 @@ void PoolAllocate::transformFunctionBody(Function *F, I->second.finalizeConstruction(); cerr << I->second.Func->getName() << " must pass pool pointer for arg #"; for (unsigned i = 0; i < I->second.ArgInfo.size(); ++i) - cerr << I->second.ArgInfo[i].first << " "; + cerr << I->second.ArgInfo[i].ArgNo << " "; cerr << "\n"; } @@ -547,10 +569,10 @@ void PoolAllocate::transformFunction(TransformFunctionInfo &TFI) { // Now add all of the arguments corresponding to pools passed in... for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) { string Name; - if (TFI.ArgInfo[i].first == -1) + if (TFI.ArgInfo[i].ArgNo == -1) Name = "retpool"; else - Name = ArgMap[TFI.ArgInfo[i].first]->getName(); // Get the arg name + Name = ArgMap[TFI.ArgInfo[i].ArgNo]->getName(); // Get the arg name FunctionArgument *NFA = new FunctionArgument(PoolTy, Name+".pool"); NewFunc->getArgumentList().push_back(NFA); } @@ -571,7 +593,7 @@ void PoolAllocate::transformFunction(TransformFunctionInfo &TFI) { // PoolDescriptors vector. // void PoolAllocate::CreatePools(Function *F, const vector &Allocs, - vector &PoolDescriptors) { + map &PoolDescriptors){ // FIXME: This should use an IP version of the UnifyAllExits pass! vector ReturnNodes; for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) @@ -585,7 +607,7 @@ void PoolAllocate::CreatePools(Function *F, const vector &Allocs, // Add an allocation and a free for each pool... AllocaInst *PoolAlloc = new AllocaInst(PoolTy, 0, "pool"); EntryNodeInsts.push_back(PoolAlloc); - PoolDescriptors.push_back(PoolAlloc); // Keep track of pool allocas + PoolDescriptors[Allocs[i]] = PoolAlloc; // Keep track of pool allocas AllocationInst *AI = Allocs[i]->getAllocation(); // Initialize the pool. We need to know how big each allocation is. For