@@ -727,12 +727,14 @@ join(llvm::ImmutableMap<K, V> A, llvm::ImmutableMap<K, V> B,
727
727
// ========================================================================= //
728
728
729
729
using OriginLoanMap = llvm::ImmutableMap<OriginID, LoanSet>;
730
+ using OriginSet = llvm::ImmutableSet<OriginID>;
730
731
731
732
// / An object to hold the factories for immutable collections, ensuring
732
733
// / that all created states share the same underlying memory management.
733
734
struct LifetimeFactory {
734
735
OriginLoanMap::Factory OriginMapFactory;
735
736
LoanSet::Factory LoanSetFactory;
737
+ OriginSet::Factory OriginSetFactory;
736
738
737
739
// / Creates a singleton set containing only the given loan ID.
738
740
LoanSet createLoanSet (LoanID LID) {
@@ -833,6 +835,78 @@ class LoanPropagationAnalysis
833
835
}
834
836
};
835
837
838
+ // ========================================================================= //
839
+ // Live Origins Analysis
840
+ // ========================================================================= //
841
+
842
+ // / The dataflow lattice for origin liveness analysis.
843
+ // / It tracks the set of origins that are live at a given program point.
844
+ struct LivenessLattice {
845
+ OriginSet LiveOrigins;
846
+
847
+ LivenessLattice () : LiveOrigins(nullptr ) {};
848
+ explicit LivenessLattice (OriginSet S) : LiveOrigins(S) {}
849
+
850
+ bool operator ==(const LivenessLattice &Other) const {
851
+ return LiveOrigins == Other.LiveOrigins ;
852
+ }
853
+ bool operator !=(const LivenessLattice &Other) const {
854
+ return !(*this == Other);
855
+ }
856
+
857
+ void dump (llvm::raw_ostream &OS) const {
858
+ OS << " LivenessLattice State:\n " ;
859
+ if (LiveOrigins.isEmpty ())
860
+ OS << " <empty>\n " ;
861
+ for (const OriginID &OID : LiveOrigins)
862
+ OS << " Origin " << OID << " is live\n " ;
863
+ }
864
+ };
865
+
866
+ // / The analysis that tracks which origins are live. This is a backward
867
+ // / analysis.
868
+ class LiveOriginAnalysis
869
+ : public DataflowAnalysis<LiveOriginAnalysis, LivenessLattice,
870
+ Direction::Backward> {
871
+
872
+ OriginSet::Factory &SetFactory;
873
+
874
+ public:
875
+ LiveOriginAnalysis (const CFG &C, AnalysisDeclContext &AC, FactManager &F,
876
+ OriginSet::Factory &SF)
877
+ : DataflowAnalysis(C, AC, F), SetFactory(SF) {}
878
+
879
+ using DataflowAnalysis<LiveOriginAnalysis, Lattice,
880
+ Direction::Backward>::transfer;
881
+
882
+ StringRef getAnalysisName () const { return " LiveOrigins" ; }
883
+
884
+ Lattice getInitialState () { return Lattice (SetFactory.getEmptySet ()); }
885
+
886
+ // / Merges two lattices by taking the union of the live origin sets.
887
+ Lattice join (Lattice L1, Lattice L2) const {
888
+ return Lattice (utils::join (L1.LiveOrigins , L2.LiveOrigins , SetFactory));
889
+ }
890
+
891
+ // / An assignment `p = q` kills the liveness of `p` and generates liveness
892
+ // / for `q`.
893
+ Lattice transfer (Lattice In, const AssignOriginFact &F) {
894
+ OriginSet S = SetFactory.remove (In.LiveOrigins , F.getDestOriginID ());
895
+ S = SetFactory.add (S, F.getSrcOriginID ());
896
+ return Lattice (S);
897
+ }
898
+
899
+ // / Issuing a new loan to an origin kills its liveness.
900
+ Lattice transfer (Lattice In, const IssueFact &F) {
901
+ return Lattice (SetFactory.remove (In.LiveOrigins , F.getOriginID ()));
902
+ }
903
+
904
+ // / A return statement generates liveness for the returned origin.
905
+ Lattice transfer (Lattice In, const ReturnOfOriginFact &F) {
906
+ return Lattice (SetFactory.add (In.LiveOrigins , F.getReturnedOriginID ()));
907
+ }
908
+ };
909
+
836
910
// ========================================================================= //
837
911
// Expired Loans Analysis
838
912
// ========================================================================= //
@@ -937,6 +1011,10 @@ void LifetimeSafetyAnalysis::run() {
937
1011
ExpiredLoans =
938
1012
std::make_unique<ExpiredLoansAnalysis>(Cfg, AC, *FactMgr, *Factory);
939
1013
ExpiredLoans->run ();
1014
+
1015
+ LiveOrigins = std::make_unique<LiveOriginAnalysis>(Cfg, AC, *FactMgr,
1016
+ Factory->OriginSetFactory );
1017
+ LiveOrigins->run ();
940
1018
}
941
1019
942
1020
LoanSet LifetimeSafetyAnalysis::getLoansAtPoint (OriginID OID,
0 commit comments