14 #include "llvm/ADT/iterator.h"
15 #include "llvm/Config/abi-breaking.h"
16 #include "llvm/Support/Casting.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/raw_ostream.h"
20 #define DEBUG_TYPE "dataflow"
21 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
22 #define DATAFLOW_DEBUG(X) LLVM_DEBUG(X)
24 #define DATAFLOW_DEBUG(X)
43 auto inserted = dependents.insert({dependent, analysis});
47 llvm::dbgs() <<
"Creating dependency between " << debugName <<
" of "
48 <<
point <<
"\nand " << debugName <<
" on " << dependent
65 if (
auto *programPoint = llvm::dyn_cast<GenericProgramPoint *>(*
this))
66 return programPoint->print(os);
67 if (
auto *op = llvm::dyn_cast<Operation *>(*
this))
69 if (
auto value = llvm::dyn_cast<Value>(*
this))
71 return get<Block *>()->print(os);
75 if (
auto *programPoint = llvm::dyn_cast<GenericProgramPoint *>(*
this))
76 return programPoint->getLoc();
77 if (
auto *op = llvm::dyn_cast<Operation *>(*
this))
79 if (
auto value = llvm::dyn_cast<Value>(*
this))
80 return value.getLoc();
81 return get<Block *>()->getParent()->getLoc();
92 <<
"Priming analysis: " << analysis.debugName <<
"\n");
93 if (
failed(analysis.initialize(top)))
100 while (!worklist.empty()) {
101 auto [point, analysis] = worklist.front();
104 DATAFLOW_DEBUG(llvm::dbgs() <<
"Invoking '" << analysis->debugName
105 <<
"' on: " << point <<
"\n");
106 if (
failed(analysis->visit(point)))
112 }
while (!worklist.empty());
120 DATAFLOW_DEBUG(llvm::dbgs() <<
"Propagating update to " << state->debugName
121 <<
" of " << state->point <<
"\n"
122 <<
"Value: " << *state <<
"\n");
123 state->onUpdate(
this);
136 state->addDependency(point,
this);
#define DATAFLOW_DEBUG(X)
Base class for generic analysis states.
LLVM_DUMP_METHOD void dump() const
virtual void print(raw_ostream &os) const =0
Print the contents of the analysis state.
void addDependency(ProgramPoint dependent, DataFlowAnalysis *analysis)
Add a dependency to this analysis state on a program point and an analysis.
ProgramPoint point
The program point to which the state belongs.
Base class for all data-flow analyses.
void propagateIfChanged(AnalysisState *state, ChangeResult changed)
Propagate an update to a state if it changed.
virtual ~DataFlowAnalysis()
DataFlowAnalysis(DataFlowSolver &solver)
Create an analysis with a reference to the parent solver.
void addDependency(AnalysisState *state, ProgramPoint point)
Create a dependency between the given analysis state and program point on this analysis.
The general data-flow analysis solver.
void propagateIfChanged(AnalysisState *state, ChangeResult changed)
Propagate an update to an analysis state if it changed by pushing dependent work items to the back of...
LogicalResult initializeAndRun(Operation *top)
Initialize the children analyses starting from the provided top-level operation and run the analysis ...
virtual ~GenericProgramPoint()
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Set of flags used to control the behavior of the various IR print methods (e.g.
Operation is the basic unit of execution within MLIR.
void print(raw_ostream &os, const OpPrintingFlags &flags=std::nullopt)
Location getLoc()
The source location the operation was defined or derived from.
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
ChangeResult
A result type used to indicate if a change happened.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.
Fundamental IR components are supported as first-class program points.
Location getLoc() const
Get the source location of the program point.
void print(raw_ostream &os) const
Print the program point.