Skip to content

Commit

Permalink
[mlir] Allow overriding AbstractDenseDataFlowAnalysis::visitOperation
Browse files Browse the repository at this point in the history
AbstractDenseDataFlowAnalysis::visitOperation controls how the dataflow
analysis proceeds around control flow. In particular, conservative
assumptions are made about call operations which can prevent some
analysis from succeeding.

The motivating case for this change is https://reviews.llvm.org/D140415,
for which it is correct and necessary for the lattice to be preserved
after call operations.

Some renaming was necessary to avoid confusion with
DenseDataFlowAnalysis::visitOperation.
AbstractDenseDataFlowAnalysis::visitRegionBranchOperation and
DenseDataFlowAnalysis::visitOperationImpl are also made protected
to allow implementation of AbstractDenseDataFlowAnalysis::visitOperation,
although I did not need these to be virtual.

Differential Revision: https://reviews.llvm.org/D140879
  • Loading branch information
tblah committed Jan 4, 2023
1 parent ec48682 commit 5bedd67
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 10 deletions.
13 changes: 6 additions & 7 deletions mlir/include/mlir/Analysis/DataFlow/DenseAnalysis.h
Expand Up @@ -93,23 +93,23 @@ class AbstractDenseDataFlowAnalysis : public DataFlowAnalysis {
propagateIfChanged(lhs, lhs->join(rhs));
}

private:
/// Visit an operation. If this is a call operation or region control-flow
/// operation, then the state after the execution of the operation is set by
/// control-flow or the callgraph. Otherwise, this function invokes the
/// operation transfer function.
void visitOperation(Operation *op);

/// Visit a block. The state at the start of the block is propagated from
/// control-flow predecessors or callsites
void visitBlock(Block *block);
virtual void processOperation(Operation *op);

/// Visit a program point within a region branch operation with predecessors
/// in it. This can either be an entry block of one of the regions of the
/// parent operation itself.
void visitRegionBranchOperation(ProgramPoint point,
RegionBranchOpInterface branch,
AbstractDenseLattice *after);

private:
/// Visit a block. The state at the start of the block is propagated from
/// control-flow predecessors or callsites
void visitBlock(Block *block);
};

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -148,7 +148,6 @@ class DenseDataFlowAnalysis : public AbstractDenseDataFlowAnalysis {
setToEntryState(static_cast<LatticeT *>(lattice));
}

private:
/// Type-erased wrappers that convert the abstract dense lattice to a derived
/// lattice and invoke the virtual hooks operating on the derived lattice.
void visitOperationImpl(Operation *op, const AbstractDenseLattice &before,
Expand Down
6 changes: 3 additions & 3 deletions mlir/lib/Analysis/DataFlow/DenseAnalysis.cpp
Expand Up @@ -20,7 +20,7 @@ using namespace mlir::dataflow;

LogicalResult AbstractDenseDataFlowAnalysis::initialize(Operation *top) {
// Visit every operation and block.
visitOperation(top);
processOperation(top);
for (Region &region : top->getRegions()) {
for (Block &block : region) {
visitBlock(&block);
Expand All @@ -34,15 +34,15 @@ LogicalResult AbstractDenseDataFlowAnalysis::initialize(Operation *top) {

LogicalResult AbstractDenseDataFlowAnalysis::visit(ProgramPoint point) {
if (auto *op = point.dyn_cast<Operation *>())
visitOperation(op);
processOperation(op);
else if (auto *block = point.dyn_cast<Block *>())
visitBlock(block);
else
return failure();
return success();
}

void AbstractDenseDataFlowAnalysis::visitOperation(Operation *op) {
void AbstractDenseDataFlowAnalysis::processOperation(Operation *op) {
// If the containing block is not executable, bail out.
if (!getOrCreateFor<Executable>(op, op->getBlock())->isLive())
return;
Expand Down

0 comments on commit 5bedd67

Please sign in to comment.