mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Inline both direct and indirect callees in the CBU phase because
a direct callee may have indirect callees and so may have changed. llvm-svn: 13649
This commit is contained in:
parent
893c53a559
commit
cf685da276
@ -37,14 +37,13 @@ bool CompleteBUDataStructures::run(Module &M) {
|
||||
GlobalsGraph = new DSGraph(BU.getGlobalsGraph());
|
||||
GlobalsGraph->setPrintAuxCalls();
|
||||
|
||||
// Our call graph is the same as the BU data structures call graph
|
||||
ActualCallees = BU.getActualCallees();
|
||||
|
||||
#if 1 // REMOVE ME EVENTUALLY
|
||||
// FIXME: TEMPORARY (remove once finalization of indirect call sites in the
|
||||
// globals graph has been implemented in the BU pass)
|
||||
TDDataStructures &TD = getAnalysis<TDDataStructures>();
|
||||
|
||||
ActualCallees.clear();
|
||||
|
||||
// The call graph extractable from the TD pass is _much more complete_ and
|
||||
// trustable than that generated by the BU pass so far. Until this is fixed,
|
||||
// we hack it like this:
|
||||
@ -53,17 +52,23 @@ bool CompleteBUDataStructures::run(Module &M) {
|
||||
const std::vector<DSCallSite> &CSs = TD.getDSGraph(*MI).getFunctionCalls();
|
||||
|
||||
for (unsigned CSi = 0, e = CSs.size(); CSi != e; ++CSi) {
|
||||
if (CSs[CSi].isIndirectCall()) {
|
||||
Instruction *TheCall = CSs[CSi].getCallSite().getInstruction();
|
||||
Instruction *TheCall = CSs[CSi].getCallSite().getInstruction();
|
||||
|
||||
if (CSs[CSi].isIndirectCall()) { // indirect call: insert all callees
|
||||
const std::vector<GlobalValue*> &Callees =
|
||||
CSs[CSi].getCalleeNode()->getGlobals();
|
||||
for (unsigned i = 0, e = Callees.size(); i != e; ++i)
|
||||
if (Function *F = dyn_cast<Function>(Callees[i]))
|
||||
ActualCallees.insert(std::make_pair(TheCall, F));
|
||||
} else { // direct call: insert the single callee directly
|
||||
ActualCallees.insert(std::make_pair(TheCall,
|
||||
CSs[CSi].getCalleeFunc()));
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Our call graph is the same as the BU data structures call graph
|
||||
ActualCallees = BU.getActualCallees();
|
||||
#endif
|
||||
|
||||
std::vector<DSGraph*> Stack;
|
||||
@ -183,35 +188,30 @@ void CompleteBUDataStructures::processGraph(DSGraph &G) {
|
||||
"Call instruction occurs multiple times in graph??");
|
||||
|
||||
|
||||
// The Normal BU pass will have taken care of direct calls well already,
|
||||
// don't worry about them.
|
||||
|
||||
// FIXME: if a direct callee had indirect callees, it seems like they could
|
||||
// be updated and we would have to reinline even direct calls!
|
||||
|
||||
if (!CS.getCallSite().getCalledFunction()) {
|
||||
// Loop over all of the actually called functions...
|
||||
ActualCalleesTy::iterator I, E;
|
||||
tie(I, E) = ActualCallees.equal_range(TheCall);
|
||||
unsigned TNum = 0, Num = std::distance(I, E);
|
||||
for (; I != E; ++I, ++TNum) {
|
||||
Function *CalleeFunc = I->second;
|
||||
if (!CalleeFunc->isExternal()) {
|
||||
// Merge the callee's graph into this graph. This works for normal
|
||||
// calls or for self recursion within an SCC.
|
||||
DSGraph &GI = getOrCreateGraph(*CalleeFunc);
|
||||
++NumCBUInlines;
|
||||
G.mergeInGraph(CS, *CalleeFunc, GI, DSGraph::KeepModRefBits |
|
||||
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes |
|
||||
DSGraph::DontCloneAuxCallNodes);
|
||||
DEBUG(std::cerr << " Inlining graph [" << i << "/" << e-1
|
||||
<< ":" << TNum << "/" << Num-1 << "] for "
|
||||
<< CalleeFunc->getName() << "["
|
||||
<< GI.getGraphSize() << "+" << GI.getAuxFunctionCalls().size()
|
||||
<< "] into '" /*<< G.getFunctionNames()*/ << "' ["
|
||||
<< G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
|
||||
<< "]\n");
|
||||
}
|
||||
// Loop over all of the potentially called functions...
|
||||
// Inline direct calls as well as indirect calls because the direct
|
||||
// callee may have indirect callees and so may have changed.
|
||||
//
|
||||
ActualCalleesTy::iterator I, E;
|
||||
tie(I, E) = ActualCallees.equal_range(TheCall);
|
||||
unsigned TNum = 0, Num = std::distance(I, E);
|
||||
for (; I != E; ++I, ++TNum) {
|
||||
Function *CalleeFunc = I->second;
|
||||
if (!CalleeFunc->isExternal()) {
|
||||
// Merge the callee's graph into this graph. This works for normal
|
||||
// calls or for self recursion within an SCC.
|
||||
DSGraph &GI = getOrCreateGraph(*CalleeFunc);
|
||||
++NumCBUInlines;
|
||||
G.mergeInGraph(CS, *CalleeFunc, GI, DSGraph::KeepModRefBits |
|
||||
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes |
|
||||
DSGraph::DontCloneAuxCallNodes);
|
||||
DEBUG(std::cerr << " Inlining graph [" << i << "/" << e-1
|
||||
<< ":" << TNum << "/" << Num-1 << "] for "
|
||||
<< CalleeFunc->getName() << "["
|
||||
<< GI.getGraphSize() << "+" << GI.getAuxFunctionCalls().size()
|
||||
<< "] into '" /*<< G.getFunctionNames()*/ << "' ["
|
||||
<< G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
|
||||
<< "]\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user