29#include <mlir/Dialect/Arith/IR/Arith.h>
30#include <mlir/Dialect/SCF/IR/SCF.h>
31#include <mlir/Dialect/SCF/Transforms/Patterns.h>
32#include <mlir/IR/Attributes.h>
33#include <mlir/IR/BuiltinAttributes.h>
34#include <mlir/IR/MLIRContext.h>
35#include <mlir/IR/Operation.h>
36#include <mlir/IR/PatternMatch.h>
37#include <mlir/IR/SymbolTable.h>
38#include <mlir/Transforms/DialectConversion.h>
40#include <llvm/ADT/DenseMap.h>
41#include <llvm/ADT/DenseSet.h>
42#include <llvm/ADT/STLExtras.h>
43#include <llvm/ADT/SmallVector.h>
44#include <llvm/Support/Debug.h>
46#define DEBUG_TYPE "poly-dialect-shared"
53template <
typename Check>
inline bool runCheck(mlir::Operation *op, Check
check) {
55 llvm::dyn_cast_if_present<
typename llvm::function_traits<Check>::template arg_t<0>>(op)) {
56 return check(specificOp);
91 llvm::DenseSet<mlir::SymbolRefAttr> &&tryToErasePaths
96 const llvm::DenseSet<mlir::SymbolOpInterface> &
getTryToEraseSet()
const {
return tryToErase; }
100 llvm::DenseSet<mlir::SymbolOpInterface> tryToErase;
102 llvm::DenseMap<mlir::SymbolOpInterface, bool> visitedPlusSafetyResult;
104 llvm::DenseMap<const SymbolUseGraphNode *, mlir::SymbolOpInterface> lookupCache;
106 bool collectSafeToErase(mlir::SymbolOpInterface
check);
128 mlir::SymbolRefAttr nameRef, mlir::MLIRContext *ctx, mlir::ArrayRef<mlir::Attribute> params
146 TemplateOp parentTemplate, mlir::ArrayAttr callParams,
147 const llvm::DenseMap<mlir::Attribute, mlir::Attribute> ¶mNameToConcrete
149 mlir::SmallVector<mlir::Attribute> remainingNames;
150 mlir::SmallVector<mlir::Attribute> attrsForInstantiatedNameSuffix;
152 auto it = paramNameToConcrete.find(paramName);
153 if (it != paramNameToConcrete.end()) {
154 attrsForInstantiatedNameSuffix.push_back(it->second);
156 attrsForInstantiatedNameSuffix.push_back(
nullptr);
157 remainingNames.push_back(paramName);
161 mlir::ArrayAttr rewrittenCallParams =
nullptr;
163 mlir::SmallVector<mlir::Attribute> remainingCallParams;
164 for (
auto [paramOp, attr] :
166 auto paramName = mlir::FlatSymbolRefAttr::get(paramOp.getSymNameAttr());
167 if (!paramNameToConcrete.contains(paramName)) {
168 remainingCallParams.push_back(attr);
171 rewrittenCallParams = mlir::ArrayAttr::get(parentTemplate.getContext(), remainingCallParams);
175 std::move(remainingNames),
200template <
typename... AdditionalOpClasses,
typename... AdditionalChecks>
202 mlir::TypeConverter &tyConv, mlir::MLIRContext *ctx, AdditionalChecks &&...checks
206 tyConv, ctx, empty, (std::forward<AdditionalChecks>(checks))...
216template <
typename... AdditionalOpClasses,
typename... AdditionalChecks>
219 AdditionalChecks &&...checks
222 auto inserter = [&](
auto... opClasses) {
223 target.addDynamicallyLegalOp<
decltype(opClasses)...>([&cb, &tyConv,
224 &checks...](mlir::Operation *op) {
226 llvm::dbgs() <<
"[newConverterDefinedTarget] checking legality of ";
234 LLVM_DEBUG(
if (legality) { llvm::dbgs() <<
"[newConverterDefinedTarget] is legal\n"; }
else {
235 llvm::dbgs() <<
"[newConverterDefinedTarget] is not legal\n";
240 std::apply(inserter, OpClassesWithStructTypes.NoGeneralBuilder);
241 std::apply(inserter, OpClassesWithStructTypes.WithGeneralBuilder);
242 applyToMoreTypes<
decltype(inserter), AdditionalOpClasses...>(inserter);
Reusable MLIR dialect conversion functions for LLZK StructType replacement.
static std::string from(mlir::Type type)
Return a brief string representation of the given LLZK type.
Builds a tree structure representing the symbol table structure.
Builds a graph structure representing the relationships between symbols and their uses.
static StructType get(::mlir::SymbolRefAttr structName)
::llvm::SmallVector<::mlir::Attribute > getConstNames()
Return the names of all ops of type OpT within the body region in the order they are defined.
::llvm::StringRef getSymName()
inline ::llvm::iterator_range<::mlir::Region::op_iterator< OpT > > getConstOps()
Return ops of type OpT within the body region.
const SymbolDefTree & defTree
const SymbolUseGraph & useGraph
mlir::SymbolTableCollection tables
CleanupBase(mlir::ModuleOp root, const SymbolDefTree &symDefTree, const SymbolUseGraph &symUseGraph)
void checkEnded(bool) override
void checkStarted() override
mlir::LogicalResult eraseUnusedDefinitions()
const llvm::DenseSet< mlir::SymbolOpInterface > & getTryToEraseSet() const
FromEraseSet(mlir::ModuleOp root, const SymbolDefTree &symDefTree, const SymbolUseGraph &symUseGraph, llvm::DenseSet< mlir::SymbolRefAttr > &&tryToErasePaths)
Note: paths in tryToErase should be relative to root.
virtual void checkStarted()=0
virtual void checkEnded(bool outcome)=0
virtual ~LegalityCheckCallback()=default
component::StructType getStructTypeWithParams(mlir::SymbolRefAttr nameRef, mlir::ArrayAttr params)
Build a struct type while representing an empty parameter list as absent.
mlir::ConversionTarget newConverterDefinedTargetWithCallback(mlir::TypeConverter &tyConv, mlir::MLIRContext *ctx, LegalityCheckCallback &cb, AdditionalChecks &&...checks)
Return a new ConversionTarget allowing all LLZK-required dialects and defining Op legality based on t...
InstantiationLayout buildInstantiationLayout(TemplateOp parentTemplate, mlir::ArrayAttr callParams, const llvm::DenseMap< mlir::Attribute, mlir::Attribute > ¶mNameToConcrete)
Derive the instantiated template name and the remaining explicit parameters that should stay on the r...
mlir::ConversionTarget newConverterDefinedTarget(mlir::TypeConverter &tyConv, mlir::MLIRContext *ctx, AdditionalChecks &&...checks)
Return a new ConversionTarget allowing all LLZK-required dialects and defining Op legality based on t...
bool isErasableDefinition(mlir::Operation *op)
Return true iff op is a cleanup candidate.
mlir::ConversionTarget newBaseTarget(mlir::MLIRContext *ctx)
Return a new ConversionTarget allowing all LLZK-required dialects.
array::ArrayType flattenInstantiatedArrayType(array::ArrayType inputTy, mlir::Type convertedElemTy)
Merge nested array dimensions produced by replacing an array element type.
bool isNullOrEmpty(mlir::ArrayAttr a)
bool defaultLegalityCheck(const mlir::TypeConverter &tyConv, mlir::Operation *op)
Check whether an op is legal with respect to the given type converter, including TypeAttr attributes ...
Groups the information needed after concrete parameters have been chosen to decide how to name a new ...
std::string templateNameWithAttrs
mlir::ArrayAttr rewrittenCallParams
mlir::SmallVector< mlir::Attribute > remainingNames