@@ -500,6 +500,9 @@ class FactGenerator : public ConstStmtVisitor<FactGenerator> {
500
500
// Generic Dataflow Analysis
501
501
// ========================================================================= //
502
502
503
+ // DO NOT SUBMIT: TODO: Document notion of before or after in the analyses.
504
+ using ProgramPoint = std::pair<const CFGBlock *, const Fact *>;
505
+
503
506
enum class Direction { Forward, Backward };
504
507
505
508
// / A generic, policy-based driver for dataflow analyses. It combines
@@ -532,6 +535,7 @@ class DataflowAnalysis {
532
535
533
536
llvm::DenseMap<const CFGBlock *, Lattice> InStates;
534
537
llvm::DenseMap<const CFGBlock *, Lattice> OutStates;
538
+ llvm::DenseMap<ProgramPoint, Lattice> PerPointStates;
535
539
536
540
static constexpr bool isForward () { return Dir == Direction::Forward; }
537
541
@@ -577,6 +581,8 @@ class DataflowAnalysis {
577
581
}
578
582
}
579
583
584
+ Lattice getState (ProgramPoint P) const { return PerPointStates.lookup (P); }
585
+
580
586
Lattice getInState (const CFGBlock *B) const { return InStates.lookup (B); }
581
587
582
588
Lattice getOutState (const CFGBlock *B) const { return OutStates.lookup (B); }
@@ -590,18 +596,22 @@ class DataflowAnalysis {
590
596
getOutState (&B).dump (llvm::dbgs ());
591
597
}
592
598
599
+ private:
593
600
// / Computes the state at one end of a block by applying all its facts
594
601
// / 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.
597
602
Lattice transferBlock (const CFGBlock *Block, Lattice State) {
598
603
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) {
601
606
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)) {
604
611
State = transferFact (State, F);
612
+ PerPointStates[{Block, F}] = State;
613
+ }
614
+ }
605
615
return State;
606
616
}
607
617
@@ -772,6 +782,10 @@ class LoanPropagationAnalysis
772
782
Factory.OriginMapFactory .add (In.Origins , DestOID, SrcLoans));
773
783
}
774
784
785
+ LoanSet getLoans (OriginID OID, ProgramPoint P) {
786
+ return getLoans (getState (P), OID);
787
+ }
788
+
775
789
private:
776
790
LoanSet getLoans (Lattice L, OriginID OID) {
777
791
if (auto *Loans = L.Origins .lookup (OID))
@@ -850,6 +864,14 @@ class LiveOriginAnalysis
850
864
Lattice transfer (Lattice In, const ReturnOfOriginFact &F) {
851
865
return Lattice (SetFactory.add (In.LiveOrigins , F.getReturnedOriginID ()));
852
866
}
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
+ }
853
875
};
854
876
855
877
// ========================================================================= //
@@ -909,14 +931,15 @@ class ExpiredLoansAnalysis
909
931
Lattice transfer (Lattice In, const IssueFact &F) {
910
932
return Lattice (Factory.remove (In.Expired , F.getLoanID ()));
911
933
}
934
+
935
+ bool isExpired (LoanID LID, ProgramPoint P) const {
936
+ return getState (P).Expired .contains (LID);
937
+ }
912
938
};
913
939
914
940
// ========================================================================= //
915
941
// 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.
920
943
// ========================================================================= //
921
944
} // anonymous namespace
922
945
0 commit comments