Skip to content

Commit

Permalink
Revert "Add support for deinits in the call graph."
Browse files Browse the repository at this point in the history
This reverts commit 309f963.

There is some concern this could break things now or in the future so it
makes sense to preemptively revert this until those concerns are
addressed.
  • Loading branch information
rudkx committed Nov 10, 2015
1 parent 65fec0a commit 0cd6a76
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 300 deletions.
11 changes: 0 additions & 11 deletions include/swift/SILAnalysis/CallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,6 @@ class CallGraphEdge {
return *CS.getPointer()->begin();
}

/// Does this edge represent an instruction that may or may not end
/// up calling any callees depending on other state (like reference
/// counts)?
bool isMayCall() const {
auto Kind = getInstruction()->getKind();
return Kind != ValueKind::ApplyInst && Kind != ValueKind::TryApplyInst;
}

unsigned getOrdinal() const {
return Ordinal;
}
Expand Down Expand Up @@ -525,16 +517,13 @@ class CallGraph {

void removeFunctionFromCalleeSets(SILFunction *F);
void computeMethodCallees();
void computeDestructorCalleesForClass(ClassDecl *CD);
void computeClassMethodCalleesForClass(ClassDecl *CD);
void computeWitnessMethodCalleesForWitnessTable(SILWitnessTable &WTable);

CallGraphNode *addCallGraphNode(SILFunction *F);
void addEdges(SILFunction *F);
CallGraphEdge *makeCallGraphEdgeForCallee(FullApplySite FAS,
SILValue Callee);
void addEdgesForApply(FullApplySite FAS, CallGraphNode *CallerNode);
CallGraphEdge *getEdgeForReleasingInstruction(SILInstruction *I);
void addEdgesForInstruction(SILInstruction *I, CallGraphNode *CallerNode);
void clearBottomUpSCCOrder();
void computeBottomUpSCCOrder();
Expand Down
151 changes: 18 additions & 133 deletions lib/SILAnalysis/CallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,47 +93,9 @@ CallGraph::~CallGraph() {
}
}

/// Update the callee set for the destructor of a given class, along
/// with all the destructors from its superclass.
void CallGraph::computeDestructorCalleesForClass(ClassDecl *CD) {
auto *Dtor = CD->getDestructor();
if (!Dtor)
return;

auto Method = SILDeclRef(Dtor);
auto *CalledFn = M.lookUpFunctionInVTable(CD, Method);
if (!CalledFn)
return;

auto *Node = getOrAddCallGraphNode(CalledFn);

while (CD) {
auto &TheCalleeSet = getOrCreateCalleeSetForMethod(Method);
assert(TheCalleeSet.getPointer() && "Unexpected null callee set!");

TheCalleeSet.getPointer()->insert(Node);

bool canCallUnknown = !calleesAreStaticallyKnowable(M, Method);
if (canCallUnknown)
TheCalleeSet.setInt(true);

if (!CD->hasSuperclass())
return;

CD = CD->getSuperclass()->getClassOrBoundGenericClass();

Dtor = CD->getDestructor();
assert(Dtor && "Expected destructor in superclass!");

Method = SILDeclRef(Dtor);
}
}

/// Update the callee set for each method of a given class, along with
/// all the overridden methods from superclasses.
void CallGraph::computeClassMethodCalleesForClass(ClassDecl *CD) {
computeDestructorCalleesForClass(CD);

for (auto *Member : CD->getMembers()) {
auto *AFD = dyn_cast<AbstractFunctionDecl>(Member);
if (!AFD)
Expand Down Expand Up @@ -390,8 +352,14 @@ static void orderEdges(const llvm::SmallPtrSetImpl<CallGraphEdge *> &Edges,
});
}

