15#ifndef MLIR_ANALYSIS_DATAFLOW_SPARSEANALYSIS_H
16#define MLIR_ANALYSIS_DATAFLOW_SPARSEANALYSIS_H
22#include "llvm/ADT/SmallPtrSet.h"
62 useDefSubscribers.insert(analysis);
84template <
typename ValueT>
117 ValueT newValue = ValueT::join(value,
rhs);
118 assert(ValueT::join(newValue, value) == newValue &&
119 "expected `join` to be monotonic");
120 assert(ValueT::join(newValue,
rhs) == newValue &&
121 "expected `join` to be monotonic");
124 if (newValue == value)
134 template <
typename T,
typename... Args>
136 template <
typename T>
142 template <
typename VT>
147 ValueT newValue = ValueT::meet(value,
rhs);
148 assert(ValueT::meet(newValue, value) == newValue &&
149 "expected `meet` to be monotonic");
150 assert(ValueT::meet(newValue,
rhs) == newValue &&
151 "expected `meet` to be monotonic");
154 if (newValue == value)
201 virtual LogicalResult
208 CallOpInterface call,
245 virtual LogicalResult
261 LogicalResult initializeRecursively(
Operation *op);
266 LogicalResult visitOperation(
Operation *op);
273 void visitBlock(
Block *block);
285 visitRegionSuccessors(
ProgramPoint *point, RegionBranchOpInterface branch,
298template <
typename StateT>
302 std::is_base_of<AbstractSparseLattice, StateT>::value,
303 "analysis state class expected to subclass AbstractSparseLattice");
332 unsigned firstIndex) {
347 return static_cast<const StateT *
>(
363 LogicalResult visitOperationImpl(
368 {
reinterpret_cast<const StateT *
const *
>(operandLattices.begin()),
369 operandLattices.size()},
370 {
reinterpret_cast<StateT *
const *
>(resultLattices.begin()),
371 resultLattices.size()});
373 void visitExternalCallImpl(
374 CallOpInterface call,
375 ArrayRef<const AbstractSparseLattice *> argumentLattices,
376 ArrayRef<AbstractSparseLattice *> resultLattices)
override {
379 {
reinterpret_cast<const StateT *
const *
>(argumentLattices.begin()),
380 argumentLattices.size()},
381 {
reinterpret_cast<StateT *
const *
>(resultLattices.begin()),
382 resultLattices.size()});
384 void visitNonControlFlowArgumentsImpl(
385 Operation *op,
const RegionSuccessor &successor,
386 ArrayRef<AbstractSparseLattice *> argLattices,
387 unsigned firstIndex)
override {
390 {
reinterpret_cast<StateT *
const *
>(argLattices.begin()),
460 virtual LogicalResult
466 LogicalResult initializeRecursively(
Operation *op);
471 LogicalResult visitOperation(
Operation *op);
474 void visitBlock(
Block *block);
477 void visitRegionSuccessors(RegionBranchOpInterface branch,
484 void visitRegionSuccessorsFromTerminator(
485 RegionBranchTerminatorOpInterface terminator,
486 RegionBranchOpInterface branch);
515template <
typename StateT>
519 std::is_base_of<AbstractSparseLattice, StateT>::value,
520 "analysis state class expected to subclass AbstractSparseLattice");
539 (
void)argumentLattices;
540 (
void)resultLattices;
541 for (
OpOperand &operand : call->getOpOperands()) {
566 LogicalResult visitOperationImpl(
571 {
reinterpret_cast<StateT *
const *
>(operandLattices.begin()),
572 operandLattices.size()},
573 {
reinterpret_cast<const StateT *
const *
>(resultLattices.begin()),
574 resultLattices.size()});
577 void visitExternalCallImpl(
578 CallOpInterface call, ArrayRef<AbstractSparseLattice *> operandLattices,
579 ArrayRef<const AbstractSparseLattice *> resultLattices)
override {
582 {
reinterpret_cast<StateT *
const *
>(operandLattices.begin()),
583 operandLattices.size()},
584 {
reinterpret_cast<const StateT *
const *
>(resultLattices.begin()),
585 resultLattices.size()});
LatticeAnchor getAnchor() const
Returns the lattice anchor this state is located at.
AnalysisState(LatticeAnchor anchor)
Create the analysis state on the given lattice anchor.
LatticeAnchor anchor
The lattice anchor to which the state belongs.
Block represents an ordered list of Operations.
Base class for all data-flow analyses.
StateT * getOrCreate(AnchorT anchor)
Get the analysis state associated with the lattice anchor.
DataFlowAnalysis(DataFlowSolver &solver)
Create an analysis with a reference to the parent solver.
friend class DataFlowSolver
Allow the data-flow solver to access the internals of this class.
The general data-flow analysis solver.
This class represents an operand of an operation.
Operation is the basic unit of execution within MLIR.
This class represents a successor of a region.
ValueRange getSuccessorInputs() const
Return the inputs to the successor that are remapped by the exit values of the current region.
This class represents a collection of SymbolTables.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
virtual void setToExitState(AbstractSparseLattice *lattice)=0
Set the given lattice element(s) at control flow exit point(s) and propagate the update if it chaned.
SmallVector< AbstractSparseLattice * > getLatticeElements(ValueRange values)
Get the lattice elements for a range of values.
AbstractSparseBackwardDataFlowAnalysis(DataFlowSolver &solver, SymbolTableCollection &symbolTable)
virtual AbstractSparseLattice * getLatticeElement(Value value)=0
Get the lattice element for a value.
virtual void visitBranchOperand(OpOperand &operand)=0
virtual void visitCallOperand(OpOperand &operand)=0
LogicalResult visit(ProgramPoint *point) override
Visit a program point.
void meet(AbstractSparseLattice *lhs, const AbstractSparseLattice &rhs)
Join the lattice element and propagate and update if it changed.
virtual LogicalResult visitCallableOperation(Operation *op, CallableOpInterface callable, ArrayRef< AbstractSparseLattice * > operandLattices)
Visits a callable operation.
virtual void visitExternalCallImpl(CallOpInterface call, ArrayRef< AbstractSparseLattice * > operandLattices, ArrayRef< const AbstractSparseLattice * > resultLattices)=0
The transfer function for calls to external functions.
LogicalResult initialize(Operation *top) override
Initialize the analysis by visiting the operation and everything nested under it.
void setAllToExitStates(ArrayRef< AbstractSparseLattice * > lattices)
Set the given lattice element(s) at control flow exit point(s) and propagate the update if it chaned.
virtual LogicalResult visitOperationImpl(Operation *op, ArrayRef< AbstractSparseLattice * > operandLattices, ArrayRef< const AbstractSparseLattice * > resultLattices)=0
The operation transfer function.
LogicalResult visit(ProgramPoint *point) override
Visit a program point.
LogicalResult initialize(Operation *top) override
Initialize the analysis by visiting every owner of an SSA value: all operations and blocks.
virtual void visitExternalCallImpl(CallOpInterface call, ArrayRef< const AbstractSparseLattice * > argumentLattices, ArrayRef< AbstractSparseLattice * > resultLattices)=0
The transfer function for calls to external functions.
AbstractSparseForwardDataFlowAnalysis(DataFlowSolver &solver)
void setAllToEntryStates(ArrayRef< AbstractSparseLattice * > lattices)
virtual void setToEntryState(AbstractSparseLattice *lattice)=0
Set the given lattice element(s) at control flow entry point(s).
const AbstractSparseLattice * getLatticeElementFor(ProgramPoint *point, Value value)
Get a read-only lattice element for a value and add it as a dependency to a program point.
virtual void visitNonControlFlowArgumentsImpl(Operation *op, const RegionSuccessor &successor, ArrayRef< AbstractSparseLattice * > argLattices, unsigned firstIndex)=0
Given an operation with region control-flow, the lattices of the operands, and a region successor,...
virtual LogicalResult visitCallOperation(CallOpInterface call, ArrayRef< const AbstractSparseLattice * > operandLattices, ArrayRef< AbstractSparseLattice * > resultLattices)
Visits a call operation.
virtual void visitCallableOperation(CallableOpInterface callable, ArrayRef< AbstractSparseLattice * > argLattices)
Visits a callable operation.
virtual AbstractSparseLattice * getLatticeElement(Value value)=0
Get the lattice element of a value.
virtual LogicalResult visitOperationImpl(Operation *op, ArrayRef< const AbstractSparseLattice * > operandLattices, ArrayRef< AbstractSparseLattice * > resultLattices)=0
The operation transfer function.
void join(AbstractSparseLattice *lhs, const AbstractSparseLattice &rhs)
Join the lattice element and propagate and update if it changed.
This class represents an abstract lattice.
void onUpdate(DataFlowSolver *solver) const override
When the lattice gets updated, propagate an update to users of the value using its use-def chain to s...
virtual ChangeResult join(const AbstractSparseLattice &rhs)
Join the information contained in 'rhs' into this lattice.
virtual ChangeResult meet(const AbstractSparseLattice &rhs)
Meet (intersect) the information in this lattice with 'rhs'.
Value getAnchor() const
Return the value this lattice is located at.
void useDefSubscribe(DataFlowAnalysis *analysis)
Subscribe an analysis to updates of the lattice.
AbstractSparseLattice(Value value)
Lattices can only be created for values.
This class represents a lattice holding a specific value of type ValueT.
ChangeResult join(const ValueT &rhs)
Join the information contained in the 'rhs' value into this lattice.
ValueT & getValue()
Return the value held by this lattice.
Value getAnchor() const
Return the value this lattice is located at.
void print(raw_ostream &os) const override
Print the lattice element.
decltype(&T::meet) has_meet
Trait to check if T provides a meet method.
llvm::is_detected< has_meet, T > lattice_has_meet
const ValueT & getValue() const
ChangeResult join(const AbstractSparseLattice &rhs) override
Join the information contained in the 'rhs' lattice into this lattice.
Lattice< ValueT > LatticeT
ChangeResult meet(const AbstractSparseLattice &rhs) override
Meet (intersect) the information contained in the 'rhs' lattice with this lattice.
AbstractSparseLattice(Value value)
Lattices can only be created for values.
ChangeResult meet(const VT &rhs)
Meet (intersect) the information contained in the 'rhs' value with this lattice.
void setAllToExitStates(ArrayRef< StateT * > lattices)
virtual void visitExternalCall(CallOpInterface call, ArrayRef< StateT * > argumentLattices, ArrayRef< const StateT * > resultLattices)
Visit a call to an external function.
void setToExitState(AbstractSparseLattice *lattice) override
Set the given lattice element(s) at control flow exit point(s) and propagate the update if it chaned.
SparseBackwardDataFlowAnalysis(DataFlowSolver &solver, SymbolTableCollection &symbolTable)
virtual void setToExitState(StateT *lattice)=0
Set the given lattice element(s) at control flow exit point(s).
virtual LogicalResult visitOperation(Operation *op, ArrayRef< StateT * > operands, ArrayRef< const StateT * > results)=0
Visit an operation with the lattices of its results.
StateT * getLatticeElement(Value value) override
Get the lattice element for a value.
virtual LogicalResult visitOperation(Operation *op, ArrayRef< const StateT * > operands, ArrayRef< StateT * > results)=0
Visit an operation with the lattices of its operands.
StateT * getLatticeElement(Value value) override
Get the lattice element for a value.
virtual void visitExternalCall(CallOpInterface call, ArrayRef< const StateT * > argumentLattices, ArrayRef< StateT * > resultLattices)
Visit a call operation to an externally defined function given the lattices of its arguments.
virtual void setToEntryState(StateT *lattice)=0
Set the given lattice element(s) at control flow entry point(s).
void setAllToEntryStates(ArrayRef< StateT * > lattices)
const StateT * getLatticeElementFor(ProgramPoint *point, Value value)
Get the lattice element for a value and create a dependency on the provided program point.
virtual void visitNonControlFlowArguments(Operation *op, const RegionSuccessor &successor, ArrayRef< StateT * > argLattices, unsigned firstIndex)
Given an operation with possible region control-flow, the lattices of the operands,...
SparseForwardDataFlowAnalysis(DataFlowSolver &solver)
Include the generated interface declarations.
ChangeResult
A result type used to indicate if a change happened.
llvm::SetVector< T, Vector, Set, N > SetVector
Program point represents a specific location in the execution of a program.