23#include <mlir/IR/AsmState.h>
25#include <llvm/ADT/STLExtras.h>
26#include <llvm/ADT/SmallVector.h>
27#include <llvm/Support/Debug.h>
28#include <llvm/Support/ErrorHandling.h>
31#define GEN_PASS_DEF_INTERVALANALYSISPRINTERPASS
35#define DEBUG_TYPE "llzk-interval-analysis-pass"
45 using Base = IntervalAnalysisPrinterPassBase<PassImpl>;
48 void runOnOperation()
override {
49 markAllAnalysesPreserved();
53 auto modOp = llvm::dyn_cast<ModuleOp>(getOperation());
55 constexpr const char *msg =
"IntervalAnalysisPrinterPass error: should be run on ModuleOp!";
56 getOperation()->emitError(msg).report();
62 if (!fieldName.empty()) {
64 if (failed(fieldLookupRes)) {
67 "IntervalAnalysisPrinterPass error: unknown field \"", fieldName,
"\" specified"
72 selectedField = fieldLookupRes.value();
74 llvm::dbgs() <<
"[IntervalAnalysisPrinterPass] using explicit -field override '"
75 << selectedField.get().name() <<
"'\n";
78 selectedField = detectedField.value();
80 llvm::dbgs() <<
"[IntervalAnalysisPrinterPass] detected module field '"
81 << selectedField.get().name() <<
"' from module felt usage\n";
84 modOp->emitWarning() <<
"could not detect a unique module field; falling back to '"
85 << selectedField.get().name() <<
'\'';
87 llvm::dbgs() <<
"[IntervalAnalysisPrinterPass] no explicit or detectable module field; "
89 << selectedField.get().name() <<
"'\n";
93 auto &mia = getAnalysis<ModuleIntervalAnalysis>();
94 mia.setField(selectedField);
95 mia.setPropagateInputConstraints(propagateInputConstraints);
96 mia.setTrackUnreducedIntervals(printUnreducedIntervals);
97 auto am = getAnalysisManager();
98 mia.ensureAnalysisRun(am);
99 AsmState asmState(modOp);
101 auto printValueInterval = [
this, &asmState, &mia](raw_ostream &out,
int indent, Value value) {
102 if (llvm::isa<llzk::array::ArrayType, StructType, llzk::pod::PodType>(value.getType())) {
112 value.printAsOperand(out, asmState);
113 if (
auto opResult = llvm::dyn_cast<OpResult>(value)) {
114 out <<
" [" << opResult.getOwner()->getName().getStringRef() <<
"]";
122 auto printFunctionSSAIntervals =
123 [&printValueInterval](raw_ostream &out,
FuncDefOp fn, llvm::StringRef fnName) {
129 out.indent(4) << fnName <<
" {";
130 for (BlockArgument arg : fn.getArguments()) {
131 printValueInterval(out, 8, arg);
133 fn.walk([&](Operation *op) {
134 if (op == fn.getOperation()) {
137 for (Value result : op->getResults()) {
138 printValueInterval(out, 8, result);
142 out.indent(4) <<
'}';
146 for (
const auto &[s, si] : mia.getCurrentResults()) {
151 "could not resolve fully qualified name of struct " + Twine(structDef.getName())
153 os << fullName.value() <<
' ';
154 si.get().print(os, printSolverConstraints, printComputeIntervals, printUnreducedIntervals);
155 if (printSSAIntervals) {
156 os << fullName.value() <<
" SSAIntervals {";
157 if (printComputeIntervals) {
161 if (
auto productFn = structDef.getProductFuncOp();
162 productFn && (!structDef.getConstrainFuncOp() || printComputeIntervals)) {
Tracks a solver expression and an interval range for that expression.
const Interval & getInterval() const
bool hasUnreducedInterval() const
const UnreducedInterval & getUnreducedInterval() const
static llvm::FailureOr< std::reference_wrapper< const Field > > tryGetField(llvm::StringRef fieldName)
Get a Field from a given field name string, or failure if the field is not defined.
static const Field & getField(llvm::StringRef fieldName, EmitErrorFn errFn)
Get a Field from a given field name string.
constexpr char FUNC_NAME_COMPUTE[]
Symbol name for the witness generation (and resp.
std::reference_wrapper< const Field > FieldRef
Typealias for a stable reference to a known Field.
constexpr char FUNC_NAME_CONSTRAIN[]
llvm::raw_ostream & toStream(OutputStream val)
void ensure(bool condition, const llvm::Twine &errMsg)
constexpr char FUNC_NAME_PRODUCT[]
FailureOr< SymbolRefAttr > getPathFromTopRoot(SymbolOpInterface to, ModuleOp *foundRoot)
std::optional< std::reference_wrapper< const Field > > tryDetectSpecifiedField(mlir::Operation *root)
Try to detect a uniquely used field from the enclosing LLZK module.