[llvm-commits] CVS: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Feb 25 16:48:12 PST 2005
Changes in directory llvm-poolalloc/lib/PoolAllocate:
PointerCompress.cpp updated: 1.30 -> 1.31
---
Log message:
Implement general support for external function calls that are passed
compressed pointers, restoring bugpoint tranquility. This also means we
don't have to handle poolalloc/poolfree as a special case at all anymore.
Implement initial continued support for passing dependent pools to
functions.
---
Diffs of the changes: (+110 -80)
PointerCompress.cpp | 190 ++++++++++++++++++++++++++++++----------------------
1 files changed, 110 insertions(+), 80 deletions(-)
Index: llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp
diff -u llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.30 llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.31
--- llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp:1.30 Fri Feb 25 15:14:12 2005
+++ llvm-poolalloc/lib/PoolAllocate/PointerCompress.cpp Fri Feb 25 18:47:56 2005
@@ -89,12 +89,15 @@
typedef std::pair<Function*, std::set<const DSNode*> > CloneID;
std::map<CloneID, Function *> ClonedFunctionMap;
+ std::map<std::pair<Function*, std::vector<unsigned> >,
+ Function*> ExtCloneFunctionMap;
+
/// ClonedFunctionInfoMap - This identifies the pool allocated function that
/// a clone came from.
std::map<Function*, FunctionCloneRecord> ClonedFunctionInfoMap;
public:
- Function *PoolInitPC, *PoolDestroyPC, *PoolAllocPC, *PoolFreePC;
+ Function *PoolInitPC, *PoolDestroyPC;
typedef std::map<const DSNode*, CompressedPoolInfo> PoolInfoMap;
bool runOnModule(Module &M);
@@ -119,12 +122,14 @@
Function *GetFunctionClone(Function *F,
std::set<const DSNode*> &PoolsToCompress,
PA::FuncInfo &FI, const DSGraph &CG);
+ Function *GetExtFunctionClone(Function *F,
+ const std::vector<unsigned> &Args);
private:
void InitializePoolLibraryFunctions(Module &M);
bool CompressPoolsInFunction(Function &F,
- std::vector<std::pair<Value*,
- Value*> > *PremappedVals = 0);
+ std::vector<std::pair<Value*, Value*> > *PremappedVals = 0,
+ std::set<const DSNode*> *ExternalPoolsToCompress = 0);
void FindPoolsToCompress(std::set<const DSNode*> &Pools, Function &F,
DSGraph &DSG, PA::FuncInfo *FI);
@@ -291,13 +296,16 @@
for (unsigned i = 0, e = FI->NodesToPA.size(); i != e; ++i) {
const DSNode *N = FI->NodesToPA[i];
- if (PoolIsCompressible(N, F)) {
- Pools.insert(N);
- ++NumCompressed;
- } else {
- DEBUG(std::cerr << "PCF: "; N->dump());
- ++NumNotCompressed;
- }
+ // Ignore potential pools that the pool allocation heuristic decided not to
+ // pool allocated.
+ if (!isa<ConstantPointerNull>(FI->PoolDescriptors[N]))
+ if (PoolIsCompressible(N, F)) {
+ Pools.insert(N);
+ ++NumCompressed;
+ } else {
+ DEBUG(std::cerr << "PCF: "; N->dump());
+ ++NumNotCompressed;
+ }
}
}
@@ -473,8 +481,6 @@
void visitCallInst(CallInst &CI);
void visitPoolInit(CallInst &CI);
void visitPoolDestroy(CallInst &CI);
- void visitPoolAlloc(CallInst &CI);
- void visitPoolFree(CallInst &CI);
void visitInstruction(Instruction &I) {
#ifndef NDEBUG
@@ -756,30 +762,6 @@
CI.eraseFromParent();
}
-void InstructionRewriter::visitPoolAlloc(CallInst &CI) {
- // Transform to poolalloc_pc if this is allocating from a compressed pool.
- const CompressedPoolInfo *PI = getPoolInfo(&CI);
- if (PI == 0) return; // Pool isn't compressed.
-
- std::vector<Value*> Ops;
- Ops.push_back(CI.getOperand(1));
- Ops.push_back(CI.getOperand(2));
- CallInst *NC = new CallInst(PtrComp.PoolAllocPC, Ops, CI.getName(), &CI);
- setTransformedValue(CI, NC);
-}
-
-void InstructionRewriter::visitPoolFree(CallInst &CI) {
- // Transform to poolfree_pc if this is freeing from a compressed pool.
- const CompressedPoolInfo *PI = getPoolInfo(CI.getOperand(2));
- if (PI == 0) return; // Pool isn't compressed.
-
- std::vector<Value*> Ops;
- Ops.push_back(CI.getOperand(1));
- Ops.push_back(getTransformedValue(CI.getOperand(2)));
- new CallInst(PtrComp.PoolFreePC, Ops, "", &CI);
- CI.eraseFromParent();
-}
-
void InstructionRewriter::visitCallInst(CallInst &CI) {
if (Function *F = CI.getCalledFunction())
// These functions are handled specially.
@@ -789,12 +771,6 @@
} else if (F->getName() == "pooldestroy") {
visitPoolDestroy(CI);
return;
- } else if (F->getName() == "poolalloc") {
- visitPoolAlloc(CI);
- return;
- } else if (F->getName() == "poolfree") {
- visitPoolFree(CI);
- return;
}
// Normal function call: check to see if this call produces or uses a pointer
@@ -808,38 +784,77 @@
// If this is a direct call, get the information about the callee.
PA::FuncInfo *FI = 0;
const DSGraph *CG = 0;
- if (Function *Callee = CI.getCalledFunction())
+ Function *Callee = CI.getCalledFunction();
+ if (Callee)
if (FI = PtrComp.getPoolAlloc()->getFuncInfoOrClone(*Callee))
CG = &PtrComp.getGraphForFunc(FI);
- // CalleeCallerMap - Mapping from nodes in the callee to nodes in the caller.
- DSGraph::NodeMapTy CalleeCallerMap;
+ if (!Callee) {
+ // Indirect call: you CAN'T passed compress pointers in. Don't even think
+ // about it.
+ return;
+ } else if (Callee->isExternal()) {
+ // We don't have a DSG for the callee in this case. Assume that things will
+ // work out if we pass compressed pointers.
+ std::vector<Value*> Operands;
+ Operands.reserve(CI.getNumOperands()-1);
+
+ std::vector<unsigned> CompressedArgs;
+ if (isa<PointerType>(CI.getType()) && getPoolInfo(&CI))
+ CompressedArgs.push_back(0); // Compress retval.
+
+ for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
+ if (isa<PointerType>(CI.getOperand(i)->getType()) &&
+ getPoolInfo(CI.getOperand(i))) {
+ CompressedArgs.push_back(i);
+ Operands.push_back(getTransformedValue(CI.getOperand(i)));
+ } else {
+ Operands.push_back(CI.getOperand(i));
+ }
+
+ if (CompressedArgs.empty())
+ return; // Nothing to compress!
+ Function *Clone = PtrComp.GetExtFunctionClone(Callee, CompressedArgs);
+ Value *NC = new CallInst(Clone, Operands, CI.getName(), &CI);
+ if (NC->getType() != CI.getType()) // Compressing return value?
+ setTransformedValue(CI, NC);
+ else {
+ if (CI.getType() != Type::VoidTy) {
+ CI.replaceAllUsesWith(NC);
+ ValueReplaced(CI, NC);
+ }
+ CI.eraseFromParent();
+ }
+ return;
+ }
+
+ // CalleeCallerMap: Mapping from nodes in the callee to nodes in the caller.
+ DSGraph::NodeMapTy CalleeCallerMap;
+
// Do we need to compress the return value?
if (isa<PointerType>(CI.getType()) && getNodeIfCompressed(&CI)) {
DSGraph::computeNodeMapping(CG->getReturnNodeFor(FI->F),
getMappedNodeHandle(&CI), CalleeCallerMap);
PoolsToCompress.insert(CG->getReturnNodeFor(FI->F).getNode());
}
-
+
// Find the arguments we need to compress.
unsigned NumPoolArgs = FI ? FI->ArgNodes.size() : 0;
for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
if (isa<PointerType>(CI.getOperand(i)->getType()) &&
getNodeIfCompressed(CI.getOperand(i))) {
Argument *FormalArg = next(FI->F.abegin(), i-1-NumPoolArgs);
-
+
DSGraph::computeNodeMapping(CG->getNodeForValue(FormalArg),
getMappedNodeHandle(CI.getOperand(i)),
CalleeCallerMap);
-
+
PoolsToCompress.insert(CG->getNodeForValue(FormalArg).getNode());
}
// If this function doesn't require compression, there is nothing to do!
if (PoolsToCompress.empty()) return;
- Function *Callee = CI.getCalledFunction();
- assert(Callee && "Indirect calls not implemented yet!");
// Now that we know the basic pools passed/returned through the
// argument/retval of the call, add the compressed pools that are reachable
@@ -851,10 +866,12 @@
if (PoolInfo.count(I->second.getNode()))
PoolsToCompress.insert(I->first);
}
-
+
// Get the clone of this function that uses compressed pointers instead of
// normal pointers.
- Function *Clone = PtrComp.GetFunctionClone(Callee, PoolsToCompress, *FI, *CG);
+ Function *Clone = PtrComp.GetFunctionClone(Callee, PoolsToCompress,
+ *FI, *CG);
+
// Okay, we now have our clone: rewrite the call instruction.
std::vector<Value*> Operands;
@@ -891,7 +908,8 @@
/// function and compress them.
bool PointerCompress::
CompressPoolsInFunction(Function &F,
- std::vector<std::pair<Value*, Value*> > *PremappedVals){
+ std::vector<std::pair<Value*, Value*> > *PremappedVals,
+ std::set<const DSNode*> *ExternalPoolsToCompress){
if (F.isExternal()) return false;
// If this is a pointer compressed clone of a pool allocated function, get the
@@ -934,18 +952,9 @@
// Handle pools that are passed into the function through arguments or
// returned by the function. If this occurs, we must be dealing with a ptr
// compressed clone of the pool allocated clone of the original function.
- if (FCR) {
- // Compressed the return value?
- if (F.getReturnType() != FCR->PAFn->getReturnType())
- PoolsToCompressSet.insert(DSG.getReturnNodeFor(FI->F).getNode());
-
- for (Function::aiterator CI = F.abegin(), OI = CloneSource->abegin(),
- E = F.aend(); CI != E; ++CI, ++OI)
- if (CI->getType() != OI->getType()) { // Compressed this argument?
- Value *OrigVal = FI->MapValueToOriginal(OI);
- PoolsToCompressSet.insert(DSG.getNodeForValue(OrigVal).getNode());
- }
- }
+ if (ExternalPoolsToCompress)
+ PoolsToCompressSet.insert(ExternalPoolsToCompress->begin(),
+ ExternalPoolsToCompress->end());
// If there is nothing that we can compress, exit now.
if (PoolsToCompressSet.empty()) return false;
@@ -986,6 +995,41 @@
}
+/// GetExtFunctionClone - Return a clone of the specified external function with
+/// the specified arguments compressed.
+Function *PointerCompress::
+GetExtFunctionClone(Function *F, const std::vector<unsigned> &ArgsToComp) {
+ assert(!ArgsToComp.empty() && "No reason to make a clone!");
+ Function *&Clone = ExtCloneFunctionMap[std::make_pair(F, ArgsToComp)];
+ if (Clone) return Clone;
+
+ const FunctionType *FTy = F->getFunctionType();
+ const Type *RetTy = FTy->getReturnType();
+ unsigned ArgIdx = 0;
+ if (isa<PointerType>(RetTy) && ArgsToComp[0] == 0) {
+ RetTy = SCALARUINTTYPE;
+ ++ArgIdx;
+ }
+
+ std::vector<const Type*> ParamTypes;
+
+ for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+ if (ArgIdx < ArgsToComp.size() && ArgsToComp[ArgIdx]-1 == i) {
+ // Compressed pool, pass an index.
+ ParamTypes.push_back(SCALARUINTTYPE);
+ ++ArgIdx;
+ } else {
+ ParamTypes.push_back(FTy->getParamType(i));
+ }
+ FunctionType *CFTy = FunctionType::get(RetTy, ParamTypes, FTy->isVarArg());
+
+ // Next, create the clone prototype and insert it into the module.
+ Clone = new Function(CFTy, GlobalValue::ExternalLinkage,
+ F->getName()+"_pc");
+ F->getParent()->getFunctionList().insert(F, Clone);
+ return Clone;
+}
+
/// GetFunctionClone - Lazily create clones of pool allocated functions that we
/// need in compressed form. This memoizes the functions that have been cloned
/// to allow only one clone of each function in a desired permutation.
@@ -1080,16 +1124,6 @@
E = ValueMap.end(); I != E; ++I)
NewToOldValueMap.insert(std::make_pair(I->second, I->first));
-
-#if 0
- /// computeNodeMapping - Given roots in two different DSGraphs, traverse the
- /// nodes reachable from the two graphs, computing the mapping of nodes from
- /// the first to the second graph.
- ///
- static void computeNodeMapping(const DSNodeHandle &NH1,
- const DSNodeHandle &NH2, NodeMapTy &NodeMap);
-#endif
-
// Compute the PoolDescriptors map for the cloned function.
for (std::map<const DSNode*, Value*>::iterator I =
FI.PoolDescriptors.begin(), E = FI.PoolDescriptors.end();
@@ -1099,7 +1133,7 @@
ValueMap.clear();
// Recursively transform the function.
- CompressPoolsInFunction(*Clone, &RemappedArgs);
+ CompressPoolsInFunction(*Clone, &RemappedArgs, &PoolsToCompress);
return Clone;
}
@@ -1115,10 +1149,6 @@
Type::UIntTy, Type::UIntTy, 0);
PoolDestroyPC = M.getOrInsertFunction("pooldestroy_pc", Type::VoidTy,
PoolDescPtrTy, 0);
- PoolAllocPC = M.getOrInsertFunction("poolalloc_pc", SCALARUINTTYPE,
- PoolDescPtrTy, Type::UIntTy, 0);
- PoolFreePC = M.getOrInsertFunction("poolfree_pc", Type::VoidTy,
- PoolDescPtrTy, SCALARUINTTYPE, 0);
// FIXME: Need bumppointer versions as well as realloc??/memalign??
}
More information about the llvm-commits
mailing list