Skip to content

Commit f668a74

Browse files
committed
EscapeAnalysis: keep a separate summary connection graph for a function.
Now we can invalidate the "real" graph for a function and still keep the summary graph as interprocedural information. This helps with the current update scheme but is also needed for a better invalidation/update scheme which we might implement.
1 parent 83e9777 commit f668a74

File tree

3 files changed

+162
-131
lines changed

3 files changed

+162
-131
lines changed

include/swift/SILAnalysis/EscapeAnalysis.h

Lines changed: 62 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -348,16 +348,6 @@ class EscapeAnalysis : public SILAnalysis {
348348
/// Use points for CGNode::UsePoints.
349349
llvm::SmallVector<ValueBase *, 32> UsePoints;
350350

351-
/// The callsites from which we have to merge the callee graphs.
352-
llvm::SmallVector<FullApplySite, 8> KnownCallees;
353-
354-
/// If true, at least one of the callee graphs has changed. We have to merge
355-
/// them again.
356-
bool NeedMergeCallees = false;
357-
358-
/// Set to false when the analysis for the function is invalidated.
359-
bool Valid = true;
360-
361351
/// True if the CGNode::UsePoints are computed.
362352
bool UsePointsComputed = false;
363353

@@ -412,28 +402,11 @@ class EscapeAnalysis : public SILAnalysis {
412402
ConnectionGraph(SILFunction *F) : F(F) {
413403
}
414404

415-
bool isValid() const { return Valid; }
416-
417-
/// Removes all nodes from the graph and sets it to invalid.
418-
void invalidate();
405+
/// Removes all nodes from the graph.
406+
void clear();
419407

420408
SILFunction *getFunction() const { return F; }
421409

422-
void addKnownCallee(FullApplySite FAS) { KnownCallees.push_back(FAS); }
423-
424-
const llvm::SmallVectorImpl<FullApplySite> &getKnownCallees() {
425-
return KnownCallees;
426-
}
427-
428-
void setNeedMergeCallees() { NeedMergeCallees = true; }
429-
430-
// Returns true if we need to merge callee graphs and sets the flag to false.
431-
bool handleMergeCallees() {
432-
bool Result = NeedMergeCallees;
433-
NeedMergeCallees = false;
434-
return Result;
435-
}
436-
437410
/// Gets or creates a node for a value \p V.
438411
/// If V is a projection(-path) then the base of the projection(-path) is
439412
/// taken. This means the node is always created for the "outermost" value
@@ -554,12 +527,38 @@ class EscapeAnalysis : public SILAnalysis {
554527
MaxGraphMerges = 4
555528
};
556529

530+
/// All the information we keep for a function.
531+
struct FunctionInfo {
532+
FunctionInfo(SILFunction *F) : Graph(F), SummaryGraph(F) { }
533+
534+
/// The connection graph for the function. This is what clients of the
535+
/// analysis will see.
536+
/// On invalidation, this graph is invalidated and recomputed on demand.
537+
ConnectionGraph Graph;
538+
539+
/// The summary graph for the function. It is used when computing the
540+
/// connection graph of caller functions.
541+
/// This graph is _not_ be invalidated on invalidation. It is only updated
542+
/// when explicitly calling recompute().
543+
ConnectionGraph SummaryGraph;
544+
545+
/// The callsites from which we have to merge the callee graphs.
546+
llvm::SmallVector<FullApplySite, 8> KnownCallees;
547+
548+
/// If true, at least one of the callee graphs has changed. We have to merge
549+
/// them again.
550+
bool NeedMergeCallees = false;
551+
552+
/// True if the Graph is valid.
553+
bool Valid = false;
554+
};
555+
557556
/// The connection graphs for all functions (does not include external
558557
/// functions).
559-
llvm::DenseMap<SILFunction *, ConnectionGraph *> Function2ConGraph;
558+
llvm::DenseMap<SILFunction *, FunctionInfo *> Function2Info;
560559

561560
/// The allocator for the connection graphs in Function2ConGraph.
562-
llvm::SpecificBumpPtrAllocator<ConnectionGraph> Allocator;
561+
llvm::SpecificBumpPtrAllocator<FunctionInfo> Allocator;
563562

564563
/// Cache for isPointer().
565564
llvm::DenseMap<SILType, bool> isPointerCache;
@@ -597,12 +596,13 @@ class EscapeAnalysis : public SILAnalysis {
597596
ConGraph->setEscapesGlobal(Node);
598597
}
599598

600-
/// Builds the connection graph for a function, but does not handle applys to
601-
/// known callees. This is done afterwards by mergeAllCallees.
602-
void buildConnectionGraph(SILFunction *F, ConnectionGraph *ConGraph);
599+
/// Builds the connection graph and the summary graph for a function, but
600+
/// does not handle applys of known callees. This is done afterwards in
601+
/// mergeAllCallees.
602+
void buildConnectionGraphs(FunctionInfo *FInfo);
603603

604604
/// Updates the graph by analysing instruction \p I.
605-
void analyzeInstruction(SILInstruction *I, ConnectionGraph *ConGraph);
605+
void analyzeInstruction(SILInstruction *I, FunctionInfo *FInfo);
606606

607607
/// Returns true if \p V is an Array or the storage reference of an array.
608608
bool isArrayOrArrayStorage(SILValue V);
@@ -611,21 +611,20 @@ class EscapeAnalysis : public SILAnalysis {
611611
void setAllEscaping(SILInstruction *I, ConnectionGraph *ConGraph);
612612

613613
/// Merge the graphs of all known callees into this graph.
614-
bool mergeAllCallees(ConnectionGraph *ConGraph, CallGraph &CG);
614+
bool mergeAllCallees(FunctionInfo *FInfo, CallGraph &CG);
615615

616616
/// Merges the graph of a callee function into the graph of
617617
/// a caller function, whereas \p FAS is the call-site.
618618
bool mergeCalleeGraph(FullApplySite FAS,
619619
ConnectionGraph *CallerGraph,
620620
ConnectionGraph *CalleeGraph);
621621

622-
/// Create a summary graph \p SummaryGraph from \p Graph. It just contains
623-
/// the content nodes of \p Graph.
624-
void createSummaryGraph(ConnectionGraph *SummaryGraph,
625-
ConnectionGraph *Graph);
622+
/// Merge the \p Graph into \p SummaryGraph.
623+
bool mergeSummaryGraph(ConnectionGraph *SummaryGraph,
624+
ConnectionGraph *Graph);
626625

627626
/// Set all arguments and return values of all callees to global escaping.
628-
void finalizeGraphConservatively(ConnectionGraph *ConGraph);
627+
void finalizeGraphsConservatively(FunctionInfo *FInfo);
629628

630629
friend struct ::CGForDotView;
631630

@@ -639,44 +638,51 @@ class EscapeAnalysis : public SILAnalysis {
639638
virtual void initialize(SILPassManager *PM);
640639

641640
/// Gets or creates a connection graph for \a F.
642-
ConnectionGraph *getConnectionGraph(SILFunction *F) const {
643-
ConnectionGraph *CG = Function2ConGraph.lookup(F);
644-
if (CG && CG->isValid())
645-
return CG;
646-
return nullptr;
641+
ConnectionGraph *getConnectionGraph(SILFunction *F) {
642+
FunctionInfo *&FInfo = Function2Info[F];
643+
if (!FInfo)
644+
FInfo = new (Allocator.Allocate()) FunctionInfo(F);
645+
646+
if (!FInfo->Valid)
647+
buildConnectionGraphs(FInfo);
648+
649+
return &FInfo->Graph;
647650
}
648651

649652
/// Recomputes the connection graphs for all functions the module.
650653
void recompute();
651654

652655
virtual void invalidate(PreserveKind K) {
653-
Function2ConGraph.clear();
656+
Function2Info.clear();
654657
Allocator.DestroyAll();
655658
shouldRecompute = true;
656659
}
657660

658661
virtual void invalidate(SILFunction *F, PreserveKind K) {
659-
if (auto *ConGraph = getConnectionGraph(F)) {
660-
ConGraph->invalidate();
662+
if (FunctionInfo *FInfo = Function2Info.lookup(F)) {
663+
FInfo->Graph.clear();
664+
FInfo->KnownCallees.clear();
665+
FInfo->Valid = false;
661666
shouldRecompute = true;
662667
}
663668
}
664669

665670
virtual void verify() const {
666671
#ifndef NDEBUG
667-
for (auto Iter : Function2ConGraph) {
668-
ConnectionGraph *ConGraph = Iter.second;
669-
if (ConGraph)
670-
ConGraph->verify();
672+
for (auto Iter : Function2Info) {
673+
FunctionInfo *FInfo = Iter.second;
674+
FInfo->Graph.verify();
675+
FInfo->SummaryGraph.verify();
671676
}
672677
#endif
673678
}
674679

675680
virtual void verify(SILFunction *F) const {
676681
#ifndef NDEBUG
677-
ConnectionGraph *ConGraph = Function2ConGraph.lookup(F);
678-
if (ConGraph)
679-
ConGraph->verify();
682+
if (FunctionInfo *FInfo = Function2Info.lookup(F)) {
683+
FInfo->Graph.verify();
684+
FInfo->SummaryGraph.verify();
685+
}
680686
#endif
681687
}
682688

0 commit comments

Comments
 (0)