From 2027b2b9fe7de933dd2721d3e8dccb6264470e6b Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 7 Mar 2022 11:20:35 -0500 Subject: [PATCH 1/7] add Brutus C-API --- CMakeLists.txt | 21 ++++++--------------- lib/CAPI/CMakeLists.txt | 5 +++++ lib/CAPI/Dialects.cpp | 16 ++++++++++++++++ lib/CMakeLists.txt | 1 + 4 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 lib/CAPI/CMakeLists.txt create mode 100644 lib/CAPI/Dialects.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c76bf1c..54f4c0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,9 @@ -cmake_minimum_required(VERSION 3.10) - -if(POLICY CMP0068) - cmake_policy(SET CMP0068 NEW) - set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) -endif() +cmake_minimum_required(VERSION 3.13.4) +project(brutus) -if(POLICY CMP0075) - cmake_policy(SET CMP0075 NEW) -endif() +set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) -if(POLICY CMP0077) - cmake_policy(SET CMP0077 NEW) -endif() - -project(brutus) -set(BRUTUS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to conform to") find_package(MLIR REQUIRED CONFIG) @@ -25,6 +14,8 @@ set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin) set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib) set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR}) +set(BRUTUS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}") list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") list(APPEND CMAKE_MODULE_PATH "${BRUTUS_SOURCE_DIR}/cmake/modules") diff --git a/lib/CAPI/CMakeLists.txt b/lib/CAPI/CMakeLists.txt new file mode 100644 index 0000000..d7c4c84 --- /dev/null +++ b/lib/CAPI/CMakeLists.txt @@ -0,0 +1,5 @@ +add_mlir_public_c_api_library(BRUTUSCAPI + Dialects.cpp + LINK_LIBS PUBLIC + MLIRJulia +) \ No newline at end of file diff --git a/lib/CAPI/Dialects.cpp b/lib/CAPI/Dialects.cpp new file mode 100644 index 0000000..c045e08 --- /dev/null +++ b/lib/CAPI/Dialects.cpp @@ -0,0 +1,16 @@ + +//===- Dialects.cpp - CAPI for dialects -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "brutus-c/Dialects.h" + +#include "brutus/Dialect/Julia/JuliaOps.h" +#include "mlir/CAPI/Registration.h" + +MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(JLIR, jlir, + mlir::jlir::JLIRDialect) \ No newline at end of file diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 072ceb2..082cab7 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(Codegen) add_subdirectory(Conversion) add_subdirectory(Dialect) +add_subdirectory(CAPI) From 86cb341392dbba54c30147edab6a8b0728dc559f Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 8 Mar 2022 11:13:35 -0500 Subject: [PATCH 2/7] make Brutus compile against LLVM 14 --- .../JLIRToStandard/JLIRToStandard.h | 2 +- include/brutus/Dialect/Julia/JuliaOps.td | 23 +-- lib/Codegen/Codegen.cpp | 9 +- lib/Conversion/JLIRToLLVM/JLIRToLLVM.cpp | 37 ++-- .../JLIRToStandard/JLIRToStandard.cpp | 168 ++++++++++-------- .../Julia/CanonicalizationPatterns.cpp | 12 +- 6 files changed, 139 insertions(+), 112 deletions(-) diff --git a/include/brutus/Conversion/JLIRToStandard/JLIRToStandard.h b/include/brutus/Conversion/JLIRToStandard/JLIRToStandard.h index c18a47e..75fad62 100644 --- a/include/brutus/Conversion/JLIRToStandard/JLIRToStandard.h +++ b/include/brutus/Conversion/JLIRToStandard/JLIRToStandard.h @@ -21,7 +21,7 @@ struct JLIRToStandardTypeConverter : public TypeConverter { /// conversion patterns capture the LLVMTypeConverter and the LowerToLLVMOptions /// by reference meaning the references have to remain alive during the entire /// pattern lifetime. -void populateJLIRToStdConversionPatterns(OwningRewritePatternList &patterns, +void populateJLIRToStdConversionPatterns(RewritePatternSet &patterns, MLIRContext &context, JLIRToStandardTypeConverter &converter); diff --git a/include/brutus/Dialect/Julia/JuliaOps.td b/include/brutus/Dialect/Julia/JuliaOps.td index b58bc54..d1a0e2d 100644 --- a/include/brutus/Dialect/Julia/JuliaOps.td +++ b/include/brutus/Dialect/Julia/JuliaOps.td @@ -8,6 +8,7 @@ #define JULIA_MLIR_JLIR_TD include "mlir/IR/OpBase.td" +include "mlir/Interfaces/InferTypeOpInterface.td" include "mlir/Interfaces/SideEffectInterfaces.td" // Provide a definition of the 'JLIR' dialect in the ODS framework so that we @@ -37,25 +38,25 @@ def JLIR_IsJLArrayTypePred : CPred<"jl_is_array_type($_self.cast().ge // * The parent dialect of the operation. // * The mnemonic for the operation, or the name without the dialect prefix. // * A list of traits for the operation. -class JLIR_Op traits = []> : +class JLIR_Op traits = []> : Op; // Base clase for JLIR intrinsics -class JLIR_IntrinsicBuiltinOp traits = []> : +class JLIR_IntrinsicBuiltinOp traits = []> : JLIR_Op { let arguments = (ins Variadic:$arguments); let results = (outs JLIR_JuliaType); } -class JLIR_ArithmeticOp traits = []>: +class JLIR_ArithmeticOp traits = []>: JLIR_IntrinsicBuiltinOp { let arguments = (ins JLIR_JuliaType:$rhs, JLIR_JuliaType:$lhs); let results = (outs JLIR_JuliaType); } -class JLIR_UnaryArithmeticOp traits = []>: +class JLIR_UnaryArithmeticOp traits = []>: JLIR_IntrinsicBuiltinOp { let arguments = (ins JLIR_JuliaType:$arg); @@ -140,11 +141,11 @@ def InvokeOp : JLIR_Op<"invoke"> { let arguments = (ins JLIR_JuliaValueAttr:$methodInstance, JLIR_JuliaType:$callee, Variadic:$arguments); - + let results = (outs JLIR_JuliaType); - + let builders = [ - OpBuilder<(ins "jl_method_instance_t *":$methodInstance, + OpBuilder<(ins "jl_method_instance_t *":$methodInstance, "Value":$callee, "ArrayRef":$arguments, "jl_datatype_t *":$type)> @@ -174,15 +175,15 @@ def GotoIfNotOp : JLIR_Op<"gotoifnot", [AttrSizedOperandSegments, Terminator]> { let arguments = (ins JLIR_JuliaType:$condition, Variadic:$branchOperands, Variadic:$fallthroughOperands); - - let successors = (successor AnySuccessor:$branchDest, + + let successors = (successor AnySuccessor:$branchDest, AnySuccessor:$fallthroughDest); let builders = [ OpBuilder<(ins "Value":$condition, - "Block *":$branchDest, + "Block *":$branchDest, "ValueRange":$branchOperands, - "Block *":$fallthroughDest, + "Block *":$fallthroughDest, "ValueRange":$fallthroughOperands), [{ build($_builder, $_state, condition, diff --git a/lib/Codegen/Codegen.cpp b/lib/Codegen/Codegen.cpp index f08f756..4b361a3 100644 --- a/lib/Codegen/Codegen.cpp +++ b/lib/Codegen/Codegen.cpp @@ -264,7 +264,7 @@ mlir::FuncOp emit_function(jl_mlirctx_t &ctx, if (fname.empty()) fname = "macro expansion"; assert(inlined_at <= i); - mlir::Location current = mlir::NameLoc::get(mlir::Identifier::get(fname, ctx.context), + mlir::Location current = mlir::NameLoc::get(mlir::StringAttr::get(ctx.context, fname), mlir::FileLineColLoc::get(ctx.context, file, line, 0)); // codegen.cpp uses a better heuristic for now just live with this @@ -416,7 +416,10 @@ mlir::FuncOp emit_function(jl_mlirctx_t &ctx, else if (jl_is_phinode(stmt)) { // add argument slot to current_block - auto arg = bbs[current_block]->addArgument((mlir::Type)JuliaType::get(ctx.context, type)); + auto arg = bbs[current_block]->addArgument( + (mlir::Type)JuliaType::get(ctx.context, type), + loc + ); // add argument reference to values ctx.values[i] = arg; } @@ -619,7 +622,7 @@ extern "C" std::string cabi_name = "ciface_" + name; ExecutionEngine *engine = expectedEngine.get().release(); - auto expectedFPtr = engine->lookup(cabi_name); + auto expectedFPtr = engine->lookupPacked(cabi_name); if (!expectedFPtr) { handleLLVMError(expectedFPtr.takeError()); diff --git a/lib/Conversion/JLIRToLLVM/JLIRToLLVM.cpp b/lib/Conversion/JLIRToLLVM/JLIRToLLVM.cpp index 4e0bbe4..fd06941 100644 --- a/lib/Conversion/JLIRToLLVM/JLIRToLLVM.cpp +++ b/lib/Conversion/JLIRToLLVM/JLIRToLLVM.cpp @@ -152,6 +152,7 @@ namespace template struct OpAndTypeConversionPattern : OpConversionPattern { + using OpConversionPattern::OpConversionPattern; JLIRToLLVMTypeConverter &lowering; OpAndTypeConversionPattern(MLIRContext *ctx, @@ -261,16 +262,17 @@ namespace struct ToLLVMOpPattern : public OpAndTypeConversionPattern { using OpAndTypeConversionPattern::OpAndTypeConversionPattern; + using OpAdaptor = typename SourceOp::Adaptor; LogicalResult matchAndRewrite(SourceOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { static_assert( std::is_base_of, SourceOp>::value, "expected single result op"); rewriter.replaceOpWithNewOp( - op, this->lowering.convertType(op.getType()), operands); + op, this->lowering.convertType(op.getType()), adaptor.getOperands()); return success(); } }; @@ -279,14 +281,16 @@ namespace struct ToUnaryLLVMOpPattern : public OpAndTypeConversionPattern { using OpAndTypeConversionPattern::OpAndTypeConversionPattern; + using OpAdaptor = typename SourceOp::Adaptor; LogicalResult matchAndRewrite(SourceOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { static_assert( std::is_base_of, SourceOp>::value, "expected single result op"); + auto operands = adaptor.getOperands(); assert(operands.size() == 1 && "expected unary operation"); rewriter.replaceOpWithNewOp( op, this->lowering.convertType(op.getType()), operands.front()); @@ -298,14 +302,16 @@ namespace struct ToTernaryLLVMOpPattern : public OpAndTypeConversionPattern { using OpAndTypeConversionPattern::OpAndTypeConversionPattern; + using OpAdaptor = typename SourceOp::Adaptor; LogicalResult matchAndRewrite(SourceOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { static_assert( std::is_base_of, SourceOp>::value, "expected single result op"); + auto operands = adaptor.getOperands(); assert(operands.size() == 3 && "expected ternary operation"); rewriter.replaceOpWithNewOp( op, this->lowering.convertType(op.getType()), @@ -320,9 +326,10 @@ namespace struct ToUndefOpPattern : public OpAndTypeConversionPattern { using OpAndTypeConversionPattern::OpAndTypeConversionPattern; + using OpAdaptor = typename SourceOp::Adaptor; LogicalResult matchAndRewrite(SourceOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { static_assert( @@ -340,9 +347,10 @@ namespace LogicalResult matchAndRewrite(ConvertStdOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); // TODO: check that this conversion is valid rewriter.replaceOp(op, operands.front()); return success(); @@ -354,7 +362,7 @@ namespace using OpAndTypeConversionPattern::OpAndTypeConversionPattern; LogicalResult matchAndRewrite(ConstantOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { jl_value_t *value = op.value(); @@ -427,9 +435,10 @@ namespace using OpAndTypeConversionPattern::OpAndTypeConversionPattern; LogicalResult matchAndRewrite(GotoIfNotOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); assert(operands.size() >= 1); rewriter.replaceOpWithNewOp( op, operands, op.getSuccessors(), op->getAttrs()); @@ -442,9 +451,10 @@ namespace using OpAndTypeConversionPattern::OpAndTypeConversionPattern; LogicalResult matchAndRewrite(GotoOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); rewriter.replaceOpWithNewOp( op, operands, op.getSuccessor(), op->getAttrs()); return success(); @@ -456,9 +466,10 @@ namespace using OpAndTypeConversionPattern::OpAndTypeConversionPattern; LogicalResult matchAndRewrite(ReturnOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); rewriter.replaceOpWithNewOp(op, operands); return success(); } @@ -469,9 +480,10 @@ namespace using OpAndTypeConversionPattern::OpAndTypeConversionPattern; LogicalResult matchAndRewrite(Intrinsic_not_int op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); jl_datatype_t *operand_type = op.getOperand(0).getType().dyn_cast().getDatatype(); bool is_bool = operand_type == jl_bool_type; @@ -499,9 +511,10 @@ namespace using OpAndTypeConversionPattern::OpAndTypeConversionPattern; LogicalResult matchAndRewrite(Builtin_is op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); assert(operands.size() == 2); jl_value_t *jt1 = (jl_value_t *)op.getOperand(0).getType().cast().getDatatype(); jl_value_t *jt2 = (jl_value_t *)op.getOperand(1).getType().cast().getDatatype(); diff --git a/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp b/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp index 756fda8..5770e20 100644 --- a/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp +++ b/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp @@ -1,6 +1,7 @@ #include "brutus/Conversion/JLIRToStandard/JLIRToStandard.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" +#include "mlir/Dialect/Arithmetic/IR/Arithmetic.h" #include "mlir/Dialect/Math/IR/Math.h" #include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/IR/AffineMap.h" @@ -120,8 +121,7 @@ struct JLIRToStdConversionPattern : OpConversionPattern { JLIRToStandardTypeConverter &lowering) : OpConversionPattern(lowering, ctx){} - Value - convertValue(ConversionPatternRewriter &rewriter, + Value convertValue(ConversionPatternRewriter &rewriter, Location location, Value value) const { @@ -156,7 +156,7 @@ struct JLIRToStdConversionPattern : OpConversionPattern { // an index, unlike most other uses, which involve a Julia type ConvertStdOp convertedIndex = rewriter.create( location, rewriter.getIndexType(), index); - SubIOp subOp = rewriter.create( + arith::SubIOp subOp = rewriter.create( location, rewriter.getIndexType(), convertedIndex.getResult(), @@ -168,10 +168,12 @@ struct JLIRToStdConversionPattern : OpConversionPattern { template struct ToStdOpPattern : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; + using OpAdaptor = typename SourceOp::Adaptor; LogicalResult matchAndRewrite(SourceOp op, - ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { + OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); auto result = this->typeConverter->convertType(op.getType()); if (!result) return failure(); @@ -185,37 +187,38 @@ struct ToStdOpPattern : public JLIRToStdConversionPattern { template struct ToCmpOpPattern : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; + using OpAdaptor = typename SourceOp::Adaptor; LogicalResult matchAndRewrite(SourceOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - - + auto operands = adaptor.getOperands(); rewriter.replaceOpWithNewOp(op, predicate, operands[0], operands[1]); return success(); } }; -template -struct ToCmpIOpPattern : public ToCmpOpPattern { - using ToCmpOpPattern::ToCmpOpPattern; +template +struct ToCmpIOpPattern : public ToCmpOpPattern { + using ToCmpOpPattern::ToCmpOpPattern; }; -template -struct ToCmpFOpPattern : public ToCmpOpPattern { - using ToCmpOpPattern::ToCmpOpPattern; +template +struct ToCmpFOpPattern : public ToCmpOpPattern { + using ToCmpOpPattern::ToCmpOpPattern; }; struct ConstantOpLowering : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; + LogicalResult matchAndRewrite(jlir::ConstantOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { JuliaType type = op.getType().cast(); jl_datatype_t *julia_type = type.getDatatype(); @@ -251,11 +254,11 @@ struct GotoOpLowering : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(GotoOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - + rewriter.replaceOpWithNewOp( - op, op.getSuccessor(), operands); + op, op.getSuccessor(), adaptor.getOperands()); return success(); } }; @@ -264,15 +267,16 @@ struct GotoIfNotOpLowering : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(GotoIfNotOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); unsigned nBranchOperands = op.branchOperands().size(); unsigned nFallthroughOperands = op.fallthroughOperands().size(); assert(operands.size() == nBranchOperands + nFallthroughOperands + 1); Value cond = this->convertValue(rewriter, op.getLoc(), operands.front()); // TODO: Go from i8 to i1 - ValueRange branchOperands = operands.slice(1, nBranchOperands); + ValueRange branchOperands = operands.slice(1, nBranchOperands); ValueRange fallthroughOperands = operands.slice(1 + nBranchOperands, nFallthroughOperands); rewriter.replaceOpWithNewOp(op, cond, @@ -286,10 +290,10 @@ struct ReturnOpLowering : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(jlir::ReturnOp op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - rewriter.replaceOpWithNewOp(op, operands); + rewriter.replaceOpWithNewOp(op, adaptor.getOperands()); return success(); } }; @@ -298,9 +302,10 @@ struct NotIntOpLowering : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(Intrinsic_not_int op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - + + auto operands = adaptor.getOperands(); IntegerType type = operands.front().getType().cast(); mlir::ConstantOp maskConstantOp = @@ -311,7 +316,7 @@ struct NotIntOpLowering : public JLIRToStdConversionPattern { APInt(type.getWidth(), -1, /*isSigned=*/true))); - rewriter.replaceOpWithNewOp( + rewriter.replaceOpWithNewOp( op, type, operands.front(), maskConstantOp.getResult()); return success(); } @@ -321,8 +326,9 @@ struct IsOpLowering : public JLIRToStdConversionPattern { using JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(Builtin_is op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); IntegerAttr falseAttr = rewriter.getIntegerAttr(rewriter.getI1Type(), 0); @@ -356,10 +362,11 @@ struct ArrayrefOpLowering : public JLIRToStdConversionPattern using JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(Builtin_arrayref op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + auto operands = adaptor.getOperands(); Value memref = operands[1]; - + if (auto memrefType = memref.getType().dyn_cast()) { // indices are reversed because Julia is column-major, but MLIR is // row-major @@ -391,11 +398,13 @@ struct ArraysetOpLowering : public JLIRToStdConversionPattern using JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(Builtin_arrayset op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { + + auto operands = adaptor.getOperands(); // arrayset(i1, Array, val, indices...) Value memref = operands[1]; - + if (auto memrefType = memref.getType().dyn_cast()) { // indices are reversed because Julia is column-major, but MLIR is // row-major @@ -427,13 +436,14 @@ struct ArraysizeOpLowering : public JLIRToStdConversionPattern::JLIRToStdConversionPattern; LogicalResult matchAndRewrite(Builtin_arraysize op, - ArrayRef operands, + OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { // TODO: Boundschecking // arraysize(array, ndim) + auto operands = adaptor.getOperands(); Value memref = operands[0]; - - if (auto memrefType = memref.getType().dyn_cast()) { + + if (auto memrefType = memref.getType().dyn_cast()) { // indices are reversed because Julia is column-major, but MLIR is // row-major auto rank = getIndexConstant(rewriter, op.getLoc(), memrefType.getRank()); @@ -441,7 +451,7 @@ struct ArraysizeOpLowering : public JLIRToStdConversionPattern(op.getLoc(), indexType, operands[1]); - SubIOp subOp = rewriter.create(op.getLoc(), indexType, rank, index); + arith::SubIOp subOp = rewriter.create(op.getLoc(), indexType, rank, index); rewriter.replaceOpWithNewOp(op, memref, subOp.getResult()); return success(); @@ -452,10 +462,10 @@ struct ArraysizeOpLowering : public JLIRToStdConversionPattern, - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, // Intrinsic_add_ptr // Intrinsic_sub_ptr - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, // Intrinsic_fma_float (JLIRToLLVM) // Intrinsic_muladd_float // Intrinsic_neg_float_fast @@ -491,38 +501,38 @@ void mlir::jlir::populateJLIRToStdConversionPatterns(RewritePatternSet &patterns // Intrinsic_mul_float_fast // Intrinsic_div_float_fast // Intrinsic_rem_float_fast - ToCmpIOpPattern, - ToCmpIOpPattern, - ToCmpIOpPattern, - ToCmpIOpPattern, - ToCmpIOpPattern, - ToCmpIOpPattern, - ToCmpFOpPattern, - ToCmpFOpPattern, - ToCmpFOpPattern, - ToCmpFOpPattern, + ToCmpIOpPattern, + ToCmpIOpPattern, + ToCmpIOpPattern, + ToCmpIOpPattern, + ToCmpIOpPattern, + ToCmpIOpPattern, + ToCmpFOpPattern, + ToCmpFOpPattern, + ToCmpFOpPattern, + ToCmpFOpPattern, // Intrinsic_fpiseq // Intrinsic_fpislt - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, NotIntOpLowering, // Intrinsic_not_int - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, // Intrinsic_bswap_int // Intrinsic_ctpop_int // Intrinsic_ctlz_int // Intrinsic_cttz_int - ToStdOpPattern, // TODO: args don't match - ToStdOpPattern, - ToStdOpPattern, + ToStdOpPattern, // TODO: args don't match + ToStdOpPattern, + ToStdOpPattern, // Intrinsic_fptoui // Intrinsic_fptosi // Intrinsic_uitofp - ToStdOpPattern, - ToStdOpPattern, - ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, // Intrinsic_checked_sadd_int // Intrinsic_checked_uadd_int // Intrinsic_checked_ssub_int @@ -533,10 +543,10 @@ void mlir::jlir::populateJLIRToStdConversionPatterns(RewritePatternSet &patterns // Intrinsic_checked_udiv_int // Intrinsic_checked_srem_int // Intrinsic_checked_urem_int - ToStdOpPattern, - ToStdOpPattern, + ToStdOpPattern, + ToStdOpPattern, // Intrinsic_flipsign_int - ToStdOpPattern, + ToStdOpPattern, // Intrinsic_floor_llvm // Intrinsic_trunc_llvm (JLIRToLLVM, but maybe could be here?) // Intrinsic_rint_llvm @@ -625,7 +635,7 @@ void JLIRToStandardLoweringPass::runOnOperation() { target.addDynamicallyLegalOp([&converter](FuncOp op) { return isFuncOpLegal(op, converter); }); - populateFuncOpTypeConversionPattern(patterns, converter); + // populateFuncOpTypeConversionPattern(patterns, converter); if (failed(applyPartialConversion( module, target, std::move(patterns)))) diff --git a/lib/Dialect/Julia/CanonicalizationPatterns.cpp b/lib/Dialect/Julia/CanonicalizationPatterns.cpp index 02a09b1..12211f5 100644 --- a/lib/Dialect/Julia/CanonicalizationPatterns.cpp +++ b/lib/Dialect/Julia/CanonicalizationPatterns.cpp @@ -95,10 +95,10 @@ struct LowerBuiltinCallPattern : public OpRewritePattern { /// Register our patterns as "canonicalization" patterns on the CallOp so /// that they can be picked up by the Canonicalization framework. -void CallOp::getCanonicalizationPatterns(OwningRewritePatternList &results, +void CallOp::getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context) { - results.insert(context); - results.insert(context); + results.add(context); + results.add(context); } namespace { @@ -115,7 +115,7 @@ struct SimplifyRedundantConvertStdOps : public OpRewritePattern { rewriter.replaceOp(op, {op.getOperand()}); return success(); } - + // 2. Check if we have a chain of convert ops ConvertStdOp inputOp = dyn_cast_or_null( op.getOperand().getDefiningOp()); @@ -131,13 +131,13 @@ struct SimplifyRedundantConvertStdOps : public OpRewritePattern { // 3. Shortcut the input op. rewriter.replaceOpWithNewOp(op, resultType, inputOp.getOperand()); - return success(); + return success(); } }; } // namespace -void ConvertStdOp::getCanonicalizationPatterns(OwningRewritePatternList &results, +void ConvertStdOp::getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context) { results.insert(context); } From 9f0edf816bf8f45efeb1d0d4dbf826bd2ec2dba5 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 8 Mar 2022 11:14:04 -0500 Subject: [PATCH 3/7] fixup! add Brutus C-API --- include/brutus-c/Dialects.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 include/brutus-c/Dialects.h diff --git a/include/brutus-c/Dialects.h b/include/brutus-c/Dialects.h new file mode 100644 index 0000000..fd4d808 --- /dev/null +++ b/include/brutus-c/Dialects.h @@ -0,0 +1,24 @@ +//===- Dialects.h - CAPI for dialects -----------------------------*- C -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef BRUTUS_C_DIALECTS_H +#define BRUTUS_C_DIALECTS_H + +#include "mlir-c/Registration.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(JLIR, jlir); + +#ifdef __cplusplus +} +#endif + +#endif // BRUTUS_C_DIALECTS_H \ No newline at end of file From 6f38970e75abdc90e3a6c96979f2c725894a59dc Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 9 Mar 2022 13:28:51 -0500 Subject: [PATCH 4/7] fix README --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8842acf..12f77a8 100644 --- a/README.md +++ b/README.md @@ -10,20 +10,16 @@ _Brutus_ `Brutus` currently requires that you create a non-standard build of Julia. ``` -export LLVM_SHA1=4743f8ded72e15f916fa1d4cc198bdfd7bfb2193 # LLVM 13.0.1-0 -export JULIA_SHA1=6c16f717f9871401eed9350f36cd84ab51778b72 # Julia 1.8-dev - git clone https://github.com/JuliaLabs/brutus cd brutus -git clone https://github.com/JuliaLang/julia +git clone https://github.com/JuliaLabs/julia-mlir cd julia -git checkout ${JULIA_SHA1} +git checkout staging make -j `nproc` \ USE_BINARYBUILDER_LLVM=0 \ DEPS_GIT=1 \ LLVM_DEBUG=0 \ USE_MLIR=1 \ - LLVM_SHA1="${LLVM_SHA1}" cd .. mkdir build && cd build cmake .. -G Ninja \ From 70e98e8ae5e1792135f1ee448dfcfd0c9707fb33 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 9 Mar 2022 13:33:41 -0500 Subject: [PATCH 5/7] use JuliaLabs/julia-mlir#staging --- .github/workflows/CI.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0719cc6..c96fa81 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,9 +15,8 @@ jobs: strategy: matrix: os: [ubuntu-18.04] - julia-repository: [JuliaLang/julia] - julia-commit: [f3e3554910a79fa38d5662d14abe04e137075e18] # Julia 1.8-dev - llvm-commit: [4743f8ded72e15f916fa1d4cc198bdfd7bfb2193] # LLVM 13.0.1-0 + julia-repository: [JuliaLabs/julia-mlir] + julia-commit: [581269b6e2366738eab09bda2a632fce755e4e43] # Julia 1.8-dev env: CCACHE_DIR: ${GITHUB_WORKSPACE}/.ccache @@ -64,10 +63,8 @@ jobs: cd julia make -j `nproc` \ USE_BINARYBUILDER_LLVM=0 \ - DEPS_GIT=1 \ LLVM_DEBUG=0 \ USE_MLIR=1 \ - LLVM_SHA1=${{ matrix.llvm-commit }} \ JULIA_CPU_TARGET="generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)" - name: Check Julia version From 490b23fc12403445e86df1ace184de0ae960e50d Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 21 Mar 2022 17:31:01 -0400 Subject: [PATCH 6/7] populateFunctionOpInterfaceTypeConversionPattern change --- lib/Conversion/JLIRToStandard/JLIRToStandard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp b/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp index 5770e20..e702642 100644 --- a/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp +++ b/lib/Conversion/JLIRToStandard/JLIRToStandard.cpp @@ -7,7 +7,7 @@ #include "mlir/IR/AffineMap.h" #include "mlir/IR/Types.h" -#include "mlir/Dialect/StandardOps/Transforms/FuncConversions.h" +#include "mlir/Transforms/DialectConversion.h" #include "llvm/Support/FormatVariadic.h" @@ -635,7 +635,7 @@ void JLIRToStandardLoweringPass::runOnOperation() { target.addDynamicallyLegalOp([&converter](FuncOp op) { return isFuncOpLegal(op, converter); }); - // populateFuncOpTypeConversionPattern(patterns, converter); + mlir::populateFunctionOpInterfaceTypeConversionPattern(patterns, converter); if (failed(applyPartialConversion( module, target, std::move(patterns)))) From 34b44764d4772f2ead2f2acdd7faa2b205af9262 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 21 Mar 2022 17:57:31 -0400 Subject: [PATCH 7/7] change type of phi node edges --- lib/Codegen/Codegen.cpp | 3 ++- test/Codegen/canonicalize/return_nothing.jl | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/Codegen/Codegen.cpp b/lib/Codegen/Codegen.cpp index 4b361a3..82a933b 100644 --- a/lib/Codegen/Codegen.cpp +++ b/lib/Codegen/Codegen.cpp @@ -327,7 +327,8 @@ mlir::FuncOp emit_function(jl_mlirctx_t &ctx, bool found = false; for (int edge = 0; edge < nedges; ++edge) { - int frombb = jl_unbox_long(jl_arrayref(edges, edge)); // frombb is 1-indexed + // Julia 1.9 PhiNode -> Int32[] + int frombb = jl_unbox_int32(jl_arrayref(edges, edge)); // frombb is 1-indexed if (frombb == current_block) { mlir::Value value = diff --git a/test/Codegen/canonicalize/return_nothing.jl b/test/Codegen/canonicalize/return_nothing.jl index 5c8f693..3f7ce50 100644 --- a/test/Codegen/canonicalize/return_nothing.jl +++ b/test/Codegen/canonicalize/return_nothing.jl @@ -3,9 +3,7 @@ f() = return emit(f) - - -# CHECK: module { +# CHECK: module { # CHECK-NEXT: func nested @"Tuple{typeof(Main.f)}"(%arg0: !jlir<"typeof(Main.f)">) -> !jlir.Nothing attributes {llvm.emit_c_interface} { # CHECK-NEXT: "jlir.goto"()[^bb1] : () -> () # CHECK-NEXT: ^bb1: // pred: ^bb0 @@ -14,7 +12,7 @@ emit(f) # CHECK-NEXT: } # CHECK-NEXT: } -# CHECK: module { +# CHECK: module { # CHECK-NEXT: func nested @"Tuple{typeof(Main.f)}"(%arg0: !jlir<"typeof(Main.f)">) -> !jlir.Nothing attributes {llvm.emit_c_interface} { # CHECK-NEXT: "jlir.goto"()[^bb1] : () -> () # CHECK-NEXT: ^bb1: // pred: ^bb0