LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
DenseAnalysis.h
Go to the documentation of this file.
1//===-- DenseAnalysis.h - Dense data-flow analysis --------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8// Adapted from mlir/include/mlir/Analysis/DataFlow/DenseAnalysis.h.
9// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
10// See https://llvm.org/LICENSE.txt for license information.
11// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12//
13//===----------------------------------------------------------------------===//
27//===----------------------------------------------------------------------===//
28
29#pragma once
30
31#include <mlir/Analysis/DataFlow/DenseAnalysis.h>
32#include <mlir/Analysis/DataFlowFramework.h>
33#include <mlir/IR/SymbolTable.h>
34#include <mlir/Interfaces/CallInterfaces.h>
35#include <mlir/Interfaces/ControlFlowInterfaces.h>
36
37namespace llzk::dataflow {
38
39//===----------------------------------------------------------------------===//
40// AbstractDenseForwardDataFlowAnalysis
41//===----------------------------------------------------------------------===//
42
43using AbstractDenseLattice = mlir::dataflow::AbstractDenseLattice;
44using CallControlFlowAction = mlir::dataflow::CallControlFlowAction;
45
59class AbstractDenseForwardDataFlowAnalysis : public mlir::DataFlowAnalysis {
60public:
61 using mlir::DataFlowAnalysis::DataFlowAnalysis;
62
65 mlir::LogicalResult initialize(mlir::Operation *top) override;
66
74 mlir::LogicalResult visit(mlir::ProgramPoint *point) override;
75
76protected:
79 virtual mlir::LogicalResult visitOperationImpl(
80 mlir::Operation *op, const AbstractDenseLattice &before, AbstractDenseLattice *after
81 ) = 0;
82
84 virtual AbstractDenseLattice *getLattice(mlir::LatticeAnchor anchor) = 0;
85
91 getLatticeFor(mlir::ProgramPoint *dependent, mlir::LatticeAnchor anchor);
92
95 virtual void setToEntryState(AbstractDenseLattice *lattice) = 0;
96
99 propagateIfChanged(lhs, lhs->join(rhs));
100 }
101
106 virtual mlir::LogicalResult processOperation(mlir::Operation *op);
107
116 mlir::RegionBranchOpInterface /*branch*/, std::optional<unsigned> regionFrom,
117 std::optional<unsigned> regionTo, const AbstractDenseLattice &before,
119 ) {
120 join(after, before);
121 }
122
131 mlir::CallOpInterface /*call*/, CallControlFlowAction action,
132 const AbstractDenseLattice &before, AbstractDenseLattice *after
133 ) {
134 join(after, before);
135 // Note that `setToEntryState` may be a "partial fixpoint" for some
136 // lattices, e.g., lattices that are lists of maps of other lattices will
137 // only set fixpoint for "known" lattices.
138 if (action == CallControlFlowAction::ExternalCallee) {
139 setToEntryState(after);
140 }
141 }
142
147 mlir::ProgramPoint *point, mlir::RegionBranchOpInterface branch, AbstractDenseLattice *after
148 );
149
151 mlir::SymbolTableCollection tables;
152
153private:
156 void visitBlock(mlir::Block *block);
157
160 void visitCallOperation(
161 mlir::CallOpInterface call, const AbstractDenseLattice &before, AbstractDenseLattice *after
162 );
163};
164
165//===----------------------------------------------------------------------===//
166// DenseForwardDataFlowAnalysis
167//===----------------------------------------------------------------------===//
168
177template <typename LatticeT>
179 static_assert(
180 std::is_base_of<AbstractDenseLattice, LatticeT>::value,
181 "analysis state class expected to subclass AbstractDenseLattice"
182 );
183
184public:
185 using AbstractDenseForwardDataFlowAnalysis::AbstractDenseForwardDataFlowAnalysis;
186
190 virtual mlir::LogicalResult
191 visitOperation(mlir::Operation *op, const LatticeT &before, LatticeT *after) = 0;
192
209 mlir::CallOpInterface call, CallControlFlowAction action, const LatticeT &before,
210 LatticeT *after
211 ) {
213 }
214
239 mlir::RegionBranchOpInterface branch, std::optional<unsigned> regionFrom,
240 std::optional<unsigned> regionTo, const LatticeT &before, LatticeT *after
241 ) {
243 branch, regionFrom, regionTo, before, after
244 );
245 }
246
247protected:
249 LatticeT *getLattice(mlir::LatticeAnchor anchor) override {
250 return getOrCreate<LatticeT>(anchor);
251 }
252
255 virtual void setToEntryState(LatticeT *lattice) = 0;
256 void setToEntryState(AbstractDenseLattice *lattice) override {
257 setToEntryState(static_cast<LatticeT *>(lattice));
258 }
259
262 mlir::LogicalResult visitOperationImpl(
263 mlir::Operation *op, const AbstractDenseLattice &before, AbstractDenseLattice *after
264 ) final {
265 return visitOperation(
266 op, static_cast<const LatticeT &>(before), static_cast<LatticeT *>(after)
267 );
268 }
270 mlir::CallOpInterface call, CallControlFlowAction action, const AbstractDenseLattice &before,
272 ) final {
274 call, action, static_cast<const LatticeT &>(before), static_cast<LatticeT *>(after)
275 );
276 }
278 mlir::RegionBranchOpInterface branch, std::optional<unsigned> regionFrom,
279 std::optional<unsigned> regionTo, const AbstractDenseLattice &before,
281 ) final {
283 branch, regionFrom, regionTo, static_cast<const LatticeT &>(before),
284 static_cast<LatticeT *>(after)
285 );
286 }
287};
288
289} // namespace llzk::dataflow
LLZK: This class has been ported from the MLIR DenseAnalysis utilities to allow for the use of custom...
void join(AbstractDenseLattice *lhs, const AbstractDenseLattice &rhs)
Join a lattice with another and propagate an update if it changed.
virtual void visitCallControlFlowTransfer(mlir::CallOpInterface, CallControlFlowAction action, const AbstractDenseLattice &before, AbstractDenseLattice *after)
Propagate the dense lattice forward along the call control flow edge, which can be either entering or...
virtual mlir::LogicalResult processOperation(mlir::Operation *op)
Visit an operation.
virtual AbstractDenseLattice * getLattice(mlir::LatticeAnchor anchor)=0
Get the dense lattice on the given lattice anchor.
mlir::LogicalResult visit(mlir::ProgramPoint *point) override
Visit a program point that modifies the state of the program.
void visitRegionBranchOperation(mlir::ProgramPoint *point, mlir::RegionBranchOpInterface branch, AbstractDenseLattice *after)
Visit a program point within a region branch operation with predecessors in it.
mlir::SymbolTableCollection tables
LLZK: Added for use of symbol helper caching.
virtual void setToEntryState(AbstractDenseLattice *lattice)=0
Set the dense lattice at control flow entry point and propagate an update if it changed.
mlir::LogicalResult initialize(mlir::Operation *top) override
Initialize the analysis by visiting every program point whose execution may modify the program state;...
virtual void visitRegionBranchControlFlowTransfer(mlir::RegionBranchOpInterface, std::optional< unsigned > regionFrom, std::optional< unsigned > regionTo, const AbstractDenseLattice &before, AbstractDenseLattice *after)
Propagate the dense lattice forward along the control flow edge from regionFrom to regionTo regions o...
const AbstractDenseLattice * getLatticeFor(mlir::ProgramPoint *dependent, mlir::LatticeAnchor anchor)
Get the dense lattice on the given lattice anchor and add dependent as its dependency.
virtual mlir::LogicalResult visitOperationImpl(mlir::Operation *op, const AbstractDenseLattice &before, AbstractDenseLattice *after)=0
Propagate the dense lattice before the execution of an operation to the lattice after its execution.
LLZK: This class has been ported so that it can inherit from our port of the AbstractDenseForwardData...
void visitCallControlFlowTransfer(mlir::CallOpInterface call, CallControlFlowAction action, const AbstractDenseLattice &before, AbstractDenseLattice *after) final
Propagate the dense lattice forward along the call control flow edge, which can be either entering or...
void setToEntryState(AbstractDenseLattice *lattice) override
Set the dense lattice at control flow entry point and propagate an update if it changed.
mlir::LogicalResult visitOperationImpl(mlir::Operation *op, const AbstractDenseLattice &before, AbstractDenseLattice *after) final
Type-erased wrappers that convert the abstract dense lattice to a derived lattice and invoke the virt...
virtual mlir::LogicalResult visitOperation(mlir::Operation *op, const LatticeT &before, LatticeT *after)=0
Visit an operation with the dense lattice before its execution.
virtual void setToEntryState(LatticeT *lattice)=0
Set the dense lattice at control flow entry point and propagate an update if it changed.
LatticeT * getLattice(mlir::LatticeAnchor anchor) override
Get the dense lattice on this lattice anchor.
virtual void visitCallControlFlowTransfer(mlir::CallOpInterface call, CallControlFlowAction action, const LatticeT &before, LatticeT *after)
Hook for customizing the behavior of lattice propagation along the call control flow edges.
virtual void visitRegionBranchControlFlowTransfer(mlir::RegionBranchOpInterface branch, std::optional< unsigned > regionFrom, std::optional< unsigned > regionTo, const LatticeT &before, LatticeT *after)
Hook for customizing the behavior of lattice propagation along the control flow edges between regions...
void visitRegionBranchControlFlowTransfer(mlir::RegionBranchOpInterface branch, std::optional< unsigned > regionFrom, std::optional< unsigned > regionTo, const AbstractDenseLattice &before, AbstractDenseLattice *after) final
Propagate the dense lattice forward along the control flow edge from regionFrom to regionTo regions o...
mlir::dataflow::AbstractDenseLattice AbstractDenseLattice
mlir::dataflow::CallControlFlowAction CallControlFlowAction