void CallGraph::addEdgesForApply(FullApplySite Apply,
CallGraphNode *CallerNode) {
void CallGraph::addEdgesForInstruction(SILInstruction *I,
CallGraphNode *CallerNode) {
auto Apply = FullApplySite::isa(I);

// TODO: Support non-apply instructions.
if (!Apply)
return;

CallerNode->MayBindDynamicSelf |=
hasDynamicSelfTypes(Apply.getSubstitutions());

Expand All @@ -410,88 +378,6 @@ void CallGraph::addEdgesForApply(FullApplySite Apply,
++NumAppliesWithEdges;
}

static SILType getReleasedType(SILInstruction *I) {
switch (I->getKind()) {
default:
llvm_unreachable("Unhandled releasing instruction!");

case ValueKind::DestroyAddrInst:
return cast<DestroyAddrInst>(I)->getOperand().getType();

case ValueKind::StrongReleaseInst:
return cast<StrongReleaseInst>(I)->getOperand().getType();

case ValueKind::UnownedReleaseInst:
return cast<UnownedReleaseInst>(I)->getOperand().getType();

case ValueKind::ReleaseValueInst:
// TODO
return SILType();

case ValueKind::UnconditionalCheckedCastAddrInst:
return cast<UnconditionalCheckedCastAddrInst>(I)->getSrc().getType();

case ValueKind::CheckedCastAddrBranchInst:
return cast<CheckedCastAddrBranchInst>(I)->getSrc().getType();

case ValueKind::CopyAddrInst:
return cast<CopyAddrInst>(I)->getDest().getType();
}
}

CallGraphEdge *CallGraph::getEdgeForReleasingInstruction(SILInstruction *I) {
auto Ty = getReleasedType(I);

// FIXME: Handle release_value, which could involve multiple types.
if (!Ty)
return new (Allocator) CallGraphEdge(I, EdgeOrdinal++);

auto CanTy = getReleasedType(I).getSwiftRValueType();
// FIXME: Handle archetypes.
if (CanTy->is<ArchetypeType>())
return new (Allocator) CallGraphEdge(I, EdgeOrdinal++);

auto *CD = CanTy.getClassOrBoundGenericClass();
// We release non-class types, e.g. BridgeObject
if (!CD)
return new (Allocator) CallGraphEdge(I, EdgeOrdinal++);

if (CD->isObjC())
return new (Allocator) CallGraphEdge(I, EdgeOrdinal++);

auto *Dtor = CD->getDestructor();
assert(Dtor && "Expected destructor for class!");

auto Found = CalleeSetCache.find(Dtor);
if (Found == CalleeSetCache.end())
return new (Allocator) CallGraphEdge(I, EdgeOrdinal++);

return new (Allocator) CallGraphEdge(I, Found->second, EdgeOrdinal++);
}

void CallGraph::addEdgesForInstruction(SILInstruction *I,
CallGraphNode *CallerNode) {
if (auto Apply = FullApplySite::isa(I)) {
addEdgesForApply(Apply, CallerNode);
return;
}

if (!I->mayRelease())
return;

auto *Edge = getEdgeForReleasingInstruction(I);

assert(Edge && "Expected to be able to make call graph edge for callee!");
assert(!InstToEdgeMap.count(I) &&
"Added instruction that already has an edge node!\n");
InstToEdgeMap[I] = Edge;

CallerNode->addCalleeEdge(Edge);

for (auto *CalleeNode : Edge->getCalleeSet())
CalleeNode->addCallerEdge(Edge);
}

void CallGraph::removeEdgeFromFunction(CallGraphEdge *Edge, SILFunction *F) {
// Remove the edge from all the potential callee call graph nodes.
auto CalleeSet = Edge->getCalleeSet();
Expand Down Expand Up @@ -543,7 +429,8 @@ void CallGraph::addEdges(SILFunction *F) {

for (auto &BB : *F) {
for (auto &I : BB) {
addEdgesForInstruction(&I, CallerNode);
if (FullApplySite::isa(&I))
addEdgesForInstruction(&I, CallerNode);

auto *FRI = dyn_cast<FunctionRefInst>(&I);
if (!FRI)
Expand Down Expand Up @@ -700,12 +587,13 @@ void CallGraphNode::dump() const {
void CallGraph::print(llvm::raw_ostream &OS) {
OS << CallGraphFileCheckPrefix << "*** Call Graph ***\n";

for (auto &F : M) {
auto *Node = getCallGraphNode(&F);
auto const &Funcs = getBottomUpFunctionOrder();
for (auto *F : Funcs) {
auto *Node = getCallGraphNode(F);
if (Node)
Node->print(OS);
else
OS << "!!! Missing node for " << F.getName() << "!!!";
OS << "!!! Missing node for " << F->getName() << "!!!";
OS << "\n";
}
}
Expand Down Expand Up @@ -1036,24 +924,21 @@ void CallGraph::verify(SILFunction *F) const {

for (auto &BB : *F) {
for (auto &I : BB) {
if (!I.mayRelease())
auto FAS = FullApplySite::isa(&I);
if (!FAS)
continue;

auto *Edge = getCallGraphEdge(&I);
auto *Edge = getCallGraphEdge(FAS.getInstruction());

numEdges++;

assert(Edge->getInstruction() == &I &&
"Edge is not linked to the correct apply site");

assert(InstToEdgeMap.lookup(&I) == Edge &&
assert(InstToEdgeMap.lookup(FAS.getInstruction()) == Edge &&
"Edge is not in InstToEdgeMap");

if (!Edge->canCallUnknownFunction()) {
auto FAS = FullApplySite::isa(&I);
if (!FAS)
continue;

// In the trivial case that we call a known function, check if we have
// exactly one callee in the edge.
SILValue Callee = FAS.getCallee();
Expand Down
Loading

0 comments on commit 0cd6a76

Please sign in to comment.