Use a callback in the linker to notify clients of newly deserialized functions.

Previous attempts to update the callgraph explicitly after calls to
linkFunction() weren't completely effective because we can deserialize
deeply and introduce multiple new function bodies in the process.

This gets us a bit closer, but only adds new call graph nodes. It does
not currently add edges for everything that gets deserialized (and this
is not fatal, so it is a step forward).

Swift SVN r27120
This commit is contained in:
Mark Lacey
2015-04-08 06:46:15 +00:00
parent 7c5f1e8c1d
commit ed66cfd544
11 changed files with 101 additions and 43 deletions

View File

@@ -103,14 +103,13 @@ bool CallGraph::tryGetCalleeSet(SILValue Callee,
SWIFT_FALLTHROUGH;
case ValueKind::FunctionRefInst: {
auto *CalleeFn = cast<FunctionRefInst>(Callee)->getReferencedFunction();
if (CalleeFn->isExternalDeclaration()) {
if (!M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll))
if (CalleeFn->isExternalDeclaration())
if (!M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll,
CallGraphLinkerEditor(*this).getCallback()))
return false;
addCallGraphNode(CalleeFn);
}
auto *CalleeNode = getCallGraphNode(CalleeFn);
assert(CalleeNode && "Expected call graph node for function definition!");
CalleeSet.insert(CalleeNode);
Complete = true;
return true;
@@ -166,14 +165,13 @@ bool CallGraph::tryGetCalleeSet(SILValue Callee,
if (!CalleeFn)
return false;
if (CalleeFn->isExternalDeclaration()) {
if (!M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll))
if (CalleeFn->isExternalDeclaration())
if (!M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll,
CallGraphLinkerEditor(*this).getCallback()))
return false;
addCallGraphNode(CalleeFn);
}
auto *CalleeNode = getCallGraphNode(CalleeFn);
assert(CalleeNode && "Expected call graph node for function definition!");
CalleeSet.insert(CalleeNode);
Complete = true;
return true;
@@ -296,13 +294,11 @@ void CallGraph::addEdges(SILFunction *F) {
if (auto *FRI = dyn_cast<FunctionRefInst>(&I)) {
auto *CalleeFn = FRI->getReferencedFunction();
if (CalleeFn->isExternalDeclaration()) {
if (!M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll))
if (CalleeFn->isExternalDeclaration())
if (!M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll,
CallGraphLinkerEditor(*this).getCallback()))
continue;
addCallGraphNode(CalleeFn);
}
if (!CalleeFn->isPossiblyUsedExternally()) {
bool hasAllApplyUsers = std::none_of(FRI->use_begin(), FRI->use_end(),
[](const Operand *Op) {
@@ -313,6 +309,8 @@ void CallGraph::addEdges(SILFunction *F) {
// as being incomplete.
if (!hasAllApplyUsers) {
auto *CalleeNode = getCallGraphNode(CalleeFn);
assert(CalleeNode &&
"Expected call graph node for function definition!");
CalleeNode->markCallerEdgesIncomplete();
}
}