15 #ifndef MLIR_ANALYSIS_DATAFLOW_SPARSEANALYSIS_H
16 #define MLIR_ANALYSIS_DATAFLOW_SPARSEANALYSIS_H
22 #include "llvm/ADT/SmallPtrSet.h"
62 useDefSubscribers.insert(analysis);
84 template <
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,
143 std::enable_if_t<lattice_has_meet<VT>::value> * =
nullptr>
145 ValueT newValue = ValueT::meet(value, rhs);
146 assert(ValueT::meet(newValue, value) == newValue &&
147 "expected `meet` to be monotonic");
148 assert(ValueT::meet(newValue, rhs) == newValue &&
149 "expected `meet` to be monotonic");
152 if (newValue == value)
159 template <
typename VT,
160 std::enable_if_t<!lattice_has_meet<VT>::value> * =
nullptr>
166 void print(raw_ostream &os)
const override { value.print(os); }
204 virtual LogicalResult
211 CallOpInterface call,
240 LogicalResult initializeRecursively(
Operation *op);
245 LogicalResult visitOperation(
Operation *op);
252 void visitBlock(
Block *block);
259 RegionBranchOpInterface branch,
272 template <
typename StateT>
276 std::is_base_of<AbstractSparseLattice, StateT>::value,
277 "analysis state class expected to subclass AbstractSparseLattice");
306 unsigned firstIndex) {
315 return getOrCreate<StateT>(value);
321 return static_cast<const StateT *
>(
337 LogicalResult visitOperationImpl(
342 {
reinterpret_cast<const StateT *
const *
>(operandLattices.begin()),
343 operandLattices.size()},
344 {
reinterpret_cast<StateT *
const *
>(resultLattices.begin()),
345 resultLattices.size()});
347 void visitExternalCallImpl(
348 CallOpInterface call,
349 ArrayRef<const AbstractSparseLattice *> argumentLattices,
350 ArrayRef<AbstractSparseLattice *> resultLattices)
override {
353 {
reinterpret_cast<const StateT *
const *
>(argumentLattices.begin()),
354 argumentLattices.size()},
355 {
reinterpret_cast<StateT *
const *
>(resultLattices.begin()),
356 resultLattices.size()});
358 void visitNonControlFlowArgumentsImpl(
359 Operation *op,
const RegionSuccessor &successor,
360 ArrayRef<AbstractSparseLattice *> argLattices,
361 unsigned firstIndex)
override {
364 {
reinterpret_cast<StateT *
const *
>(argLattices.begin()),
428 LogicalResult initializeRecursively(
Operation *op);
433 LogicalResult visitOperation(
Operation *op);
436 void visitBlock(
Block *block);
439 void visitRegionSuccessors(RegionBranchOpInterface branch,
446 void visitRegionSuccessorsFromTerminator(
447 RegionBranchTerminatorOpInterface terminator,
448 RegionBranchOpInterface branch);
477 template <
typename StateT>
497 (void)argumentLattices;
498 (void)resultLattices;
499 for (
OpOperand &operand : call->getOpOperands()) {
507 return getOrCreate<StateT>(value);
524 LogicalResult visitOperationImpl(
529 {
reinterpret_cast<StateT *
const *
>(operandLattices.begin()),
530 operandLattices.size()},
531 {
reinterpret_cast<const StateT *
const *
>(resultLattices.begin()),
532 resultLattices.size()});
535 void visitExternalCallImpl(
536 CallOpInterface call, ArrayRef<AbstractSparseLattice *> operandLattices,
537 ArrayRef<const AbstractSparseLattice *> resultLattices)
override {
540 {
reinterpret_cast<StateT *
const *
>(operandLattices.begin()),
541 operandLattices.size()},
542 {
reinterpret_cast<const StateT *
const *
>(resultLattices.begin()),
543 resultLattices.size()});
Base class for generic analysis states.
LatticeAnchor getAnchor() const
Returns the lattice anchor this state is located at.
LatticeAnchor anchor
The lattice anchor to which the state belongs.
Block represents an ordered list of Operations.
Base class for all data-flow analyses.
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 point being branched from in the methods of the RegionBranchOpInterface.
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...
Base class for sparse backward data-flow analyses.
virtual void setToExitState(AbstractSparseLattice *lattice)=0
Set the given lattice element(s) at control flow exit point(s).
SmallVector< AbstractSparseLattice * > getLatticeElements(ValueRange values)
Get the lattice elements for a range of values.
AbstractSparseBackwardDataFlowAnalysis(DataFlowSolver &solver, SymbolTableCollection &symbolTable)
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 void visitExternalCallImpl(CallOpInterface call, ArrayRef< AbstractSparseLattice * > operandLattices, ArrayRef< const AbstractSparseLattice * > resultLattices)=0
The transfer function for calls to external functions.
virtual AbstractSparseLattice * getLatticeElement(Value value)=0
Get the lattice element for a value.
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).
virtual LogicalResult visitOperationImpl(Operation *op, ArrayRef< AbstractSparseLattice * > operandLattices, ArrayRef< const AbstractSparseLattice * > resultLattices)=0
The operation transfer function.
Base class for sparse forward data-flow analyses.
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 AbstractSparseLattice * getLatticeElement(Value value)=0
Get the lattice element of a value.
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 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.
Value getAnchor() const
Return the value this lattice is located at.
void print(raw_ostream &os) const override
Print the lattice element.
ChangeResult meet(const VT &rhs)
Meet (intersect) the information contained in the 'rhs' value with this lattice.
decltype(&T::meet) has_meet
Trait to check if T provides a meet method.
const ValueT & getValue() const
ValueT & getValue()
Return the value held by this lattice.
llvm::is_detected< has_meet, T > lattice_has_meet
ChangeResult join(const AbstractSparseLattice &rhs) override
Join the information contained in the 'rhs' lattice into this lattice.
ChangeResult meet(const AbstractSparseLattice &rhs) override
Meet (intersect) the information contained in the 'rhs' lattice with this lattice.
A sparse (backward) data-flow analysis for propagating SSA value lattices backwards across the IR by ...
StateT * getLatticeElement(Value value) override
Get the lattice element for a value.
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).
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.
A sparse forward data-flow analysis for propagating SSA value lattices across the IR by implementing ...
const StateT * getLatticeElementFor(ProgramPoint *point, Value value)
Get the lattice element for a value and create a dependency on the provided program point.
virtual LogicalResult visitOperation(Operation *op, ArrayRef< const StateT * > operands, ArrayRef< StateT * > results)=0
Visit an operation with the lattices of its operands.
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.
StateT * getLatticeElement(Value value) override
Get the lattice element for a value.
virtual void setToEntryState(StateT *lattice)=0
Set the given lattice element(s) at control flow entry point(s).
void setAllToEntryStates(ArrayRef< StateT * > lattices)
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.
Program point represents a specific location in the execution of a program.