Eliminate use of DSCallSiteIterator in key loop. This is a half step to

a tasty speedup.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19978 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-02-01 21:37:27 +00:00
parent 321f68306f
commit af8650e9c7

View File

@ -72,9 +72,6 @@ bool BUDataStructures::runOnModule(Module &M) {
return false; return false;
} }
void BUDataStructures::calculateReachableGraphs(Function *F) {
}
DSGraph &BUDataStructures::getOrCreateGraph(Function *F) { DSGraph &BUDataStructures::getOrCreateGraph(Function *F) {
// Has the graph already been created? // Has the graph already been created?
DSGraph *&Graph = DSInfo[F]; DSGraph *&Graph = DSInfo[F];
@ -244,6 +241,20 @@ void BUDataStructures::releaseMemory() {
GlobalsGraph = 0; GlobalsGraph = 0;
} }
static bool isVAHackFn(const Function *F) {
return F->getName() == "printf" || F->getName() == "sscanf" ||
F->getName() == "fprintf" || F->getName() == "open" ||
F->getName() == "sprintf" || F->getName() == "fputs" ||
F->getName() == "fscanf";
}
// isUnresolvableFunction - Return true if this is an unresolvable
// external function. A direct or indirect call to this cannot be resolved.
//
static bool isResolvableFunc(const Function* callee) {
return !callee->isExternal() || isVAHackFn(callee);
}
void BUDataStructures::calculateGraph(DSGraph &Graph) { void BUDataStructures::calculateGraph(DSGraph &Graph) {
// Move our call site list into TempFCs so that inline call sites go into the // Move our call site list into TempFCs so that inline call sites go into the
// new call site list and doesn't invalidate our iterators! // new call site list and doesn't invalidate our iterators!
@ -263,7 +274,8 @@ void BUDataStructures::calculateGraph(DSGraph &Graph) {
if (!Printed) if (!Printed)
std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n"; std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n";
std::cerr << " calls " << Node->getGlobals().size() std::cerr << " calls " << Node->getGlobals().size()
<< " fns from site: " << *I->getCallSite().getInstruction(); << " fns from site: " << I->getCallSite().getInstruction()
<< " " << *I->getCallSite().getInstruction();
unsigned NumToPrint = Node->getGlobals().size(); unsigned NumToPrint = Node->getGlobals().size();
if (NumToPrint > 5) NumToPrint = 5; if (NumToPrint > 5) NumToPrint = 5;
std::cerr << " Fns ="; std::cerr << " Fns =";
@ -274,75 +286,121 @@ void BUDataStructures::calculateGraph(DSGraph &Graph) {
} }
} }
while (!TempFCs.empty()) {
DSCallSite &CS = *TempFCs.begin();
// Loop over all of the resolvable call sites. std::set<Function*> CalledFuncs;
DSCallSiteIterator I = DSCallSiteIterator::begin(TempFCs);
DSCallSiteIterator E = DSCallSiteIterator::end(TempFCs);
// If DSCallSiteIterator skipped over any call sites, they are unresolvable:
// move them back to the AuxCallsList.
std::list<DSCallSite>::iterator LastCallSiteIdx = TempFCs.begin();
while (LastCallSiteIdx != I.getCallSiteIdx())
AuxCallsList.splice(AuxCallsList.end(), TempFCs, LastCallSiteIdx++);
while (I != E) {
// Resolve the current call...
Function *Callee = *I;
DSCallSite CS = I.getCallSite();
if (Callee->isExternal()) {
// Ignore this case, simple varargs functions we cannot stub out!
} else if (ReturnNodes.count(Callee)) {
// Self recursion... simply link up the formal arguments with the
// actual arguments...
DEBUG(std::cerr << " Self Inlining: " << Callee->getName() << "\n");
// Handle self recursion by resolving the arguments and return value
Graph.mergeInGraph(CS, *Callee, Graph, 0);
if (CS.isDirectCall()) {
Function *F = CS.getCalleeFunc();
if (isResolvableFunc(F))
if (F->isExternal()) { // Call to fprintf, etc.
TempFCs.erase(TempFCs.begin());
continue;
} else {
CalledFuncs.insert(F);
}
} else { } else {
ActualCallees.insert(std::make_pair(CS.getCallSite().getInstruction(), DSNode *Node = CS.getCalleeNode();
Callee));
// Get the data structure graph for the called function. if (!Node->isIncomplete())
// for (unsigned i = 0, e = Node->getGlobals().size(); i != e; ++i)
DSGraph &GI = getDSGraph(*Callee); // Graph to inline if (Function *CF = dyn_cast<Function>(Node->getGlobals()[i]))
if (isResolvableFunc(CF) && !CF->isExternal())
CalledFuncs.insert(CF);
}
DEBUG(std::cerr << " Inlining graph for " << Callee->getName() if (CalledFuncs.empty()) {
<< "[" << GI.getGraphSize() << "+" // Remember that we could not resolve this yet!
<< GI.getAuxFunctionCalls().size() << "] into '" AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
<< Graph.getFunctionNames() << "' [" << Graph.getGraphSize() << "+" } else if (CalledFuncs.size() == 1) {
<< Graph.getAuxFunctionCalls().size() << "]\n"); Function *Callee = *CalledFuncs.begin();
Graph.mergeInGraph(CS, *Callee, GI,
DSGraph::KeepModRefBits | if (ReturnNodes.count(Callee)) {
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); // Self recursion... simply link up the formal arguments with the
++NumBUInlines; // actual arguments.
DEBUG(std::cerr << " Self Inlining: " << Callee->getName() << "\n");
// Handle self recursion by resolving the arguments and return value
Graph.mergeInGraph(CS, *Callee, Graph, 0);
} else {
ActualCallees.insert(std::make_pair(CS.getCallSite().getInstruction(),
Callee));
// Get the data structure graph for the called function.
//
DSGraph &GI = getDSGraph(*Callee); // Graph to inline
DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
<< "[" << GI.getGraphSize() << "+"
<< GI.getAuxFunctionCalls().size() << "] into '"
<< Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
<< Graph.getAuxFunctionCalls().size() << "]\n");
Graph.mergeInGraph(CS, *Callee, GI,
DSGraph::KeepModRefBits |
DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
++NumBUInlines;
#if 0 #if 0
Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_after_" + Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_after_" +
Callee->getName()); Callee->getName());
#endif #endif
} }
LastCallSiteIdx = I.getCallSiteIdx(); TempFCs.erase(TempFCs.begin());
++I; // Move to the next call site. } else {
if (!Printed)
std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n";
std::cerr << " calls " << CalledFuncs.size()
<< " fns from site: " << CS.getCallSite().getInstruction()
<< " " << *CS.getCallSite().getInstruction();
unsigned NumToPrint = CalledFuncs.size();
if (NumToPrint > 8) NumToPrint = 8;
std::cerr << " Fns =";
for (std::set<Function*>::iterator I = CalledFuncs.begin(),
E = CalledFuncs.end(); I != E && NumToPrint; ++I, --NumToPrint)
std::cerr << " " << (*I)->getName();
std::cerr << "\n";
if (I.getCallSiteIdx() != LastCallSiteIdx) { // Inline all of the called functions.
++LastCallSiteIdx; // Skip over the site we already processed. for (std::set<Function*>::iterator I = CalledFuncs.begin(),
E = CalledFuncs.end(); I != E; ++I) {
// If there are call sites that get skipped over, move them to the aux Function *Callee = *I;
// calls list: they are not resolvable. if (ReturnNodes.count(Callee)) {
if (I != E) // Self recursion... simply link up the formal arguments with the
while (LastCallSiteIdx != I.getCallSiteIdx()) // actual arguments.
AuxCallsList.splice(AuxCallsList.end(), TempFCs, LastCallSiteIdx++); DEBUG(std::cerr << " Self Inlining: " << Callee->getName() << "\n");
else
while (LastCallSiteIdx != TempFCs.end()) // Handle self recursion by resolving the arguments and return value
AuxCallsList.splice(AuxCallsList.end(), TempFCs, LastCallSiteIdx++); Graph.mergeInGraph(CS, *Callee, Graph, 0);
} else {
ActualCallees.insert(std::make_pair(CS.getCallSite().getInstruction(),
Callee));
// Get the data structure graph for the called function.
//
DSGraph &GI = getDSGraph(*Callee); // Graph to inline
DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
<< "[" << GI.getGraphSize() << "+"
<< GI.getAuxFunctionCalls().size() << "] into '"
<< Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
<< Graph.getAuxFunctionCalls().size() << "]\n");
Graph.mergeInGraph(CS, *Callee, GI,
DSGraph::KeepModRefBits |
DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
++NumBUInlines;
#if 0
Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_after_" +
Callee->getName());
#endif
}
}
TempFCs.erase(TempFCs.begin());
} }
} }
TempFCs.clear();
// Recompute the Incomplete markers // Recompute the Incomplete markers
assert(Graph.getInlinedGlobals().empty()); assert(Graph.getInlinedGlobals().empty());
Graph.maskIncompleteMarkers(); Graph.maskIncompleteMarkers();