Skip to content

Commit 6d91a96

Browse files
committed
add-liveness-finally
1 parent 8bbae58 commit 6d91a96

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

clang/lib/Analysis/LifetimeSafety.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,12 +675,14 @@ join(llvm::ImmutableMap<K, V> A, llvm::ImmutableMap<K, V> B,
675675
// TODO(opt): Consider using a bitset to represent the set of loans.
676676
using LoanSet = llvm::ImmutableSet<LoanID>;
677677
using OriginLoanMap = llvm::ImmutableMap<OriginID, LoanSet>;
678+
using OriginSet = llvm::ImmutableSet<OriginID>;
678679

679680
/// An object to hold the factories for immutable collections, ensuring
680681
/// that all created states share the same underlying memory management.
681682
struct LifetimeFactory {
682683
OriginLoanMap::Factory OriginMapFactory;
683684
LoanSet::Factory LoanSetFactory;
685+
OriginSet::Factory OriginSetFactory;
684686

685687
/// Creates a singleton set containing only the given loan ID.
686688
LoanSet createLoanSet(LoanID LID) {
@@ -778,6 +780,78 @@ class LoanPropagationAnalysis
778780
}
779781
};
780782

783+
// ========================================================================= //
784+
// Live Origins Analysis
785+
// ========================================================================= //
786+
787+
/// The dataflow lattice for origin liveness analysis.
788+
/// It tracks the set of origins that are live at a given program point.
789+
struct LivenessLattice {
790+
OriginSet LiveOrigins;
791+
792+
LivenessLattice() : LiveOrigins(nullptr) {};
793+
explicit LivenessLattice(OriginSet S) : LiveOrigins(S) {}
794+
795+
bool operator==(const LivenessLattice &Other) const {
796+
return LiveOrigins == Other.LiveOrigins;
797+
}
798+
bool operator!=(const LivenessLattice &Other) const {
799+
return !(*this == Other);
800+
}
801+
802+
void dump(llvm::raw_ostream &OS) const {
803+
OS << "LivenessLattice State:\n";
804+
if (LiveOrigins.isEmpty())
805+
OS << " <empty>\n";
806+
for (const OriginID &OID : LiveOrigins)
807+
OS << " Origin " << OID << " is live\n";
808+
}
809+
};
810+
811+
/// The analysis that tracks which origins are live. This is a backward
812+
/// analysis.
813+
class LiveOriginAnalysis
814+
: public DataflowAnalysis<LiveOriginAnalysis, LivenessLattice,
815+
Direction::Backward> {
816+
817+
OriginSet::Factory &SetFactory;
818+
819+
public:
820+
LiveOriginAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
821+
OriginSet::Factory &SF)
822+
: DataflowAnalysis(C, AC, F), SetFactory(SF) {}
823+
824+
using DataflowAnalysis<LiveOriginAnalysis, Lattice,
825+
Direction::Backward>::transfer;
826+
827+
StringRef getAnalysisName() const { return "LiveOrigins"; }
828+
829+
Lattice getInitialState() { return Lattice(SetFactory.getEmptySet()); }
830+
831+
/// Merges two lattices by taking the union of the live origin sets.
832+
Lattice join(Lattice L1, Lattice L2) const {
833+
return Lattice(utils::join(L1.LiveOrigins, L2.LiveOrigins, SetFactory));
834+
}
835+
836+
/// An assignment `p = q` kills the liveness of `p` and generates liveness
837+
/// for `q`.
838+
Lattice transfer(Lattice In, const AssignOriginFact &F) {
839+
OriginSet S = SetFactory.remove(In.LiveOrigins, F.getDestOriginID());
840+
S = SetFactory.add(S, F.getSrcOriginID());
841+
return Lattice(S);
842+
}
843+
844+
/// Issuing a new loan to an origin kills its liveness.
845+
Lattice transfer(Lattice In, const IssueFact &F) {
846+
return Lattice(SetFactory.remove(In.LiveOrigins, F.getOriginID()));
847+
}
848+
849+
/// A return statement generates liveness for the returned origin.
850+
Lattice transfer(Lattice In, const ReturnOfOriginFact &F) {
851+
return Lattice(SetFactory.add(In.LiveOrigins, F.getReturnedOriginID()));
852+
}
853+
};
854+
781855
// ========================================================================= //
782856
// Expired Loans Analysis
783857
// ========================================================================= //
@@ -872,5 +946,10 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
872946

873947
ExpiredLoansAnalysis ExpiredLoans(Cfg, AC, FactMgr, Factory);
874948
ExpiredLoans.run();
949+
DEBUG_WITH_TYPE("LifetimeExpiredLoans", ExpiredLoans.dump());
950+
951+
LiveOriginAnalysis Liveness(Cfg, AC, FactMgr, Factory.OriginSetFactory);
952+
Liveness.run();
953+
DEBUG_WITH_TYPE("LifetimeLiveOrigins", Liveness.dump());
875954
}
876955
} // namespace clang

0 commit comments

Comments
 (0)