.. _program_listing_file_lib_Conversion_ArithToEmitHLS_ArithToEmitHLS.cpp: Program Listing for File ArithToEmitHLS.cpp =========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``lib/Conversion/ArithToEmitHLS/ArithToEmitHLS.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "laksa-mlir/Conversion/ArithToEmitHLS/ArithToEmitHLS.h" #include "laksa-mlir/Dialect/EmitHLS/IR/EmitHLS.h" #include "laksa-mlir/Dialect/EmitHLS/IR/EmitHLSOps.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/IR/PatternMatch.h" #include #define DEBUG_TYPE "arith-to-emithls" #define LAKSA_DEBUG(X) \ LLVM_DEBUG(llvm::dbgs() << "[arith-to-emithls] "; X; llvm::dbgs() << "\n") namespace mlir { #define GEN_PASS_DEF_CONVERTARITHTOEMITHLS #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( arith::ConstantOp op, arith::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.getOut().getType(), op.getIn()); LAKSA_DEBUG( llvm::dbgs() << "Replaced " << op->getName() << " with equivalent emithls operation."); return success(); } }; struct ConvertCompare : OpConversionPattern { using OpConversionPattern::OpConversionPattern; LogicalResult matchAndRewrite( arith::CmpIOp op, arith::CmpIOpAdaptor, ConversionPatternRewriter &rewriter) const override { // Create map from arith predicate to emithls using AP = arith::CmpIPredicate; using EP = emithls::CmpPredicate; static const DenseMap predMap = { { AP::eq, EP::eq}, { AP::ne, EP::ne}, {AP::slt, EP::lt}, {AP::ult, EP::lt}, {AP::sle, EP::le}, {AP::ule, EP::le}, {AP::sgt, EP::gt}, {AP::ugt, EP::gt}, {AP::sge, EP::ge}, {AP::uge, EP::ge}, }; auto it = predMap.find(op.getPredicate()); 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(); } }; struct ConvertSelect : OpConversionPattern { using OpConversionPattern::OpConversionPattern; ConvertSelect(TypeConverter &typeConverter, MLIRContext* context) : OpConversionPattern(typeConverter, context) {}; LogicalResult matchAndRewrite( arith::SelectOp op, arith::SelectOpAdaptor, ConversionPatternRewriter &rewriter) const override { rewriter.replaceOpWithNewOp( op, op.getCondition(), op.getTrueValue(), op.getFalseValue()); LAKSA_DEBUG( llvm::dbgs() << "Replaced select operation with equivalent emithls operation."); return success(); } }; } // namespace void mlir::populateArithToEmitHLSConversionPatterns( 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()); patterns.add>( typeConverter, patterns.getContext()); patterns.add>( typeConverter, patterns.getContext()); patterns.add(typeConverter, patterns.getContext()); patterns.add(typeConverter, patterns.getContext()); } namespace { struct ConvertArithToEmitHLSPass : public impl::ConvertArithToEmitHLSBase { void runOnOperation() final; }; } // namespace void ConvertArithToEmitHLSPass::runOnOperation() { ConversionTarget target(getContext()); RewritePatternSet patterns(&getContext()); TypeConverter converter; converter.addConversion([&](Type type) { return type; }); populateArithToEmitHLSConversionPatterns(converter, patterns); target.addLegalDialect(); target.addIllegalDialect(); target.markUnknownOpDynamicallyLegal([](Operation*) { return true; }); if (failed(applyPartialConversion( getOperation(), target, std::move(patterns)))) { signalPassFailure(); } } std::unique_ptr mlir::createConvertArithToEmitHLSPass() { return std::make_unique(); }