@@ -127,6 +127,19 @@ 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, *getLatticeFor (
140+ point, getProgramPointAfter (predecessor->getTerminator ())));
141+ }
142+
130143 // / Propagate the dense lattice forward along the control flow edge from
131144 // / `regionFrom` to `regionTo` regions of the `branch` operation. `nullopt`
132145 // / values correspond to control flow branches originating at or targeting the
@@ -259,6 +272,22 @@ class DenseForwardDataFlowAnalysis
259272 branch, regionFrom, regionTo, before, after);
260273 }
261274
275+ // / Hook for customizing the behavior of lattice propagation along the control
276+ // / flow edges between blocks. The control flows from `predecessor` to
277+ // / `block`. The lattice is propagated forward along this edge. The lattices
278+ // / are as follows:
279+ // / - `before` is the lattice at the end of the predecessor block;
280+ // / - `after` is the lattice at the beginning of the block.
281+ // / By default, the `after` state is simply joined with the `before` state.
282+ // / Concrete analyses can override this behavior or delegate to the parent
283+ // / call for the default behavior.
284+ virtual void visitBlockTransfer (Block *block, ProgramPoint *point,
285+ Block *predecessor, const LatticeT &before,
286+ LatticeT *after) {
287+ AbstractDenseForwardDataFlowAnalysis::visitBlockTransfer (
288+ block, point, predecessor, before, after);
289+ }
290+
262291protected:
263292 // / Get the dense lattice on this lattice anchor.
264293 LatticeT *getLattice (LatticeAnchor anchor) override {
@@ -306,6 +335,13 @@ class DenseForwardDataFlowAnalysis
306335 static_cast <const LatticeT &>(before),
307336 static_cast <LatticeT *>(after));
308337 }
338+ void visitBlockTransfer (Block *block, ProgramPoint *point, Block *predecessor,
339+ const AbstractDenseLattice &before,
340+ AbstractDenseLattice *after) final {
341+ visitBlockTransfer (block, point, predecessor,
342+ static_cast <const LatticeT &>(before),
343+ static_cast <LatticeT *>(after));
344+ }
309345};
310346
311347// ===----------------------------------------------------------------------===//
@@ -388,6 +424,17 @@ class AbstractDenseBackwardDataFlowAnalysis : public DataFlowAnalysis {
388424 // / them into the same equivalent class.
389425 virtual void buildOperationEquivalentLatticeAnchor (Operation *op) {}
390426
427+ // / Visit a block and propagate the dense lattice backward along the control
428+ // / flow edge from successor to block. `point` corresponds to the program
429+ // / point after `block`. The default implementation merges in the state from
430+ // / the successor's first operation or the block itself when empty.
431+ virtual void visitBlockTransfer (Block *block, ProgramPoint *point,
432+ Block *successor,
433+ const AbstractDenseLattice &after,
434+ AbstractDenseLattice *before) {
435+ meet (before, *getLatticeFor (point, getProgramPointBefore (successor)));
436+ }
437+
391438 // / Propagate the dense lattice backwards along the control flow edge from
392439 // / `regionFrom` to `regionTo` regions of the `branch` operation. `nullopt`
393440 // / values correspond to control flow branches originating at or targeting the
@@ -531,6 +578,22 @@ class DenseBackwardDataFlowAnalysis
531578 branch, regionFrom, regionTo, after, before);
532579 }
533580
581+ // / Hook for customizing the behavior of lattice propagation along the control
582+ // / flow edges between blocks. The control flows from `successor` to
583+ // / `block`. The lattice is propagated back along this edge. The lattices
584+ // / are as follows:
585+ // / - `after` is the lattice at the beginning of the successor block;
586+ // / - `before` is the lattice at the end of the block.
587+ // / By default, the `before` state is simply met with the `after` state.
588+ // / Concrete analyses can override this behavior or delegate to the parent
589+ // / call for the default behavior.
590+ virtual void visitBlockTransfer (Block *block, ProgramPoint *point,
591+ Block *successor, const LatticeT &after,
592+ LatticeT *before) {
593+ AbstractDenseBackwardDataFlowAnalysis::visitBlockTransfer (
594+ block, point, successor, after, before);
595+ }
596+
534597protected:
535598 // / Get the dense lattice at the given lattice anchor.
536599 LatticeT *getLattice (LatticeAnchor anchor) override {
@@ -577,6 +640,13 @@ class DenseBackwardDataFlowAnalysis
577640 static_cast <const LatticeT &>(after),
578641 static_cast <LatticeT *>(before));
579642 }
643+ void visitBlockTransfer (Block *block, ProgramPoint *point, Block *successor,
644+ const AbstractDenseLattice &after,
645+ AbstractDenseLattice *before) final {
646+ visitBlockTransfer (block, point, successor,
647+ static_cast <const LatticeT &>(after),
648+ static_cast <LatticeT *>(before));
649+ }
580650};
581651
582652} // end namespace dataflow
0 commit comments