@@ -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
@@ -771,6 +781,10 @@ class LoanPropagationAnalysis
771781 Factory.OriginMapFactory .add (In.Origins , DestOID, SrcLoans));
772782 }
773783
784+ LoanSet getLoans (OriginID OID, ProgramPoint P) {
785+ return getLoans (getState (P), OID);
786+ }
787+
774788private:
775789 LoanSet getLoans (Lattice L, OriginID OID) {
776790 if (auto *Loans = L.Origins .lookup (OID))
@@ -849,6 +863,14 @@ class LiveOriginAnalysis
849863 Lattice transfer (Lattice In, const ReturnOfOriginFact &F) {
850864 return Lattice (SetFactory.add (In.LiveOrigins , F.getReturnedOriginID ()));
851865 }
866+
867+ bool isLive (OriginID OID, ProgramPoint P) const {
868+ return getState (P).LiveOrigins .contains (OID);
869+ }
870+
871+ OriginSet getLiveOrigins (ProgramPoint P) const {
872+ return getState (P).LiveOrigins ;
873+ }
852874};
853875
854876// ========================================================================= //
@@ -908,14 +930,15 @@ class ExpiredLoansAnalysis
908930 Lattice transfer (Lattice In, const IssueFact &F) {
909931 return Lattice (Factory.remove (In.Expired , F.getLoanID ()));
910932 }
933+
934+ bool isExpired (LoanID LID, ProgramPoint P) const {
935+ return getState (P).Expired .contains (LID);
936+ }
911937};
912938
913939// ========================================================================= //
914940// TODO:
915- // - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
916- // - Modify loan expiry analysis to answer `bool isExpired(Loan L, Point P)`
917- // - Modify origin liveness analysis to answer `bool isLive(Origin O, Point P)`
918- // - Using the above three to perform the final error reporting.
941+ // - Add error reporting <DO NOT SUBMIT> Add how would it work.
919942// ========================================================================= //
920943} // anonymous namespace
921944
0 commit comments