31#include <mlir/IR/BuiltinOps.h>
32#include <mlir/Pass/AnalysisManager.h>
48 structDefOp = mlir::dyn_cast<component::StructDefOp>(op);
50 auto error_message =
"StructAnalysis expects provided op to be a StructDefOp!";
51 op->emitError(error_message);
52 llvm::report_fatal_error(error_message);
55 if (mlir::failed(maybeModOp)) {
56 auto error_message =
"StructAnalysis could not find root module from StructDefOp!";
57 op->emitError(error_message);
58 llvm::report_fatal_error(error_message);
76 mlir::DataFlowSolver &solver, mlir::AnalysisManager &moduleAnalysisManager, Context &ctx
84 ensure(
constructed(), mlir::Twine(__PRETTY_FUNCTION__) +
": result has not been constructed");
96 void setResult(Result &&r) { res = std::make_unique<Result>(r); }
101 std::unique_ptr<Result> res;
109template <
typename Analysis,
typename Result,
typename Context>
111 requires {
requires std::is_base_of<StructAnalysis<Result, Context>, Analysis>::value; };
119template <
typename Result,
typename Context, StructAnalysisType<Result, Context> StructAnalysisTy>
123 using ResultMap = std::map<
133 if (modOp = mlir::dyn_cast<mlir::ModuleOp>(op); !modOp) {
134 auto error_message =
"ModuleAnalysis expects provided op to be an mlir::ModuleOp!";
135 op->emitError(error_message);
136 llvm::report_fatal_error(error_message);
152 ensureResultCreated(op);
153 return results.at(op).get();
156 ResultMap::iterator
begin() {
return results.begin(); }
157 ResultMap::iterator
end() {
return results.end(); }
158 ResultMap::const_iterator
cbegin()
const {
return results.cbegin(); }
159 ResultMap::const_iterator
cend()
const {
return results.cend(); }
185 auto res =
solver.initializeAndRun(modOp);
186 ensure(res.succeeded(),
"solver failed to run on module!");
190 auto &childAnalysis = am.getChildAnalysis<StructAnalysisTy>(s);
191 if (mlir::failed(childAnalysis.runAnalysis(
solver, am, ctx))) {
192 auto error_message =
"StructAnalysis failed to run for " + mlir::Twine(s.getName());
193 s->emitError(error_message);
194 llvm::report_fatal_error(error_message);
196 ensure(results.find(s) == results.end(),
"struct location conflict");
197 results.insert(std::make_pair(s, std::reference_wrapper(childAnalysis.getResult())));
198 return mlir::WalkResult::skip();
203 mlir::ModuleOp modOp;
209 ensure(
hasResult(op),
"Result does not exist for StructDefOp " + mlir::Twine(op.getName()));
This file implements (LLZK-tailored) dense data-flow analysis using the data-flow analysis framework.
mlir::DataFlowSolver solver
virtual Context getContext()=0
Create and return a valid Context object.
ModuleAnalysis(mlir::Operation *op)
Asserts that the analysis is being run on a ModuleOp.
ResultMap::const_iterator cbegin() const
virtual ~ModuleAnalysis()=default
ResultMap::iterator begin()
virtual void initializeSolver()=0
Initialize the shared dataflow solver with any common analyses required by the contained struct analy...
virtual void runAnalysis(mlir::AnalysisManager &am)
Run the StructAnalysisTy struct analysis on all child structs.
ResultMap::iterator end()
const Result & getResult(component::StructDefOp op) const
Asserts that op has a result and returns it.
void constructChildAnalyses(mlir::AnalysisManager &am)
Construct and run the StructAnalysisTy analyses on each StructDefOp contained in the ModuleOp that is...
ResultMap::const_iterator cend() const
bool hasResult(component::StructDefOp op) const
Checks if op has a result contained in the current result map.
const mlir::DataFlowSolver & getSolver() const
StructAnalysis(mlir::Operation *op)
Assert that this analysis is being run on a StructDefOp and initializes the analysis with the current...
component::StructDefOp getStruct() const
Get the current StructDefOp that is under analysis.
virtual mlir::LogicalResult runAnalysis(mlir::DataFlowSolver &solver, mlir::AnalysisManager &moduleAnalysisManager, Context &ctx)=0
Perform the analysis and construct the Result output.
mlir::ModuleOp getModule() const
Get the ModuleOp that is the parent of the StructDefOp that is under analysis.
bool constructed() const
Query if the analysis has constructed a Result object.
void setResult(Result &&r)
Initialize the final Result object.
const Result & getResult() const
Access the result iff it has been created.
virtual ~StructAnalysis()=default
Any type that is a subclass of StructAnalysis.
void markAllOpsAsLive(mlir::DataFlowSolver &solver, mlir::Operation *top)
LLZK: Added this utility to ensure analysis is performed for all structs in a given module.
FailureOr< ModuleOp > getRootModule(Operation *from)
void ensure(bool condition, llvm::Twine errMsg)
An empty struct that is used for convenience for analyses that do not require any context.