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,32 +286,43 @@ 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: if (CS.isDirectCall()) {
// move them back to the AuxCallsList. Function *F = CS.getCalleeFunc();
std::list<DSCallSite>::iterator LastCallSiteIdx = TempFCs.begin(); if (isResolvableFunc(F))
while (LastCallSiteIdx != I.getCallSiteIdx()) if (F->isExternal()) { // Call to fprintf, etc.
AuxCallsList.splice(AuxCallsList.end(), TempFCs, LastCallSiteIdx++); TempFCs.erase(TempFCs.begin());
continue;
} else {
CalledFuncs.insert(F);
}
} else {
DSNode *Node = CS.getCalleeNode();
while (I != E) { if (!Node->isIncomplete())
// Resolve the current call... for (unsigned i = 0, e = Node->getGlobals().size(); i != e; ++i)
Function *Callee = *I; if (Function *CF = dyn_cast<Function>(Node->getGlobals()[i]))
DSCallSite CS = I.getCallSite(); if (isResolvableFunc(CF) && !CF->isExternal())
CalledFuncs.insert(CF);
}
if (Callee->isExternal()) { if (CalledFuncs.empty()) {
// Ignore this case, simple varargs functions we cannot stub out! // Remember that we could not resolve this yet!
} else if (ReturnNodes.count(Callee)) { AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
} else if (CalledFuncs.size() == 1) {
Function *Callee = *CalledFuncs.begin();
if (ReturnNodes.count(Callee)) {
// Self recursion... simply link up the formal arguments with the // Self recursion... simply link up the formal arguments with the
// actual arguments... // actual arguments.
DEBUG(std::cerr << " Self Inlining: " << Callee->getName() << "\n"); DEBUG(std::cerr << " Self Inlining: " << Callee->getName() << "\n");
// Handle self recursion by resolving the arguments and return value // Handle self recursion by resolving the arguments and return value
Graph.mergeInGraph(CS, *Callee, Graph, 0); Graph.mergeInGraph(CS, *Callee, Graph, 0);
} else { } else {
ActualCallees.insert(std::make_pair(CS.getCallSite().getInstruction(), ActualCallees.insert(std::make_pair(CS.getCallSite().getInstruction(),
Callee)); Callee));
@ -311,11 +334,11 @@ void BUDataStructures::calculateGraph(DSGraph &Graph) {
DEBUG(std::cerr << " Inlining graph for " << Callee->getName() DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
<< "[" << GI.getGraphSize() << "+" << "[" << GI.getGraphSize() << "+"
<< GI.getAuxFunctionCalls().size() << "] into '" << GI.getAuxFunctionCalls().size() << "] into '"
<< Graph.getFunctionNames() << "' [" << Graph.getGraphSize() << "+" << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
<< Graph.getAuxFunctionCalls().size() << "]\n"); << Graph.getAuxFunctionCalls().size() << "]\n");
Graph.mergeInGraph(CS, *Callee, GI, Graph.mergeInGraph(CS, *Callee, GI,
DSGraph::KeepModRefBits | DSGraph::KeepModRefBits |
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
++NumBUInlines; ++NumBUInlines;
#if 0 #if 0
@ -324,24 +347,59 @@ void BUDataStructures::calculateGraph(DSGraph &Graph) {
#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) {
Function *Callee = *I;
if (ReturnNodes.count(Callee)) {
// Self recursion... simply link up the formal arguments with the
// actual arguments.
DEBUG(std::cerr << " Self Inlining: " << Callee->getName() << "\n");
// If there are call sites that get skipped over, move them to the aux // Handle self recursion by resolving the arguments and return value
// calls list: they are not resolvable. Graph.mergeInGraph(CS, *Callee, Graph, 0);
if (I != E) } else {
while (LastCallSiteIdx != I.getCallSiteIdx()) ActualCallees.insert(std::make_pair(CS.getCallSite().getInstruction(),
AuxCallsList.splice(AuxCallsList.end(), TempFCs, LastCallSiteIdx++); Callee));
else
while (LastCallSiteIdx != TempFCs.end()) // Get the data structure graph for the called function.
AuxCallsList.splice(AuxCallsList.end(), TempFCs, LastCallSiteIdx++); //
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());