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