[callgraph] Teach the callgraph how to determine for simple cases if we have a complete caller set.

We specifically only handle cases of functions that are not visible externally
and for whom all function_refs to the function only have apply inst users.

<rdar://problem/19137435>

Swift SVN r23714
This commit is contained in:
Michael Gottesman
2014-12-05 02:08:36 +00:00
parent d0068877f5
commit ebfcc123a3
3 changed files with 60 additions and 12 deletions

View File

@@ -154,10 +154,29 @@ void CallGraph::addEdges(SILFunction *F) {
auto *CallerNode = getCallGraphNode(F);
assert(CallerNode && "Expected call graph node for function!");
for (auto &BB : *F)
for (auto &I : BB)
if (auto *AI = dyn_cast<ApplyInst>(&I))
for (auto &BB : *F) {
for (auto &I : BB) {
if (auto *AI = dyn_cast<ApplyInst>(&I)) {
addEdgesForApply(AI, CallerNode);
}
if (auto *FRI = dyn_cast<FunctionRefInst>(&I)) {
auto *CalleeFn = FRI->getReferencedFunction();
if (!CalleeFn->isPossiblyUsedExternally()) {
bool hasAllApplyUsers = std::none_of(FRI->use_begin(), FRI->use_end(),
[](const Operand *Op) {
return !isa<ApplyInst>(Op->getUser());
});
// If we have a non-apply user of this function, return false.
if (!hasAllApplyUsers) {
auto *CalleeNode = getCallGraphNode(CalleeFn);
CalleeNode->markCallerSetIncomplete();
}
}
}
}
}
}
static void orderCallees(const CallGraphEdge::CalleeSetType &Callees,