.. _program_listing_file_lib_Conversion_IndexToEmitHLS_IndexToEmitHLS.cpp: Program Listing for File IndexToEmitHLS.cpp =========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``lib/Conversion/IndexToEmitHLS/IndexToEmitHLS.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "laksa-mlir/Conversion/IndexToEmitHLS/IndexToEmitHLS.h" #include "laksa-mlir/Dialect/EmitHLS/IR/EmitHLS.h" #include "laksa-mlir/Dialect/EmitHLS/IR/EmitHLSOps.h" #include "mlir/Dialect/Index/IR/IndexOps.h" #include "mlir/IR/PatternMatch.h" #include #include #define DEBUG_TYPE "index-to-emithls" #define LAKSA_DEBUG(X) \ LLVM_DEBUG(llvm::dbgs() << "[index-to-emithls] "; X; llvm::dbgs() << "\n") namespace mlir { #define GEN_PASS_DEF_CONVERTINDEXTOEMITHLS #include "laksa-mlir/Conversion/Passes.h.inc" } // namespace mlir using namespace mlir; using namespace mlir::emithls; namespace { struct ConstantVariable : OpConversionPattern { using OpConversionPattern::OpConversionPattern; ConstantVariable(TypeConverter &typeConverter, MLIRContext* context) : OpConversionPattern(typeConverter, context) {}; LogicalResult matchAndRewrite( index::ConstantOp op, index::ConstantOpAdaptor, ConversionPatternRewriter &rewriter) const override { rewriter.replaceOpWithNewOp( op, op.getType(), /*init*/ op.getValueAttr(), /*is_const*/ true); LAKSA_DEBUG( llvm::dbgs() << "Replaced constant with a constant variable."); return success(); } }; template struct ConvertBinaryOp : OpConversionPattern { using OpConversionPattern::OpConversionPattern; ConvertBinaryOp(TypeConverter &typeConverter, MLIRContext* context) : OpConversionPattern(typeConverter, context) {}; LogicalResult matchAndRewrite( OpFrom op, typename OpFrom::Adaptor, ConversionPatternRewriter &rewriter) const override { rewriter.replaceOpWithNewOp(op, op.getLhs(), op.getRhs()); LAKSA_DEBUG( llvm::dbgs() << "Replaced " << op->getName() << " with equivalent emithls operation."); return success(); } }; template struct ConvertCast : OpConversionPattern { using OpConversionPattern::OpConversionPattern; ConvertCast(TypeConverter &typeConverter, MLIRContext* context) : OpConversionPattern(typeConverter, context) {}; LogicalResult matchAndRewrite( OpFrom op, typename OpFrom::Adaptor, ConversionPatternRewriter &rewriter) const override { rewriter.replaceOpWithNewOp( op, op.getOutput().getType(), op.getInput()); LAKSA_DEBUG( llvm::dbgs() << "Replaced " << op->getName() << " with equivalent emithls operation."); return success(); } }; struct ConvertCompare : OpConversionPattern { using OpConversionPattern::OpConversionPattern; LogicalResult matchAndRewrite( index::CmpOp op, index::CmpOpAdaptor, ConversionPatternRewriter &rewriter) const override { // Create map from index predicate to emithls using IP = index::IndexCmpPredicate; using EP = emithls::CmpPredicate; static const DenseMap predMap = { { IP::EQ, EP::eq}, { IP::NE, EP::ne}, {IP::SLT, EP::lt}, {IP::ULT, EP::lt}, {IP::SLE, EP::le}, {IP::ULE, EP::le}, {IP::SGT, EP::gt}, {IP::UGT, EP::gt}, {IP::SGE, EP::ge}, {IP::UGE, EP::ge}, }; auto it = predMap.find(op.getPred()); if (it == predMap.end()) return rewriter.notifyMatchFailure(op, "unsupported predicate"); rewriter.replaceOpWithNewOp( op, it->second, op.getLhs(), op.getRhs()); LAKSA_DEBUG( llvm::dbgs() << "Replaced compare operation with equivalent emithls operation."); return success(); } }; } // namespace void mlir::populateIndexToEmitHLSConversionPatterns( TypeConverter &typeConverter, RewritePatternSet &patterns) { patterns.add(typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add(typeConverter, patterns.getContext()); } namespace { struct ConvertIndexToEmitHLSPass : public impl::ConvertIndexToEmitHLSBase { void runOnOperation() final; }; } // namespace void ConvertIndexToEmitHLSPass::runOnOperation() { ConversionTarget target(getContext()); RewritePatternSet patterns(&getContext()); TypeConverter converter; converter.addConversion([&](Type type) { return type; }); populateIndexToEmitHLSConversionPatterns(converter, patterns); target.addLegalDialect(); target.addIllegalDialect(); target.markUnknownOpDynamicallyLegal([](Operation*) { return true; }); if (failed(applyPartialConversion( getOperation(), target, std::move(patterns)))) { signalPassFailure(); } } std::unique_ptr mlir::createConvertIndexToEmitHLSPass() { return std::make_unique(); }