@@ -127,6 +127,18 @@ class AbstractDenseForwardDataFlowAnalysis : public DataFlowAnalysis {
127127 // / them into the same equivalent class.
128128 virtual void buildOperationEquivalentLatticeAnchor (Operation *op) {}
129129
130+ // / Visit a block and propagate the dense lattice forward along the control
131+ // / flow edge from predecessor to block. `point` corresponds to the program
132+ // / point before `block`. The default implementation merges in the state from
133+ // / the predecessor's terminator.
134+ virtual void visitBlockTransfer (Block *block, ProgramPoint *point,
135+ Block *predecessor,
136+ const AbstractDenseLattice &before,
137+ AbstractDenseLattice *after) {
138+ // Merge in the state from the predecessor's terminator.
139+ join (after, before);
140+ }
141+
130142 // / Propagate the dense lattice forward along the control flow edge from
131143 // / `regionFrom` to `regionTo` regions of the `branch` operation. `nullopt`
132144 // / values correspond to control flow branches originating at or targeting the
@@ -259,6 +271,22 @@ class DenseForwardDataFlowAnalysis
259271 branch, regionFrom, regionTo, before, after);
260272 }
261273
274+ // / Hook for customizing the behavior of lattice propagation along the control
275+ // / flow edges between blocks. The control flows from `predecessor` to
276+ // / `block`. The lattice is propagated forward along this edge. The lattices
277+ // / are as follows:
278+ // / - `before` is the lattice at the end of the predecessor block;
279+ // / - `after` is the lattice at the beginning of the block.
280+ // / By default, the `after` state is simply joined with the `before` state.
281+ // / Concrete analyses can override this behavior or delegate to the parent
282+ // / call for the default behavior.
283+ virtual void visitBlockTransfer (Block *block, ProgramPoint *point,
284+ Block *predecessor, const LatticeT &before,
285+ LatticeT *after) {
286+ AbstractDenseForwardDataFlowAnalysis::visitBlockTransfer (
287+ block, point, predecessor, before, after);
288+ }
289+
262290protected:
263291 // / Get the dense lattice on this lattice anchor.
264292 LatticeT *getLattice (LatticeAnchor anchor) override {
@@ -306,6 +334,13 @@ class DenseForwardDataFlowAnalysis
306334 static_cast <const LatticeT &>(before),
307335 static_cast <LatticeT *>(after));
308336 }
337+ void visitBlockTransfer (Block *block, ProgramPoint *point, Block *predecessor,
338+ const AbstractDenseLattice &before,
339+ AbstractDenseLattice *after) final {
340+ visitBlockTransfer (block, point, predecessor,
341+ static_cast <const LatticeT &>(before),
342+ static_cast <LatticeT *>(after));
343+ }
309344};
310345
311346// ===----------------------------------------------------------------------===//
@@ -388,6 +423,17 @@ class AbstractDenseBackwardDataFlowAnalysis : public DataFlowAnalysis {
388423 // / them into the same equivalent class.
389424 virtual void buildOperationEquivalentLatticeAnchor (Operation *op) {}
390425
426+ // / Visit a block and propagate the dense lattice backward along the control
427+ // / flow edge from successor to block. `point` corresponds to the program
428+ // / point after `block`. The default implementation merges in the state from
429+ // / the successor's first operation or the block itself when empty.
430+ virtual void visitBlockTransfer (Block *block, ProgramPoint *point,
431+ Block *successor,
432+ const AbstractDenseLattice &after,
433+ AbstractDenseLattice *before) {
434+ meet (before, after);
435+ }
436+
391437 // / Propagate the dense lattice backwards along the control flow edge from
392438 // / `regionFrom` to `regionTo` regions of the `branch` operation. `nullopt`
393439 // / values correspond to control flow branches originating at or targeting the
@@ -531,6 +577,22 @@ class DenseBackwardDataFlowAnalysis
531577 branch, regionFrom, regionTo, after, before);
532578 }
533579
580+ // / Hook for customizing the behavior of lattice propagation along the control
581+ // / flow edges between blocks. The control flows from `successor` to
582+ // / `block`. The lattice is propagated back along this edge. The lattices
583+ // / are as follows:
584+ // / - `after` is the lattice at the beginning of the successor block;
585+ // / - `before` is the lattice at the end of the block.
586+ // / By default, the `before` state is simply met with the `after` state.
587+ // / Concrete analyses can override this behavior or delegate to the parent
588+ // / call for the default behavior.
589+ virtual void visitBlockTransfer (Block *block, ProgramPoint *point,
590+ Block *successor, const LatticeT &after,
591+ LatticeT *before) {
592+ AbstractDenseBackwardDataFlowAnalysis::visitBlockTransfer (
593+ block, point, successor, after, before);
594+ }
595+
534596protected:
535597 // / Get the dense lattice at the given lattice anchor.
536598 LatticeT *getLattice (LatticeAnchor anchor) override {
@@ -577,6 +639,13 @@ class DenseBackwardDataFlowAnalysis
577639 static_cast <const LatticeT &>(after),
578640 static_cast <LatticeT *>(before));
579641 }
642+ void visitBlockTransfer (Block *block, ProgramPoint *point, Block *successor,
643+ const AbstractDenseLattice &after,
644+ AbstractDenseLattice *before) final {
645+ visitBlockTransfer (block, point, successor,
646+ static_cast <const LatticeT &>(after),
647+ static_cast <LatticeT *>(before));
648+ }
580649};
581650
582651} // end namespace dataflow
0 commit comments