@@ -502,6 +502,12 @@ class FactGenerator : public ConstStmtVisitor<FactGenerator> {
502
502
503
503
enum class Direction { Forward, Backward };
504
504
505
+ // / A program point is a pair of a CFGBlock and a Fact within that block.
506
+ // /
507
+ // / This is used to represent the state of the program *after* the Fact is
508
+ // / executed.
509
+ using ProgramPoint = std::pair<const CFGBlock *, const Fact *>;
510
+
505
511
// / A generic, policy-based driver for dataflow analyses. It combines
506
512
// / the dataflow runner and the transferer logic into a single class hierarchy.
507
513
// /
@@ -532,6 +538,7 @@ class DataflowAnalysis {
532
538
533
539
llvm::DenseMap<const CFGBlock *, Lattice> InStates;
534
540
llvm::DenseMap<const CFGBlock *, Lattice> OutStates;
541
+ llvm::DenseMap<ProgramPoint, Lattice> PerPointStates;
535
542
536
543
static constexpr bool isForward () { return Dir == Direction::Forward; }
537
544
@@ -577,6 +584,8 @@ class DataflowAnalysis {
577
584
}
578
585
}
579
586
587
+ Lattice getState (ProgramPoint P) const { return PerPointStates.lookup (P); }
588
+
580
589
Lattice getInState (const CFGBlock *B) const { return InStates.lookup (B); }
581
590
582
591
Lattice getOutState (const CFGBlock *B) const { return OutStates.lookup (B); }
@@ -590,18 +599,22 @@ class DataflowAnalysis {
590
599
getOutState (&B).dump (llvm::dbgs ());
591
600
}
592
601
602
+ private:
593
603
// / Computes the state at one end of a block by applying all its facts
594
604
// / 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
605
Lattice transferBlock (const CFGBlock *Block, Lattice State) {
598
606
auto Facts = AllFacts.getFacts (Block);
599
- if constexpr (isForward ())
600
- for (const Fact *F : Facts)
607
+ if constexpr (isForward ()) {
608
+ for (const Fact *F : Facts) {
601
609
State = transferFact (State, F);
602
- else
603
- for (const Fact *F : llvm::reverse (Facts))
610
+ PerPointStates[{Block, F}] = State;
611
+ }
612
+ } else {
613
+ for (const Fact *F : llvm::reverse (Facts)) {
604
614
State = transferFact (State, F);
615
+ PerPointStates[{Block, F}] = State;
616
+ }
617
+ }
605
618
return State;
606
619
}
607
620
@@ -769,6 +782,10 @@ class LoanPropagationAnalysis
769
782
Factory.OriginMapFactory .add (In.Origins , DestOID, SrcLoans));
770
783
}
771
784
785
+ LoanSet getLoans (OriginID OID, ProgramPoint P) {
786
+ return getLoans (getState (P), OID);
787
+ }
788
+
772
789
private:
773
790
LoanSet getLoans (Lattice L, OriginID OID) {
774
791
if (auto *Loans = L.Origins .lookup (OID))
@@ -779,7 +796,6 @@ class LoanPropagationAnalysis
779
796
780
797
// ========================================================================= //
781
798
// TODO:
782
- // - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
783
799
// - Modify loan expiry analysis to answer `bool isExpired(Loan L, Point P)`
784
800
// - Modify origin liveness analysis to answer `bool isLive(Origin O, Point P)`
785
801
// - Using the above three to perform the final error reporting.
0 commit comments