let cppNamespace = "mlir";
let hasConstantMaterializer = 1;
let dependentDialects = ["arith::ArithDialect"];
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
// Base class for Affine dialect ops.
kEscapeAttrName = "bufferization.escape";
}];
let hasOperationAttrVerify = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
#endif // BUFFERIZATION_BASE
let dependentDialects = ["arith::ArithDialect"];
let hasConstantMaterializer = 1;
let useDefaultAttributePrinterParser = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
#endif // COMPLEX_BASE
let hasConstantMaterializer = 1;
let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
#endif // MLIR_DIALECT_EMITC_IR_EMITCBASE
let cppNamespace = "::mlir::func";
let dependentDialects = ["cf::ControlFlowDialect"];
let hasConstantMaterializer = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
// Base class for Func dialect ops.
let dependentDialects = ["arith::ArithDialect"];
let useDefaultAttributePrinterParser = 1;
let useDefaultTypePrinterParser = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
def GPU_AsyncToken : DialectType<
let hasRegionArgAttrVerify = 1;
let hasRegionResultAttrVerify = 1;
let hasOperationAttrVerify = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
let extraClassDeclaration = [{
/// Name of the data layout attributes.
let hasCanonicalizer = 1;
let hasOperationAttrVerify = 1;
let hasConstantMaterializer = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
let extraClassDeclaration = [{
/// Attribute name used to to memoize indexing maps for named ops.
constexpr const static ::llvm::StringLiteral
let cppNamespace = "::mlir::quant";
let useDefaultTypePrinterParser = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
//===----------------------------------------------------------------------===//
let name = "scf";
let cppNamespace = "::mlir::scf";
let dependentDialects = ["arith::ArithDialect"];
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
// Base class for SCF dialect ops.
let useDefaultAttributePrinterParser = 1;
let useDefaultTypePrinterParser = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
#endif // SPARSETENSOR_BASE
"::mlir::pdl_interp::PDLInterpDialect",
];
+ let useFoldAPI = kEmitFoldAdaptorFolder;
+
let extraClassDeclaration = [{
/// Returns the named PDL constraint functions available in the dialect
/// as a map from their name to the function.
public:
}];
+
+ let useFoldAPI = kEmitFoldAdaptorFolder;
}
#endif // BUILTIN_BASE
});
}
-OpFoldResult AffineApplyOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult AffineApplyOp::fold(FoldAdaptor adaptor) {
auto map = getAffineMap();
// Fold dims and symbols to existing values.
// Otherwise, default to folding the map.
SmallVector<Attribute, 1> result;
- if (failed(map.constantFold(operands, result)))
+ if (failed(map.constantFold(adaptor.getMapOperands(), result)))
return {};
return result[0];
}
return tripCount && *tripCount == 0;
}
-LogicalResult AffineForOp::fold(ArrayRef<Attribute> operands,
+LogicalResult AffineForOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
bool folded = succeeded(foldLoopBounds(*this));
folded |= succeeded(canonicalizeLoopBounds(*this));
}
/// Canonicalize an affine if op's conditional (integer set + operands).
-LogicalResult AffineIfOp::fold(ArrayRef<Attribute>,
+LogicalResult AffineIfOp::fold(FoldAdaptor,
SmallVectorImpl<OpFoldResult> &) {
auto set = getIntegerSet();
SmallVector<Value, 4> operands(getOperands());
results.add<SimplifyAffineOp<AffineLoadOp>>(context);
}
-OpFoldResult AffineLoadOp::fold(ArrayRef<Attribute> cstOperands) {
+OpFoldResult AffineLoadOp::fold(FoldAdaptor adaptor) {
/// load(memrefcast) -> load
if (succeeded(memref::foldMemRefCast(*this)))
return getResult();
results.add<SimplifyAffineOp<AffineStoreOp>>(context);
}
-LogicalResult AffineStoreOp::fold(ArrayRef<Attribute> cstOperands,
+LogicalResult AffineStoreOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
/// store(memrefcast) -> store
return memref::foldMemRefCast(*this, getValueToStore());
// %0 = affine.min (d0) -> (1000, d0 + 512) (%i0)
//
-OpFoldResult AffineMinOp::fold(ArrayRef<Attribute> operands) {
- return foldMinMaxOp(*this, operands);
+OpFoldResult AffineMinOp::fold(FoldAdaptor adaptor) {
+ return foldMinMaxOp(*this, adaptor.getOperands());
}
void AffineMinOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
// %0 = affine.max (d0) -> (1000, d0 + 512) (%i0)
//
-OpFoldResult AffineMaxOp::fold(ArrayRef<Attribute> operands) {
- return foldMinMaxOp(*this, operands);
+OpFoldResult AffineMaxOp::fold(FoldAdaptor adaptor) {
+ return foldMinMaxOp(*this, adaptor.getOperands());
}
void AffineMaxOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
results.add<SimplifyAffineOp<AffinePrefetchOp>>(context);
}
-LogicalResult AffinePrefetchOp::fold(ArrayRef<Attribute> cstOperands,
+LogicalResult AffinePrefetchOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
/// prefetch(memrefcast) -> prefetch
return memref::foldMemRefCast(*this);
return success();
}
-LogicalResult AffineParallelOp::fold(ArrayRef<Attribute> operands,
+LogicalResult AffineParallelOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
return canonicalizeLoopBounds(*this);
}
SideEffects::DefaultResource::get());
}
-OpFoldResult CloneOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult CloneOp::fold(FoldAdaptor adaptor) {
return succeeded(memref::foldMemRefCast(*this)) ? getResult() : Value();
}
// ToTensorOp
//===----------------------------------------------------------------------===//
-OpFoldResult ToTensorOp::fold(ArrayRef<Attribute>) {
+OpFoldResult ToTensorOp::fold(FoldAdaptor) {
if (auto toMemref = getMemref().getDefiningOp<ToMemrefOp>())
// Approximate alias analysis by conservatively folding only when no there
// is no interleaved operation.
// ToMemrefOp
//===----------------------------------------------------------------------===//
-OpFoldResult ToMemrefOp::fold(ArrayRef<Attribute>) {
+OpFoldResult ToMemrefOp::fold(FoldAdaptor) {
if (auto memrefToTensor = getTensor().getDefiningOp<ToTensorOp>())
if (memrefToTensor.getMemref().getType() == getType())
return memrefToTensor.getMemref();
// ConstantOp
//===----------------------------------------------------------------------===//
-OpFoldResult ConstantOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.empty() && "constant has no operands");
+OpFoldResult ConstantOp::fold(FoldAdaptor adaptor) {
return getValue();
}
// CreateOp
//===----------------------------------------------------------------------===//
-OpFoldResult CreateOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 2 && "binary op takes two operands");
+OpFoldResult CreateOp::fold(FoldAdaptor adaptor) {
// Fold complex.create(complex.re(op), complex.im(op)).
if (auto reOp = getOperand(0).getDefiningOp<ReOp>()) {
if (auto imOp = getOperand(1).getDefiningOp<ImOp>()) {
// ImOp
//===----------------------------------------------------------------------===//
-OpFoldResult ImOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 1 && "unary op takes 1 operand");
- ArrayAttr arrayAttr = operands[0].dyn_cast_or_null<ArrayAttr>();
+OpFoldResult ImOp::fold(FoldAdaptor adaptor) {
+ ArrayAttr arrayAttr = adaptor.getComplex().dyn_cast_or_null<ArrayAttr>();
if (arrayAttr && arrayAttr.size() == 2)
return arrayAttr[1];
if (auto createOp = getOperand().getDefiningOp<CreateOp>())
// ReOp
//===----------------------------------------------------------------------===//
-OpFoldResult ReOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 1 && "unary op takes 1 operand");
- ArrayAttr arrayAttr = operands[0].dyn_cast_or_null<ArrayAttr>();
+OpFoldResult ReOp::fold(FoldAdaptor adaptor) {
+ ArrayAttr arrayAttr = adaptor.getComplex().dyn_cast_or_null<ArrayAttr>();
if (arrayAttr && arrayAttr.size() == 2)
return arrayAttr[0];
if (auto createOp = getOperand().getDefiningOp<CreateOp>())
// AddOp
//===----------------------------------------------------------------------===//
-OpFoldResult AddOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 2 && "binary op takes 2 operands");
-
+OpFoldResult AddOp::fold(FoldAdaptor adaptor) {
// complex.add(complex.sub(a, b), b) -> a
if (auto sub = getLhs().getDefiningOp<SubOp>())
if (getRhs() == sub.getRhs())
// SubOp
//===----------------------------------------------------------------------===//
-OpFoldResult SubOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 2 && "binary op takes 2 operands");
-
+OpFoldResult SubOp::fold(FoldAdaptor adaptor) {
// complex.sub(complex.add(a, b), b) -> a
if (auto add = getLhs().getDefiningOp<AddOp>())
if (getRhs() == add.getRhs())
// NegOp
//===----------------------------------------------------------------------===//
-OpFoldResult NegOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 1 && "unary op takes 1 operand");
-
+OpFoldResult NegOp::fold(FoldAdaptor adaptor) {
// complex.neg(complex.neg(a)) -> a
if (auto negOp = getOperand().getDefiningOp<NegOp>())
return negOp.getOperand();
// LogOp
//===----------------------------------------------------------------------===//
-OpFoldResult LogOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 1 && "unary op takes 1 operand");
-
+OpFoldResult LogOp::fold(FoldAdaptor adaptor) {
// complex.log(complex.exp(a)) -> a
if (auto expOp = getOperand().getDefiningOp<ExpOp>())
return expOp.getOperand();
// ExpOp
//===----------------------------------------------------------------------===//
-OpFoldResult ExpOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 1 && "unary op takes 1 operand");
-
+OpFoldResult ExpOp::fold(FoldAdaptor adaptor) {
// complex.exp(complex.log(a)) -> a
if (auto logOp = getOperand().getDefiningOp<LogOp>())
return logOp.getOperand();
// ConjOp
//===----------------------------------------------------------------------===//
-OpFoldResult ConjOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 1 && "unary op takes 1 operand");
-
+OpFoldResult ConjOp::fold(FoldAdaptor adaptor) {
// complex.conj(complex.conj(a)) -> a
if (auto conjOp = getOperand().getDefiningOp<ConjOp>())
return conjOp.getOperand();
return success();
}
-OpFoldResult emitc::ConstantOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.empty() && "constant has no operands");
+OpFoldResult emitc::ConstantOp::fold(FoldAdaptor adaptor) {
return getValue();
}
return success();
}
-OpFoldResult ConstantOp::fold(ArrayRef<Attribute> operands) {
- assert(operands.empty() && "constant has no operands");
+OpFoldResult ConstantOp::fold(FoldAdaptor adaptor) {
return getValueAttr();
}
return success();
}
-LogicalResult MemcpyOp::fold(ArrayRef<Attribute> operands,
+LogicalResult MemcpyOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<::mlir::OpFoldResult> &results) {
return memref::foldMemRefCast(*this);
}
-LogicalResult MemsetOp::fold(ArrayRef<Attribute> operands,
+LogicalResult MemsetOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<::mlir::OpFoldResult> &results) {
return memref::foldMemRefCast(*this);
}
return llvmType;
}
-OpFoldResult LLVM::ExtractValueOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult LLVM::ExtractValueOp::fold(FoldAdaptor adaptor) {
auto insertValueOp = getContainer().getDefiningOp<InsertValueOp>();
OpFoldResult result = {};
while (insertValueOp) {
}
// Constant op constant-folds to its value.
-OpFoldResult LLVM::ConstantOp::fold(ArrayRef<Attribute>) { return getValue(); }
+OpFoldResult LLVM::ConstantOp::fold(FoldAdaptor) { return getValue(); }
//===----------------------------------------------------------------------===//
// Utility functions for parsing atomic ops
// Folder for LLVM::BitcastOp
//===----------------------------------------------------------------------===//
-OpFoldResult LLVM::BitcastOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult LLVM::BitcastOp::fold(FoldAdaptor adaptor) {
// bitcast(x : T0, T0) -> x
if (getArg().getType() == getType())
return getArg();
// Folder for LLVM::AddrSpaceCastOp
//===----------------------------------------------------------------------===//
-OpFoldResult LLVM::AddrSpaceCastOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult LLVM::AddrSpaceCastOp::fold(FoldAdaptor adaptor) {
// addrcast(x : T0, T0) -> x
if (getArg().getType() == getType())
return getArg();
// Folder for LLVM::GEPOp
//===----------------------------------------------------------------------===//
-OpFoldResult LLVM::GEPOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult LLVM::GEPOp::fold(FoldAdaptor adaptor) {
GEPIndicesAdaptor<ArrayRef<Attribute>> indices(getRawConstantIndicesAttr(),
- operands.drop_front());
+ adaptor.getDynamicIndices());
// gep %x:T, 0 -> %x
if (getBase().getType() == getType() && indices.size() == 1)
results.add<EraseIdentityGenericOp>(context);
}
-LogicalResult GenericOp::fold(ArrayRef<Attribute>,
- SmallVectorImpl<OpFoldResult> &) {
+LogicalResult GenericOp::fold(FoldAdaptor, SmallVectorImpl<OpFoldResult> &) {
return memref::foldMemRefCast(*this);
}
addBytecodeInterface(this);
}
-OpFoldResult StorageCastOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult StorageCastOp::fold(FoldAdaptor adaptor) {
// Matches x -> [scast -> scast] -> y, replacing the second scast with the
// value of x if the casts invert each other.
auto srcScastOp = getArg().getDefiningOp<StorageCastOp>();
regions.push_back(RegionSuccessor(condition ? &getThenRegion() : elseRegion));
}
-LogicalResult IfOp::fold(ArrayRef<Attribute> operands,
+LogicalResult IfOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
// if (!c) then A() else B() -> if c then B() else A()
if (getElseRegion().empty())
return emitError("unexpected type in convert");
}
-OpFoldResult ConvertOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult ConvertOp::fold(FoldAdaptor adaptor) {
Type dstType = getType();
// Fold trivial dense-to-dense convert and leave trivial sparse-to-sparse
// convert for codegen to remove. This is because we use trivial
return op.getSpecifier().template getDefiningOp<SetStorageSpecifierOp>();
}
-OpFoldResult GetStorageSpecifierOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult GetStorageSpecifierOp::fold(FoldAdaptor adaptor) {
StorageSpecifierKind kind = getSpecifierKind();
std::optional<APInt> dim = getDim();
for (auto op = getSpecifierSetDef(*this); op; op = getSpecifierSetDef(op))
// manipulation.
}
-OpFoldResult transform::MergeHandlesOp::fold(ArrayRef<Attribute> operands) {
+OpFoldResult transform::MergeHandlesOp::fold(FoldAdaptor adaptor) {
if (getDeduplicate() || getHandles().size() != 1)
return {};
//===----------------------------------------------------------------------===//
LogicalResult
-UnrealizedConversionCastOp::fold(ArrayRef<Attribute> attrOperands,
+UnrealizedConversionCastOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &foldResults) {
OperandRange operands = getInputs();
ResultRange results = getOutputs();
results.add<TestRemoveOpWithInnerOps>(context);
}
-OpFoldResult TestOpWithRegionFold::fold(ArrayRef<Attribute> operands) {
+OpFoldResult TestOpWithRegionFold::fold(FoldAdaptor adaptor) {
return getOperand();
}
-OpFoldResult TestOpConstant::fold(ArrayRef<Attribute> operands) {
+OpFoldResult TestOpConstant::fold(FoldAdaptor adaptor) {
return getValue();
}
LogicalResult TestOpWithVariadicResultsAndFolder::fold(
- ArrayRef<Attribute> operands, SmallVectorImpl<OpFoldResult> &results) {
+ FoldAdaptor adaptor, SmallVectorImpl<OpFoldResult> &results) {
for (Value input : this->getOperands()) {
results.push_back(input);
}
return success();
}
-OpFoldResult TestOpInPlaceFold::fold(ArrayRef<Attribute> operands) {
- assert(operands.size() == 1);
- if (operands.front()) {
- (*this)->setAttr("attr", operands.front());
+OpFoldResult TestOpInPlaceFold::fold(FoldAdaptor adaptor) {
+ if (adaptor.getOp()) {
+ (*this)->setAttr("attr", adaptor.getOp());
return getResult();
}
return {};
}
-OpFoldResult TestPassthroughFold::fold(ArrayRef<Attribute> operands) {
+OpFoldResult TestPassthroughFold::fold(FoldAdaptor adaptor) {
return getOperand();
}
let hasNonDefaultDestructor = 1;
let useDefaultTypePrinterParser = 0;
let useDefaultAttributePrinterParser = 1;
+ let useFoldAPI = kEmitFoldAdaptorFolder;
let isExtensible = 1;
let dependentDialects = ["::mlir::DLTIDialect"];
let results = (outs Variadic<I1>);
let hasFolder = 1;
let extraClassDefinition = [{
- ::mlir::LogicalResult $cppClass::fold(ArrayRef<Attribute> operands,
+ ::mlir::LogicalResult $cppClass::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
return success();
}
$op `,` `[` $variadic `]` `,` `{` $var_of_var `}` $body attr-dict-with-keyword
}];
- let hasFolder = 0;
-
- let extraClassDeclaration = [{
- ::mlir::OpFoldResult fold(FoldAdaptor adaptor);
- }];
+ let hasFolder = 1;
}
// An op that always fold itself.
//===----------------------------------------------------------------------===//
OpFoldResult TestInvolutionTraitFailingOperationFolderOp::fold(
- ArrayRef<Attribute> operands) {
+ FoldAdaptor adaptor) {
// This failure should cause the trait fold to run instead.
return {};
}
OpFoldResult TestInvolutionTraitSuccesfulOperationFolderOp::fold(
- ArrayRef<Attribute> operands) {
+ FoldAdaptor adaptor) {
auto argumentOp = getOperand();
// The success case should cause the trait fold to be supressed.
return argumentOp.getDefiningOp() ? argumentOp : OpFoldResult{};
// Parameters:
// {0}: Class name
const char structuredOpFoldersFormat[] = R"FMT(
-LogicalResult {0}::fold(ArrayRef<Attribute>,
+LogicalResult {0}::fold(FoldAdaptor,
SmallVectorImpl<OpFoldResult> &) {{
return memref::foldMemRefCast(*this);
}