@@ -348,16 +348,6 @@ class EscapeAnalysis : public SILAnalysis {
348
348
// / Use points for CGNode::UsePoints.
349
349
llvm::SmallVector<ValueBase *, 32 > UsePoints;
350
350
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
-
361
351
// / True if the CGNode::UsePoints are computed.
362
352
bool UsePointsComputed = false ;
363
353
@@ -412,28 +402,11 @@ class EscapeAnalysis : public SILAnalysis {
412
402
ConnectionGraph (SILFunction *F) : F(F) {
413
403
}
414
404
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 ();
419
407
420
408
SILFunction *getFunction () const { return F; }
421
409
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
-
437
410
// / Gets or creates a node for a value \p V.
438
411
// / If V is a projection(-path) then the base of the projection(-path) is
439
412
// / taken. This means the node is always created for the "outermost" value
@@ -554,12 +527,38 @@ class EscapeAnalysis : public SILAnalysis {
554
527
MaxGraphMerges = 4
555
528
};
556
529
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
+
557
556
// / The connection graphs for all functions (does not include external
558
557
// / functions).
559
- llvm::DenseMap<SILFunction *, ConnectionGraph *> Function2ConGraph ;
558
+ llvm::DenseMap<SILFunction *, FunctionInfo *> Function2Info ;
560
559
561
560
// / The allocator for the connection graphs in Function2ConGraph.
562
- llvm::SpecificBumpPtrAllocator<ConnectionGraph > Allocator;
561
+ llvm::SpecificBumpPtrAllocator<FunctionInfo > Allocator;
563
562
564
563
// / Cache for isPointer().
565
564
llvm::DenseMap<SILType, bool > isPointerCache;
@@ -597,12 +596,13 @@ class EscapeAnalysis : public SILAnalysis {
597
596
ConGraph->setEscapesGlobal (Node);
598
597
}
599
598
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);
603
603
604
604
// / Updates the graph by analysing instruction \p I.
605
- void analyzeInstruction (SILInstruction *I, ConnectionGraph *ConGraph );
605
+ void analyzeInstruction (SILInstruction *I, FunctionInfo *FInfo );
606
606
607
607
// / Returns true if \p V is an Array or the storage reference of an array.
608
608
bool isArrayOrArrayStorage (SILValue V);
@@ -611,21 +611,20 @@ class EscapeAnalysis : public SILAnalysis {
611
611
void setAllEscaping (SILInstruction *I, ConnectionGraph *ConGraph);
612
612
613
613
// / Merge the graphs of all known callees into this graph.
614
- bool mergeAllCallees (ConnectionGraph *ConGraph , CallGraph &CG);
614
+ bool mergeAllCallees (FunctionInfo *FInfo , CallGraph &CG);
615
615
616
616
// / Merges the graph of a callee function into the graph of
617
617
// / a caller function, whereas \p FAS is the call-site.
618
618
bool mergeCalleeGraph (FullApplySite FAS,
619
619
ConnectionGraph *CallerGraph,
620
620
ConnectionGraph *CalleeGraph);
621
621
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);
626
625
627
626
// / Set all arguments and return values of all callees to global escaping.
628
- void finalizeGraphConservatively (ConnectionGraph *ConGraph );
627
+ void finalizeGraphsConservatively (FunctionInfo *FInfo );
629
628
630
629
friend struct ::CGForDotView;
631
630
@@ -639,44 +638,51 @@ class EscapeAnalysis : public SILAnalysis {
639
638
virtual void initialize (SILPassManager *PM);
640
639
641
640
// / 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 ;
647
650
}
648
651
649
652
// / Recomputes the connection graphs for all functions the module.
650
653
void recompute ();
651
654
652
655
virtual void invalidate (PreserveKind K) {
653
- Function2ConGraph .clear ();
656
+ Function2Info .clear ();
654
657
Allocator.DestroyAll ();
655
658
shouldRecompute = true ;
656
659
}
657
660
658
661
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 ;
661
666
shouldRecompute = true ;
662
667
}
663
668
}
664
669
665
670
virtual void verify () const {
666
671
#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 ();
671
676
}
672
677
#endif
673
678
}
674
679
675
680
virtual void verify (SILFunction *F) const {
676
681
#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
+ }
680
686
#endif
681
687
}
682
688
0 commit comments