[llvm-commits] [poolalloc] r56847 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DSNode.h include/dsa/DataStructure.h lib/DSA/BottomUpClosure.cpp lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/StdLibPass.cpp lib/DSA/TopDownClosure.cpp
Andrew Lenharth
alenhar2 at cs.uiuc.edu
Tue Sep 30 08:28:27 PDT 2008
Author: alenhar2
Date: Tue Sep 30 10:28:27 2008
New Revision: 56847
URL: http://llvm.org/viewvc/llvm-project?rev=56847&view=rev
Log:
fix recent bug on mailing list
Modified:
poolalloc/trunk/include/dsa/DSGraph.h
poolalloc/trunk/include/dsa/DSNode.h
poolalloc/trunk/include/dsa/DataStructure.h
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
poolalloc/trunk/lib/DSA/DataStructure.cpp
poolalloc/trunk/lib/DSA/Local.cpp
poolalloc/trunk/lib/DSA/StdLibPass.cpp
poolalloc/trunk/lib/DSA/TopDownClosure.cpp
Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Tue Sep 30 10:28:27 2008
@@ -305,6 +305,10 @@
return AuxFunctionCalls;
}
+ /// removeFunction - Specify that all call sites to the function have been
+ /// fully specified by a pass such as StdLibPass.
+ void removeFunctionCalls(Function& F);
+
// Function Call iteration
typedef std::list<DSCallSite>::const_iterator fc_iterator;
fc_iterator fc_begin() const { return FunctionCalls.begin(); }
Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Tue Sep 30 10:28:27 2008
@@ -462,7 +462,7 @@
}
inline void DSNodeHandle::setTo(DSNode *n, unsigned NewOffset) const {
- assert(!n || !n->isForwarding() && "Cannot set node to a forwarded node!");
+ assert((!n || !n->isForwarding()) && "Cannot set node to a forwarded node!");
if (N) getNode()->NumReferrers--;
N = n;
Offset = NewOffset;
Modified: poolalloc/trunk/include/dsa/DataStructure.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DataStructure.h (original)
+++ poolalloc/trunk/include/dsa/DataStructure.h Tue Sep 30 10:28:27 2008
@@ -189,8 +189,6 @@
virtual bool runOnModule(Module &M);
- DSGraph &CreateGraphForExternalFunction(const Function &F);
-
/// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
/// These correspond to the interfaces defined in the AliasAnalysis class.
void deleteValue(Value *V);
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Sep 30 10:28:27 2008
@@ -121,10 +121,19 @@
static void GetAllCallees(const DSCallSite &CS,
std::vector<Function*> &Callees) {
if (CS.isDirectCall()) {
- Callees.push_back(CS.getCalleeFunc());
+ if (!CS.getCalleeFunc()->isDeclaration())
+ Callees.push_back(CS.getCalleeFunc());
} else if (!CS.getCalleeNode()->isIncompleteNode()) {
// Get all callees.
+ unsigned OldSize = Callees.size();
CS.getCalleeNode()->addFullFunctionList(Callees);
+
+ // If any of the callees are unresolvable, remove the whole batch!
+ for (unsigned i = OldSize, e = Callees.size(); i != e; ++i)
+ if (Callees[i]->isDeclaration()) {
+ Callees.erase(Callees.begin()+OldSize, Callees.end());
+ return;
+ }
}
}
@@ -145,6 +154,16 @@
ValMap[F] = Min;
Stack.push_back(F);
+ // FIXME! This test should be generalized to be any function that we have
+ // already processed, in the case when there isn't a main or there are
+ // unreachable functions!
+ if (F->isDeclaration()) { // sprintf, fprintf, sscanf, etc...
+ // No callees!
+ Stack.pop_back();
+ ValMap[F] = ~0;
+ return Min;
+ }
+
DSGraph &Graph = getOrCreateGraph(F);
// Find all callee functions.
@@ -269,31 +288,6 @@
GlobalsGraph = 0;
}
-DSGraph &BUDataStructures::CreateGraphForExternalFunction(const Function &Fn) {
- Function *F = const_cast<Function*>(&Fn);
- DSGraph *DSG = new DSGraph(GlobalECs, GlobalsGraph->getTargetData());
- DSInfo[F] = DSG;
- DSG->setGlobalsGraph(GlobalsGraph);
- DSG->setPrintAuxCalls();
-
- // Add function to the graph.
- DSG->getReturnNodes().insert(std::make_pair(F, DSNodeHandle()));
-
- if (F->getName() == "free") { // Taking the address of free.
-
- // Free should take a single pointer argument, mark it as heap memory.
- DSNodeHandle N(new DSNode(0, DSG));
- N.getNode()->setHeapMarker();
- DSG->getNodeForValue(F->arg_begin()).mergeWith(N);
-
- } else {
- cerr << "Unrecognized external function: " << F->getName() << "\n";
- abort();
- }
-
- return *DSG;
-}
-
void BUDataStructures::calculateGraph(DSGraph &Graph) {
// If this graph contains the main function, clone the globals graph into this
// graph before we inline callees and other fun stuff.
Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Tue Sep 30 10:28:27 2008
@@ -186,8 +186,8 @@
void DSNode::assertOK() const {
assert((Ty != Type::VoidTy ||
- Ty == Type::VoidTy && (Size == 0 ||
- (NodeType & DSNode::ArrayNode))) &&
+ (Ty == Type::VoidTy && (Size == 0 ||
+ (NodeType & DSNode::ArrayNode)))) &&
"Node not OK!");
assert(ParentGraph && "Node has no parent?");
@@ -756,8 +756,8 @@
// Check to see if we have a pointer & integer mismatch going on here,
// loading a pointer as a long, for example.
//
- if (SubType->isInteger() && isa<PointerType>(NewTy) ||
- NewTy->isInteger() && isa<PointerType>(SubType))
+ if ((SubType->isInteger() && isa<PointerType>(NewTy)) ||
+ (NewTy->isInteger() && isa<PointerType>(SubType)))
return false;
} else if (NewTySize > SubTypeSize && NewTySize <= PadSize) {
// We are accessing the field, plus some structure padding. Ignore the
@@ -1490,6 +1490,22 @@
}
}
+void DSGraph::removeFunctionCalls(Function& F) {
+ for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
+ E = FunctionCalls.end(); I != E; ++I)
+ if (I->isDirectCall() && &I->getCaller() == &F) {
+ FunctionCalls.erase(I);
+ break;
+ }
+
+ for (std::list<DSCallSite>::iterator I = AuxFunctionCalls.begin(),
+ E = AuxFunctionCalls.end(); I != E; ++I)
+ if (I->isDirectCall() && &I->getCaller() == &F) {
+ AuxFunctionCalls.erase(I);
+ break;
+ }
+}
+
/// addObjectToGraph - This method can be used to add global, stack, and heap
/// objects to the graph. This can be used when updating DSGraphs due to the
/// introduction of new temporary objects. The new object is not pointed to
@@ -1891,11 +1907,12 @@
// Calculate the arguments vector...
for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
- if (isa<PointerType>((*I)->getType()))
+ if (isa<PointerType>((*I)->getType())) {
if (isa<ConstantPointerNull>(*I))
Args.push_back(DSNodeHandle());
else
Args.push_back(getNodeForValue(*I));
+ }
// Add a new function call entry...
if (Function *F = CS.getCalledFunction())
@@ -2730,7 +2747,7 @@
//Clone or Steal the Source Graph
DSGraph &BaseGraph = GraphSource->getDSGraph(*F);
if (Clone) {
- G = new DSGraph(BaseGraph, GlobalECs, DSGraph::DontCloneAuxCallNodes);
+ G = new DSGraph(BaseGraph, GlobalECs);
} else {
G = new DSGraph(GlobalECs, GraphSource->getTargetData());
G->spliceFrom(BaseGraph);
Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Tue Sep 30 10:28:27 2008
@@ -137,37 +137,27 @@
if (isa<PointerType>(I->getType())) {
DSNode * Node = getValueDest(*I).getNode();
- if (!f.hasInternalLinkage() || f.isDeclaration()) {
+ if (!f.hasInternalLinkage())
Node->setExternalMarker();
- //pecimistic assumptions on externals
- if (f.isDeclaration())
- Node->setReadMarker()->setModifiedMarker();
- }
+
}
}
// Create an entry for the return, which tracks which functions are in the graph
g.getOrCreateReturnNodeFor(f);
- if (!f.isDeclaration()) {
- visit(f); // Single pass over the function
+ visit(f); // Single pass over the function
- // If there are any constant globals referenced in this function, merge their
- // initializers into the local graph from the globals graph.
- if (g.getScalarMap().global_begin() != g.getScalarMap().global_end()) {
- ReachabilityCloner RC(g, *g.getGlobalsGraph(), 0);
-
- for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
- I != g.getScalarMap().global_end(); ++I)
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
- if (!GV->isDeclaration() && GV->isConstant())
- RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
- }
- } else {
- DSNodeHandle& RNH = g.getOrCreateReturnNodeFor(f);
- //Make sure return values from externals are marked as such
- if (isa<PointerType>(f.getReturnType()))
- RNH.mergeWith(createNode()->setReadMarker()->setModifiedMarker()->setExternalMarker());
+ // If there are any constant globals referenced in this function, merge their
+ // initializers into the local graph from the globals graph.
+ if (g.getScalarMap().global_begin() != g.getScalarMap().global_end()) {
+ ReachabilityCloner RC(g, *g.getGlobalsGraph(), 0);
+
+ for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
+ I != g.getScalarMap().global_end(); ++I)
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
+ if (!GV->isDeclaration() && GV->isConstant())
+ RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
}
g.markIncompleteNodes(DSGraph::MarkFormalArgs);
@@ -762,11 +752,12 @@
formGlobalECs();
// Calculate all of the graphs...
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
- DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
- GraphBuilder GGB(*I, *G);
- DSInfo.insert(std::make_pair(I, G));
- }
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!I->isDeclaration()) {
+ DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
+ GraphBuilder GGB(*I, *G);
+ DSInfo.insert(std::make_pair(I, G));
+ }
GlobalsGraph->removeTriviallyDeadNodes();
GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original)
+++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Tue Sep 30 10:28:27 2008
@@ -31,6 +31,69 @@
char StdLibDataStructures::ID;
+struct libAction {
+ bool ret_read, ret_write, ret_heap;
+ bool args_read, args_write, args_heap;
+ bool mergeAllArgs;
+ bool mergeWithRet;
+ bool collapse;
+};
+
+const struct {
+ const char* name;
+ libAction action;
+} recFuncs[] = {
+ {"calloc", {false, true, true, false, false, false, false, false, false}},
+ {"malloc", {false, true, true, false, false, false, false, false, false}},
+ {"valloc", {false, true, true, false, false, false, false, false, false}},
+ {"memalign", {false, true, true, false, false, false, false, false, false}},
+ {"strdup", {false, true, true, false, false, false, false, false, true}},
+ {"wcsdup", {false, true, true, false, false, false, false, false, true}},
+ {"free", {false, false, false, false, true, true, false, false, false}},
+ {"realloc", {false, true, true, false, true, true, false, true, true}},
+ {"atoi", {false, false, false, true, false, false, false, false, false}},
+ {"atof", {false, false, false, true, false, false, false, false, false}},
+ {"atol", {false, false, false, true, false, false, false, false, false}},
+ {"atoll", {false, false, false, true, false, false, false, false, false}},
+ {"remove", {false, false, false, true, false, false, false, false, false}},
+ {"unlink", {false, false, false, true, false, false, false, false, false}},
+ {"rename", {false, false, false, true, false, false, false, false, false}},
+ {"memcmp", {false, false, false, true, false, false, false, false, false}},
+ {"strcmp", {false, false, false, true, false, false, false, false, false}},
+ {"strncmp", {false, false, false, true, false, false, false, false, false}},
+ {"execl", {false, false, false, true, false, false, false, false, false}},
+ {"execlp", {false, false, false, true, false, false, false, false, false}},
+ {"execle", {false, false, false, true, false, false, false, false, false}},
+ {"execv", {false, false, false, true, false, false, false, false, false}},
+ {"execvp", {false, false, false, true, false, false, false, false, false}},
+ {"chmod", {false, false, false, true, false, false, false, false, false}},
+ {"puts", {false, false, false, true, false, false, false, false, false}},
+ {"write", {false, false, false, true, false, false, false, false, false}},
+ {"open", {false, false, false, true, false, false, false, false, false}},
+ {"create", {false, false, false, true, false, false, false, false, false}},
+ {"truncate", {false, false, false, true, false, false, false, false, false}},
+ {"chdir", {false, false, false, true, false, false, false, false, false}},
+ {"mkdir", {false, false, false, true, false, false, false, false, false}},
+ {"rmdir", {false, false, false, true, false, false, false, false, false}},
+ {"strlen", {false, false, false, true, false, false, false, false, false}},
+ {"read", {false, false, false, false, true, false, false, false, false}},
+ {"pipe", {false, false, false, false, true, false, false, false, false}},
+ {"wait", {false, false, false, false, true, false, false, false, false}},
+ {"time", {false, false, false, false, true, false, false, false, false}},
+ {"getrusage",{false, false, false, false, true, false, false, false, false}},
+ {"memchr", { true, false, false, true, false, false, false, true, true}},
+ {"memrchr", { true, false, false, true, false, false, false, true, true}},
+ {"rawmemchr",{ true, false, false, true, false, false, false, true, true}},
+ {"memmove", {false, true, false, true, true, false, true, true, true}},
+ {"bcopy", {false, false, false, true, true, false, true, false, true}},
+ {"strcpy", {false, true, false, true, true, false, true, true, true}},
+ {"strncpy", {false, true, false, true, true, false, true, true, true}},
+ {"memccpy", {false, true, false, true, true, false, true, true, true}},
+ {"wcscpy", {false, true, false, true, true, false, true, true, true}},
+ {"wcsncpy", {false, true, false, true, true, false, true, true, true}},
+ {"wmemccpy", {false, true, false, true, true, false, true, true, true}},
+};
+
bool StdLibDataStructures::runOnModule(Module &M) {
LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
setGraphSource(&LocalDSA);
@@ -41,108 +104,61 @@
GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs);
GlobalsGraph->setPrintAuxCalls();
- // Calculate all of the graphs...
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
- DSGraph &Graph = getOrCreateGraph(&*I);
- //If this is an true external, check it out
- if (I->isDeclaration() && !I->isIntrinsic() && !(I->isVarArg())) {
- const std::string& Name = I->getName();
- if (Name == "calloc" ||
- Name == "malloc" ||
- Name == "valloc" ||
- Name == "memalign") {
- Graph.getReturnNodeFor(*I).getNode()->clearNodeFlags()
- ->setHeapMarker()->setModifiedMarker();
- } else if (Name == "realloc") {
- if (isa<PointerType>(I->getReturnType())) {
- Graph.getReturnNodeFor(*I).getNode()->clearNodeFlags()
- ->setHeapMarker()->setModifiedMarker();
- Graph.getNodeForValue(I->arg_begin()).getNode()->clearNodeFlags()
- ->mergeWith(Graph.getReturnNodeFor(*I), 0);
- }
- } else if (Name == "strdup") {
- Graph.getReturnNodeFor(*I).getNode()->clearNodeFlags()
- ->setHeapMarker()->setModifiedMarker();
- } else if (Name == "free") {
- Graph.getNodeForValue(&*I->arg_begin()).getNode()->clearNodeFlags()
- ->setHeapMarker()->setModifiedMarker();
- } else if (Name == "atoi" || Name == "atof" ||
- Name == "atol" || Name == "atoll" ||
- Name == "remove" || Name == "unlink" ||
- Name == "rename" || Name == "memcmp" ||
- Name == "strcmp" || Name == "strncmp" ||
- Name == "execl" || Name == "execlp" ||
- Name == "execle" || Name == "execv" ||
- Name == "execvp" || Name == "chmod" ||
- Name == "puts" || Name == "write" ||
- Name == "open" || Name == "create" ||
- Name == "truncate" || Name == "chdir" ||
- Name == "mkdir" || Name == "rmdir" ||
- Name == "strlen") {
- for (Function::arg_iterator AI = I->arg_begin(), E = I->arg_end();
- AI != E; ++AI) {
- if (isa<PointerType>(AI->getType()))
- Graph.getNodeForValue(&*AI).getNode()->clearNodeFlags()
- ->setReadMarker();
- }
- } else if (Name == "read" || Name == "pipe" ||
- Name == "wait" || Name == "time" ||
- Name == "getrusage") {
- for (Function::arg_iterator AI = I->arg_begin(), E = I->arg_end();
- AI != E; ++AI) {
- if (isa<PointerType>(AI->getType()))
- Graph.getNodeForValue(&*AI).getNode()->clearNodeFlags()
- ->setModifiedMarker();
- }
- } else if (Name == "memchr" || Name == "memrchr") {
- DSNodeHandle RetNH = Graph.getReturnNodeFor(*I);
- DSNodeHandle Result = Graph.getNodeForValue(&*I->arg_begin());
- RetNH.mergeWith(Result);
- RetNH.getNode()->clearNodeFlags()->setReadMarker();
- } else if (Name == "memmove") {
- // Merge the first & second arguments, and mark the memory read and
- // modified.
- DSNodeHandle& RetNH = Graph.getNodeForValue(&*I->arg_begin());
- RetNH.mergeWith(Graph.getNodeForValue(&*(++(I->arg_begin()))));
- RetNH.getNode()->clearNodeFlags()->setModifiedMarker()->setReadMarker();
- } else if (Name == "stat" || Name == "fstat" || Name == "lstat") {
- // These functions read their first operand if its a pointer.
- Function::arg_iterator AI = I->arg_begin();
- if (isa<PointerType>(AI->getType()))
- Graph.getNodeForValue(&*AI).getNode()
- ->clearNodeFlags()->setReadMarker();
- // Then they write into the stat buffer.
- DSNodeHandle StatBuf = Graph.getNodeForValue(&*++AI);
- DSNode *N = StatBuf.getNode();
- N->setModifiedMarker();
- const Type *StatTy = I->getFunctionType()->getParamType(1);
- if (const PointerType *PTy = dyn_cast<PointerType>(StatTy))
- N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset());
- } else if (Name == "strtod" || Name == "strtof" || Name == "strtold") {
- // These functions read the first pointer
- DSNodeHandle& Str = Graph.getNodeForValue(&*I->arg_begin());
- Str.getNode()->clearNodeFlags()->setReadMarker();
- // If the second parameter is passed, it will point to the first
- // argument node.
- DSNodeHandle& EndNH = Graph.getNodeForValue(&*(++(I->arg_begin())));
- EndNH.getNode()->clearNodeFlags()->setModifiedMarker();
- EndNH.getNode()->mergeTypeInfo(PointerType::getUnqual(Type::Int8Ty),
- EndNH.getOffset(), false);
- DSNodeHandle &Link = EndNH.getLink(0);
- Link.mergeWith(Str);
- } else {
- //ignore pointer free functions
- bool hasPtr = isa<PointerType>(I->getReturnType());
- for (Function::const_arg_iterator AI = I->arg_begin(), AE = I->arg_end();
- AI != AE && !hasPtr; ++AI)
- if (isa<PointerType>(AI->getType()))
- hasPtr = true;
- if (hasPtr)
- std::cerr << "Unhandled External: " << Name << "\n";
- }
- }
- }
-
+ //Clone Module
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!I->isDeclaration())
+ getOrCreateGraph(&*I);
+
+ for (int x = 0; recFuncs[x].name; ++x)
+ if (Function* F = M.getFunction(recFuncs[x].name))
+ if (F->isDeclaration())
+ for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+ ii != ee; ++ii)
+ if (CallInst* CI = dyn_cast<CallInst>(ii))
+ if (CI->getOperand(0) == F) {
+ DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
+ if (recFuncs[x].action.ret_read)
+ Graph.getNodeForValue(CI).getNode()->setReadMarker();
+ if (recFuncs[x].action.ret_write)
+ Graph.getNodeForValue(CI).getNode()->setModifiedMarker();
+ if (recFuncs[x].action.ret_heap)
+ Graph.getNodeForValue(CI).getNode()->setHeapMarker();
+
+ if (recFuncs[x].action.args_read)
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (isa<PointerType>(CI->getOperand(y)->getType()))
+ Graph.getNodeForValue(CI->getOperand(y)).getNode()->setReadMarker();
+ if (recFuncs[x].action.args_write)
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (isa<PointerType>(CI->getOperand(y)->getType()))
+ Graph.getNodeForValue(CI->getOperand(y)).getNode()->setModifiedMarker();
+ if (recFuncs[x].action.args_heap)
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (isa<PointerType>(CI->getOperand(y)->getType()))
+ Graph.getNodeForValue(CI->getOperand(y)).getNode()->setHeapMarker();
+
+ std::vector<DSNodeHandle> toMerge;
+ if (recFuncs[x].action.mergeWithRet)
+ toMerge.push_back(Graph.getNodeForValue(CI));
+ if (recFuncs[x].action.mergeAllArgs || recFuncs[x].action.mergeWithRet)
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (isa<PointerType>(CI->getOperand(y)->getType()))
+ toMerge.push_back(Graph.getNodeForValue(CI->getOperand(y)));
+ for (unsigned y = 1; y < toMerge.size(); ++y)
+ toMerge[0].mergeWith(toMerge[y]);
+
+ if (recFuncs[x].action.collapse) {
+ Graph.getNodeForValue(CI).getNode()->foldNodeCompletely();
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (isa<PointerType>(CI->getOperand(y)->getType()))
+ Graph.getNodeForValue(CI->getOperand(y)).getNode()->foldNodeCompletely();
+ }
+
+ //delete the call
+ DOUT << "Removing " << F->getName() << " from " << CI->getParent()->getParent()->getName() << "\n";
+ Graph.removeFunctionCalls(*F);
+ }
+
return false;
}
Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=56847&r1=56846&r2=56847&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Tue Sep 30 10:28:27 2008
@@ -95,7 +95,7 @@
// Functions without internal linkage also have unknown incoming arguments!
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (!I->hasInternalLinkage())
+ if (!I->isDeclaration() && !I->hasInternalLinkage())
ArgsRemainIncomplete.insert(I);
// We want to traverse the call graph in reverse post-order. To do this, we
@@ -108,7 +108,8 @@
// Visit each of the graphs in reverse post-order now!
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- getOrCreateGraph(*I);
+ if (!I->isDeclaration(*I)
+ getOrCreateGraph(*I);
return false;
}
#endif
@@ -153,6 +154,7 @@
void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
std::vector<DSGraph*> &PostOrder) {
+ if (F.isDeclaration()) return;
DSGraph &G = getOrCreateGraph(&F);
if (Visited.count(&G)) return;
Visited.insert(&G);
@@ -297,7 +299,8 @@
// Handle direct calls efficiently.
if (CI->isDirectCall()) {
- if (!DSG.getReturnNodes().count(CI->getCalleeFunc()))
+ if (!CI->getCalleeFunc()->isDeclaration() &&
+ !DSG.getReturnNodes().count(CI->getCalleeFunc()))
CallerEdges[&getOrCreateGraph(CI->getCalleeFunc())]
.push_back(CallerCallEdge(&DSG, &*CI, CI->getCalleeFunc()));
continue;
@@ -309,7 +312,7 @@
BUInfo->callee_begin(CallI), IPE = BUInfo->callee_end(CallI);
// Skip over all calls to this graph (SCC calls).
- while (IPI != IPE && &getOrCreateGraph(IPI->second) == &DSG)
+ while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
++IPI;
// All SCC calls?
@@ -319,14 +322,15 @@
++IPI;
// Skip over more SCC calls.
- while (IPI != IPE && &getOrCreateGraph(IPI->second) == &DSG)
+ while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
++IPI;
// If there is exactly one callee from this call site, remember the edge in
// CallerEdges.
if (IPI == IPE) {
- CallerEdges[&getOrCreateGraph(FirstCallee)]
- .push_back(CallerCallEdge(&DSG, &*CI, FirstCallee));
+ if (!FirstCallee->isDeclaration())
+ CallerEdges[&getOrCreateGraph(FirstCallee)]
+ .push_back(CallerCallEdge(&DSG, &*CI, FirstCallee));
continue;
}
@@ -339,7 +343,8 @@
for (BUDataStructures::ActualCalleesTy::const_iterator I =
BUInfo->callee_begin(CallI), E = BUInfo->callee_end(CallI);
I != E; ++I)
- Callees.push_back(I->second);
+ if (!I->second->isDeclaration())
+ Callees.push_back(I->second);
std::sort(Callees.begin(), Callees.end());
std::map<std::vector<Function*>, DSGraph*>::iterator IndCallRecI =
@@ -370,7 +375,7 @@
// exactly once.
DSCallSite *NCS = &IndCallGraph->getFunctionCalls().front();
for (unsigned i = 0, e = Callees.size(); i != e; ++i) {
- DSGraph& CalleeGraph = getOrCreateGraph(Callees[i]);
+ DSGraph& CalleeGraph = getDSGraph(*Callees[i]);
if (&CalleeGraph != &DSG)
CallerEdges[&CalleeGraph].push_back(CallerCallEdge(IndCallGraph, NCS,
Callees[i]));
More information about the llvm-commits
mailing list