aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-03-30 04:02:31 +0000
committerChris Lattner <sabre@nondot.org>2002-03-30 04:02:31 +0000
commit4c7f3dfeaac9c9ca155c00f0eb05ffa90ed317f9 (patch)
tree98b0da187df0efc8c700544a8326928b095e04e7 /lib/Transforms
parent9d3493e533f73e4e955e10a830d582fb48508fca (diff)
downloadexternal_llvm-4c7f3dfeaac9c9ca155c00f0eb05ffa90ed317f9.zip
external_llvm-4c7f3dfeaac9c9ca155c00f0eb05ffa90ed317f9.tar.gz
external_llvm-4c7f3dfeaac9c9ca155c00f0eb05ffa90ed317f9.tar.bz2
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/OldPoolAllocate.cpp110
1 files changed, 66 insertions, 44 deletions
diff --git a/lib/Transforms/IPO/OldPoolAllocate.cpp b/lib/Transforms/IPO/OldPoolAllocate.cpp
index 395fe9e..17ce3dd 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 <algorithm>
@@ -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<pair<int, Value*> > ArgInfo;
+ vector<CallArgInfo> 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<AllocDSNode*> &Allocs,
- vector<AllocaInst*> &PoolDescriptors);
+ map<AllocDSNode*, AllocaInst*> &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<ScalarInfo> &Scalars);
+ void transformFunctionBody(Function *F, vector<ScalarInfo> &Scalars,
+ map<AllocDSNode*, AllocaInst*> &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<AllocaInst*> PoolDescriptors;
+ map<AllocDSNode*, AllocaInst*> 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<AllocDSNode*>::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<AllocDSNode*, AllocaInst*>::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<FunctionBodyTransformer> {
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<AllocDSNode*, AllocaInst*> &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<DSNode*> I = df_begin(AllocNode), E = df_end(AllocNode);
+ I != E; ++I) {
+ if (AllocDSNode *AN = dyn_cast<AllocDSNode>(*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<ScalarInfo> &Scalars) {
+ vector<ScalarInfo> &Scalars,
+ map<AllocDSNode*, AllocaInst*> &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<CallInst>(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<AllocDSNode*> &Allocs,
- vector<AllocaInst*> &PoolDescriptors) {
+ map<AllocDSNode*, AllocaInst*> &PoolDescriptors){
// FIXME: This should use an IP version of the UnifyAllExits pass!
vector<BasicBlock*> ReturnNodes;
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
@@ -585,7 +607,7 @@ void PoolAllocate::CreatePools(Function *F, const vector<AllocDSNode*> &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