Hi,
Problem Statement is to write an operation which does exactly what scf ForOp do. I created an operation custom::CForOp which has the same .td defintion as scf::ForOp, with only getters written in the custom.cpp file.
def Custom_CForOp : Custom_Op<"for",
[AutomaticAllocationScope, DeclareOpInterfaceMethods<LoopLikeOpInterface,
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep",
"getSingleUpperBound"]>,
AllTypesMatch<["lowerBound", "upperBound", "step"]>,
ConditionallySpeculatable,
DeclareOpInterfaceMethods<RegionBranchOpInterface>,
SingleBlockImplicitTerminator<"custom::YieldOp">,
RecursiveMemoryEffects]> {
let summary = "for operation";
let arguments = (ins AnySignlessIntegerOrIndex:$lowerBound,
AnySignlessIntegerOrIndex:$upperBound,
AnySignlessIntegerOrIndex:$step,
Variadic<AnyType>:$initArgs);
let results = (outs Variadic<AnyType>:$results);
let regions = (region SizedRegion<1>:$region);
let skipDefaultBuilders = 1;
let builders = [
OpBuilder<(ins "Value":$lowerBound, "Value":$upperBound, "Value":$step,
CArg<"ValueRange", "std::nullopt">:$iterArgs,
CArg<"function_ref<void(OpBuilder &, Location, Value, ValueRange)>",
"nullptr">)>
];
let extraClassDeclaration = [{ /* ..... SAME AS OF SCF FOROP.... */
}];
}
def Custom_YieldOp : Custom_Op<"yield", [Pure, ReturnLike, Terminator,
ParentOneOf<["CForOp"]>]> {
let summary = "loop yield and termination operation";
let arguments = (ins Variadic<AnyType>:$results);
let builders = [OpBuilder<(ins), [{ /* nothing to do */ }]>];
let assemblyFormat =
[{ attr-dict ($results^ `:` type($results))? }];
}
Then i write a pass for it’s conversion.
template <class OpClass, class StdOpClass>
struct CustomForOpLowering : public OpConversionPattern<OpClass> {
public:
using OpConversionPattern<OpClass>::OpConversionPattern;
LogicalResult
matchAndRewrite(OpClass customForOp,
typename OpConversionPattern<OpClass>::OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
//auto type = getBaseType(binOp.left().getType());
rewriter.template replaceOpWithNewOp<StdOpClass>(
customForOp, adaptor.getLowerBound() , adaptor.getUpperBound(), adaptor.getStep());
return success();
}
};
using CustomForOpLoweringToSCF = CustomForOpLowering<custom::CForOp, scf::ForOp>;
I am facing ld unrefenrced error :
undefined reference to `mlir::custom::CForOp::build(mlir::OpBuilder&, mlir::OperationState&, mlir::Value, mlir::Value, mlir::Value, mlir::ValueRange, llvm::function_ref<void (mlir::OpBuilder&, mlir::Location, mlir::Value, mlir::ValueRange)>)'
collect2: error: ld returned 1 exit status
please help as possible. my idea is to just have an operation which i can translate directly to scf::ForOp. Do i have to write the whole ForOp classes, definitions and logic again ?
It might be a trivial query as i am learning the codebase as a beginner.