@@ -500,6 +500,9 @@ class FactGenerator : public ConstStmtVisitor<FactGenerator> {
500500// Generic Dataflow Analysis
501501// ========================================================================= //
502502
503+ // DO NOT SUBMIT: TODO: Document notion of before or after in the analyses.
504+ using ProgramPoint = std::pair<const CFGBlock *, const Fact *>;
505+
503506enum class Direction { Forward, Backward };
504507
505508// / A generic, policy-based driver for dataflow analyses. It combines
@@ -532,6 +535,7 @@ class DataflowAnalysis {
532535
533536 llvm::DenseMap<const CFGBlock *, Lattice> InStates;
534537 llvm::DenseMap<const CFGBlock *, Lattice> OutStates;
538+ llvm::DenseMap<ProgramPoint, Lattice> PerPointStates;
535539
536540 static constexpr bool isForward () { return Dir == Direction::Forward; }
537541
@@ -577,6 +581,8 @@ class DataflowAnalysis {
577581 }
578582 }
579583
584+ Lattice getState (ProgramPoint P) const { return PerPointStates.lookup (P); }
585+
580586 Lattice getInState (const CFGBlock *B) const { return InStates.lookup (B); }
581587
582588 Lattice getOutState (const CFGBlock *B) const { return OutStates.lookup (B); }
@@ -590,18 +596,22 @@ class DataflowAnalysis {
590596 getOutState (&B).dump (llvm::dbgs ());
591597 }
592598
599+ private:
593600 // / Computes the state at one end of a block by applying all its facts
594601 // / sequentially to a given state from the other end.
595- // / TODO: We might need to store intermediate states per-fact in the block for
596- // / later analysis.
597602 Lattice transferBlock (const CFGBlock *Block, Lattice State) {
598603 auto Facts = AllFacts.getFacts (Block);
599- if constexpr (isForward ())
600- for (const Fact *F : Facts)
604+ if constexpr (isForward ()) {
605+ for (const Fact *F : Facts) {
601606 State = transferFact (State, F);
602- else
603- for (const Fact *F : llvm::reverse (Facts))
607+ PerPointStates[{Block, F}] = State;
608+ }
609+ } else {
610+ for (const Fact *F : llvm::reverse (Facts)) {
604611 State = transferFact (State, F);
612+ PerPointStates[{Block, F}] = State;
613+ }
614+ }
605615 return State;
606616 }
607617
@@ -772,6 +782,10 @@ class LoanPropagationAnalysis
772782 Factory.OriginMapFactory .add (In.Origins , DestOID, SrcLoans));
773783 }
774784
785+ LoanSet getLoans (OriginID OID, ProgramPoint P) {
786+ return getLoans (getState (P), OID);
787+ }
788+
775789private:
776790 LoanSet getLoans (Lattice L, OriginID OID) {
777791 if (auto *Loans = L.Origins .lookup (OID))
@@ -850,6 +864,14 @@ class LiveOriginAnalysis
850864 Lattice transfer (Lattice In, const ReturnOfOriginFact &F) {
851865 return Lattice (SetFactory.add (In.LiveOrigins , F.getReturnedOriginID ()));
852866 }
867+
868+ bool isLive (OriginID OID, ProgramPoint P) const {
869+ return getState (P).LiveOrigins .contains (OID);
870+ }
871+
872+ OriginSet getLiveOrigins (ProgramPoint P) const {
873+ return getState (P).LiveOrigins ;
874+ }
853875};
854876
855877// ========================================================================= //
@@ -909,14 +931,15 @@ class ExpiredLoansAnalysis
909931 Lattice transfer (Lattice In, const IssueFact &F) {
910932 return Lattice (Factory.remove (In.Expired , F.getLoanID ()));
911933 }
934+
935+ bool isExpired (LoanID LID, ProgramPoint P) const {
936+ return getState (P).Expired .contains (LID);
937+ }
912938};
913939
914940// ========================================================================= //
915941// TODO:
916- // - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
917- // - Modify loan expiry analysis to answer `bool isExpired(Loan L, Point P)`
918- // - Modify origin liveness analysis to answer `bool isLive(Origin O, Point P)`
919- // - Using the above three to perform the final error reporting.
942+ // - Add error reporting <DO NOT SUBMIT> Add how would it work.
920943// ========================================================================= //
921944} // anonymous namespace
922945
0 commit comments