summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-03-29 19:05:48 +0000
committerChris Lattner <sabre@nondot.org>2002-03-29 19:05:48 +0000
commit291a1b1eb240578d265baa45ac191f6ebe2f14ce (patch)
treeb541682d9c65010411d60095325e83f0aee0ace0 /llvm/lib/Transforms
parentf50cffce109fb27a845fb007bf2a8b0af83e7de8 (diff)
downloadbcm5719-llvm-291a1b1eb240578d265baa45ac191f6ebe2f14ce.tar.gz
bcm5719-llvm-291a1b1eb240578d265baa45ac191f6ebe2f14ce.zip
Correctly clone the function with the extra argument types. Now we need
to modify the function next. This also properly recycles functions so that we don't get exponential code blowup in the common case. llvm-svn: 2049
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/OldPoolAllocate.cpp80
1 files changed, 74 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/IPO/OldPoolAllocate.cpp b/llvm/lib/Transforms/IPO/OldPoolAllocate.cpp
index 7e9f15556aa..bf5c4003031 100644
--- a/llvm/lib/Transforms/IPO/OldPoolAllocate.cpp
+++ b/llvm/lib/Transforms/IPO/OldPoolAllocate.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/PoolAllocate.h"
+#include "llvm/Transforms/CloneFunction.h"
#include "llvm/Analysis/DataStructure.h"
#include "llvm/Pass.h"
#include "llvm/Module.h"
@@ -56,7 +57,19 @@ namespace {
TransformFunctionInfo() : Func(0) {}
inline bool operator<(const TransformFunctionInfo &TFI) const {
- return Func < TFI.Func || (Func == TFI.Func && ArgInfo < TFI.ArgInfo);
+ 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
}
void finalizeConstruction() {
@@ -291,7 +304,7 @@ 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(), Scalars[i].PoolHandle);
+ addCallInfo(CallMap[CI], CI, OI-CI->op_begin()-1,Scalars[i].PoolHandle);
}
}
}
@@ -302,7 +315,7 @@ void PoolAllocate::transformFunctionBody(Function *F,
cerr << "\nFor call: ";
I->first->dump();
I->second.finalizeConstruction();
- cerr << " must pass pool pointer for arg #";
+ 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 << "\n";
@@ -330,8 +343,60 @@ void PoolAllocate::transformFunctionBody(Function *F,
void PoolAllocate::transformFunction(TransformFunctionInfo &TFI) {
if (getTransformedFunction(TFI)) return; // Function xformation already done?
+ Function *FuncToXForm = TFI.Func;
+ const FunctionType *OldFuncType = FuncToXForm->getFunctionType();
+
+ assert(!OldFuncType->isVarArg() && "Vararg functions not handled yet!");
+ // Build the type for the new function that we are transforming
+ vector<const Type*> ArgTys;
+ for (unsigned i = 0, e = OldFuncType->getNumParams(); i != e; ++i)
+ ArgTys.push_back(OldFuncType->getParamType(i));
+
+ // Add one pool pointer for every argument that needs to be supplemented.
+ ArgTys.insert(ArgTys.end(), TFI.ArgInfo.size(), PoolTy);
+
+ // Build the new function type...
+ const // FIXME when types are not const
+ FunctionType *NewFuncType = FunctionType::get(OldFuncType->getReturnType(),
+ ArgTys,OldFuncType->isVarArg());
+
+ // The new function is internal, because we know that only we can call it.
+ // This also helps subsequent IP transformations to eliminate duplicated pool
+ // pointers. [in the future when they are implemented].
+ //
+ Function *NewFunc = new Function(NewFuncType, true,
+ FuncToXForm->getName()+".poolxform");
+ CurModule->getFunctionList().push_back(NewFunc);
+ // Add the newly formed function to the TransformedFunctions table so that
+ // infinite recursion does not occur!
+ //
+ TransformedFunctions[TFI] = NewFunc;
+
+ // Add arguments to the function... starting with all of the old arguments
+ vector<Value*> ArgMap;
+ for (unsigned i = 0, e = FuncToXForm->getArgumentList().size(); i != e; ++i) {
+ const FunctionArgument *OFA = FuncToXForm->getArgumentList()[i];
+ FunctionArgument *NFA = new FunctionArgument(OFA->getType(),OFA->getName());
+ NewFunc->getArgumentList().push_back(NFA);
+ ArgMap.push_back(NFA); // Keep track of the arguments
+ }
+
+ // 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)
+ Name = "retpool";
+ else
+ Name = ArgMap[TFI.ArgInfo[i].first]->getName(); // Get the arg name
+ FunctionArgument *NFA = new FunctionArgument(PoolTy, Name+".pool");
+ NewFunc->getArgumentList().push_back(NFA);
+ }
+
+ // Now clone the body of the old function into the new function...
+ CloneFunctionInto(NewFunc, FuncToXForm, ArgMap);
+
}
@@ -427,9 +492,12 @@ bool PoolAllocate::run(Module *M) {
DS = &getAnalysis<DataStructure>();
bool Changed = false;
- for (Module::iterator I = M->begin(); I != M->end(); ++I)
- if (!(*I)->isExternal())
- Changed |= processFunction(*I);
+
+ // We cannot use an iterator here because it will get invalidated when we add
+ // functions to the module later...
+ for (unsigned i = 0; i != M->size(); ++i)
+ if (!M->getFunctionList()[i]->isExternal())
+ Changed |= processFunction(M->getFunctionList()[i]);
CurModule = 0;
DS = 0;
OpenPOWER on IntegriCloud