├── examples ├── CMakeLists.txt ├── toy │ ├── Ch1 │ │ ├── CMakeLists.txt │ │ └── toyc.cpp │ ├── README.md │ ├── CMakeLists.txt │ ├── Ch2 │ │ ├── CMakeLists.txt │ │ └── include │ │ │ └── toy │ │ │ └── MLIRGen.h │ └── Ch3 │ │ ├── CMakeLists.txt │ │ └── include │ │ └── toy │ │ └── MLIRGen.h └── Linalg │ ├── Linalg2 │ ├── include │ │ └── linalg2 │ │ │ ├── Analysis.h │ │ │ ├── Ops.h │ │ │ ├── Intrinsics.h │ │ │ └── Transforms.h │ └── lib │ │ └── DialectRegistration.cpp │ ├── Linalg3 │ ├── include │ │ └── linalg3 │ │ │ ├── Ops.h │ │ │ ├── Intrinsics.h │ │ │ ├── Analysis.h │ │ │ ├── Transforms.h │ │ │ └── TensorOps.h │ └── lib │ │ ├── DialectRegistration.cpp │ │ └── Analysis.cpp │ └── Linalg1 │ ├── include │ └── linalg1 │ │ ├── Ops.h │ │ ├── ConvertToLLVMDialect.h │ │ ├── Utils.h │ │ ├── Types.h │ │ ├── Intrinsics.h │ │ ├── Dialect.h │ │ ├── RangeType.h │ │ ├── Analysis.h │ │ ├── ViewType.h │ │ └── RangeOp.h │ ├── lib │ ├── Utils.cpp │ ├── DialectRegistration.cpp │ ├── Dialect.cpp │ ├── Common.cpp │ └── RangeOp.cpp │ └── TestHarness.h ├── lib ├── Target │ ├── CMakeLists.txt │ └── LLVMIR │ │ └── CMakeLists.txt ├── VectorOps │ ├── CMakeLists.txt │ └── DialectRegistration.cpp ├── Dialect │ └── CMakeLists.txt ├── Support │ ├── CMakeLists.txt │ └── FileUtilities.cpp ├── Translation │ └── CMakeLists.txt ├── EDSC │ ├── CMakeLists.txt │ └── Helpers.cpp ├── IR │ ├── CMakeLists.txt │ ├── Module.cpp │ ├── IntegerSetDetail.h │ ├── AffineMapDetail.h │ ├── Location.cpp │ └── IntegerSet.cpp ├── Parser │ ├── CMakeLists.txt │ └── Lexer.h ├── Pass │ └── CMakeLists.txt ├── AffineOps │ ├── CMakeLists.txt │ └── DialectRegistration.cpp ├── StandardOps │ ├── CMakeLists.txt │ └── DialectRegistration.cpp ├── TableGen │ ├── CMakeLists.txt │ ├── Argument.cpp │ ├── Type.cpp │ ├── OpTrait.cpp │ └── Constraint.cpp ├── LLVMIR │ └── CMakeLists.txt ├── ExecutionEngine │ └── CMakeLists.txt ├── FxpMathOps │ ├── CMakeLists.txt │ └── IR │ │ ├── DialectRegistration.cpp │ │ └── FxpMathOps.cpp ├── Analysis │ ├── CMakeLists.txt │ ├── TestParallelismDetection.cpp │ └── MemRefBoundCheck.cpp ├── CMakeLists.txt ├── Quantization │ ├── CMakeLists.txt │ └── IR │ │ └── DialectRegistration.cpp └── Transforms │ ├── CMakeLists.txt │ ├── StripDebugInfo.cpp │ └── Canonicalizer.cpp ├── .clang-format ├── test ├── Examples │ ├── lit.local.cfg │ └── Toy │ │ ├── Ch2 │ │ ├── invalid.mlir │ │ └── codegen.toy │ │ └── Ch3 │ │ ├── invalid.mlir │ │ ├── scalar.toy │ │ └── codegen.toy ├── IR │ ├── check-help-output.mlir │ ├── locations.mlir │ ├── pretty-locations.mlir │ ├── op-stats.mlir │ └── invalid-locations.mlir ├── LLVMIR │ ├── convert-argattrs.mlir │ └── convert-funcs.mlir ├── Transforms │ ├── strip-debuginfo.mlir │ ├── parallelism-detection.mlir │ └── Vectorize │ │ ├── vectorize_3d.mlir │ │ ├── vectorize_outer_loop_2d.mlir │ │ ├── vector_utils.mlir │ │ ├── materialize.mlir │ │ └── normalize_maps.mlir ├── mlir-tblgen │ ├── reference-impl.td │ ├── op-operand.td │ ├── pattern-benefit.td │ ├── directive-verifyUnusedValue.td │ ├── one-op-one-result.td │ ├── attr-enum.td │ ├── op-decl.td │ ├── pattern-tAttr.td │ └── op-attribute.td ├── Unit │ ├── lit.site.cfg.py.in │ └── lit.cfg.py ├── CMakeLists.txt ├── mlir-cpu-runner │ └── simple.mlir ├── Quantization │ └── convert-fakequant-invalid.mlir ├── AffineOps │ └── ops.mlir ├── lit.site.cfg.py.in ├── lit.cfg.py └── Pass │ ├── ir-printing.mlir │ └── pass-timing.mlir ├── tools ├── CMakeLists.txt ├── mlir-tblgen │ └── CMakeLists.txt ├── mlir-opt │ └── CMakeLists.txt ├── mlir-translate │ └── CMakeLists.txt └── mlir-cpu-runner │ └── CMakeLists.txt ├── unittests ├── Pass │ └── CMakeLists.txt ├── IR │ ├── CMakeLists.txt │ └── DialectTest.cpp ├── Dialect │ └── CMakeLists.txt └── CMakeLists.txt ├── g3doc └── includes │ └── style.css ├── include └── mlir │ ├── CMakeLists.txt │ ├── StandardOps │ └── CMakeLists.txt │ ├── FxpMathOps │ ├── CMakeLists.txt │ ├── FxpMathOps.h │ └── Passes.h │ ├── Quantization │ ├── CMakeLists.txt │ └── Passes.h │ ├── EDSC │ └── CMakeLists.txt │ ├── LLVMIR │ ├── CMakeLists.txt │ └── Transforms.h │ ├── TableGen │ ├── GenNameParser.h │ ├── Type.h │ └── Argument.h │ ├── Analysis │ └── Passes.h │ ├── Target │ └── LLVMIR.h │ ├── Support │ ├── FileUtilities.h │ ├── LogicalResult.h │ └── MathExtras.h │ ├── IR │ └── DialectTypeRegistry.def │ ├── Transforms │ └── ViewFunctionGraph.h │ ├── ExecutionEngine │ ├── MemRefUtils.h │ └── OptUtils.h │ ├── Parser.h │ └── Translation.h ├── CONTRIBUTING.md ├── CMakeLists.txt └── utils └── vim └── mlir.vim /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(toy) 2 | 3 | -------------------------------------------------------------------------------- /lib/Target/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(LLVMIR) 2 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | AlwaysBreakTemplateDeclarations: Yes -------------------------------------------------------------------------------- /test/Examples/lit.local.cfg: -------------------------------------------------------------------------------- 1 | if not config.build_examples: 2 | config.unsupported = True 3 | -------------------------------------------------------------------------------- /test/IR/check-help-output.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt --help | FileCheck %s 2 | // 3 | // CHECK: OVERVIEW: MLIR modular optimizer driver 4 | 5 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(mlir-cpu-runner) 2 | add_subdirectory(mlir-opt) 3 | add_subdirectory(mlir-tblgen) 4 | add_subdirectory(mlir-translate) 5 | -------------------------------------------------------------------------------- /unittests/Pass/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_mlir_unittest(MLIRPassTests 2 | AnalysisManagerTest.cpp 3 | ) 4 | target_link_libraries(MLIRPassTests 5 | PRIVATE 6 | MLIRPass) 7 | -------------------------------------------------------------------------------- /g3doc/includes/style.css: -------------------------------------------------------------------------------- 1 | .mlir { 2 | background-color: #eef; 3 | } 4 | 5 | .ebnf { 6 | background-color: #ffe; 7 | } 8 | 9 | .td { 10 | background-color: #eef; 11 | } 12 | -------------------------------------------------------------------------------- /include/mlir/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(FxpMathOps) 2 | add_subdirectory(LLVMIR) 3 | add_subdirectory(Quantization) 4 | add_subdirectory(StandardOps) 5 | add_subdirectory(EDSC) 6 | -------------------------------------------------------------------------------- /unittests/IR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_mlir_unittest(MLIRIRTests 2 | DialectTest.cpp 3 | OperationSupportTest.cpp 4 | ) 5 | target_link_libraries(MLIRIRTests 6 | PRIVATE 7 | MLIRIR) 8 | -------------------------------------------------------------------------------- /examples/toy/Ch1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS 2 | Support 3 | ) 4 | 5 | add_toy_chapter(toyc-ch1 6 | toyc.cpp 7 | parser/AST.cpp 8 | ) 9 | include_directories(include/) -------------------------------------------------------------------------------- /unittests/Dialect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_mlir_unittest(MLIRDialectTests 2 | BroadcastShapeTest.cpp 3 | ) 4 | target_link_libraries(MLIRDialectTests 5 | PRIVATE 6 | MLIRIR 7 | MLIRDialect) 8 | -------------------------------------------------------------------------------- /lib/VectorOps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRVectorOps 2 | DialectRegistration.cpp 3 | VectorOps.cpp 4 | 5 | ADDITIONAL_HEADER_DIRS 6 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/VectorOps 7 | ) 8 | -------------------------------------------------------------------------------- /lib/Dialect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRDialect 2 | Traits.cpp 3 | 4 | ADDITIONAL_HEADER_DIRS 5 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect 6 | ) 7 | target_link_libraries(MLIRDialect MLIRIR) 8 | -------------------------------------------------------------------------------- /include/mlir/StandardOps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS Ops.td) 2 | mlir_tablegen(Ops.h.inc -gen-op-decls) 3 | mlir_tablegen(Ops.cpp.inc -gen-op-defs) 4 | add_public_tablegen_target(MLIRStandardOpsIncGen) 5 | -------------------------------------------------------------------------------- /lib/Support/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRSupport 2 | FileUtilities.cpp 3 | 4 | ADDITIONAL_HEADER_DIRS 5 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Support 6 | ) 7 | target_link_libraries(MLIRSupport LLVMSupport) 8 | -------------------------------------------------------------------------------- /lib/Translation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRTranslation 2 | Translation.cpp 3 | 4 | ADDITIONAL_HEADER_DIRS 5 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Translation 6 | ) 7 | target_link_libraries(MLIRTranslation LLVMSupport) 8 | -------------------------------------------------------------------------------- /include/mlir/FxpMathOps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS FxpMathOps.td) 2 | mlir_tablegen(FxpMathOps.h.inc -gen-op-decls) 3 | mlir_tablegen(FxpMathOps.cpp.inc -gen-op-defs) 4 | add_public_tablegen_target(MLIRFxpMathOpsIncGen) 5 | -------------------------------------------------------------------------------- /include/mlir/Quantization/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS QuantOps.td) 2 | mlir_tablegen(QuantOps.h.inc -gen-op-decls) 3 | mlir_tablegen(QuantOps.cpp.inc -gen-op-defs) 4 | add_public_tablegen_target(MLIRQuantizationOpsIncGen) 5 | -------------------------------------------------------------------------------- /include/mlir/EDSC/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS "${MLIR_MAIN_SRC_DIR}/../test/mlir-tblgen/reference-impl.td") 2 | mlir_tablegen("reference-impl.inc" -gen-reference-implementations) 3 | add_public_tablegen_target(MLIRReferenceImplementationTestGen) 4 | -------------------------------------------------------------------------------- /examples/toy/README.md: -------------------------------------------------------------------------------- 1 | # Toy Tutorial 2 | 3 | This contains sample code to support the tutorial on using MLIR for 4 | building a compiler for a simple Toy language. 5 | 6 | See [g3doc/Tutorials/Toy](../../g3doc/Tutorials/Toy) at the root of 7 | the repository for more informations. 8 | -------------------------------------------------------------------------------- /lib/EDSC/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIREDSC 2 | Builders.cpp 3 | CoreAPIs.cpp 4 | Helpers.cpp 5 | Intrinsics.cpp 6 | 7 | ADDITIONAL_HEADER_DIRS 8 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/EDSC 9 | ) 10 | add_dependencies(MLIREDSC MLIRReferenceImplementationTestGen) 11 | -------------------------------------------------------------------------------- /lib/IR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB globbed *.c *.cpp) 2 | add_llvm_library(MLIRIR 3 | ${globbed} 4 | 5 | ADDITIONAL_HEADER_DIRS 6 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/IR 7 | ) 8 | add_dependencies(MLIRIR MLIRSupport LLVMSupport) 9 | target_link_libraries(MLIRIR LLVMSupport) 10 | -------------------------------------------------------------------------------- /lib/Parser/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRParser 2 | Lexer.cpp 3 | Parser.cpp 4 | Token.cpp 5 | 6 | ADDITIONAL_HEADER_DIRS 7 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Parser 8 | ) 9 | add_dependencies(MLIRParser MLIRIR MLIRAnalysis) 10 | target_link_libraries(MLIRParser MLIRIR MLIRAnalysis) 11 | -------------------------------------------------------------------------------- /test/LLVMIR/convert-argattrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt -convert-to-llvmir %s | FileCheck %s 2 | 3 | 4 | // CHECK-LABEL: func @check_attributes(%arg0: !llvm<"float*"> {dialect.a: true, dialect.b: 4}) { 5 | func @check_attributes(%static: memref<10x20xf32> {dialect.a: true, dialect.b: 4 }) { 6 | return 7 | } 8 | 9 | -------------------------------------------------------------------------------- /lib/Pass/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB globbed *.c *.cpp) 2 | add_llvm_library(MLIRPass 3 | ${globbed} 4 | 5 | ADDITIONAL_HEADER_DIRS 6 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Pass 7 | ) 8 | add_dependencies(MLIRPass MLIRAnalysis MLIRIR LLVMSupport) 9 | target_link_libraries(MLIRPass MLIRAnalysis MLIRIR LLVMSupport) 10 | -------------------------------------------------------------------------------- /lib/AffineOps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRAffineOps 2 | AffineOps.cpp 3 | DialectRegistration.cpp 4 | 5 | ADDITIONAL_HEADER_DIRS 6 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/AffineOps 7 | ) 8 | add_dependencies(MLIRAffineOps MLIRIR MLIRStandardOps) 9 | target_link_libraries(MLIRAffineOps MLIRIR MLIRStandardOps) 10 | 11 | -------------------------------------------------------------------------------- /lib/StandardOps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB globbed *.c *.cpp) 2 | add_llvm_library(MLIRStandardOps 3 | ${globbed} 4 | 5 | ADDITIONAL_HEADER_DIRS 6 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/StandardOps 7 | ) 8 | add_dependencies(MLIRStandardOps MLIRStandardOpsIncGen LLVMSupport) 9 | target_link_libraries(MLIRStandardOps LLVMSupport) 10 | -------------------------------------------------------------------------------- /lib/Target/LLVMIR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRTargetLLVMIR 2 | ConvertToLLVMIR.cpp 3 | 4 | ADDITIONAL_HEADER_DIRS 5 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Target/LLVMIR 6 | DEPENDS 7 | intrinsics_gen 8 | ) 9 | target_link_libraries(MLIRTargetLLVMIR MLIRLLVMIR MLIRTranslation LLVMCore LLVMSupport LLVMTransformUtils) 10 | -------------------------------------------------------------------------------- /examples/toy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_target(Toy) 2 | set_target_properties(Toy PROPERTIES FOLDER Examples) 3 | 4 | macro(add_toy_chapter name) 5 | add_dependencies(Toy ${name}) 6 | add_llvm_example(${name} ${ARGN}) 7 | endmacro(add_toy_chapter name) 8 | 9 | add_subdirectory(Ch1) 10 | add_subdirectory(Ch2) 11 | add_subdirectory(Ch3) 12 | -------------------------------------------------------------------------------- /unittests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_target(MLIRUnitTests) 2 | set_target_properties(MLIRUnitTests PROPERTIES FOLDER "MLIR Tests") 3 | 4 | function(add_mlir_unittest test_dirname) 5 | add_unittest(MLIRUnitTests ${test_dirname} ${ARGN}) 6 | endfunction() 7 | 8 | add_subdirectory(Dialect) 9 | add_subdirectory(IR) 10 | add_subdirectory(Pass) 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project soon. But we 4 | are not yet ready to accept community contributions at this time. 5 | 6 | ## Community Guidelines 7 | 8 | This project follows [Google's Open Source Community 9 | Guidelines](https://opensource.google.com/conduct/). 10 | -------------------------------------------------------------------------------- /examples/toy/Ch2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS 2 | Support 3 | ) 4 | 5 | add_toy_chapter(toyc-ch2 6 | toyc.cpp 7 | parser/AST.cpp 8 | mlir/MLIRGen.cpp 9 | ) 10 | include_directories(include/) 11 | target_link_libraries(toyc-ch2 12 | PRIVATE 13 | MLIRAnalysis 14 | MLIRIR 15 | MLIRParser 16 | MLIRTransforms) 17 | -------------------------------------------------------------------------------- /tools/mlir-tblgen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS 2 | MLIRTableGen 3 | Support 4 | ) 5 | 6 | add_tablegen(mlir-tblgen MLIR 7 | LLVMIRConversionGen.cpp 8 | mlir-tblgen.cpp 9 | OpDefinitionsGen.cpp 10 | OpDocGen.cpp 11 | ReferenceImplGen.cpp 12 | RewriterGen.cpp 13 | ) 14 | set_target_properties(mlir-tblgen PROPERTIES FOLDER "Tablegenning") 15 | -------------------------------------------------------------------------------- /include/mlir/LLVMIR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS LLVMOps.td) 2 | mlir_tablegen(LLVMOps.h.inc -gen-op-decls) 3 | mlir_tablegen(LLVMOps.cpp.inc -gen-op-defs) 4 | add_public_tablegen_target(MLIRLLVMOpsIncGen) 5 | set(LLVM_TARGET_DEFINITIONS LLVMOps.td) 6 | mlir_tablegen(LLVMConversions.inc -gen-llvmir-conversions) 7 | add_public_tablegen_target(MLIRLLVMConversionsIncGen) 8 | -------------------------------------------------------------------------------- /lib/TableGen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(LLVMMLIRTableGen 2 | Argument.cpp 3 | Attribute.cpp 4 | Constraint.cpp 5 | Operator.cpp 6 | OpTrait.cpp 7 | Pattern.cpp 8 | Predicate.cpp 9 | Type.cpp 10 | 11 | ADDITIONAL_HEADER_DIRS 12 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/TableGen 13 | ) 14 | target_link_libraries(LLVMMLIRTableGen LLVMSupport LLVMTableGen) 15 | -------------------------------------------------------------------------------- /examples/toy/Ch3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS 2 | Support 3 | ) 4 | 5 | add_toy_chapter(toyc-ch3 6 | toyc.cpp 7 | parser/AST.cpp 8 | mlir/MLIRGen.cpp 9 | mlir/ToyDialect.cpp 10 | ) 11 | include_directories(include/) 12 | target_link_libraries(toyc-ch3 13 | PRIVATE 14 | MLIRAnalysis 15 | MLIRIR 16 | MLIRParser 17 | MLIRTransforms) 18 | -------------------------------------------------------------------------------- /test/Examples/Toy/Ch2/invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: toyc-ch2 %s -emit=mlir 2>&1 2 | 3 | 4 | // This IR is not "valid": 5 | // - toy.print should not return a value. 6 | // - toy.print should take an argument. 7 | // - There should be a block terminator. 8 | // This all round-trip since this is opaque for MLIR. 9 | func @main() { 10 | %0 = "toy.print"() : () -> !toy<"array<2, 3>"> 11 | } 12 | -------------------------------------------------------------------------------- /test/Examples/Toy/Ch3/invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: not toyc-ch3 %s -emit=mlir 2>&1 2 | 3 | 4 | // This IR is not "valid": 5 | // - toy.print should not return a value. 6 | // - toy.print should take an argument. 7 | // - There should be a block terminator. 8 | // This all round-trip since this is opaque for MLIR. 9 | func @main() { 10 | %0 = "toy.print"() : () -> !toy<"array<2, 3>"> 11 | } 12 | -------------------------------------------------------------------------------- /lib/LLVMIR/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRLLVMIR 2 | Transforms/ConvertToLLVMDialect.cpp 3 | IR/LLVMDialect.cpp 4 | 5 | ADDITIONAL_HEADER_DIRS 6 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/LLVMIR 7 | ) 8 | add_dependencies(MLIRLLVMIR MLIRLLVMOpsIncGen MLIRLLVMConversionsIncGen LLVMAsmParser LLVMCore LLVMSupport) 9 | target_link_libraries(MLIRLLVMIR LLVMAsmParser LLVMCore LLVMSupport) 10 | -------------------------------------------------------------------------------- /lib/ExecutionEngine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | llvm_map_components_to_libnames(outlibs "nativecodegen" "IPO") 2 | add_llvm_library(MLIRExecutionEngine 3 | ExecutionEngine.cpp 4 | MemRefUtils.cpp 5 | OptUtils.cpp 6 | 7 | ADDITIONAL_HEADER_DIRS 8 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/ExecutionEngine 9 | ) 10 | target_link_libraries(MLIRExecutionEngine MLIRLLVMIR MLIRPass MLIRTransforms LLVMExecutionEngine LLVMOrcJIT LLVMSupport ${outlibs}) 11 | -------------------------------------------------------------------------------- /tools/mlir-opt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LIBS 2 | MLIRAffineOps 3 | MLIRAnalysis 4 | MLIREDSC 5 | MLIRFxpMathOps 6 | MLIRLLVMIR 7 | MLIRParser 8 | MLIRPass 9 | MLIRQuantization 10 | MLIRStandardOps 11 | MLIRTransforms 12 | MLIRSupport 13 | MLIRVectorOps 14 | ) 15 | add_executable(mlir-opt 16 | mlir-opt.cpp 17 | ) 18 | llvm_update_compile_flags(mlir-opt) 19 | whole_archive_link(mlir-opt ${LIBS}) 20 | target_link_libraries(mlir-opt MLIRIR ${LIBS} LLVMSupport) 21 | -------------------------------------------------------------------------------- /tools/mlir-translate/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LIBS 2 | MLIRAffineOps 3 | MLIRAnalysis 4 | MLIREDSC 5 | MLIRParser 6 | MLIRPass 7 | MLIRStandardOps 8 | MLIRTargetLLVMIR 9 | MLIRTransforms 10 | MLIRTranslation 11 | MLIRSupport 12 | MLIRVectorOps 13 | ) 14 | add_executable(mlir-translate 15 | mlir-translate.cpp 16 | ) 17 | llvm_update_compile_flags(mlir-translate) 18 | whole_archive_link(mlir-translate ${LIBS}) 19 | target_link_libraries(mlir-translate MLIRIR ${LIBS} LLVMSupport) 20 | -------------------------------------------------------------------------------- /lib/FxpMathOps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRFxpMathOps 2 | IR/FxpMathOps.cpp 3 | IR/DialectRegistration.cpp 4 | Transforms/LowerUniformRealMath.cpp 5 | 6 | ADDITIONAL_HEADER_DIRS 7 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/FxpMathOps 8 | ) 9 | add_dependencies(MLIRFxpMathOps 10 | MLIRFxpMathOpsIncGen 11 | MLIRQuantization 12 | MLIRIR 13 | MLIRPass 14 | MLIRSupport 15 | MLIRStandardOps) 16 | -------------------------------------------------------------------------------- /tools/mlir-cpu-runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LIBS 2 | MLIRAffineOps 3 | MLIRAnalysis 4 | MLIREDSC 5 | MLIRExecutionEngine 6 | MLIRIR 7 | MLIRParser 8 | MLIRTransforms 9 | MLIRSupport 10 | LLVMCore 11 | LLVMSupport 12 | ) 13 | add_executable(mlir-cpu-runner 14 | mlir-cpu-runner.cpp 15 | ) 16 | llvm_update_compile_flags(mlir-cpu-runner) 17 | whole_archive_link(mlir-cpu-runner MLIRLLVMIR MLIRStandardOps MLIRTargetLLVMIR MLIRTransforms MLIRTranslation) 18 | target_link_libraries(mlir-cpu-runner MLIRIR ${LIBS}) 19 | -------------------------------------------------------------------------------- /test/Examples/Toy/Ch3/scalar.toy: -------------------------------------------------------------------------------- 1 | # RUN: toyc-ch3 %s -emit=mlir 2>&1 | FileCheck %s 2 | 3 | def main() { 4 | var a<2, 2> = 5.5; 5 | print(a); 6 | } 7 | 8 | # CHECK-LABEL: func @main() { 9 | # CHECK-NEXT: %0 = "toy.constant"() {value: dense, [5.500000e+00]>} : () -> !toy<"array<1>"> 10 | # CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<1>">) -> !toy<"array<2, 2>"> 11 | # CHECK-NEXT: "toy.print"(%1) : (!toy<"array<2, 2>">) -> () 12 | # CHECK-NEXT: "toy.return"() : () -> () 13 | # CHECK-NEXT: } 14 | 15 | -------------------------------------------------------------------------------- /lib/Analysis/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRAnalysis STATIC 2 | AffineAnalysis.cpp 3 | AffineStructures.cpp 4 | Dominance.cpp 5 | LoopAnalysis.cpp 6 | MemRefBoundCheck.cpp 7 | MemRefDependenceCheck.cpp 8 | NestedMatcher.cpp 9 | OpStats.cpp 10 | SliceAnalysis.cpp 11 | TestParallelismDetection.cpp 12 | Utils.cpp 13 | VectorAnalysis.cpp 14 | Verifier.cpp 15 | 16 | ADDITIONAL_HEADER_DIRS 17 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Analysis 18 | ) 19 | add_dependencies(MLIRAnalysis MLIRAffineOps) 20 | target_link_libraries(MLIRAnalysis MLIRAffineOps) 21 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(AffineOps) 2 | add_subdirectory(Analysis) 3 | add_subdirectory(Dialect) 4 | add_subdirectory(EDSC) 5 | add_subdirectory(ExecutionEngine) 6 | add_subdirectory(FxpMathOps) 7 | add_subdirectory(IR) 8 | add_subdirectory(LLVMIR) 9 | add_subdirectory(Parser) 10 | add_subdirectory(Pass) 11 | add_subdirectory(Quantization) 12 | add_subdirectory(StandardOps) 13 | add_subdirectory(Support) 14 | add_subdirectory(TableGen) 15 | add_subdirectory(Target) 16 | add_subdirectory(Transforms) 17 | add_subdirectory(Translation) 18 | add_subdirectory(VectorOps) 19 | -------------------------------------------------------------------------------- /lib/Quantization/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRQuantization 2 | IR/DialectRegistration.cpp 3 | IR/FakeQuantSupport.cpp 4 | IR/QuantOps.cpp 5 | IR/TypeDetail.h 6 | IR/TypeParser.cpp 7 | IR/UniformSupport.cpp 8 | Transforms/ConvertConst.cpp 9 | Transforms/ConvertSimQuant.cpp 10 | Utils/QuantizeUtils.cpp 11 | 12 | ADDITIONAL_HEADER_DIRS 13 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Quantization 14 | ) 15 | add_dependencies(MLIRQuantization 16 | MLIRQuantizationOpsIncGen 17 | MLIRIR 18 | MLIRPass 19 | MLIRSupport 20 | MLIRStandardOps) 21 | -------------------------------------------------------------------------------- /test/Transforms/strip-debuginfo.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -mlir-print-debuginfo -strip-debuginfo | FileCheck %s 2 | // This test verifies that debug locations are stripped. 3 | 4 | #set0 = (d0) : (1 == 0) 5 | 6 | // CHECK-LABEL: inline_notation 7 | // CHECK: () -> i32 loc(unknown) { 8 | func @inline_notation() -> i32 loc("mysource.cc":10:8) { 9 | // CHECK: "foo"() : () -> i32 loc(unknown) 10 | %1 = "foo"() : () -> i32 loc("foo") 11 | 12 | // CHECK: } loc(unknown) 13 | affine.for %i0 = 0 to 8 { 14 | } loc(fused["foo", "mysource.cc":10:8]) 15 | 16 | // CHECK: } loc(unknown) 17 | %2 = constant 4 : index 18 | affine.if #set0(%2) { 19 | } loc(fused<"myPass">["foo", "foo2"]) 20 | 21 | // CHECK: return %0 : i32 loc(unknown) 22 | return %1 : i32 loc("bar") 23 | } 24 | -------------------------------------------------------------------------------- /test/mlir-tblgen/reference-impl.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-reference-implementations -I %S/../../include %s | FileCheck %s 2 | 3 | #ifdef OP_BASE 4 | #else 5 | include "mlir/IR/OpBase.td" 6 | #endif // OP_BASE 7 | 8 | def X_AddOp : Op<"x.add">, 9 | Arguments<(ins Tensor:$A, Tensor:$B)>, 10 | Results<(outs Tensor: $C)> { 11 | // TODO: extract referenceImplementation to Op. 12 | code referenceImplementation = [{ 13 | auto ivs = IndexHandle::makeIndexHandles(view_A.rank()); 14 | auto pivs = IndexHandle::makeIndexHandlePointers(ivs); 15 | IndexedValue A(arg_A), B(arg_B), C(arg_C); 16 | LoopNestBuilder(pivs, view_A.getLbs(), view_A.getUbs(), view_A.getSteps())({ 17 | C(ivs) = A(ivs) + B(ivs) 18 | }); 19 | }]; 20 | } 21 | 22 | // CHECK: printRefImplementation 23 | -------------------------------------------------------------------------------- /lib/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_llvm_library(MLIRTransforms 2 | Canonicalizer.cpp 3 | CMakeLists.txt 4 | ConstantFold.cpp 5 | CSE.cpp 6 | DialectConversion.cpp 7 | DmaGeneration.cpp 8 | LoopFusion.cpp 9 | LoopTiling.cpp 10 | LoopUnrollAndJam.cpp 11 | LoopUnroll.cpp 12 | LowerAffine.cpp 13 | LowerVectorTransfers.cpp 14 | MaterializeVectors.cpp 15 | MemRefDataFlowOpt.cpp 16 | PipelineDataTransfer.cpp 17 | SimplifyAffineStructures.cpp 18 | StripDebugInfo.cpp 19 | Utils/GreedyPatternRewriteDriver.cpp 20 | Utils/LoopUtils.cpp 21 | Utils/Utils.cpp 22 | Vectorization 23 | Vectorize.cpp 24 | Vectorization/VectorizerTestPass.cpp 25 | ViewFunctionGraph.cpp 26 | 27 | ADDITIONAL_HEADER_DIRS 28 | ${MLIR_MAIN_INCLUDE_DIR}/mlir/Transforms 29 | ) 30 | add_dependencies(MLIRTransforms MLIRStandardOpsIncGen) 31 | target_link_libraries(MLIRTransforms MLIRVectorOps) 32 | -------------------------------------------------------------------------------- /test/mlir-tblgen/op-operand.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s 2 | 3 | include "mlir/IR/OpBase.td" 4 | 5 | def OneOperandOp : Op<"one_operand_op", []> { 6 | let arguments = (ins I32:$input); 7 | } 8 | 9 | // CHECK-LABEL: OneOperandOp definitions 10 | 11 | // CHECK: void OneOperandOp::build 12 | // CHECK-SAME: Value *input 13 | // CHECK: tblgen_state->addOperands({input}); 14 | 15 | // CHECK: void OneOperandOp::build 16 | // CHECK-SAME: ArrayRef operands 17 | // CHECK: assert(operands.size() == 1u && "mismatched number of parameters"); 18 | // CHECK: tblgen_state->addOperands(operands); 19 | 20 | // CHECK: LogicalResult OneOperandOp::verify() { 21 | // CHECK: if (!((this->getOperation()->getOperand(0)->getType().isInteger(32)))) 22 | // CHECK-NEXT: return emitOpError("operand #0 must be 32-bit integer"); 23 | -------------------------------------------------------------------------------- /test/IR/locations.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -mlir-print-debuginfo | FileCheck %s 2 | // This test verifies that debug locations are round-trippable. 3 | 4 | #set0 = (d0) : (1 == 0) 5 | 6 | // CHECK-LABEL: inline_notation 7 | // CHECK () -> i32 loc("mysource.cc":10:8) 8 | func @inline_notation() -> i32 loc("mysource.cc":10:8) { 9 | // CHECK: -> i32 loc("foo") 10 | %1 = "foo"() : () -> i32 loc("foo") 11 | 12 | // CHECK: constant 4 : index loc(callsite("foo" at "mysource.cc":10:8)) 13 | %2 = constant 4 : index loc(callsite("foo" at "mysource.cc":10:8)) 14 | 15 | // CHECK: } loc(fused["foo", "mysource.cc":10:8]) 16 | affine.for %i0 = 0 to 8 { 17 | } loc(fused["foo", "mysource.cc":10:8]) 18 | 19 | // CHECK: } loc(fused<"myPass">["foo", "foo2"]) 20 | affine.if #set0(%2) { 21 | } loc(fused<"myPass">["foo", "foo2"]) 22 | 23 | // CHECK: return %0 : i32 loc(unknown) 24 | return %1 : i32 loc(unknown) 25 | } 26 | -------------------------------------------------------------------------------- /test/mlir-tblgen/pattern-benefit.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s 2 | 3 | include "mlir/IR/OpBase.td" 4 | 5 | def IfEqual : Constraint">>; 6 | 7 | // Define ops to rewrite. 8 | def U: Type, "U">; 9 | def X_AddOp : Op<"x.add"> { 10 | let arguments = (ins U, U); 11 | } 12 | def Y_AddOp : Op<"y.add"> { 13 | let arguments = (ins U, U, U); 14 | } 15 | def Z_AddOp : Op<"z.add"> { 16 | let arguments = (ins U); 17 | } 18 | 19 | // Define rewrite patterns. 20 | def : Pat<(X_AddOp (X_AddOp $lhs, $rhs), $rhs), (Y_AddOp $lhs, $rhs, $rhs)>; 21 | 22 | // CHECK-LABEL: struct GeneratedConvert0 23 | // CHECK: GeneratedConvert0(MLIRContext *context) : RewritePattern("x.add", 2, context) {} 24 | 25 | def : Pat<(X_AddOp $lhs, $rhs), (Z_AddOp $lhs), [(IfEqual $lhs, $rhs)], (addBenefit 100)>; 26 | 27 | // CHECK-LABEL: struct GeneratedConvert1 28 | // CHECK: GeneratedConvert1(MLIRContext *context) : RewritePattern("x.add", 101, context) {} -------------------------------------------------------------------------------- /examples/Linalg/Linalg2/include/linalg2/Analysis.h: -------------------------------------------------------------------------------- 1 | //===- Analysis.h - Linalg dialect Analysis function definitions ----------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG2_ANALYSIS_H_ 19 | #define LINALG2_ANALYSIS_H_ 20 | 21 | #include "linalg1/Analysis.h" 22 | 23 | #endif // LINALG2_ANALYSIS_H_ 24 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg2/include/linalg2/Ops.h: -------------------------------------------------------------------------------- 1 | //===- Ops.h - Linalg Ops single entry point ------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG2_OPS_H_ 19 | #define LINALG2_OPS_H_ 20 | 21 | #include "linalg1/Ops.h" 22 | #include "linalg2/TensorOps.h" 23 | 24 | #endif // LINALG2_OPS_H_ 25 | -------------------------------------------------------------------------------- /test/Transforms/parallelism-detection.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -test-detect-parallel -split-input-file -verify | FileCheck %s 2 | 3 | // CHECK-LABEL: func @loop_nest_3d_outer_two_parallel 4 | func @loop_nest_3d_outer_two_parallel(%N : index) { 5 | %0 = alloc() : memref<1024 x 1024 x vector<64xf32>> 6 | %1 = alloc() : memref<1024 x 1024 x vector<64xf32>> 7 | %2 = alloc() : memref<1024 x 1024 x vector<64xf32>> 8 | affine.for %i = 0 to %N { 9 | // expected-note@-1 {{parallel loop}} 10 | affine.for %j = 0 to %N { 11 | // expected-note@-1 {{parallel loop}} 12 | affine.for %k = 0 to %N { 13 | %5 = load %0[%i, %k] : memref<1024x1024xvector<64xf32>> 14 | %6 = load %1[%k, %j] : memref<1024x1024xvector<64xf32>> 15 | %7 = load %2[%i, %j] : memref<1024x1024xvector<64xf32>> 16 | %8 = mulf %5, %6 : vector<64xf32> 17 | %9 = addf %7, %8 : vector<64xf32> 18 | store %9, %2[%i, %j] : memref<1024x1024xvector<64xf32>> 19 | } 20 | } 21 | } 22 | return 23 | } 24 | -------------------------------------------------------------------------------- /test/mlir-tblgen/directive-verifyUnusedValue.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s 2 | 3 | include "mlir/IR/OpBase.td" 4 | 5 | def ThreeResultOp : Op<"three_result_op", []> { 6 | let arguments = (ins I32:$input); 7 | let results = (outs I32:$r1, I32:$r2, I32:$r3); 8 | } 9 | 10 | def OneResultOp : Op<"one_result_op", []> { 11 | let arguments = (ins I32:$input); 12 | let results = (outs I32:$r1); 13 | } 14 | 15 | def : Pattern<(ThreeResultOp $input), [ 16 | (verifyUnusedValue), 17 | (OneResultOp $input), 18 | (verifyUnusedValue) 19 | ]>; 20 | 21 | // CHECK-LABEL: struct GeneratedConvert0 22 | 23 | // CHECK: PatternMatchResult match( 24 | // CHECK: if (!op0->getResult(0)->use_empty()) return matchFailure(); 25 | // CHECK: if (!op0->getResult(2)->use_empty()) return matchFailure(); 26 | 27 | // CHECK: void rewrite( 28 | // CHECK: auto vOneResultOp0 = rewriter.create( 29 | // CHECK: rewriter.replaceOp(op, {nullptr, vOneResultOp0, nullptr}); 30 | -------------------------------------------------------------------------------- /lib/AffineOps/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Register Affine Op dialect ---------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/AffineOps/AffineOps.h" 19 | using namespace mlir; 20 | 21 | // Static initialization for Affine op dialect registration. 22 | static DialectRegistration StandardOps; 23 | -------------------------------------------------------------------------------- /lib/StandardOps/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Register standard Op dialect -------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/StandardOps/Ops.h" 19 | using namespace mlir; 20 | 21 | // Static initialization for standard op dialect registration. 22 | static DialectRegistration StandardOps; 23 | -------------------------------------------------------------------------------- /lib/VectorOps/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Register super vectorization dialect -----===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/VectorOps/VectorOps.h" 19 | using namespace mlir; 20 | 21 | // Static initialization for VectorOps dialect registration. 22 | static DialectRegistration VectorOps; 23 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg3/include/linalg3/Ops.h: -------------------------------------------------------------------------------- 1 | //===- Ops.h - Linalg Ops single entry point ------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG3_OPS_H_ 19 | #define LINALG3_OPS_H_ 20 | 21 | #include "linalg2/Ops.h" 22 | #include "linalg3/LoadStoreOps.h" 23 | #include "linalg3/TensorOps.h" 24 | 25 | #endif // LINALG3_OPS_H_ 26 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/Ops.h: -------------------------------------------------------------------------------- 1 | //===- Ops.h - Linalg Ops single entry point ------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_OPS_H_ 19 | #define LINALG1_OPS_H_ 20 | 21 | #include "linalg1/Types.h" 22 | #include "linalg1/RangeOp.h" 23 | #include "linalg1/SliceOp.h" 24 | #include "linalg1/ViewOp.h" 25 | 26 | #endif // LINALG1_OPS_H_ 27 | -------------------------------------------------------------------------------- /test/Unit/lit.site.cfg.py.in: -------------------------------------------------------------------------------- 1 | @LIT_SITE_CFG_IN_HEADER@ 2 | 3 | import sys 4 | 5 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" 6 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" 7 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" 8 | config.llvm_build_mode = "@LLVM_BUILD_MODE@" 9 | config.enable_shared = @ENABLE_SHARED@ 10 | config.shlibdir = "@SHLIBDIR@" 11 | config.mlir_src_root = "@MLIR_SOURCE_DIR@" 12 | config.mlir_obj_root = "@MLIR_BINARY_DIR@" 13 | config.mlir_tools_dir = "@MLIR_TOOLS_DIR@" 14 | 15 | # Support substitution of the tools_dir and build_mode with user parameters. 16 | # This is used when we can't determine the tool dir at configuration time. 17 | try: 18 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params 19 | config.llvm_build_mode = config.llvm_build_mode % lit_config.params 20 | except KeyError: 21 | e = sys.exc_info()[1] 22 | key, = e.args 23 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) 24 | 25 | # Let the main config do the real work. 26 | lit_config.load_config(config, "@MLIR_SOURCE_DIR@/test/Unit/lit.cfg.py") 27 | -------------------------------------------------------------------------------- /lib/FxpMathOps/IR/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Register FxpMathOps dialect --------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/FxpMathOps/FxpMathOps.h" 19 | 20 | using namespace mlir; 21 | using namespace mlir::fxpmath; 22 | 23 | // Static initialization for the fxpmath ops dialect registration. 24 | static mlir::DialectRegistration FxpMathOps; 25 | -------------------------------------------------------------------------------- /lib/Quantization/IR/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Register Quantization dialect ------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/Quantization/QuantOps.h" 19 | 20 | using namespace mlir; 21 | using namespace mlir::quant; 22 | 23 | // Static initialization for Quantization dialect registration. 24 | static mlir::DialectRegistration QuantizationOps; 25 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | llvm_canonicalize_cmake_booleans( 2 | LLVM_BUILD_EXAMPLES 3 | ) 4 | 5 | 6 | configure_lit_site_cfg( 7 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in 8 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py 9 | MAIN_CONFIG 10 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py 11 | ) 12 | configure_lit_site_cfg( 13 | ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in 14 | ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py 15 | MAIN_CONFIG 16 | ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py 17 | ) 18 | 19 | set(MLIR_TEST_DEPENDS 20 | FileCheck count not 21 | MLIRUnitTests 22 | mlir-cpu-runner 23 | mlir-opt 24 | mlir-tblgen 25 | mlir-translate 26 | ) 27 | 28 | 29 | if(LLVM_BUILD_EXAMPLES) 30 | list(APPEND MLIR_TEST_DEPENDS 31 | toyc-ch1 32 | toyc-ch2 33 | toyc-ch3 34 | ) 35 | endif() 36 | 37 | add_lit_testsuite(check-mlir "Running the MLIR regression tests" 38 | ${CMAKE_CURRENT_BINARY_DIR} 39 | DEPENDS ${MLIR_TEST_DEPENDS} 40 | ) 41 | set_target_properties(check-mlir PROPERTIES FOLDER "Tests") 42 | 43 | add_lit_testsuites(MLIR ${CMAKE_CURRENT_SOURCE_DIR} 44 | DEPENDS ${MLIR_TEST_DEPS} 45 | ) 46 | -------------------------------------------------------------------------------- /test/IR/pretty-locations.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -mlir-print-debuginfo -mlir-pretty-debuginfo | FileCheck %s 2 | 3 | #set0 = (d0) : (1 == 0) 4 | 5 | // CHECK-LABEL: inline_notation 6 | // CHECK () -> i32 mysource.cc:10:8 7 | func @inline_notation() -> i32 loc("mysource.cc":10:8) { 8 | // CHECK: -> i32 "foo" 9 | %1 = "foo"() : () -> i32 loc("foo") 10 | 11 | // CHECK: constant 4 : index "foo" at mysource.cc:10:8 12 | %2 = constant 4 : index loc(callsite("foo" at "mysource.cc":10:8)) 13 | 14 | // CHECK: constant 4 : index "foo" 15 | // CHECK-NEXT: at mysource1.cc:10:8 16 | // CHECK-NEXT: at mysource2.cc:13:8 17 | // CHECK-NEXT: at mysource3.cc:100:10 18 | %3 = constant 4 : index loc(callsite("foo" at callsite("mysource1.cc":10:8 at callsite("mysource2.cc":13:8 at "mysource3.cc":100:10)))) 19 | 20 | // CHECK: } ["foo", mysource.cc:10:8] 21 | affine.for %i0 = 0 to 8 { 22 | } loc(fused["foo", "mysource.cc":10:8]) 23 | 24 | // CHECK: } <"myPass">["foo", "foo2"] 25 | affine.if #set0(%2) { 26 | } loc(fused<"myPass">["foo", "foo2"]) 27 | 28 | // CHECK: return %0 : i32 [unknown] 29 | return %1 : i32 loc(unknown) 30 | } 31 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/ConvertToLLVMDialect.h: -------------------------------------------------------------------------------- 1 | //===- ConvertToLLVMDialect.h - conversion from Linalg to LLVM --*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG_CONVERTTOLLVMDIALECT_H_ 19 | #define LINALG_CONVERTTOLLVMDIALECT_H_ 20 | 21 | namespace mlir { 22 | class Module; 23 | } // end namespace mlir 24 | 25 | namespace linalg { 26 | void convertToLLVM(mlir::Module &module); 27 | } // end namespace linalg 28 | 29 | #endif // LINALG_CONVERTTOLLVMDIALECT_H_ 30 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/Utils.h: -------------------------------------------------------------------------------- 1 | //===- Utils.h - Linalg dialect utility functions definitions -------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_UTILS_H_ 19 | #define LINALG1_UTILS_H_ 20 | 21 | namespace mlir { 22 | class Value; 23 | } // namespace mlir 24 | 25 | namespace linalg { 26 | 27 | /// Asserts `view` is of ViewType and returns its rank. 28 | unsigned getViewRank(mlir::Value *view); 29 | 30 | } // namespace linalg 31 | 32 | #endif // LINALG1_UTILS_H_ 33 | -------------------------------------------------------------------------------- /test/mlir-cpu-runner/simple.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-cpu-runner %s | FileCheck %s 2 | // RUN: mlir-cpu-runner -e foo -init-value 1000 %s | FileCheck -check-prefix=NOMAIN %s 3 | // RUN: mlir-cpu-runner %s -O3 | FileCheck %s 4 | // RUN: mlir-cpu-runner %s -O3 -loop-distribute -loop-vectorize | FileCheck %s 5 | // RUN: mlir-cpu-runner %s -loop-distribute -loop-vectorize | FileCheck %s 6 | 7 | func @fabsf(f32) -> f32 8 | 9 | func @main(%a : memref<2xf32>, %b : memref<1xf32>) { 10 | %c0 = constant 0 : index 11 | %c1 = constant 1 : index 12 | %0 = constant -420.0 : f32 13 | %1 = load %a[%c0] : memref<2xf32> 14 | %2 = load %a[%c1] : memref<2xf32> 15 | %3 = addf %0, %1 : f32 16 | %4 = addf %3, %2 : f32 17 | %5 = call @fabsf(%4) : (f32) -> f32 18 | store %5, %b[%c0] : memref<1xf32> 19 | return 20 | } 21 | // CHECK: 0.000000e+00 0.000000e+00 22 | // CHECK-NEXT: 4.200000e+02 23 | 24 | func @foo(%a : memref<1x1xf32>) -> memref<1x1xf32> { 25 | %c0 = constant 0 : index 26 | %0 = constant 1234.0 : f32 27 | %1 = load %a[%c0, %c0] : memref<1x1xf32> 28 | %2 = addf %1, %0 : f32 29 | store %2, %a[%c0, %c0] : memref<1x1xf32> 30 | return %a : memref<1x1xf32> 31 | } 32 | // NOMAIN: 2.234000e+03 33 | // NOMAIN-NEXT: 2.234000e+03 34 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/Types.h: -------------------------------------------------------------------------------- 1 | //===- Types.h - Linalg Types forward declarations ------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_TYPES_H_ 19 | #define LINALG1_TYPES_H_ 20 | 21 | #include "mlir/IR/Types.h" 22 | 23 | namespace linalg { 24 | 25 | enum LinalgTypes { 26 | Range = mlir::Type::FIRST_LINALG_TYPE, 27 | View, 28 | LAST_USED_LINALG_TYPE = View, 29 | }; 30 | 31 | } // namespace linalg 32 | 33 | #include "linalg1/RangeType.h" 34 | #include "linalg1/ViewType.h" 35 | 36 | #endif // LINALG1_TYPES_H_ 37 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg3/include/linalg3/Intrinsics.h: -------------------------------------------------------------------------------- 1 | //===- Intrinsics.h - Linalg intrinsics definitions -----------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG3_INTRINSICS_H_ 19 | #define LINALG3_INTRINSICS_H_ 20 | 21 | #include "linalg2/Intrinsics.h" 22 | #include "linalg3/Ops.h" 23 | 24 | namespace linalg { 25 | namespace intrinsics { 26 | using load = mlir::edsc::intrinsics::ValueBuilder; 27 | using store = mlir::edsc::intrinsics::OperationBuilder; 28 | } // namespace intrinsics 29 | } // namespace linalg 30 | 31 | #endif // LINALG3_INTRINSICS_H_ 32 | -------------------------------------------------------------------------------- /test/Transforms/Vectorize/vectorize_3d.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -vectorize -virtual-vector-size 32 -virtual-vector-size 64 -virtual-vector-size 256 --test-fastest-varying=2 --test-fastest-varying=1 --test-fastest-varying=0 | FileCheck %s 2 | 3 | // Permutation maps used in vectorization. 4 | // CHECK: #[[map_proj_d0d1d2_d0d1d2:map[0-9]+]] = (d0, d1, d2) -> (d0, d1, d2) 5 | 6 | func @vec3d(%A : memref) { 7 | %0 = dim %A, 0 : memref 8 | %1 = dim %A, 1 : memref 9 | %2 = dim %A, 2 : memref 10 | // CHECK: affine.for %i0 = 0 to %0 { 11 | // CHECK: affine.for %i1 = 0 to %0 { 12 | // CHECK: affine.for %i2 = 0 to %0 step 32 { 13 | // CHECK: affine.for %i3 = 0 to %1 step 64 { 14 | // CHECK: affine.for %i4 = 0 to %2 step 256 { 15 | // CHECK: %3 = vector.transfer_read %arg0[%i2, %i3, %i4] {permutation_map: #[[map_proj_d0d1d2_d0d1d2]]} : memref, vector<32x64x256xf32> 16 | affine.for %t0 = 0 to %0 { 17 | affine.for %t1 = 0 to %0 { 18 | affine.for %i0 = 0 to %0 { 19 | affine.for %i1 = 0 to %1 { 20 | affine.for %i2 = 0 to %2 { 21 | %a2 = load %A[%i0, %i1, %i2] : memref 22 | } 23 | } 24 | } 25 | } 26 | } 27 | return 28 | } 29 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/Intrinsics.h: -------------------------------------------------------------------------------- 1 | //===- Intrinsics.h - Linalg intrinsics definitions -----------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_INTRINSICS_H_ 19 | #define LINALG1_INTRINSICS_H_ 20 | 21 | #include "linalg1/Ops.h" 22 | #include "mlir/EDSC/Intrinsics.h" 23 | 24 | namespace linalg { 25 | namespace intrinsics { 26 | using range = mlir::edsc::intrinsics::ValueBuilder; 27 | using slice = mlir::edsc::intrinsics::ValueBuilder; 28 | using view = mlir::edsc::intrinsics::ValueBuilder; 29 | } // namespace intrinsics 30 | } // namespace linalg 31 | 32 | #endif // LINALG1_INTRINSICS_H_ 33 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg2/include/linalg2/Intrinsics.h: -------------------------------------------------------------------------------- 1 | //===- Intrinsics.h - Linalg intrinsics definitions -----------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG2_INTRINSICS_H_ 19 | #define LINALG2_INTRINSICS_H_ 20 | 21 | #include "linalg1/Intrinsics.h" 22 | #include "linalg2/Ops.h" 23 | 24 | namespace linalg { 25 | namespace intrinsics { 26 | using dot = mlir::edsc::intrinsics::OperationBuilder; 27 | using matmul = mlir::edsc::intrinsics::OperationBuilder; 28 | using matvec = mlir::edsc::intrinsics::OperationBuilder; 29 | } // namespace intrinsics 30 | } // namespace linalg 31 | 32 | #endif // LINALG2_INTRINSICS_H_ 33 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg2/include/linalg2/Transforms.h: -------------------------------------------------------------------------------- 1 | //===- Transforms.h - Linalg dialect Transformations definition -----------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG2_TRANSFORMS_H_ 19 | #define LINALG2_TRANSFORMS_H_ 20 | 21 | namespace mlir { 22 | class Value; 23 | } // namespace mlir 24 | 25 | namespace linalg { 26 | 27 | class ViewOp; 28 | 29 | /// Takes a `view` of type ViewType (i.e. either a ViewOp or a SliceOp) and 30 | /// composes away all the SliceOp to return a single ViewOp. 31 | /// Inserts the required operations after `view`. 32 | ViewOp createFullyComposedView(mlir::Value *v); 33 | 34 | } // namespace linalg 35 | 36 | #endif // LINALG2_TRANSFORMS_H_ 37 | -------------------------------------------------------------------------------- /test/mlir-tblgen/one-op-one-result.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s 2 | 3 | include "mlir/IR/OpBase.td" 4 | 5 | // Create a Type and Attribute. 6 | def T : BuildableType<"buildT">; 7 | def T_Attr : TypeBasedAttr; 8 | def T_Const_Attr : ConstantAttr; 9 | 10 | // Define ops to rewrite. 11 | def U: Type, "U">; 12 | def X_AddOp : Op<"x.add"> { 13 | let arguments = (ins U, U); 14 | } 15 | def Y_AddOp : Op<"y.add"> { 16 | let arguments = (ins U, U, T_Attr:$attrName); 17 | } 18 | 19 | // Define rewrite pattern. 20 | def : Pat<(X_AddOp:$res $lhs, $rhs), (Y_AddOp $lhs, U:$rhs, T_Const_Attr:$x)>; 21 | def : Pat<(X_AddOp (X_AddOp $lhs, $rhs):$res, $rrhs), (Y_AddOp $lhs, U:$rhs, T_Const_Attr:$x)>; 22 | def : Pat<(X_AddOp (X_AddOp:$res $lhs, $rhs), $rrhs), (Y_AddOp $lhs, U:$rhs, T_Const_Attr:$x)>; 23 | 24 | // CHECK: struct GeneratedConvert0 : public RewritePattern 25 | // CHECK: RewritePattern("x.add", 1, context) 26 | // CHECK: PatternMatchResult match(Operation * 27 | // CHECK: void rewrite(Operation *op, std::unique_ptr 28 | // CHECK: PatternRewriter &rewriter) 29 | // CHECK: rewriter.create(loc, op->getResult(0)->getType() 30 | // CHECK: void populateWithGenerated 31 | // CHECK: patterns->push_back(llvm::make_unique(context)) 32 | -------------------------------------------------------------------------------- /include/mlir/FxpMathOps/FxpMathOps.h: -------------------------------------------------------------------------------- 1 | //===- FxpMathOps/FxpMathOps.h - Fixed point ops ----------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef MLIR_FXPMATH_QUANTOPS_H_ 19 | #define MLIR_FXPMATH_QUANTOPS_H_ 20 | 21 | #include "mlir/IR/Dialect.h" 22 | #include "mlir/IR/OpDefinition.h" 23 | 24 | namespace mlir { 25 | namespace fxpmath { 26 | 27 | /// Defines the 'FxpMathOps' dialect. 28 | class FxpMathOpsDialect : public Dialect { 29 | public: 30 | FxpMathOpsDialect(MLIRContext *context); 31 | }; 32 | 33 | #define GET_OP_CLASSES 34 | #include "mlir/FxpMathOps/FxpMathOps.h.inc" 35 | 36 | } // namespace fxpmath 37 | } // namespace mlir 38 | 39 | #endif // MLIR_FXPMATH_QUANTOPS_H_ 40 | -------------------------------------------------------------------------------- /lib/TableGen/Argument.cpp: -------------------------------------------------------------------------------- 1 | //===- Argument.cpp - Argument definitions ----------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/TableGen/Argument.h" 19 | #include "llvm/ADT/StringExtras.h" 20 | #include "llvm/TableGen/Record.h" 21 | 22 | using namespace mlir; 23 | 24 | std::string tblgen::NamedAttribute::getName() const { 25 | // TODO(jpienaar): Revise this post dialect prefixing attribute discussion. 26 | auto split = name.split("__"); 27 | if (split.second.empty()) 28 | return name; 29 | return llvm::join_items(".", split.first, split.second); 30 | } 31 | 32 | bool tblgen::NamedTypeConstraint::hasPredicate() const { 33 | return !constraint.getPredicate().isNull(); 34 | } 35 | -------------------------------------------------------------------------------- /test/Quantization/convert-fakequant-invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -split-input-file -verify -quant-convert-simulated-quantization 2 | 3 | // ----- 4 | // Verify that a mismatched range errors. 5 | func @fakeQuantArgs(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { 6 | ^bb0(%arg0: tensor<8x4x3xf32>): 7 | // expected-error@+1 {{FakeQuant range must straddle zero: [1.100000,1.500000]}} 8 | %0 = "quant.const_fake_quant"(%arg0) { 9 | min: 1.1, max: 1.5, num_bits: 8 10 | } : (tensor<8x4x3xf32>) -> tensor<8x4x3xf32> 11 | return %0 : tensor<8x4x3xf32> 12 | } 13 | 14 | // ----- 15 | // Verify that a valid range errors. 16 | func @fakeQuantArgs(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { 17 | ^bb0(%arg0: tensor<8x4x3xf32>): 18 | // expected-error@+1 {{FakeQuant range must straddle zero: [1.100000,1.000000}} 19 | %0 = "quant.const_fake_quant"(%arg0) { 20 | min: 1.1, max: 1.0, num_bits: 8 21 | } : (tensor<8x4x3xf32>) -> tensor<8x4x3xf32> 22 | return %0 : tensor<8x4x3xf32> 23 | } 24 | 25 | // ----- 26 | // Unsupported quantizable type (i1 is currently not a supported element type). 27 | func @fakeQuantArgs(tensor<8x4x3xi1>) -> tensor<8x4x3xi1> { 28 | ^bb0(%arg0: tensor<8x4x3xi1>): 29 | // expected-error@+1 {{op operand #0 must be tensor of 32-bit float values}} 30 | %0 = "quant.const_fake_quant"(%arg0) { 31 | min: 1.1, max: 1.0, num_bits: 8 32 | } : (tensor<8x4x3xi1>) -> tensor<8x4x3xi1> 33 | return %0 : tensor<8x4x3xi1> 34 | } 35 | -------------------------------------------------------------------------------- /unittests/IR/DialectTest.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectTest.cpp - Dialect unit tests -------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/IR/Dialect.h" 19 | #include "gtest/gtest.h" 20 | 21 | using namespace mlir; 22 | using namespace mlir::detail; 23 | 24 | namespace { 25 | struct TestDialect : public Dialect { 26 | TestDialect(MLIRContext *context) : Dialect(/*name=*/"test", context) {} 27 | }; 28 | 29 | TEST(DialectDeathTest, MultipleDialectsWithSameNamespace) { 30 | MLIRContext context; 31 | 32 | // Registering a dialect with the same namespace twice should result in a 33 | // failure. 34 | new TestDialect(&context); 35 | ASSERT_DEATH(new TestDialect(&context), ""); 36 | } 37 | 38 | } // end namespace 39 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg3/include/linalg3/Analysis.h: -------------------------------------------------------------------------------- 1 | //===- Analysis.h - Linalg dialect Analysis function definitions ----------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG3_ANALYSIS_H_ 19 | #define LINALG3_ANALYSIS_H_ 20 | 21 | #include "linalg2/Analysis.h" 22 | 23 | namespace mlir { 24 | class AffineMap; 25 | } // namespace mlir 26 | 27 | namespace linalg { 28 | 29 | /// Given a `map` specification and a subset of its results 30 | /// `[beginResult, endResult)`, returns the inverse map that maps result 31 | /// positions to dim positions. 32 | mlir::AffineMap inverseSubMap(mlir::AffineMap map, unsigned beginResult = 0, 33 | unsigned endResult = 0); 34 | 35 | } // namespace linalg 36 | 37 | #endif // LINALG3_ANALYSIS_H_ 38 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/lib/Utils.cpp: -------------------------------------------------------------------------------- 1 | //===- Utils.cpp - Implementation of utiliy functions for Linalg ----------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements utility functions for the linalg dialect. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #include "linalg1/Utils.h" 23 | #include "linalg1/Ops.h" 24 | #include "mlir/IR/StandardTypes.h" 25 | 26 | using namespace mlir; 27 | using namespace linalg; 28 | 29 | unsigned linalg::getViewRank(Value *view) { 30 | assert(view->getType().isa() && "expected a ViewType"); 31 | if (auto viewOp = view->getDefiningOp()->dyn_cast()) 32 | return viewOp.getRank(); 33 | return view->getDefiningOp()->dyn_cast().getRank(); 34 | } 35 | -------------------------------------------------------------------------------- /test/Transforms/Vectorize/vectorize_outer_loop_2d.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -vectorize -virtual-vector-size 32 -virtual-vector-size 256 --test-fastest-varying=2 --test-fastest-varying=0 | FileCheck %s 2 | 3 | // Permutation maps used in vectorization. 4 | // CHECK: #[[map_proj_d0d1d2_d0d2:map[0-9]+]] = (d0, d1, d2) -> (d0, d2) 5 | 6 | func @vec2d(%A : memref) { 7 | %M = dim %A, 0 : memref 8 | %N = dim %A, 1 : memref 9 | %P = dim %A, 2 : memref 10 | // CHECK: affine.for %i0 = 0 to %0 step 32 11 | // CHECK: affine.for %i1 = 0 to %1 { 12 | // CHECK: affine.for %i2 = 0 to %2 step 256 13 | // CHECK: {{.*}} = vector.transfer_read %arg0[%i0, %i1, %i2] {permutation_map: #[[map_proj_d0d1d2_d0d2]]} : memref, vector<32x256xf32> 14 | affine.for %i0 = 0 to %M { 15 | affine.for %i1 = 0 to %N { 16 | affine.for %i2 = 0 to %P { 17 | %a2 = load %A[%i0, %i1, %i2] : memref 18 | } 19 | } 20 | } 21 | // CHECK: for {{.*}} = 0 to %0 { 22 | // CHECK: for {{.*}} = 0 to %1 { 23 | // CHECK: for {{.*}} = 0 to %2 { 24 | // For the case: --test-fastest-varying=2 --test-fastest-varying=0 no 25 | // vectorization happens because of loop nesting order 26 | affine.for %i3 = 0 to %M { 27 | affine.for %i4 = 0 to %N { 28 | affine.for %i5 = 0 to %P { 29 | %a5 = load %A[%i4, %i5, %i3] : memref 30 | } 31 | } 32 | } 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /lib/FxpMathOps/IR/FxpMathOps.cpp: -------------------------------------------------------------------------------- 1 | //===- FxpMathOps.cpp - Op implementation for FxpMathOps ------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/FxpMathOps/FxpMathOps.h" 19 | #include "mlir/IR/MLIRContext.h" 20 | #include "mlir/IR/StandardTypes.h" 21 | #include "mlir/Quantization/QuantOps.h" 22 | #include "llvm/ADT/StringRef.h" 23 | #include "llvm/ADT/Twine.h" 24 | #include "llvm/Support/MathExtras.h" 25 | 26 | using namespace mlir; 27 | using namespace mlir::fxpmath; 28 | 29 | #define GET_OP_CLASSES 30 | #include "mlir/FxpMathOps/FxpMathOps.cpp.inc" 31 | 32 | FxpMathOpsDialect::FxpMathOpsDialect(MLIRContext *context) 33 | : Dialect(/*name=*/"fxpmath", context) { 34 | addOperations< 35 | #define GET_OP_LIST 36 | #include "mlir/FxpMathOps/FxpMathOps.cpp.inc" 37 | >(); 38 | } 39 | -------------------------------------------------------------------------------- /lib/IR/Module.cpp: -------------------------------------------------------------------------------- 1 | //===- Module.cpp - MLIR Module Class -------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/IR/Module.h" 19 | using namespace mlir; 20 | 21 | Module::Module(MLIRContext *context) : context(context) {} 22 | 23 | /// Look up a function with the specified name, returning null if no such 24 | /// name exists. Function names never include the @ on them. 25 | Function *Module::getNamedFunction(StringRef name) { 26 | return getNamedFunction(Identifier::get(name, context)); 27 | } 28 | 29 | /// Look up a function with the specified name, returning null if no such 30 | /// name exists. Function names never include the @ on them. 31 | Function *Module::getNamedFunction(Identifier name) { 32 | auto it = symbolTable.find(name); 33 | return it != symbolTable.end() ? it->second : nullptr; 34 | } 35 | -------------------------------------------------------------------------------- /test/Unit/lit.cfg.py: -------------------------------------------------------------------------------- 1 | # -*- Python -*- 2 | 3 | # Configuration file for the 'lit' test runner. 4 | 5 | import os 6 | import subprocess 7 | 8 | import lit.formats 9 | 10 | # name: The name of this test suite. 11 | config.name = 'MLIR-Unit' 12 | 13 | # suffixes: A list of file extensions to treat as test files. 14 | config.suffixes = [] 15 | 16 | # is_early; Request to run this suite early. 17 | config.is_early = True 18 | 19 | # test_source_root: The root path where tests are located. 20 | # test_exec_root: The root path where tests should be run. 21 | config.test_exec_root = os.path.join(config.mlir_obj_root, 'unittests') 22 | config.test_source_root = config.test_exec_root 23 | 24 | # testFormat: The test format to use to interpret tests. 25 | config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests') 26 | 27 | # Propagate the temp directory. Windows requires this because it uses \Windows\ 28 | # if none of these are present. 29 | if 'TMP' in os.environ: 30 | config.environment['TMP'] = os.environ['TMP'] 31 | if 'TEMP' in os.environ: 32 | config.environment['TEMP'] = os.environ['TEMP'] 33 | 34 | # Propagate HOME as it can be used to override incorrect homedir in passwd 35 | # that causes the tests to fail. 36 | if 'HOME' in os.environ: 37 | config.environment['HOME'] = os.environ['HOME'] 38 | 39 | # Propagate path to symbolizer for ASan/MSan. 40 | for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']: 41 | if symbolizer in os.environ: 42 | config.environment[symbolizer] = os.environ[symbolizer] 43 | -------------------------------------------------------------------------------- /include/mlir/FxpMathOps/Passes.h: -------------------------------------------------------------------------------- 1 | //===- Passes.h - Fixed point math passes -----------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file defines all of the passes owned by the FxpMathOps dialect. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_FXPMATH_PASSES_H 23 | #define MLIR_FXPMATH_PASSES_H 24 | 25 | namespace mlir { 26 | class FunctionPassBase; 27 | 28 | namespace fxpmath { 29 | 30 | /// Creates a pass that lowers uniform-quantized real math ops to integer 31 | /// arithmetic. This will leave unrecognized real math ops as-is and is 32 | /// typically followed by a pass that lowers any unrecognized ops to a pure 33 | /// floating point form. 34 | FunctionPassBase *createLowerUniformRealMathPass(); 35 | 36 | } // namespace fxpmath 37 | } // namespace mlir 38 | 39 | #endif // MLIR_FXPMATH_PASSES_H 40 | -------------------------------------------------------------------------------- /include/mlir/TableGen/GenNameParser.h: -------------------------------------------------------------------------------- 1 | //===- GenNameParser.h - Command line parser for generators -----*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // The GenNameParser class adds all passes linked in to the system that are 19 | // creatable to the tool. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #ifndef MLIR_TABLEGEN_GENNAMEPARSER_H_ 24 | #define MLIR_TABLEGEN_GENNAMEPARSER_H_ 25 | 26 | #include "llvm/Support/CommandLine.h" 27 | 28 | namespace mlir { 29 | class GenInfo; 30 | 31 | /// Adds command line option for each registered generator. 32 | struct GenNameParser : public llvm::cl::parser { 33 | GenNameParser(llvm::cl::Option &opt); 34 | 35 | void printOptionInfo(const llvm::cl::Option &O, 36 | size_t GlobalWidth) const override; 37 | }; 38 | } // end namespace mlir 39 | 40 | #endif // MLIR_TABLEGEN_GENNAMEPARSER_H_ 41 | -------------------------------------------------------------------------------- /examples/toy/Ch2/include/toy/MLIRGen.h: -------------------------------------------------------------------------------- 1 | //===- MLIRGen.h - MLIR Generation from a Toy AST -------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file declares a simple interface to perform IR generation targeting MLIR 19 | // from a Module AST for the Toy language. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #ifndef MLIR_TUTORIAL_TOY_MLIRGEN_H_ 24 | #define MLIR_TUTORIAL_TOY_MLIRGEN_H_ 25 | 26 | #include 27 | 28 | namespace mlir { 29 | class MLIRContext; 30 | class Module; 31 | } // namespace mlir 32 | 33 | namespace toy { 34 | class ModuleAST; 35 | 36 | /// Emit IR for the given Toy moduleAST, returns a newly created MLIR module 37 | /// or nullptr on failure. 38 | std::unique_ptr mlirGen(mlir::MLIRContext &context, 39 | ModuleAST &moduleAST); 40 | } // namespace toy 41 | 42 | #endif // MLIR_TUTORIAL_TOY_MLIRGEN_H_ 43 | -------------------------------------------------------------------------------- /examples/toy/Ch3/include/toy/MLIRGen.h: -------------------------------------------------------------------------------- 1 | //===- MLIRGen.h - MLIR Generation from a Toy AST -------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file declares a simple interface to perform IR generation targeting MLIR 19 | // from a Module AST for the Toy language. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #ifndef MLIR_TUTORIAL_TOY_MLIRGEN_H_ 24 | #define MLIR_TUTORIAL_TOY_MLIRGEN_H_ 25 | 26 | #include 27 | 28 | namespace mlir { 29 | class MLIRContext; 30 | class Module; 31 | } // namespace mlir 32 | 33 | namespace toy { 34 | class ModuleAST; 35 | 36 | /// Emit IR for the given Toy moduleAST, returns a newly created MLIR module 37 | /// or nullptr on failure. 38 | std::unique_ptr mlirGen(mlir::MLIRContext &context, 39 | ModuleAST &moduleAST); 40 | } // namespace toy 41 | 42 | #endif // MLIR_TUTORIAL_TOY_MLIRGEN_H_ 43 | -------------------------------------------------------------------------------- /lib/IR/IntegerSetDetail.h: -------------------------------------------------------------------------------- 1 | //===- IntegerSetDetail.h - MLIR IntegerSet storage details -----*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This holds implementation details of IntegerSet. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef INTEGERSETDETAIL_H_ 23 | #define INTEGERSETDETAIL_H_ 24 | 25 | #include "mlir/IR/AffineExpr.h" 26 | #include "llvm/ADT/ArrayRef.h" 27 | 28 | namespace mlir { 29 | namespace detail { 30 | 31 | struct IntegerSetStorage { 32 | unsigned dimCount; 33 | unsigned symbolCount; 34 | 35 | /// Array of affine constraints: a constraint is either an equality 36 | /// (affine_expr == 0) or an inequality (affine_expr >= 0). 37 | ArrayRef constraints; 38 | 39 | // Bits to check whether a constraint is an equality or an inequality. 40 | ArrayRef eqFlags; 41 | }; 42 | 43 | } // end namespace detail 44 | } // end namespace mlir 45 | #endif // INTEGERSETDETAIL_H_ 46 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg2/lib/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Registration of the Linalg dialect -------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file registers the Linalg dialect and should live in a standalone 19 | // library. Linking with this library will create a static global object that 20 | // performs dialect registration. 21 | // 22 | //===----------------------------------------------------------------------===// 23 | 24 | #include "linalg1/Dialect.h" 25 | #include "linalg2/Ops.h" 26 | 27 | using namespace linalg; 28 | 29 | LinalgDialect::LinalgDialect(mlir::MLIRContext *context) 30 | : Dialect("linalg", context) { 31 | addTypes(); 32 | addOperations(); 33 | } 34 | 35 | // Dialect registration triggers the creation of a `LinalgDialect` object which 36 | // adds the proper types and operations to the dialect. 37 | static mlir::DialectRegistration LinalgOps; 38 | -------------------------------------------------------------------------------- /include/mlir/Analysis/Passes.h: -------------------------------------------------------------------------------- 1 | //===- Passes.h - Pass Entrypoints ------------------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This header file defines prototypes that expose pass constructors in the 19 | // analysis library. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #ifndef MLIR_ANALYSIS_PASSES_H 24 | #define MLIR_ANALYSIS_PASSES_H 25 | 26 | #include "mlir/Support/LLVM.h" 27 | 28 | namespace mlir { 29 | 30 | class FunctionPassBase; 31 | 32 | /// Creates a pass to check memref accesses in an ML Function. 33 | FunctionPassBase *createMemRefBoundCheckPass(); 34 | 35 | /// Creates a pass to check memref access dependences in an ML Function. 36 | FunctionPassBase *createMemRefDependenceCheckPass(); 37 | 38 | /// Creates a pass to test parallelism detection; emits note for parallel loops. 39 | FunctionPassBase *createParallelismDetectionTestPass(); 40 | 41 | } // end namespace mlir 42 | 43 | #endif // MLIR_ANALYSIS_PASSES_H 44 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/lib/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Registration of the Linalg dialect -------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file registers the Linalg dialect and should live in a standalone 19 | // library. Linking with this library will create a static global object that 20 | // performs dialect registration. 21 | // 22 | //===----------------------------------------------------------------------===// 23 | 24 | #include "linalg1/Dialect.h" 25 | #include "linalg1/Ops.h" 26 | #include "linalg1/Types.h" 27 | 28 | using namespace mlir; 29 | using namespace linalg; 30 | 31 | LinalgDialect::LinalgDialect(MLIRContext *context) 32 | : Dialect("linalg", context) { 33 | addTypes(); 34 | addOperations(); 35 | } 36 | 37 | // Dialect registration triggers the creation of a `LinalgDialect` object which 38 | // adds the proper types and operations to the dialect. 39 | static mlir::DialectRegistration LinalgOps; 40 | -------------------------------------------------------------------------------- /test/mlir-tblgen/attr-enum.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF 2 | // RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s --check-prefix=PAT 3 | 4 | include "mlir/IR/OpBase.td" 5 | 6 | def NS_SomeEnum_A : EnumAttrCase<"A">; 7 | def NS_SomeEnum_B : EnumAttrCase<"B">; 8 | def NS_SomeEnum_C : EnumAttrCase<"C">; 9 | 10 | def NS_SomeEnum : EnumAttr< 11 | "SomeEnum", "some enum", 12 | [NS_SomeEnum_A, NS_SomeEnum_B, NS_SomeEnum_C]>; 13 | 14 | def NS_OpA : Op<"op_a_with_enum_attr", []> { 15 | let arguments = (ins NS_SomeEnum:$attr); 16 | } 17 | 18 | // DEF-LABEL: StringRef OpA::attr() 19 | // DEF-NEXT: auto attr = this->getAttr("attr").dyn_cast_or_null(); 20 | // DEF-NEXT: return attr.getValue(); 21 | 22 | // DEF-LABEL: OpA::verify() 23 | // DEF: if (!(((this->getAttr("attr").cast().getValue() == "A")) || ((this->getAttr("attr").cast().getValue() == "B")) || ((this->getAttr("attr").cast().getValue() == "C")))) 24 | // DEF-SAME: return emitOpError("attribute 'attr' failed to satisfy some enum attribute constraints"); 25 | 26 | def NS_OpB : Op<"op_b_with_enum_attr", []> { 27 | let arguments = (ins NS_SomeEnum:$attr); 28 | } 29 | 30 | def : Pat<(NS_OpA NS_SomeEnum_A:$attr), (NS_OpB NS_SomeEnum_B)>; 31 | 32 | // PAT-LABEL: struct GeneratedConvert0 33 | // PAT: PatternMatchResult match 34 | // PAT: if (!((op0->getAttrOfType("attr").cast().getValue() == "A"))) return matchFailure(); 35 | // PAT: void rewrite 36 | // PAT: auto vOpB0 = rewriter.create(loc, 37 | // PAT-NEXT: rewriter.getStringAttr("B") 38 | // PAT-NEXT: ); 39 | -------------------------------------------------------------------------------- /lib/IR/AffineMapDetail.h: -------------------------------------------------------------------------------- 1 | //===- AffineMapDetail.h - MLIR Affine Map details Class --------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This holds implementation details of AffineMap. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef AFFINEMAPDETAIL_H_ 23 | #define AFFINEMAPDETAIL_H_ 24 | 25 | #include "mlir/IR/AffineExpr.h" 26 | #include "mlir/IR/AffineMap.h" 27 | #include "llvm/ADT/ArrayRef.h" 28 | 29 | namespace mlir { 30 | namespace detail { 31 | 32 | struct AffineMapStorage { 33 | unsigned numDims; 34 | unsigned numSymbols; 35 | 36 | /// The affine expressions for this (multi-dimensional) map. 37 | /// TODO: use trailing objects for this. 38 | ArrayRef results; 39 | 40 | /// The extents along each of the range dimensions if the map is bounded, 41 | /// nullptr otherwise. 42 | ArrayRef rangeSizes; 43 | }; 44 | 45 | } // end namespace detail 46 | } // end namespace mlir 47 | 48 | #endif // AFFINEMAPDETAIL_H_ 49 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/Dialect.h: -------------------------------------------------------------------------------- 1 | //===- Dialect.h - Definition of the Linalg dialect -----------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_DIALECT_H_ 19 | #define LINALG1_DIALECT_H_ 20 | 21 | #include "mlir/IR/Dialect.h" 22 | 23 | namespace linalg { 24 | 25 | /// The Linalg Dialect is not exposed to the outside world. It is registered by 26 | /// linking and accessed via generic MLIR accessors. 27 | class LinalgDialect : public mlir::Dialect { 28 | public: 29 | /// Create a new Dialect that is registered on construction and adds the 30 | /// relevant types and operations. 31 | explicit LinalgDialect(mlir::MLIRContext *context); 32 | 33 | /// Parse a type registered to this dialect. 34 | mlir::Type parseType(llvm::StringRef spec, mlir::Location loc) const override; 35 | 36 | /// Print a type registered to this dialect. 37 | void printType(mlir::Type type, llvm::raw_ostream &os) const override; 38 | }; 39 | 40 | } // namespace linalg 41 | 42 | #endif // LINALG1_DIALECT_H_ 43 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg3/lib/DialectRegistration.cpp: -------------------------------------------------------------------------------- 1 | //===- DialectRegistration.cpp - Registration of the Linalg dialect -------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file registers the Linalg dialect and should live in a standalone 19 | // library. Linking with this library will create a static global object that 20 | // performs dialect registration. 21 | // 22 | //===----------------------------------------------------------------------===// 23 | 24 | #include "linalg1/Dialect.h" 25 | #include "linalg1/Types.h" 26 | #include "linalg3/Ops.h" 27 | 28 | using namespace linalg; 29 | 30 | LinalgDialect::LinalgDialect(mlir::MLIRContext *context) 31 | : Dialect("linalg", context) { 32 | addTypes(); 33 | addOperations(); 35 | } 36 | 37 | // Dialect registration triggers the creation of a `LinalgDialect` object which 38 | // adds the proper types and operations to the dialect. 39 | static mlir::DialectRegistration LinalgOps; 40 | -------------------------------------------------------------------------------- /include/mlir/Target/LLVMIR.h: -------------------------------------------------------------------------------- 1 | //===- LLVMIR.h - MLIR to LLVM IR conversion --------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file declares the entry point for the MLIR to LLVM IR conversion. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_TARGET_LLVMIR_H 23 | #define MLIR_TARGET_LLVMIR_H 24 | 25 | #include 26 | 27 | // Forward-declare LLVM classses. 28 | namespace llvm { 29 | class LLVMContext; 30 | class Module; 31 | } // namespace llvm 32 | 33 | namespace mlir { 34 | 35 | class Module; 36 | 37 | /// Convert the given MLIR module into LLVM IR. Create an LLVM IR module in 38 | /// "llvmContext" and return a unique pointer to it. In case of error, report it 39 | /// to the error handler registered with the MLIR context, if any (obtained from 40 | /// the MLIR module), and return `nullptr`. 41 | std::unique_ptr 42 | convertModuleToLLVMIR(Module &module, llvm::LLVMContext &llvmContext); 43 | 44 | } // namespace mlir 45 | 46 | #endif // MLIR_TARGET_LLVMIR_H 47 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # MLIR project. 2 | set(MLIR_MAIN_SRC_DIR ${LLVM_MAIN_SRC_DIR}/projects/mlir/include ) # --src-root 3 | set(MLIR_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) # --includedir 4 | set(MLIR_TABLEGEN_EXE mlir-tblgen) 5 | 6 | set(MLIR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 7 | set(MLIR_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) 8 | 9 | # TODO: Temporary, remove when no longer needed. 10 | set(CMAKE_CXX_STANDARD 11) 11 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 12 | set(CMAKE_CXX_EXTENSIONS OFF) 13 | 14 | function(mlir_tablegen ofn) 15 | tablegen(MLIR ${ARGV} "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}") 16 | set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} 17 | PARENT_SCOPE) 18 | endfunction() 19 | 20 | # TODO: This is to handle the current static registration, but should be 21 | # factored out a bit. 22 | function(whole_archive_link target) 23 | if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") 24 | set(link_flags "-Llib -Wl,-all_load ") 25 | FOREACH(LIB ${ARGN}) 26 | string(CONCAT link_flags ${link_flags} "-l${LIB} ") 27 | ENDFOREACH(LIB) 28 | else() 29 | set(link_flags "-Llib -Wl,--whole-archive,") 30 | FOREACH(LIB ${ARGN}) 31 | string(CONCAT link_flags ${link_flags} "-l${LIB},") 32 | ENDFOREACH(LIB) 33 | string(CONCAT link_flags ${link_flags} "--no-whole-archive") 34 | endif() 35 | set_target_properties(${target} PROPERTIES LINK_FLAGS ${link_flags}) 36 | endfunction(whole_archive_link) 37 | 38 | include_directories( "include") 39 | include_directories( ${MLIR_INCLUDE_DIR}) 40 | 41 | add_subdirectory(include/mlir) 42 | add_subdirectory(lib) 43 | add_subdirectory(tools) 44 | add_subdirectory(unittests) 45 | add_subdirectory(test) 46 | 47 | if( LLVM_INCLUDE_EXAMPLES ) 48 | add_subdirectory(examples) 49 | endif() 50 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg3/include/linalg3/Transforms.h: -------------------------------------------------------------------------------- 1 | //===- Transforms.h - Linalg dialect Transformations definition -----------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG3_TRANSFORMS_H_ 19 | #define LINALG3_TRANSFORMS_H_ 20 | 21 | #include "linalg2/Transforms.h" 22 | 23 | namespace mlir { 24 | class Function; 25 | } // namespace mlir 26 | 27 | namespace linalg { 28 | 29 | /// Traverses `f` and rewrites linalg.slice, and the operations it depends on, 30 | /// to only use linalg.view operations. 31 | void composeSliceOps(mlir::Function *f); 32 | 33 | /// Traverses `f` and rewrites linalg.load and linalg.store to affine.load and 34 | /// affine.store operations. 35 | void lowerLinalgLoadStores(mlir::Function *f); 36 | 37 | /// Traverses `f` and rewrites linalg.matmul (resp. linalg.matvec) 38 | /// as linalg.matvec (resp. linalg.dot). 39 | void lowerToFinerGrainedTensorContraction(mlir::Function *f); 40 | 41 | /// Traverses `f` and rewrites linalg operations in loop form. 42 | void lowerToLoops(mlir::Function *f); 43 | 44 | } // namespace linalg 45 | 46 | #endif // LINALG3_TRANSFORMS_H_ 47 | -------------------------------------------------------------------------------- /lib/Transforms/StripDebugInfo.cpp: -------------------------------------------------------------------------------- 1 | //===- StripDebugInfo.cpp - Pass to strip debug information ---------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/IR/Function.h" 19 | #include "mlir/IR/Operation.h" 20 | #include "mlir/Pass/Pass.h" 21 | #include "mlir/Transforms/Passes.h" 22 | 23 | using namespace mlir; 24 | 25 | namespace { 26 | struct StripDebugInfo : public FunctionPass { 27 | void runOnFunction() override; 28 | }; 29 | } // end anonymous namespace 30 | 31 | void StripDebugInfo::runOnFunction() { 32 | Function &func = getFunction(); 33 | UnknownLoc unknownLoc = UnknownLoc::get(&getContext()); 34 | 35 | // Strip the debug info from the function and its operations. 36 | func.setLoc(unknownLoc); 37 | func.walk([&](Operation *op) { op->setLoc(unknownLoc); }); 38 | } 39 | 40 | /// Creates a pass to strip debug information from a function. 41 | FunctionPassBase *mlir::createStripDebugInfoPass() { 42 | return new StripDebugInfo(); 43 | } 44 | 45 | static PassRegistration 46 | pass("strip-debuginfo", "Strip debug info from functions and operations"); 47 | -------------------------------------------------------------------------------- /test/Examples/Toy/Ch2/codegen.toy: -------------------------------------------------------------------------------- 1 | # RUN: toyc-ch2 %s -emit=mlir 2>&1 | FileCheck %s 2 | 3 | # User defined generic function that operates on unknown shaped arguments 4 | def multiply_transpose(a, b) { 5 | return a * transpose(b); 6 | } 7 | 8 | def main() { 9 | var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; 10 | var b<2, 3> = [1, 2, 3, 4, 5, 6]; 11 | var c = multiply_transpose(a, b); 12 | var d = multiply_transpose(b, a); 13 | print(d); 14 | } 15 | 16 | # CHECK-LABEL: func @multiply_transpose(%arg0: !toy<"array">, %arg1: !toy<"array">) 17 | # CHECK-NEXT: attributes {toy.generic: true} { 18 | # CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy<"array">) -> !toy<"array"> 19 | # CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy<"array">, !toy<"array">) -> !toy<"array"> 20 | # CHECK-NEXT: "toy.return"(%1) : (!toy<"array">) -> () 21 | # CHECK-NEXT: } 22 | 23 | # CHECK-LABEL: func @main() { 24 | # CHECK-NEXT: %0 = "toy.constant"() {value: dense, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy<"array<2, 3>"> 25 | # CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<2, 3>">) -> !toy<"array<2, 3>"> 26 | # CHECK-NEXT: %2 = "toy.constant"() {value: dense, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy<"array<6>"> 27 | # CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy<"array<6>">) -> !toy<"array<2, 3>"> 28 | # CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array"> 29 | # CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array"> 30 | # CHECK-NEXT: "toy.print"(%5) : (!toy<"array">) -> () 31 | # CHECK-NEXT: "toy.return"() : () -> () 32 | 33 | -------------------------------------------------------------------------------- /test/Examples/Toy/Ch3/codegen.toy: -------------------------------------------------------------------------------- 1 | # RUN: toyc-ch3 %s -emit=mlir 2>&1 | FileCheck %s 2 | 3 | # User defined generic function that operates on unknown shaped arguments 4 | def multiply_transpose(a, b) { 5 | return a * transpose(b); 6 | } 7 | 8 | def main() { 9 | var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; 10 | var b<2, 3> = [1, 2, 3, 4, 5, 6]; 11 | var c = multiply_transpose(a, b); 12 | var d = multiply_transpose(b, a); 13 | print(d); 14 | } 15 | 16 | # CHECK-LABEL: func @multiply_transpose(%arg0: !toy<"array">, %arg1: !toy<"array">) 17 | # CHECK-NEXT: attributes {toy.generic: true} { 18 | # CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy<"array">) -> !toy<"array"> 19 | # CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy<"array">, !toy<"array">) -> !toy<"array"> 20 | # CHECK-NEXT: "toy.return"(%1) : (!toy<"array">) -> () 21 | # CHECK-NEXT: } 22 | 23 | # CHECK-LABEL: func @main() { 24 | # CHECK-NEXT: %0 = "toy.constant"() {value: dense, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy<"array<2, 3>"> 25 | # CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<2, 3>">) -> !toy<"array<2, 3>"> 26 | # CHECK-NEXT: %2 = "toy.constant"() {value: dense, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy<"array<6>"> 27 | # CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy<"array<6>">) -> !toy<"array<2, 3>"> 28 | # CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array"> 29 | # CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array"> 30 | # CHECK-NEXT: "toy.print"(%5) : (!toy<"array">) -> () 31 | # CHECK-NEXT: "toy.return"() : () -> () 32 | 33 | -------------------------------------------------------------------------------- /include/mlir/LLVMIR/Transforms.h: -------------------------------------------------------------------------------- 1 | //===- Transforms.h - Pass Entrypoints --------------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef MLIR_LLVMIR_TRANSFORMS_H_ 19 | #define MLIR_LLVMIR_TRANSFORMS_H_ 20 | 21 | #include 22 | 23 | namespace mlir { 24 | class DialectConversion; 25 | class Module; 26 | class ModulePassBase; 27 | 28 | /// Creates a pass to convert Standard dialects into the LLVMIR dialect. 29 | ModulePassBase *createConvertToLLVMIRPass(); 30 | 31 | /// Creates a dialect converter from the standard dialect to the LLVM IR 32 | /// dialect and transfers ownership to the caller. 33 | std::unique_ptr createStdToLLVMConverter(); 34 | 35 | namespace LLVM { 36 | /// Make argument-taking successors of each block distinct. PHI nodes in LLVM 37 | /// IR use the predecessor ID to identify which value to take. They do not 38 | /// support different values coming from the same predecessor. If a block has 39 | /// another block as a successor more than once with different values, insert 40 | /// a new dummy block for LLVM PHI nodes to tell the sources apart. 41 | void ensureDistinctSuccessors(Module *m); 42 | } // namespace LLVM 43 | 44 | } // namespace mlir 45 | 46 | #endif // MLIR_LLVMIR_TRANSFORMS_H_ 47 | -------------------------------------------------------------------------------- /include/mlir/Support/FileUtilities.h: -------------------------------------------------------------------------------- 1 | //===- FileUtilities.h - utilities for working with files -------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // Common utilities for working with files. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_SUPPORT_FILEUTILITIES_H_ 23 | #define MLIR_SUPPORT_FILEUTILITIES_H_ 24 | 25 | #include 26 | #include 27 | 28 | namespace llvm { 29 | class MemoryBuffer; 30 | class ToolOutputFile; 31 | class StringRef; 32 | } // namespace llvm 33 | 34 | namespace mlir { 35 | 36 | /// Open the file specified by its name for reading. Write the error message to 37 | /// `errorMessage` if errors occur and `errorMessage` is not nullptr. 38 | std::unique_ptr 39 | openInputFile(llvm::StringRef inputFilename, 40 | std::string *errorMessage = nullptr); 41 | 42 | /// Open the file specified by its name for writing. Write the error message to 43 | /// `errorMessage` if errors occur and `errorMessage` is not nullptr. 44 | std::unique_ptr 45 | openOutputFile(llvm::StringRef outputFilename, 46 | std::string *errorMessage = nullptr); 47 | 48 | } // namespace mlir 49 | 50 | #endif // MLIR_SUPPORT_FILEUTILITIES_H_ 51 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/RangeType.h: -------------------------------------------------------------------------------- 1 | //===- RangeType.h - Linalg RangeType definition --------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_RANGETYPE_H_ 19 | #define LINALG1_RANGETYPE_H_ 20 | 21 | #include "linalg1/Types.h" 22 | #include "mlir/IR/Types.h" 23 | 24 | namespace mlir { 25 | class MLIRContext; 26 | } 27 | 28 | namespace linalg { 29 | 30 | /// A RangeType is the simplest possible form of a type in MLIR. It represents 31 | /// a minimal range abstraction (min, max, step). Since RangeType is constructed 32 | /// without any additional argument, this example illustrates the minimal 33 | /// amount of information required to implement a new custom MLIR type. 34 | class RangeType : public mlir::Type::TypeBase { 35 | public: 36 | // Used to implement llvm-style cast. 37 | using Base::Base; 38 | /// Construction hook. 39 | static RangeType get(mlir::MLIRContext *context) { 40 | /// Custom, uniqu'ed construction in the mlir::MLIRContext. 41 | return Base::get(context, LinalgTypes::Range); 42 | } 43 | /// Used to implement llvm-style cast. 44 | static bool kindof(unsigned kind) { return kind == LinalgTypes::Range; } 45 | }; 46 | 47 | } // namespace linalg 48 | 49 | #endif // LINALG1_RANGETYPE_H_ 50 | -------------------------------------------------------------------------------- /test/AffineOps/ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s | FileCheck %s 2 | // RUN: mlir-opt %s -mlir-print-op-generic | FileCheck -check-prefix=GENERIC %s 3 | 4 | // Check that the attributes for the affine operations are round-tripped. 5 | // Check that `affine.terminator` is visible in the generic form. 6 | // CHECK-LABEL: @empty 7 | func @empty() { 8 | // CHECK: affine.for %i 9 | // CHECK-NEXT: } {some_attr: true} 10 | // 11 | // GENERIC: "affine.for"() 12 | // GENERIC-NEXT: ^bb1(%i0: index): 13 | // GENERIC-NEXT: "affine.terminator"() : () -> () 14 | // GENERIC-NEXT: } 15 | affine.for %i = 0 to 10 { 16 | } {some_attr: true} 17 | 18 | // CHECK: affine.if 19 | // CHECK-NEXT: } {some_attr: true} 20 | // 21 | // GENERIC: "affine.if"() 22 | // GENERIC-NEXT: "affine.terminator"() : () -> () 23 | // GENERIC-NEXT: } { 24 | // GENERIC-NEXT: } 25 | affine.if () : () () { 26 | } {some_attr: true} 27 | 28 | // CHECK: } else { 29 | // CHECK: } {some_attr: true} 30 | // 31 | // GENERIC: "affine.if"() 32 | // GENERIC-NEXT: "affine.terminator"() : () -> () 33 | // GENERIC-NEXT: } { 34 | // GENERIC-NEXT: "foo"() : () -> () 35 | // GENERIC-NEXT: "affine.terminator"() : () -> () 36 | // GENERIC-NEXT: } 37 | affine.if () : () () { 38 | } else { 39 | "foo"() : () -> () 40 | } {some_attr: true} 41 | 42 | return 43 | } 44 | 45 | // Check that an explicit affine terminator is not printed in custom format. 46 | // Check that no extra terminator is introduced. 47 | // CHEKC-LABEL: @affine_terminator 48 | func @affine_terminator() { 49 | // CHECK: affine.for %i 50 | // CHECK-NEXT: } 51 | // 52 | // GENERIC: "affine.for"() {lower_bound: #map0, step: 1 : index, upper_bound: #map1} : () -> () { 53 | // GENERIC-NEXT: ^bb1(%i0: index): // no predecessors 54 | // GENERIC-NEXT: "affine.terminator"() : () -> () 55 | // GENERIC-NEXT: } 56 | affine.for %i = 0 to 10 { 57 | "affine.terminator"() : () -> () 58 | } 59 | return 60 | } 61 | -------------------------------------------------------------------------------- /test/mlir-tblgen/op-decl.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s 2 | 3 | include "mlir/IR/OpBase.td" 4 | 5 | def NS_AOp : Op<"a_op", [NoSideEffect]> { 6 | let arguments = (ins 7 | I32:$a, 8 | Variadic:$b, 9 | 10 | I32Attr:$attr1, 11 | OptionalAttr:$attr2 12 | ); 13 | 14 | let results = (outs 15 | I32:$r, 16 | Variadic:$s 17 | ); 18 | 19 | let builders = [OpBuilder<"Value *val">]; 20 | let parser = [{ foo }]; 21 | let printer = [{ bar }]; 22 | let verifier = [{ baz }]; 23 | 24 | let hasCanonicalizer = 1; 25 | let hasConstantFolder = 1; 26 | let hasFolder = 1; 27 | } 28 | 29 | // CHECK-LABEL: NS::AOp declarations 30 | 31 | // CHECK: class AOp : public Op::Impl, OpTrait::HasNoSideEffect, OpTrait::AtLeastNOperands<1>::Impl> { 32 | // CHECK: public: 33 | // CHECK: using Op::Op; 34 | // CHECK: static StringRef getOperationName(); 35 | // CHECK: Value *a(); 36 | // CHECK: Operation::operand_range b(); 37 | // CHECK: Value *r(); 38 | // CHECK: APInt attr1(); 39 | // CHECK: Optional< APFloat > attr2(); 40 | // CHECK: static void build(Value *val); 41 | // CHECK: static void build(Builder *, OperationState *tblgen_state, Type r, ArrayRef s, Value *a, ArrayRef b, IntegerAttr attr1, /*optional*/FloatAttr attr2); 42 | // CHECK: static void build(Builder *, OperationState *tblgen_state, ArrayRef resultTypes, ArrayRef operands, ArrayRef attributes); 43 | // CHECK: static bool parse(OpAsmParser *parser, OperationState *result); 44 | // CHECK: void print(OpAsmPrinter *p); 45 | // CHECK: LogicalResult verify(); 46 | // CHECK: static void getCanonicalizationPatterns(OwningRewritePatternList &results, MLIRContext *context); 47 | // CHECK: LogicalResult constantFold(ArrayRef operands, SmallVectorImpl &results, MLIRContext *context); 48 | // CHECK: bool fold(SmallVectorImpl &results); 49 | // CHECK: }; 50 | -------------------------------------------------------------------------------- /test/lit.site.cfg.py.in: -------------------------------------------------------------------------------- 1 | @LIT_SITE_CFG_IN_HEADER@ 2 | 3 | import sys 4 | 5 | config.host_triple = "@LLVM_HOST_TRIPLE@" 6 | config.target_triple = "@TARGET_TRIPLE@" 7 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" 8 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" 9 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" 10 | config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" 11 | config.llvm_shlib_dir = "@SHLIBDIR@" 12 | config.llvm_shlib_ext = "@SHLIBEXT@" 13 | config.llvm_exe_ext = "@EXEEXT@" 14 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" 15 | config.python_executable = "@PYTHON_EXECUTABLE@" 16 | config.gold_executable = "@GOLD_EXECUTABLE@" 17 | config.ld64_executable = "@LD64_EXECUTABLE@" 18 | config.enable_shared = @ENABLE_SHARED@ 19 | config.enable_assertions = @ENABLE_ASSERTIONS@ 20 | config.targets_to_build = "@TARGETS_TO_BUILD@" 21 | config.native_target = "@LLVM_NATIVE_ARCH@" 22 | config.llvm_bindings = "@LLVM_BINDINGS@".split(' ') 23 | config.host_os = "@HOST_OS@" 24 | config.host_cc = "@HOST_CC@" 25 | config.host_cxx = "@HOST_CXX@" 26 | config.host_ldflags = "@HOST_LDFLAGS@" 27 | config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" 28 | config.llvm_host_triple = '@LLVM_HOST_TRIPLE@' 29 | config.host_arch = "@HOST_ARCH@" 30 | config.mlir_src_root = "@MLIR_SOURCE_DIR@" 31 | config.mlir_obj_root = "@MLIR_BINARY_DIR@" 32 | config.mlir_tools_dir = "@MLIR_TOOLS_DIR@" 33 | config.build_examples = @LLVM_BUILD_EXAMPLES@ 34 | 35 | # Support substitution of the tools_dir with user parameters. This is 36 | # used when we can't determine the tool dir at configuration time. 37 | try: 38 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params 39 | config.llvm_shlib_dir = config.llvm_shlib_dir % lit_config.params 40 | except KeyError: 41 | e = sys.exc_info()[1] 42 | key, = e.args 43 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) 44 | 45 | import lit.llvm 46 | lit.llvm.initialize(lit_config, config) 47 | 48 | # Let the main config do the real work. 49 | lit_config.load_config(config, "@MLIR_SOURCE_DIR@/test/lit.cfg.py") 50 | -------------------------------------------------------------------------------- /lib/Analysis/TestParallelismDetection.cpp: -------------------------------------------------------------------------------- 1 | //===- ParallelismDetection.cpp - Parallelism Detection pass ------------*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements a pass to detect parallel affine 'affine.for' ops. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #include "mlir/AffineOps/AffineOps.h" 23 | #include "mlir/Analysis/Passes.h" 24 | #include "mlir/Analysis/Utils.h" 25 | #include "mlir/IR/Builders.h" 26 | #include "mlir/Pass/Pass.h" 27 | 28 | using namespace mlir; 29 | 30 | namespace { 31 | 32 | struct TestParallelismDetection 33 | : public FunctionPass { 34 | void runOnFunction() override; 35 | }; 36 | 37 | } // end anonymous namespace 38 | 39 | FunctionPassBase *mlir::createParallelismDetectionTestPass() { 40 | return new TestParallelismDetection(); 41 | } 42 | 43 | // Walks the function and emits a note for all 'affine.for' ops detected as 44 | // parallel. 45 | void TestParallelismDetection::runOnFunction() { 46 | Function &f = getFunction(); 47 | FuncBuilder b(f); 48 | f.walk([&](AffineForOp forOp) { 49 | if (isLoopParallel(forOp)) 50 | forOp.emitNote("parallel loop"); 51 | }); 52 | } 53 | 54 | static PassRegistration 55 | pass("test-detect-parallel", "Test parallelism detection "); 56 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/Analysis.h: -------------------------------------------------------------------------------- 1 | //===- Analysis.h - Linalg dialect Analysis function definitions ----------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_ANALYSIS_H_ 19 | #define LINALG1_ANALYSIS_H_ 20 | 21 | #include "mlir/Support/LLVM.h" 22 | 23 | namespace mlir { 24 | class Value; 25 | } // namespace mlir 26 | 27 | namespace linalg { 28 | class ViewOp; 29 | 30 | /// Walks the chain of SliceOp until the unique base ViewOp. 31 | ViewOp getViewBaseViewOp(mlir::Value *view); 32 | 33 | /// Walks the chain of SliceOp until the unique base ViewOp and returns the 34 | /// MemRef upon which the ViewOp is laid. 35 | mlir::Value *getViewSupportingMemRef(mlir::Value *view); 36 | 37 | /// Extract the indexing from the root ViewOp that this slice constrins along 38 | /// `dim`. To achieve this, it walks back the chain of SliceOp and determine the 39 | /// first slice that constrains `dim`. 40 | /// Note that the dimension in the original ViewOp may shift due to 41 | /// rank-reducing operations. 42 | /// Returns a pair, with the indexing as the first element and the actual 43 | /// dimension, in the root ViewOp, as the second element. 44 | std::pair getViewRootIndexing(mlir::Value *view, 45 | unsigned dim); 46 | 47 | } // namespace linalg 48 | 49 | #endif // LINALG1_ANALYSIS_H_ 50 | -------------------------------------------------------------------------------- /utils/vim/mlir.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2019 The MLIR Authors. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | " Vim syntax file 16 | " Language: MLIR 17 | 18 | " quit when a syntax file was already loaded 19 | if exists("b:current_syntax") 20 | finish 21 | endif 22 | 23 | syn keyword mlirType index i1 i2 i4 i8 i13 i16 i32 i64 24 | \ f16 f32 tf_control 25 | syn keyword mlirType memref tensor vector 26 | 27 | syntax keyword mlirKeywords extfunc cfgfunc mlfunc for to step return 28 | syntax keyword mlirConditional if else 29 | syntax keyword mlirCoreOps dim addf addi subf subi mulf muli cmpi select constant affine.apply call call_indirect extract_element getTensor memref_cast tensor_cast load store alloc dealloc dma_start dma_wait 30 | 31 | syn match mlirInt "-\=\<\d\+\>" 32 | syn match mlirFloat "-\=\<\d\+\.\d\+\>" 33 | syn match mlirMapOutline "#.*$" 34 | syn match mlirOperator "[+\-*=]" 35 | 36 | syn region mlirComment start="//" skip="\\$" end="$" 37 | syn region mlirString matchgroup=mlirString start=+"+ end=+"+ 38 | 39 | hi def link mlirComment Comment 40 | hi def link mlirKeywords Instruction 41 | hi def link mlirCoreOps Instruction 42 | hi def link mlirInt Constant 43 | hi def link mlirType Type 44 | hi def link mlirMapOutline PreProc 45 | hi def link mlirConditional Conditional 46 | hi def link mlirString String 47 | hi def link mlirOperator Operator 48 | hi def link mlirInstruction Operator 49 | hi def link mlirAffineOp Operator 50 | 51 | let b:current_syntax = "mlir" 52 | -------------------------------------------------------------------------------- /include/mlir/Quantization/Passes.h: -------------------------------------------------------------------------------- 1 | //===- Passes.h - Quantization Passes ------ --------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file defines all of the passes owned by the quantization dialect. As 19 | // things mature, it is expected that passes specific to certain frontend or 20 | // backend dialects will move to those dialects directly. For now, they are 21 | // incubated here. 22 | // 23 | //===----------------------------------------------------------------------===// 24 | 25 | #ifndef MLIR_QUANTIZATION_PASSES_H 26 | #define MLIR_QUANTIZATION_PASSES_H 27 | 28 | namespace mlir { 29 | class FunctionPassBase; 30 | 31 | namespace quant { 32 | 33 | /// Creates a pass that converts quantization simulation operations (i.e. 34 | /// FakeQuant and those like it) to casts into/out of supported QuantizedTypes. 35 | FunctionPassBase *createConvertSimulatedQuantPass(); 36 | 37 | /// Creates a pass that converts constants followed by a qbarrier to a 38 | /// constant whose value is quantized. This is typically one of the last 39 | /// passes done when lowering to express actual quantized arithmetic in a 40 | /// low level representation. Because it modifies the constant, it is 41 | /// destructive and cannot be undone. 42 | FunctionPassBase *createConvertConstPass(); 43 | 44 | } // namespace quant 45 | } // namespace mlir 46 | 47 | #endif // MLIR_QUANTIZATION_PASSES_H 48 | -------------------------------------------------------------------------------- /test/IR/op-stats.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt -print-op-stats %s -o=/dev/null 2>&1 | FileCheck %s 2 | 3 | func @main(tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32> { 4 | ^bb0(%arg0: tensor<4xf32>, %arg1: tensor<4xf32>): 5 | %0 = addf %arg0, %arg1 : tensor<4xf32> 6 | %1 = addf %arg0, %arg1 : tensor<4xf32> 7 | %2 = addf %arg0, %arg1 : tensor<4xf32> 8 | %3 = addf %arg0, %arg1 : tensor<4xf32> 9 | %4 = addf %arg0, %arg1 : tensor<4xf32> 10 | %5 = addf %arg0, %arg1 : tensor<4xf32> 11 | %10 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 12 | %11 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 13 | %12 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 14 | %13 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 15 | %14 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 16 | %15 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 17 | %16 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 18 | %17 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 19 | %18 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 20 | %19 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 21 | %20 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 22 | %21 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 23 | %22 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 24 | %23 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 25 | %24 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 26 | %25 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 27 | %26 = "xla.add"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 28 | %30 = "long_op_name"(%0, %arg1) : (tensor<4xf32>,tensor<4xf32>)-> tensor<4xf32> 29 | return %1 : tensor<4xf32> 30 | } 31 | 32 | // CHECK-LABEL: Operations encountered 33 | // CHECK: long_op_name , 1 34 | // CHECK: std.addf , 6 35 | // CHECK: std.return , 1 36 | // CHECK: xla.add , 17 37 | -------------------------------------------------------------------------------- /lib/TableGen/Type.cpp: -------------------------------------------------------------------------------- 1 | //===- Type.cpp - Type class ----------------------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // Type wrapper to simplify using TableGen Record defining a MLIR Type. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #include "mlir/TableGen/Type.h" 23 | #include "llvm/TableGen/Record.h" 24 | 25 | using namespace mlir; 26 | 27 | tblgen::TypeConstraint::TypeConstraint(const llvm::Record *record) 28 | : Constraint(Constraint::CK_Type, record) { 29 | assert(def->isSubClassOf("TypeConstraint") && 30 | "must be subclass of TableGen 'TypeConstraint' class"); 31 | } 32 | 33 | tblgen::TypeConstraint::TypeConstraint(const llvm::DefInit *init) 34 | : TypeConstraint(init->getDef()) {} 35 | 36 | bool tblgen::TypeConstraint::isVariadic() const { 37 | return def->isSubClassOf("Variadic"); 38 | } 39 | 40 | tblgen::Type::Type(const llvm::Record *record) : TypeConstraint(record) { 41 | assert(def->isSubClassOf("Type") && 42 | "must be subclass of TableGen 'Type' class"); 43 | } 44 | 45 | tblgen::Type::Type(const llvm::DefInit *init) : Type(init->getDef()) {} 46 | 47 | StringRef tblgen::Type::getTableGenDefName() const { return def->getName(); } 48 | 49 | tblgen::Type tblgen::Type::getVariadicBaseType() const { 50 | assert(isVariadic() && "must be variadic type constraint"); 51 | return Type(def->getValueAsDef("baseType")); 52 | } 53 | -------------------------------------------------------------------------------- /include/mlir/IR/DialectTypeRegistry.def: -------------------------------------------------------------------------------- 1 | //===- DialectTypeRegistry.def - MLIR Dialect Type Registry -----*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file enumerates the different dialects that define custom classes 19 | // within the type system. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | DEFINE_TYPE_KIND_RANGE(STANDARD) 24 | DEFINE_TYPE_KIND_RANGE(TENSORFLOW_CONTROL) 25 | DEFINE_TYPE_KIND_RANGE(TENSORFLOW) 26 | DEFINE_TYPE_KIND_RANGE(LLVM) 27 | DEFINE_TYPE_KIND_RANGE(QUANTIZATION) 28 | DEFINE_TYPE_KIND_RANGE(IREE) // IREE stands for IR Execution Engine 29 | DEFINE_TYPE_KIND_RANGE(LINALG) // Linear Algebra Dialect 30 | DEFINE_TYPE_KIND_RANGE(TOY) // Toy language (tutorial) Dialect 31 | 32 | // The following ranges are reserved for experimenting with MLIR dialects in a 33 | // private context without having to register them here. 34 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_0) 35 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_1) 36 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_2) 37 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_3) 38 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_4) 39 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_5) 40 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_6) 41 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_7) 42 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_8) 43 | DEFINE_TYPE_KIND_RANGE(PRIVATE_EXPERIMENTAL_9) 44 | 45 | #undef DEFINE_TYPE_KIND_RANGE 46 | -------------------------------------------------------------------------------- /test/IR/invalid-locations.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -split-input-file -verify 2 | 3 | // ----- 4 | 5 | func @location_missing_l_paren() { 6 | ^bb: 7 | return loc) // expected-error {{expected '(' in inline location}} 8 | } 9 | 10 | // ----- 11 | 12 | func @location_missing_r_paren() { 13 | ^bb: 14 | return loc(unknown // expected-error@+1 {{expected ')' in inline location}} 15 | } 16 | 17 | // ----- 18 | 19 | func @location_invalid_instance() { 20 | ^bb: 21 | return loc() // expected-error {{expected location instance}} 22 | } 23 | 24 | // ----- 25 | 26 | func @location_callsite_missing_l_paren() { 27 | ^bb: 28 | return loc(callsite unknown // expected-error {{expected '(' in callsite location}} 29 | } 30 | 31 | // ----- 32 | 33 | func @location_callsite_missing_callee() { 34 | ^bb: 35 | return loc(callsite( at ) // expected-error {{expected location instance}} 36 | } 37 | 38 | // ----- 39 | 40 | func @location_callsite_missing_at() { 41 | ^bb: 42 | return loc(callsite(unknown unknown) // expected-error {{expected 'at' in callsite location}} 43 | } 44 | 45 | // ----- 46 | 47 | func @location_callsite_missing_caller() { 48 | ^bb: 49 | return loc(callsite(unknown at ) // expected-error {{expected location instance}} 50 | } 51 | 52 | // ----- 53 | 54 | func @location_callsite_missing_r_paren() { 55 | ^bb: 56 | return loc(callsite( unknown at unknown // expected-error@+1 {{expected ')' in callsite location}} 57 | } 58 | 59 | // ----- 60 | 61 | func @location_fused_missing_greater() { 62 | ^bb: 63 | return loc(fused' after fused location metadata}} 64 | } 65 | 66 | // ----- 67 | 68 | func @location_fused_missing_metadata() { 69 | ^bb: 70 | // expected-error@+1 {{expected non-function type}} 71 | return loc(fused<) // expected-error {{expected valid attribute metadata}} 72 | } 73 | 74 | // ----- 75 | 76 | func @location_fused_missing_l_square() { 77 | ^bb: 78 | return loc(fusedunknown]) // expected-error {{expected '[' in fused location}} 79 | } 80 | 81 | // ----- 82 | 83 | func @location_fused_missing_r_square() { 84 | ^bb: 85 | return loc(fused[unknown) // expected-error {{expected ']' in fused location}} 86 | } 87 | -------------------------------------------------------------------------------- /include/mlir/Transforms/ViewFunctionGraph.h: -------------------------------------------------------------------------------- 1 | //===- ViewFunctionGraph.h - View/write graphviz graphs ---------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // Defines interface to produce Graphviz outputs of MLIR Functions. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_TRANSFORMS_VIEWFUNCTIONGRAPH_H_ 23 | #define MLIR_TRANSFORMS_VIEWFUNCTIONGRAPH_H_ 24 | 25 | #include "mlir/Support/LLVM.h" 26 | #include "llvm/Support/GraphWriter.h" 27 | #include "llvm/Support/raw_ostream.h" 28 | 29 | namespace mlir { 30 | 31 | class Function; 32 | class FunctionPassBase; 33 | 34 | /// Displays the CFG in a window. This is for use from the debugger and 35 | /// depends on Graphviz to generate the graph. 36 | void viewGraph(Function &function, const Twine &name, bool shortNames = false, 37 | const Twine &title = "", 38 | llvm::GraphProgram::Name program = llvm::GraphProgram::DOT); 39 | 40 | llvm::raw_ostream &writeGraph(llvm::raw_ostream &os, Function &function, 41 | bool shortNames = false, const Twine &title = ""); 42 | 43 | /// Creates a pass to print CFG graphs. 44 | FunctionPassBase *createPrintCFGGraphPass(llvm::raw_ostream &os = llvm::errs(), 45 | bool shortNames = false, 46 | const llvm::Twine &title = ""); 47 | 48 | } // end namespace mlir 49 | 50 | #endif // MLIR_TRANSFORMS_VIEWFUNCTIONGRAPH_H_ 51 | -------------------------------------------------------------------------------- /test/lit.cfg.py: -------------------------------------------------------------------------------- 1 | # -*- Python -*- 2 | 3 | import os 4 | import platform 5 | import re 6 | import subprocess 7 | import tempfile 8 | 9 | import lit.formats 10 | import lit.util 11 | 12 | from lit.llvm import llvm_config 13 | from lit.llvm.subst import ToolSubst 14 | from lit.llvm.subst import FindTool 15 | 16 | # Configuration file for the 'lit' test runner. 17 | 18 | # name: The name of this test suite. 19 | config.name = 'MLIR' 20 | 21 | config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) 22 | 23 | # suffixes: A list of file extensions to treat as test files. 24 | config.suffixes = ['.td', '.mlir', '.toy'] 25 | 26 | # test_source_root: The root path where tests are located. 27 | config.test_source_root = os.path.dirname(__file__) 28 | 29 | # test_exec_root: The root path where tests should be run. 30 | config.test_exec_root = os.path.join(config.mlir_obj_root, 'test') 31 | 32 | config.substitutions.append(('%PATH%', config.environment['PATH'])) 33 | 34 | llvm_config.with_system_environment( 35 | ['HOME', 'INCLUDE', 'LIB', 'TMP', 'TEMP']) 36 | 37 | llvm_config.use_default_substitutions() 38 | 39 | # excludes: A list of directories to exclude from the testsuite. The 'Inputs' 40 | # subdirectories contain auxiliary inputs for various tests in their parent 41 | # directories. 42 | config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt'] 43 | 44 | # test_source_root: The root path where tests are located. 45 | config.test_source_root = os.path.dirname(__file__) 46 | 47 | # test_exec_root: The root path where tests should be run. 48 | config.test_exec_root = os.path.join(config.mlir_obj_root, 'test') 49 | 50 | # Tweak the PATH to include the tools dir. 51 | llvm_config.with_environment('PATH', config.llvm_tools_dir, append_path=True) 52 | 53 | tool_dirs = [config.mlir_tools_dir, config.llvm_tools_dir] 54 | tools = [ 55 | 'mlir-opt', 'mlir-tblgen', 'mlir-translate', 56 | ] 57 | 58 | # The following tools are optional 59 | tools.extend([ 60 | ToolSubst('toy-ch1', unresolved='ignore'), 61 | ToolSubst('toy-ch2', unresolved='ignore'), 62 | ToolSubst('toy-ch3', unresolved='ignore'), 63 | ]) 64 | 65 | llvm_config.add_tool_substitutions(tools, tool_dirs) 66 | -------------------------------------------------------------------------------- /test/Transforms/Vectorize/vector_utils.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -vectorizer-test -vector-shape-ratio 4 -vector-shape-ratio 8 2>&1 | FileCheck %s 2 | // RUN: mlir-opt %s -vectorizer-test -vector-shape-ratio 2 -vector-shape-ratio 5 -vector-shape-ratio 2 2>&1 | FileCheck %s -check-prefix=TEST-3x4x5x8 3 | 4 | func @vector_add_2d(%arg0: index, %arg1: index) -> f32 { 5 | // Nothing should be matched in this first block. 6 | // CHECK-NOT:matched: {{.*}} = alloc{{.*}} 7 | // CHECK-NOT:matched: {{.*}} = constant 0{{.*}} 8 | // CHECK-NOT:matched: {{.*}} = constant 1{{.*}} 9 | %0 = alloc(%arg0, %arg1) : memref 10 | %1 = alloc(%arg0, %arg1) : memref 11 | %2 = alloc(%arg0, %arg1) : memref 12 | %c0 = constant 0 : index 13 | %cst = constant 1.000000e+00 : f32 14 | 15 | // CHECK:matched: {{.*}} constant splat{{.*}} with shape ratio: 2, 32 16 | %cst_1 = constant splat, 1.000000e+00> : vector<8x256xf32> 17 | // CHECK:matched: {{.*}} constant splat{{.*}} with shape ratio: 1, 3, 7, 2, 1 18 | %cst_a = constant splat, 1.000000e+00> : vector<1x3x7x8x8xf32> 19 | // CHECK-NOT:matched: {{.*}} constant splat{{.*}} with shape ratio: 1, 3, 7, 1{{.*}} 20 | %cst_b = constant splat, 1.000000e+00> : vector<1x3x7x8x8xf32> 21 | // TEST-3x4x5x8:matched: {{.*}} constant splat{{.*}} with shape ratio: 3, 2, 1, 4 22 | %cst_c = constant splat, 1.000000e+00> : vector<3x4x5x8xf32> 23 | // TEST-3x4x4x8-NOT:matched: {{.*}} constant splat{{.*}} with shape ratio{{.*}} 24 | %cst_d = constant splat, 1.000000e+00> : vector<3x4x4x8xf32> 25 | // TEST-3x4x4x8:matched: {{.*}} constant splat{{.*}} with shape ratio: 1, 1, 2, 16 26 | %cst_e = constant splat, 1.000000e+00> : vector<1x2x10x32xf32> 27 | 28 | // Nothing should be matched in this last block. 29 | // CHECK-NOT:matched: {{.*}} = constant 7{{.*}} 30 | // CHECK-NOT:matched: {{.*}} = constant 42{{.*}} 31 | // CHECK-NOT:matched: {{.*}} = load{{.*}} 32 | // CHECK-NOT:matched: return {{.*}} 33 | %c7 = constant 7 : index 34 | %c42 = constant 42 : index 35 | %9 = load %2[%c7, %c42] : memref 36 | return %9 : f32 37 | } -------------------------------------------------------------------------------- /include/mlir/ExecutionEngine/MemRefUtils.h: -------------------------------------------------------------------------------- 1 | //===- MemRefUtils.h - MLIR runtime utilities for memrefs -------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This is a set of utilities to working with objects of memref type in an JIT 19 | // context using the MLIR execution engine. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #ifndef MLIR_EXECUTIONENGINE_MEMREFUTILS_H_ 24 | #define MLIR_EXECUTIONENGINE_MEMREFUTILS_H_ 25 | 26 | #include "mlir/Support/LLVM.h" 27 | 28 | namespace llvm { 29 | template class Expected; 30 | } 31 | 32 | namespace mlir { 33 | 34 | class Function; 35 | 36 | /// Simple memref descriptor class compatible with the ABI of functions emitted 37 | /// by MLIR to LLVM IR conversion for statically-shaped memrefs of float type. 38 | struct StaticFloatMemRef { 39 | float *data; 40 | }; 41 | 42 | /// Given an MLIR function that takes only statically-shaped memrefs with 43 | /// element type f32, allocate the memref descriptor and the data storage for 44 | /// each of the arguments, initialize the storage with `initialValue`, and 45 | /// return a list of type-erased descriptor pointers. 46 | llvm::Expected> 47 | allocateMemRefArguments(Function *func, float initialValue = 0.0); 48 | 49 | /// Free a list of type-erased descriptors to statically-shaped memrefs with 50 | /// element type f32. 51 | void freeMemRefArguments(ArrayRef args); 52 | 53 | } // namespace mlir 54 | 55 | #endif // MLIR_EXECUTIONENGINE_MEMREFUTILS_H_ 56 | -------------------------------------------------------------------------------- /test/LLVMIR/convert-funcs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt -convert-to-llvmir %s | FileCheck %s 2 | 3 | //CHECK: func @second_order_arg(!llvm<"void ()*">) 4 | func @second_order_arg(%arg0 : () -> ()) 5 | 6 | //CHECK: func @second_order_result() -> !llvm<"void ()*"> 7 | func @second_order_result() -> (() -> ()) 8 | 9 | //CHECK: func @second_order_multi_result() -> !llvm<"{ i32 ()*, i64 ()*, float ()* }"> 10 | func @second_order_multi_result() -> (() -> (i32), () -> (i64), () -> (f32)) 11 | 12 | //CHECK: func @third_order(!llvm<"void ()* (void ()*)*">) -> !llvm<"void ()* (void ()*)*"> 13 | func @third_order(%arg0 : (() -> ()) -> (() -> ())) -> ((() -> ()) -> (() -> ())) 14 | 15 | //CHECK: func @fifth_order_left(!llvm<"void (void (void (void ()*)*)*)*">) 16 | func @fifth_order_left(%arg0: (((() -> ()) -> ()) -> ()) -> ()) 17 | 18 | //CHECK: func @fifth_order_right(!llvm<"void ()* ()* ()* ()*">) 19 | func @fifth_order_right(%arg0: () -> (() -> (() -> (() -> ())))) 20 | 21 | //CHECK-LABEL: func @pass_through(%arg0: !llvm<"void ()*">) -> !llvm<"void ()*"> { 22 | func @pass_through(%arg0: () -> ()) -> (() -> ()) { 23 | // CHECK-NEXT: llvm.br ^bb1(%arg0 : !llvm<"void ()*">) 24 | br ^bb1(%arg0 : () -> ()) 25 | 26 | //CHECK-NEXT: ^bb1(%0: !llvm<"void ()*">): // pred: ^bb0 27 | ^bb1(%bbarg: () -> ()): 28 | // CHECK-NEXT: llvm.return %0 : !llvm<"void ()*"> 29 | return %bbarg : () -> () 30 | } 31 | 32 | // CHECK-LABEL: func @body(!llvm<"i32">) 33 | func @body(i32) 34 | 35 | // CHECK-LABEL: func @indirect_const_call(%arg0: !llvm<"i32">) { 36 | func @indirect_const_call(%arg0: i32) { 37 | // CHECK-NEXT: %0 = llvm.constant(@body : (!llvm<"i32">) -> ()) : !llvm<"void (i32)*"> 38 | %0 = constant @body : (i32) -> () 39 | // CHECK-NEXT: llvm.call %0(%arg0) : (!llvm<"i32">) -> () 40 | call_indirect %0(%arg0) : (i32) -> () 41 | // CHECK-NEXT: llvm.return 42 | return 43 | } 44 | 45 | // CHECK-LABEL: func @indirect_call(%arg0: !llvm<"i32 (float)*">, %arg1: !llvm<"float">) -> !llvm<"i32"> { 46 | func @indirect_call(%arg0: (f32) -> i32, %arg1: f32) -> i32 { 47 | // CHECK-NEXT: %0 = llvm.call %arg0(%arg1) : (!llvm<"float">) -> !llvm<"i32"> 48 | %0 = call_indirect %arg0(%arg1) : (f32) -> i32 49 | // CHECK-NEXT: llvm.return %0 : !llvm<"i32"> 50 | return %0 : i32 51 | } 52 | 53 | -------------------------------------------------------------------------------- /include/mlir/Parser.h: -------------------------------------------------------------------------------- 1 | //===- Parser.h - MLIR Parser Library Interface -----------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file is contains the interface to the MLIR parser library. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_PARSER_H 23 | #define MLIR_PARSER_H 24 | 25 | namespace llvm { 26 | class SourceMgr; 27 | class SMDiagnostic; 28 | class StringRef; 29 | } // end namespace llvm 30 | 31 | namespace mlir { 32 | class Module; 33 | class MLIRContext; 34 | 35 | /// This parses the file specified by the indicated SourceMgr and returns an 36 | /// MLIR module if it was valid. If not, the error message is emitted through 37 | /// the error handler registered in the context, and a null pointer is returned. 38 | Module *parseSourceFile(const llvm::SourceMgr &sourceMgr, MLIRContext *context); 39 | 40 | /// This parses the file specified by the indicated filename and returns an 41 | /// MLIR module if it was valid. If not, the error message is emitted through 42 | /// the error handler registered in the context, and a null pointer is returned. 43 | Module *parseSourceFile(llvm::StringRef filename, MLIRContext *context); 44 | 45 | /// This parses the module string to a MLIR module if it was valid. If not, the 46 | /// error message is emitted through / the error handler registered in the 47 | /// context, and a null pointer is returned. 48 | Module *parseSourceString(llvm::StringRef moduleStr, MLIRContext *context); 49 | 50 | } // end namespace mlir 51 | 52 | #endif // MLIR_PARSER_H 53 | -------------------------------------------------------------------------------- /lib/Support/FileUtilities.cpp: -------------------------------------------------------------------------------- 1 | //===- FileUtilities.cpp - utilities for working with files -----*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // Definitions of common utilities for working with files. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #include "mlir/Support/FileUtilities.h" 23 | #include "mlir/Support/LLVM.h" 24 | #include "llvm/Support/FileUtilities.h" 25 | #include "llvm/Support/MemoryBuffer.h" 26 | #include "llvm/Support/ToolOutputFile.h" 27 | 28 | using namespace mlir; 29 | 30 | std::unique_ptr 31 | mlir::openInputFile(StringRef inputFilename, std::string *errorMessage) { 32 | auto fileOrErr = llvm::MemoryBuffer::getFileOrSTDIN(inputFilename); 33 | if (std::error_code error = fileOrErr.getError()) { 34 | if (errorMessage) 35 | *errorMessage = "cannot open input file '" + inputFilename.str() + 36 | "': " + error.message(); 37 | return nullptr; 38 | } 39 | 40 | return std::move(*fileOrErr); 41 | } 42 | 43 | std::unique_ptr 44 | mlir::openOutputFile(StringRef outputFilename, std::string *errorMessage) { 45 | std::error_code error; 46 | auto result = llvm::make_unique(outputFilename, error, 47 | llvm::sys::fs::F_None); 48 | if (error) { 49 | if (errorMessage) 50 | *errorMessage = "cannot open output file '" + outputFilename.str() + 51 | "': " + error.message(); 52 | return nullptr; 53 | } 54 | 55 | return result; 56 | } 57 | -------------------------------------------------------------------------------- /lib/IR/Location.cpp: -------------------------------------------------------------------------------- 1 | //===- Location.cpp - MLIR Location Classes -------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/IR/Location.h" 19 | #include "LocationDetail.h" 20 | 21 | using namespace mlir; 22 | using namespace mlir::detail; 23 | 24 | Location::Kind Location::getKind() const { return loc->kind; } 25 | 26 | UnknownLoc::UnknownLoc(Location::ImplType *ptr) : Location(ptr) {} 27 | 28 | FileLineColLoc::FileLineColLoc(Location::ImplType *ptr) : Location(ptr) {} 29 | 30 | StringRef FileLineColLoc::getFilename() const { 31 | return static_cast(loc)->filename.getRef(); 32 | } 33 | unsigned FileLineColLoc::getLine() const { 34 | return static_cast(loc)->line; 35 | } 36 | unsigned FileLineColLoc::getColumn() const { 37 | return static_cast(loc)->column; 38 | } 39 | 40 | NameLoc::NameLoc(Location::ImplType *ptr) : Location(ptr) {} 41 | 42 | Identifier NameLoc::getName() const { 43 | return static_cast(loc)->name; 44 | } 45 | 46 | CallSiteLoc::CallSiteLoc(Location::ImplType *ptr) : Location(ptr) {} 47 | 48 | Location CallSiteLoc::getCallee() const { 49 | return static_cast(loc)->callee; 50 | } 51 | 52 | Location CallSiteLoc::getCaller() const { 53 | return static_cast(loc)->caller; 54 | } 55 | 56 | FusedLoc::FusedLoc(Location::ImplType *ptr) : Location(ptr) {} 57 | 58 | ArrayRef FusedLoc::getLocations() const { 59 | return static_cast(loc)->getLocations(); 60 | } 61 | 62 | Attribute FusedLoc::getMetadata() const { 63 | return static_cast(loc)->metadata; 64 | } 65 | -------------------------------------------------------------------------------- /test/Pass/ir-printing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -cse -canonicalize -print-ir-before=cse -o /dev/null 2>&1 | FileCheck -check-prefix=BEFORE %s 2 | // RUN: mlir-opt %s -cse -canonicalize -print-ir-before-all -o /dev/null 2>&1 | FileCheck -check-prefix=BEFORE_ALL %s 3 | // RUN: mlir-opt %s -cse -canonicalize -print-ir-after=cse -o /dev/null 2>&1 | FileCheck -check-prefix=AFTER %s 4 | // RUN: mlir-opt %s -cse -canonicalize -print-ir-after-all -o /dev/null 2>&1 | FileCheck -check-prefix=AFTER_ALL %s 5 | // RUN: mlir-opt %s -cse -canonicalize -print-ir-before=cse -print-ir-module-scope -o /dev/null 2>&1 | FileCheck -check-prefix=BEFORE_MODULE %s 6 | 7 | func @foo() { 8 | return 9 | } 10 | 11 | func @bar() { 12 | return 13 | } 14 | 15 | // BEFORE: *** IR Dump Before{{.*}}CSE *** 16 | // BEFORE-NEXT: func @foo() 17 | // BEFORE: *** IR Dump Before{{.*}}CSE *** 18 | // BEFORE-NEXT: func @bar() 19 | // BEFORE-NOT: *** IR Dump Before{{.*}}Canonicalizer *** 20 | // BEFORE-NOT: *** IR Dump After 21 | 22 | // BEFORE_ALL: *** IR Dump Before{{.*}}CSE *** 23 | // BEFORE_ALL-NEXT: func @foo() 24 | // BEFORE_ALL: *** IR Dump Before{{.*}}Canonicalizer *** 25 | // BEFORE_ALL-NEXT: func @foo() 26 | // BEFORE_ALL: *** IR Dump Before{{.*}}CSE *** 27 | // BEFORE_ALL-NEXT: func @bar() 28 | // BEFORE_ALL: *** IR Dump Before{{.*}}Canonicalizer *** 29 | // BEFORE_ALL-NEXT: func @bar() 30 | // BEFORE_ALL-NOT: *** IR Dump After 31 | 32 | // AFTER-NOT: *** IR Dump Before 33 | // AFTER: *** IR Dump After{{.*}}CSE *** 34 | // AFTER-NEXT: func @foo() 35 | // AFTER: *** IR Dump After{{.*}}CSE *** 36 | // AFTER-NEXT: func @bar() 37 | // AFTER-NOT: *** IR Dump After{{.*}}Canonicalizer *** 38 | 39 | // AFTER_ALL-NOT: *** IR Dump Before 40 | // AFTER_ALL: *** IR Dump After{{.*}}CSE *** 41 | // AFTER_ALL-NEXT: func @foo() 42 | // AFTER_ALL: *** IR Dump After{{.*}}Canonicalizer *** 43 | // AFTER_ALL-NEXT: func @foo() 44 | // AFTER_ALL: *** IR Dump After{{.*}}CSE *** 45 | // AFTER_ALL-NEXT: func @bar() 46 | // AFTER_ALL: *** IR Dump After{{.*}}Canonicalizer *** 47 | // AFTER_ALL-NEXT: func @bar() 48 | 49 | // BEFORE_MODULE: *** IR Dump Before{{.*}}CSE *** (function: foo) 50 | // BEFORE_MODULE: func @foo() 51 | // BEFORE_MODULE: func @bar() 52 | // BEFORE_MODULE: *** IR Dump Before{{.*}}CSE *** (function: bar) 53 | // BEFORE_MODULE: func @foo() 54 | // BEFORE_MODULE: func @bar() 55 | -------------------------------------------------------------------------------- /lib/Analysis/MemRefBoundCheck.cpp: -------------------------------------------------------------------------------- 1 | //===- MemRefBoundCheck.cpp - MLIR Affine Structures Class-----*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements a pass to check memref accessses for out of bound 19 | // accesses. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #include "mlir/Analysis/AffineAnalysis.h" 24 | #include "mlir/Analysis/AffineStructures.h" 25 | #include "mlir/Analysis/Passes.h" 26 | #include "mlir/Analysis/Utils.h" 27 | #include "mlir/IR/Builders.h" 28 | #include "mlir/Pass/Pass.h" 29 | #include "mlir/StandardOps/Ops.h" 30 | #include "llvm/Support/Debug.h" 31 | 32 | #define DEBUG_TYPE "memref-bound-check" 33 | 34 | using namespace mlir; 35 | 36 | namespace { 37 | 38 | /// Checks for out of bound memef access subscripts.. 39 | struct MemRefBoundCheck : public FunctionPass { 40 | void runOnFunction() override; 41 | }; 42 | 43 | } // end anonymous namespace 44 | 45 | FunctionPassBase *mlir::createMemRefBoundCheckPass() { 46 | return new MemRefBoundCheck(); 47 | } 48 | 49 | void MemRefBoundCheck::runOnFunction() { 50 | getFunction().walk([](Operation *opInst) { 51 | if (auto loadOp = opInst->dyn_cast()) { 52 | boundCheckLoadOrStoreOp(loadOp); 53 | } else if (auto storeOp = opInst->dyn_cast()) { 54 | boundCheckLoadOrStoreOp(storeOp); 55 | } 56 | // TODO(bondhugula): do this for DMA ops as well. 57 | }); 58 | } 59 | 60 | static PassRegistration 61 | memRefBoundCheck("memref-bound-check", 62 | "Check memref access bounds in a Function"); 63 | -------------------------------------------------------------------------------- /lib/TableGen/OpTrait.cpp: -------------------------------------------------------------------------------- 1 | //===- OpTrait.cpp - OpTrait class ----------------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // OpTrait wrapper to simplify using TableGen Record defining a MLIR OpTrait. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #include "mlir/TableGen/OpTrait.h" 23 | #include "mlir/TableGen/Predicate.h" 24 | #include "llvm/ADT/StringExtras.h" 25 | #include "llvm/Support/FormatVariadic.h" 26 | #include "llvm/TableGen/Error.h" 27 | #include "llvm/TableGen/Record.h" 28 | 29 | using namespace mlir; 30 | 31 | mlir::tblgen::OpTrait mlir::tblgen::OpTrait::create(const llvm::Init *init) { 32 | auto def = cast(init)->getDef(); 33 | if (def->isSubClassOf("PredOpTrait")) 34 | return OpTrait(Kind::Pred, def); 35 | if (def->isSubClassOf("OpGenInternalTrait")) 36 | return OpTrait(Kind::Internal, def); 37 | assert(def->isSubClassOf("NativeOpTrait")); 38 | return OpTrait(Kind::Native, def); 39 | } 40 | 41 | mlir::tblgen::OpTrait::OpTrait(Kind kind, const llvm::Record *def) 42 | : def(def), kind(kind){}; 43 | 44 | llvm::StringRef mlir::tblgen::NativeOpTrait::getTrait() const { 45 | return def->getValueAsString("trait"); 46 | } 47 | 48 | llvm::StringRef mlir::tblgen::InternalOpTrait::getTrait() const { 49 | return def->getValueAsString("trait"); 50 | } 51 | 52 | std::string mlir::tblgen::PredOpTrait::getPredTemplate() const { 53 | auto pred = tblgen::Pred(def->getValueInit("pred")); 54 | return pred.getCondition(); 55 | } 56 | 57 | llvm::StringRef mlir::tblgen::PredOpTrait::getDescription() const { 58 | return def->getValueAsString("desc"); 59 | } 60 | -------------------------------------------------------------------------------- /test/Transforms/Vectorize/materialize.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -materialize-vectors -vector-size=4 -vector-size=4 | FileCheck %s 2 | 3 | // CHECK-DAG: #[[ID1:map[0-9]+]] = (d0) -> (d0) 4 | // CHECK-DAG: #[[D0D1D2D3TOD1D0:map[0-9]+]] = (d0, d1, d2, d3) -> (d1, d0) 5 | // CHECK-DAG: #[[D0P1:map[0-9]+]] = (d0) -> (d0 + 1) 6 | // CHECK-DAG: #[[D0P2:map[0-9]+]] = (d0) -> (d0 + 2) 7 | // CHECK-DAG: #[[D0P3:map[0-9]+]] = (d0) -> (d0 + 3) 8 | 9 | // CHECK-LABEL: func @materialize 10 | func @materialize(%M : index, %N : index, %O : index, %P : index) { 11 | %A = alloc (%M, %N, %O, %P) : memref 12 | %f1 = constant splat, 1.000000e+00> : vector<4x4x4xf32> 13 | // CHECK: affine.for %i0 = 0 to %arg0 step 4 { 14 | // CHECK-NEXT: affine.for %i1 = 0 to %arg1 step 4 { 15 | // CHECK-NEXT: affine.for %i2 = 0 to %arg2 { 16 | // CHECK-NEXT: affine.for %i3 = 0 to %arg3 step 4 { 17 | // CHECK-NEXT: %[[a:[0-9]+]] = {{.*}}[[ID1]](%i0) 18 | // CHECK-NEXT: %[[b:[0-9]+]] = {{.*}}[[ID1]](%i1) 19 | // CHECK-NEXT: %[[c:[0-9]+]] = {{.*}}[[ID1]](%i2) 20 | // CHECK-NEXT: %[[d:[0-9]+]] = {{.*}}[[ID1]](%i3) 21 | // CHECK-NEXT: vector.transfer_write {{.*}}, %0[%[[a]], %[[b]], %[[c]], %[[d]]] {permutation_map: #[[D0D1D2D3TOD1D0]]} : vector<4x4xf32>, memref 22 | // CHECK: %[[b1:[0-9]+]] = {{.*}}[[D0P1]](%i1) 23 | // CHECK: vector.transfer_write {{.*}}, %0[{{.*}}, %[[b1]], {{.*}}] {permutation_map: #[[D0D1D2D3TOD1D0]]} : vector<4x4xf32>, memref 24 | // CHECK: %[[b2:[0-9]+]] = {{.*}}[[D0P2]](%i1) 25 | // CHECK: vector.transfer_write {{.*}}, %0[{{.*}}, %[[b2]], {{.*}}] {permutation_map: #[[D0D1D2D3TOD1D0]]} : vector<4x4xf32>, memref 26 | // CHECK: %[[b3:[0-9]+]] = {{.*}}[[D0P3]](%i1) 27 | // CHECK: vector.transfer_write {{.*}}, %0[{{.*}}, %[[b3]], {{.*}}] {permutation_map: #[[D0D1D2D3TOD1D0]]} : vector<4x4xf32>, memref 28 | affine.for %i0 = 0 to %M step 4 { 29 | affine.for %i1 = 0 to %N step 4 { 30 | affine.for %i2 = 0 to %O { 31 | affine.for %i3 = 0 to %P step 4 { 32 | vector.transfer_write %f1, %A[%i0, %i1, %i2, %i3] {permutation_map: (d0, d1, d2, d3) -> (d3, d1, d0)} : vector<4x4x4xf32>, memref 33 | } 34 | } 35 | } 36 | } 37 | return 38 | } -------------------------------------------------------------------------------- /examples/Linalg/Linalg3/include/linalg3/TensorOps.h: -------------------------------------------------------------------------------- 1 | //===- TensorOps.h - Linalg dialect TensorOps operation definition --------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG3_TENSOROPS_H_ 19 | #define LINALG3_TENSOROPS_H_ 20 | 21 | #include "linalg2/TensorOps.h" 22 | 23 | namespace linalg { 24 | 25 | /// 26 | /// Ideally all these functions would go in an Analysis but until 27 | /// TensorContractionBase is templated, they need to remain close enough. 28 | /// 29 | 30 | /// Takes a `tensorContraction` and a returns an AffineMap that can be used to 31 | /// map ranges to enclosing loops for all the operands' ranges. 32 | template 33 | mlir::AffineMap operandRangesToLoopsMap( 34 | linalg::TensorContractionBase &tensorContraction); 35 | 36 | /// Takes a `tensorContraction` and returns the ranges of all its operands. 37 | /// When an operand comes from a ViewOp, things are simple: 38 | /// just traverse the indexings and get all the ranges 39 | /// (i.e. drop the rank-reducing indices). 40 | /// In the case of a SliceOp, things are more involved because we need to handle 41 | /// potential rank-reductions. 42 | /// This function abstracts this complexity away and returns all the ranges. 43 | template 44 | llvm::SmallVector 45 | getRanges(linalg::TensorContractionBase &tensorContraction); 46 | 47 | } // namespace linalg 48 | 49 | /// The TensorOp-inl.h inclusion pattern is chosen to allow gradual extension of 50 | /// TensorOps by adding implementations as they are needed in the appropriate 51 | /// step in the tutorial. 52 | #include "linalg3/TensorOps-inl.h" 53 | 54 | #endif // LINALG3_TENSOROPS_H_ 55 | -------------------------------------------------------------------------------- /include/mlir/ExecutionEngine/OptUtils.h: -------------------------------------------------------------------------------- 1 | //===- OptUtils.h - MLIR Execution Engine opt pass utilities ----*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file declares the utility functions to trigger LLVM optimizations from 19 | // MLIR Execution Engine. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #ifndef MLIR_EXECUTIONENGINE_OPTUTILS_H_ 24 | #define MLIR_EXECUTIONENGINE_OPTUTILS_H_ 25 | 26 | #include "llvm/Pass.h" 27 | 28 | #include 29 | #include 30 | 31 | namespace llvm { 32 | class Module; 33 | class Error; 34 | } // namespace llvm 35 | 36 | namespace mlir { 37 | 38 | /// Initialize LLVM passes that can be when running MLIR code using 39 | /// ExecutionEngine. 40 | void initializeLLVMPasses(); 41 | 42 | /// Create a module transformer function for MLIR ExecutionEngine that runs 43 | /// LLVM IR passes corresponding to the given speed and size optimization 44 | /// levels (e.g. -O2 or -Os). 45 | std::function 46 | makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel); 47 | 48 | /// Create a module transformer function for MLIR ExecutionEngine that runs 49 | /// LLVM IR passes explicitly specified, plus an optional optimization level, 50 | /// Any optimization passes, if present, will be inserted before the pass at 51 | /// position optPassesInsertPos. 52 | std::function 53 | makeLLVMPassesTransformer(llvm::ArrayRef llvmPasses, 54 | llvm::Optional mbOptLevel, 55 | unsigned optPassesInsertPos = 0); 56 | 57 | } // end namespace mlir 58 | 59 | #endif // LIR_EXECUTIONENGINE_OPTUTILS_H_ 60 | -------------------------------------------------------------------------------- /lib/EDSC/Helpers.cpp: -------------------------------------------------------------------------------- 1 | //===- Helpers.cpp - MLIR Declarative Helper Functionality ------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/EDSC/Helpers.h" 19 | #include "mlir/IR/AffineExpr.h" 20 | #include "mlir/StandardOps/Ops.h" 21 | 22 | using namespace mlir; 23 | using namespace mlir::edsc; 24 | 25 | static SmallVector getMemRefSizes(Value *memRef) { 26 | MemRefType memRefType = memRef->getType().cast(); 27 | 28 | auto maps = memRefType.getAffineMaps(); 29 | (void)maps; 30 | assert((maps.empty() || (maps.size() == 1 && maps[0].isIdentity())) && 31 | "Layout maps not supported"); 32 | SmallVector res; 33 | res.reserve(memRefType.getShape().size()); 34 | const auto &shape = memRefType.getShape(); 35 | for (unsigned idx = 0, n = shape.size(); idx < n; ++idx) { 36 | if (shape[idx] == -1) { 37 | res.push_back(ValueHandle::create(memRef, idx)); 38 | } else { 39 | res.push_back(static_cast(shape[idx])); 40 | } 41 | } 42 | return res; 43 | } 44 | 45 | mlir::edsc::MemRefView::MemRefView(Value *v) : base(v) { 46 | assert(v->getType().isa() && "MemRefType expected"); 47 | 48 | auto memrefSizeValues = getMemRefSizes(v); 49 | for (auto &size : memrefSizeValues) { 50 | lbs.push_back(static_cast(0)); 51 | ubs.push_back(size); 52 | steps.push_back(1); 53 | } 54 | } 55 | 56 | mlir::edsc::VectorView::VectorView(Value *v) : base(v) { 57 | auto vectorType = v->getType().cast(); 58 | 59 | for (auto s : vectorType.getShape()) { 60 | lbs.push_back(static_cast(0)); 61 | ubs.push_back(static_cast(s)); 62 | steps.push_back(1); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/ViewType.h: -------------------------------------------------------------------------------- 1 | //===- ViewType.h - Linalg ViewType definition --------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_VIEWTYPE_H_ 19 | #define LINALG1_VIEWTYPE_H_ 20 | 21 | #include "linalg1/Types.h" 22 | #include "mlir/IR/Types.h" 23 | 24 | namespace linalg { 25 | 26 | class ViewTypeStorage; 27 | 28 | /// A ViewType represents a range abstraction on top of an underlying storage 29 | /// type. It is parameterizable by the underlying element type and the rank of 30 | /// the view. 31 | class ViewType 32 | : public mlir::Type::TypeBase { 33 | public: 34 | ////////////////////////////////////////////////////////////////////////////// 35 | // Hooks to customize the behavior of this type. 36 | ////////////////////////////////////////////////////////////////////////////// 37 | // Used to implement llvm-style cast. 38 | using Base::Base; 39 | // Used to implement llvm-style cast. 40 | static bool kindof(unsigned kind) { return kind == LinalgTypes::View; } 41 | /// Construction hook. 42 | static ViewType get(mlir::MLIRContext *context, mlir::Type elementType, 43 | unsigned rank); 44 | 45 | ////////////////////////////////////////////////////////////////////////////// 46 | // Type-specific functionality. 47 | ////////////////////////////////////////////////////////////////////////////// 48 | /// Return the underlying elemental type. 49 | mlir::Type getElementType(); 50 | /// Return the rank of the view. 51 | /// This is the number of indexings needed to reach an underlying element. 52 | unsigned getRank(); 53 | }; 54 | 55 | } // namespace linalg 56 | 57 | #endif // LINALG1_VIEWTYPE_H_ 58 | -------------------------------------------------------------------------------- /lib/TableGen/Constraint.cpp: -------------------------------------------------------------------------------- 1 | //===- Constraint.cpp - Constraint class ----------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // Constraint wrapper to simplify using TableGen Record for constraints. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #include "mlir/TableGen/Constraint.h" 23 | #include "llvm/TableGen/Record.h" 24 | 25 | using namespace mlir::tblgen; 26 | 27 | Constraint::Constraint(const llvm::Record *record) 28 | : def(record), kind(CK_Uncategorized) { 29 | if (record->isSubClassOf("TypeConstraint")) { 30 | kind = CK_Type; 31 | } else if (record->isSubClassOf("AttrConstraint")) { 32 | kind = CK_Attr; 33 | } else { 34 | assert(record->isSubClassOf("Constraint")); 35 | } 36 | } 37 | 38 | Constraint::Constraint(Kind kind, const llvm::Record *record) 39 | : def(record), kind(kind) {} 40 | 41 | Pred Constraint::getPredicate() const { 42 | auto *val = def->getValue("predicate"); 43 | 44 | // If no predicate is specified, then return the null predicate (which 45 | // corresponds to true). 46 | if (!val) 47 | return Pred(); 48 | 49 | const auto *pred = dyn_cast(val->getValue()); 50 | return Pred(pred); 51 | } 52 | 53 | std::string Constraint::getConditionTemplate() const { 54 | return getPredicate().getCondition(); 55 | } 56 | 57 | llvm::StringRef Constraint::getDescription() const { 58 | auto doc = def->getValueAsString("description"); 59 | if (doc.empty()) 60 | return def->getName(); 61 | return doc; 62 | } 63 | 64 | AppliedConstraint::AppliedConstraint(Constraint &&c, 65 | std::vector &&e) 66 | : constraint(c), entities(std::move(e)) {} 67 | -------------------------------------------------------------------------------- /include/mlir/TableGen/Type.h: -------------------------------------------------------------------------------- 1 | //===- Type.h - Type class --------------------------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // Type wrapper to simplify using TableGen Record defining a MLIR Type. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_TABLEGEN_TYPE_H_ 23 | #define MLIR_TABLEGEN_TYPE_H_ 24 | 25 | #include "mlir/Support/LLVM.h" 26 | #include "mlir/TableGen/Constraint.h" 27 | 28 | namespace llvm { 29 | class DefInit; 30 | class Record; 31 | } // end namespace llvm 32 | 33 | namespace mlir { 34 | namespace tblgen { 35 | 36 | // Wrapper class with helper methods for accessing Type constraints defined in 37 | // TableGen. 38 | class TypeConstraint : public Constraint { 39 | public: 40 | explicit TypeConstraint(const llvm::Record *record); 41 | explicit TypeConstraint(const llvm::DefInit *init); 42 | 43 | static bool classof(const Constraint *c) { return c->getKind() == CK_Type; } 44 | 45 | // Returns true if this is a variadic type constraint. 46 | bool isVariadic() const; 47 | }; 48 | 49 | // Wrapper class providing helper methods for accessing MLIR Type defined 50 | // in TableGen. This class should closely reflect what is defined as 51 | // class Type in TableGen. 52 | class Type : public TypeConstraint { 53 | public: 54 | explicit Type(const llvm::Record *record); 55 | explicit Type(const llvm::DefInit *init); 56 | 57 | // Returns the TableGen def name for this type. 58 | StringRef getTableGenDefName() const; 59 | 60 | // Gets the base type of this variadic type constraint. 61 | // Precondition: isVariadic() is true. 62 | Type getVariadicBaseType() const; 63 | }; 64 | 65 | } // end namespace tblgen 66 | } // end namespace mlir 67 | 68 | #endif // MLIR_TABLEGEN_TYPE_H_ 69 | -------------------------------------------------------------------------------- /test/Pass/pass-timing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -verify-each=true -cse -canonicalize -cse -pass-timing -pass-timing-display=list 2>&1 | FileCheck -check-prefix=LIST %s 2 | // RUN: mlir-opt %s -verify-each=true -cse -canonicalize -cse -pass-timing -pass-timing-display=pipeline 2>&1 | FileCheck -check-prefix=PIPELINE %s 3 | // RUN: mlir-opt %s -experimental-mt-pm=true -verify-each=true -cse -canonicalize -cse -pass-timing -pass-timing-display=list 2>&1 | FileCheck -check-prefix=MT_LIST %s 4 | // RUN: mlir-opt %s -experimental-mt-pm=true -verify-each=true -cse -canonicalize -cse -pass-timing -pass-timing-display=pipeline 2>&1 | FileCheck -check-prefix=MT_PIPELINE %s 5 | 6 | // LIST: Pass execution timing report 7 | // LIST: Total Execution Time: 8 | // LIST: Name 9 | // LIST-DAG: Canonicalizer 10 | // LIST-DAG: FunctionVerifier 11 | // LIST-DAG: CSE 12 | // LIST-DAG: ModuleVerifier 13 | // LIST-DAG: DominanceInfo 14 | // LIST: Total 15 | 16 | // PIPELINE: Pass execution timing report 17 | // PIPELINE: Total Execution Time: 18 | // PIPELINE: Name 19 | // PIPELINE-NEXT: Function Pipeline 20 | // PIPELINE-NEXT: CSE 21 | // PIPELINE-NEXT: (A) DominanceInfo 22 | // PIPELINE-NEXT: FunctionVerifier 23 | // PIPELINE-NEXT: Canonicalizer 24 | // PIPELINE-NEXT: FunctionVerifier 25 | // PIPELINE-NEXT: CSE 26 | // PIPELINE-NEXT: (A) DominanceInfo 27 | // PIPELINE-NEXT: FunctionVerifier 28 | // PIPELINE-NEXT: ModuleVerifier 29 | // PIPELINE-NEXT: Total 30 | 31 | // MT_LIST: Pass execution timing report 32 | // MT_LIST: Total Execution Time: 33 | // MT_LIST: Name 34 | // MT_LIST-DAG: Canonicalizer 35 | // MT_LIST-DAG: FunctionVerifier 36 | // MT_LIST-DAG: CSE 37 | // MT_LIST-DAG: ModuleVerifier 38 | // MT_LIST-DAG: DominanceInfo 39 | // MT_LIST: Total 40 | 41 | // MT_PIPELINE: Pass execution timing report 42 | // MT_PIPELINE: Total Execution Time: 43 | // MT_PIPELINE: Name 44 | // MT_PIPELINE-NEXT: Function Pipeline 45 | // MT_PIPELINE-NEXT: CSE 46 | // MT_PIPELINE-NEXT: (A) DominanceInfo 47 | // MT_PIPELINE-NEXT: FunctionVerifier 48 | // MT_PIPELINE-NEXT: Canonicalizer 49 | // MT_PIPELINE-NEXT: FunctionVerifier 50 | // MT_PIPELINE-NEXT: CSE 51 | // MT_PIPELINE-NEXT: (A) DominanceInfo 52 | // MT_PIPELINE-NEXT: FunctionVerifier 53 | // MT_PIPELINE-NEXT: ModuleVerifier 54 | // MT_PIPELINE-NEXT: Total 55 | 56 | func @foo() { 57 | return 58 | } 59 | 60 | func @bar() { 61 | return 62 | } 63 | 64 | func @baz() { 65 | return 66 | } 67 | 68 | func @foobar() { 69 | return 70 | } 71 | -------------------------------------------------------------------------------- /include/mlir/Support/LogicalResult.h: -------------------------------------------------------------------------------- 1 | //===- LogicalResult.h - Utilities for handling success/failure -*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef MLIR_SUPPORT_LOGICAL_RESULT_H 19 | #define MLIR_SUPPORT_LOGICAL_RESULT_H 20 | 21 | #include "mlir/Support/LLVM.h" 22 | 23 | namespace mlir { 24 | 25 | // Values that can be used to signal success/failure. This should be used in 26 | // conjunction with the utility functions below. 27 | struct LogicalResult { 28 | enum ResultEnum { Success, Failure } value; 29 | LogicalResult(ResultEnum v) : value(v) {} 30 | }; 31 | 32 | /// Utility function to generate a LogicalResult. If isSuccess is true a 33 | /// `success` result is generated, otherwise a 'failure' result is generated. 34 | inline LogicalResult success(bool isSuccess = true) { 35 | return LogicalResult{isSuccess ? LogicalResult::Success 36 | : LogicalResult::Failure}; 37 | } 38 | 39 | /// Utility function to generate a LogicalResult. If isFailure is true a 40 | /// `failure` result is generated, otherwise a 'success' result is generated. 41 | inline LogicalResult failure(bool isFailure = true) { 42 | return LogicalResult{isFailure ? LogicalResult::Failure 43 | : LogicalResult::Success}; 44 | } 45 | 46 | /// Utility function that returns true if the provided LogicalResult corresponds 47 | /// to a success value. 48 | inline bool succeeded(LogicalResult result) { 49 | return result.value == LogicalResult::Success; 50 | } 51 | 52 | /// Utility function that returns true if the provided LogicalResult corresponds 53 | /// to a failure value. 54 | inline bool failed(LogicalResult result) { 55 | return result.value == LogicalResult::Failure; 56 | } 57 | 58 | } // namespace mlir 59 | 60 | #endif // MLIR_SUPPORT_LOGICAL_RESULT_H 61 | -------------------------------------------------------------------------------- /test/mlir-tblgen/pattern-tAttr.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-rewriters -I %S/../../include %s | FileCheck %s 2 | 3 | include "mlir/IR/OpBase.td" 4 | 5 | // Create a Type and Attribute. 6 | def T : BuildableType<"buildT">; 7 | def T_Attr : TypeBasedAttr; 8 | def T_Const_Attr : ConstantAttr; 9 | def T_Compose_Attr : tAttr<"{0}.getArrayAttr({{{1}, {2}})">; 10 | 11 | // Define ops to rewrite. 12 | def U: Type, "U">; 13 | def X_AddOp : Op<"x.add"> { 14 | let arguments = (ins U, U); 15 | } 16 | def Y_AddOp : Op<"y.add"> { 17 | let arguments = (ins U, U, T_Attr:$attrName); 18 | let results = (outs U); 19 | } 20 | def Z_AddOp : Op<"z.add"> { 21 | let arguments = (ins U, U, T_Attr:$attrName1, T_Attr:$attrName2); 22 | let results = (outs U); 23 | } 24 | 25 | // Define rewrite pattern. 26 | def : Pat<(Y_AddOp $lhs, $rhs, $attr1), (Y_AddOp $lhs, $rhs, (T_Compose_Attr $attr1, T_Const_Attr:$attr2))>; 27 | // CHECK: struct GeneratedConvert0 : public RewritePattern 28 | // CHECK: RewritePattern("y.add", 1, context) 29 | // CHECK: PatternMatchResult match(Operation * 30 | // CHECK: void rewrite(Operation *op, std::unique_ptr 31 | // CHECK-NEXT: PatternRewriter &rewriter) 32 | // CHECK: auto vAddOp0 = rewriter.create(loc, op->getResult(0)->getType(), 33 | // CHECK-NEXT: s.lhs, 34 | // CHECK-NEXT: s.rhs, 35 | // CHECK-NEXT: /*attrName=*/rewriter.getArrayAttr({s.attr1, rewriter.getAttribute(rewriter.buildT, attrValue)}) 36 | // CHECK-NEXT: ); 37 | // CHECK-NEXT: rewriter.replaceOp(op, {vAddOp0}); 38 | 39 | def : Pat<(Z_AddOp $lhs, $rhs, $attr1, $attr2), (Y_AddOp $lhs, $rhs, (T_Compose_Attr $attr1, $attr2))>; 40 | // CHECK: struct GeneratedConvert1 : public RewritePattern 41 | // CHECK: RewritePattern("z.add", 1, context) 42 | // CHECK: PatternMatchResult match(Operation * 43 | // CHECK: void rewrite(Operation *op, std::unique_ptr 44 | // CHECK-NEXT: PatternRewriter &rewriter) 45 | // CHECK: auto vAddOp0 = rewriter.create(loc, op->getResult(0)->getType(), 46 | // CHECK-NEXT: s.lhs, 47 | // CHECK-NEXT: s.rhs, 48 | // CHECK-NEXT: /*attrName=*/rewriter.getArrayAttr({s.attr1, s.attr2}) 49 | // CHECK-NEXT: ); 50 | // CHECK-NEXT: rewriter.replaceOp(op, {vAddOp0}); 51 | 52 | // CHECK: void populateWithGenerated 53 | // CHECK: patterns->push_back(llvm::make_unique(context)) 54 | // CHECK: patterns->push_back(llvm::make_unique(context)) 55 | -------------------------------------------------------------------------------- /include/mlir/TableGen/Argument.h: -------------------------------------------------------------------------------- 1 | //===- Argument.h - Argument definitions ------------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This header file contains definitions for TableGen operation's arguments. 19 | // Operation arguments fall into two categories: 20 | // 21 | // 1. Operands: SSA values operated on by the operation 22 | // 2. Attributes: compile-time known properties that have influence over 23 | // the operation's behavior 24 | // 25 | // These two categories are modelled with the unified argument concept in 26 | // TableGen because we need similar pattern matching mechanisms for them. 27 | // 28 | //===----------------------------------------------------------------------===// 29 | 30 | #ifndef MLIR_TABLEGEN_ARGUMENT_H_ 31 | #define MLIR_TABLEGEN_ARGUMENT_H_ 32 | 33 | #include "mlir/TableGen/Attribute.h" 34 | #include "mlir/TableGen/Type.h" 35 | #include "llvm/ADT/PointerUnion.h" 36 | #include 37 | 38 | namespace llvm { 39 | class StringRef; 40 | } // end namespace llvm 41 | 42 | namespace mlir { 43 | namespace tblgen { 44 | 45 | // A struct wrapping an op attribute and its name together 46 | struct NamedAttribute { 47 | // Returns the MLIR attribute name. 48 | std::string getName() const; 49 | 50 | llvm::StringRef name; 51 | Attribute attr; 52 | }; 53 | 54 | // A struct wrapping an op operand/result and its name together 55 | struct NamedTypeConstraint { 56 | // Returns true if this operand has constraint that need to be satisfied. 57 | bool hasPredicate() const; 58 | 59 | llvm::StringRef name; 60 | TypeConstraint constraint; 61 | }; 62 | 63 | // Operation argument: either attribute or operand 64 | using Argument = llvm::PointerUnion; 65 | 66 | } // end namespace tblgen 67 | } // end namespace mlir 68 | 69 | #endif // MLIR_TABLEGEN_ARGUMENT_H_ 70 | -------------------------------------------------------------------------------- /lib/Transforms/Canonicalizer.cpp: -------------------------------------------------------------------------------- 1 | //===- Canonicalizer.cpp - Canonicalize MLIR operations -------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This transformation pass converts operations into their canonical forms by 19 | // folding constants, applying operation identity transformations etc. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #include "mlir/IR/MLIRContext.h" 24 | #include "mlir/IR/PatternMatch.h" 25 | #include "mlir/Pass/Pass.h" 26 | #include "mlir/Transforms/Passes.h" 27 | using namespace mlir; 28 | 29 | //===----------------------------------------------------------------------===// 30 | // The actual Canonicalizer Pass. 31 | //===----------------------------------------------------------------------===// 32 | 33 | namespace { 34 | 35 | /// Canonicalize operations in functions. 36 | struct Canonicalizer : public FunctionPass { 37 | void runOnFunction() override; 38 | }; 39 | } // end anonymous namespace 40 | 41 | void Canonicalizer::runOnFunction() { 42 | OwningRewritePatternList patterns; 43 | auto &func = getFunction(); 44 | 45 | // TODO: Instead of adding all known patterns from the whole system lazily add 46 | // and cache the canonicalization patterns for ops we see in practice when 47 | // building the worklist. For now, we just grab everything. 48 | auto *context = &getContext(); 49 | for (auto *op : context->getRegisteredOperations()) 50 | op->getCanonicalizationPatterns(patterns, context); 51 | 52 | applyPatternsGreedily(func, std::move(patterns)); 53 | } 54 | 55 | /// Create a Canonicalizer pass. 56 | FunctionPassBase *mlir::createCanonicalizerPass() { 57 | return new Canonicalizer(); 58 | } 59 | 60 | static PassRegistration pass("canonicalize", 61 | "Canonicalize operations"); 62 | -------------------------------------------------------------------------------- /test/Transforms/Vectorize/normalize_maps.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s -vectorizer-test -normalize-maps | FileCheck %s 2 | 3 | // CHECK-DAG: #[[ZERO:[a-zA-Z0-9]+]] = () -> (0) 4 | // CHECK-DAG: #[[ID1:[a-zA-Z0-9]+]] = (d0) -> (d0) 5 | // CHECK-DAG: #[[D0TIMES2:[a-zA-Z0-9]+]] = (d0) -> (d0 * 2) 6 | // CHECK-DAG: #[[D0PLUSD1:[a-zA-Z0-9]+]] = (d0, d1) -> (d0 + d1) 7 | // CHECK-DAG: #[[MINSD0PLUSD1:[a-zA-Z0-9]+]] = (d0, d1) -> (-d0 + d1) 8 | // CHECK-DAG: #[[D0MINUSD1:[a-zA-Z0-9]+]] = (d0, d1) -> (d0 - d1) 9 | 10 | // CHECK-LABEL: func @simple() 11 | func @simple() { 12 | affine.for %i0 = 0 to 7 { 13 | %0 = affine.apply (d0) -> (d0) (%i0) 14 | %1 = affine.apply (d0) -> (d0) (%0) 15 | %2 = affine.apply (d0, d1) -> (d0 + d1) (%0, %0) 16 | %3 = affine.apply (d0, d1) -> (d0 - d1) (%0, %0) 17 | } 18 | // CHECK-NEXT: affine.for %i0 = 0 to 7 19 | // CHECK-NEXT: {{.*}} affine.apply #[[ID1]](%i0) 20 | // CHECK-NEXT: {{.*}} affine.apply #[[D0TIMES2]](%i0) 21 | // CHECK-NEXT: {{.*}} affine.apply #[[ZERO]]() 22 | 23 | affine.for %i1 = 0 to 7 { 24 | affine.for %i2 = 0 to 42 { 25 | %20 = affine.apply (d0, d1) -> (d1) (%i1, %i2) 26 | %21 = affine.apply (d0, d1) -> (d0) (%i1, %i2) 27 | %22 = affine.apply (d0, d1) -> (d0 + d1) (%20, %21) 28 | %23 = affine.apply (d0, d1) -> (d0 - d1) (%20, %21) 29 | %24 = affine.apply (d0, d1) -> (-d0 + d1) (%20, %21) 30 | } 31 | } 32 | // CHECK: affine.for %i1 = 0 to 7 33 | // CHECK-NEXT: affine.for %i2 = 0 to 42 34 | // CHECK-NEXT: {{.*}} affine.apply #[[D0PLUSD1]](%i1, %i2) 35 | // CHECK-NEXT: {{.*}} affine.apply #[[MINSD0PLUSD1]](%i1, %i2) 36 | // CHECK-NEXT: {{.*}} affine.apply #[[D0MINUSD1]](%i1, %i2) 37 | 38 | affine.for %i3 = 0 to 16 { 39 | affine.for %i4 = 0 to 47 step 2 { 40 | affine.for %i5 = 0 to 78 step 16 { 41 | %50 = affine.apply (d0) -> (d0) (%i3) 42 | %51 = affine.apply (d0) -> (d0) (%i4) 43 | %52 = affine.apply (d0) -> (d0) (%i5) 44 | %53 = affine.apply (d0, d1, d2) -> (d0) (%50, %51, %52) 45 | %54 = affine.apply (d0, d1, d2) -> (d1) (%50, %51, %52) 46 | %55 = affine.apply (d0, d1, d2) -> (d2) (%50, %51, %52) 47 | } 48 | } 49 | } 50 | // CHECK: affine.for %i3 = 0 to 16 51 | // CHECK-NEXT: affine.for %i4 = 0 to 47 step 2 52 | // CHECK-NEXT: affine.for %i5 = 0 to 78 step 16 53 | // CHECK-NEXT: {{.*}} affine.apply #[[ID1]](%i3) 54 | // CHECK-NEXT: {{.*}} affine.apply #[[ID1]](%i4) 55 | // CHECK-NEXT: {{.*}} affine.apply #[[ID1]](%i5) 56 | 57 | return 58 | } 59 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/include/linalg1/RangeOp.h: -------------------------------------------------------------------------------- 1 | //===- RangeOp.h - Linalg dialect RangeOp operation definition ------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_RANGEOP_H_ 19 | #define LINALG1_RANGEOP_H_ 20 | 21 | #include "mlir/IR/OpDefinition.h" 22 | #include "mlir/Support/LLVM.h" 23 | 24 | namespace linalg { 25 | 26 | /// A RangeOp is used to create a value of RangeType from 3 values of type index 27 | /// that represent the min, max and step values of the range. 28 | /// Note: step must be an mlir::ConstantIndexOp for now due to current 29 | /// `affine.for` limitations. 30 | class RangeOp : public mlir::Op::Impl, 31 | mlir::OpTrait::OneResult, 32 | mlir::OpTrait::HasNoSideEffect> { 33 | public: 34 | using Op::Op; 35 | 36 | ////////////////////////////////////////////////////////////////////////////// 37 | // Hooks to customize the behavior of this op. 38 | ////////////////////////////////////////////////////////////////////////////// 39 | static llvm::StringRef getOperationName() { return "linalg.range"; } 40 | static void build(mlir::Builder *b, mlir::OperationState *result, 41 | mlir::Value *min, mlir::Value *max, mlir::Value *step); 42 | mlir::LogicalResult verify(); 43 | static bool parse(mlir::OpAsmParser *parser, mlir::OperationState *result); 44 | void print(mlir::OpAsmPrinter *p); 45 | 46 | ////////////////////////////////////////////////////////////////////////////// 47 | // Op-specific functionality. 48 | ////////////////////////////////////////////////////////////////////////////// 49 | mlir::Value *getMin() { return getOperand(0); } 50 | mlir::Value *getMax() { return getOperand(1); } 51 | mlir::Value *getStep() { return getOperand(2); } 52 | }; 53 | 54 | } // namespace linalg 55 | 56 | #endif // LINALG1_RANGEOP_H_ 57 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/lib/Dialect.cpp: -------------------------------------------------------------------------------- 1 | //===- Dialect.cpp - Implementation of the linalg dialect -----------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements a simple Linalg dialect to which we gradually add 19 | // complexity. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #include "linalg1/Dialect.h" 24 | #include "linalg1/Ops.h" 25 | #include "linalg1/Types.h" 26 | #include "mlir/IR/Dialect.h" 27 | #include "llvm/Support/raw_ostream.h" 28 | 29 | using llvm::raw_ostream; 30 | using llvm::StringRef; 31 | using mlir::Location; 32 | using mlir::Type; 33 | 34 | using namespace linalg; 35 | 36 | Type LinalgDialect::parseType(StringRef spec, Location loc) const { 37 | llvm_unreachable("Unhandled linalg dialect parsing"); 38 | return Type(); 39 | } 40 | 41 | /// RangeType prints as just "range". 42 | static void print(RangeType rt, raw_ostream &os) { os << "range"; } 43 | 44 | /// ViewType prints as: 45 | /// 46 | /// ```{.mlir} 47 | /// view 48 | /// ``` 49 | /// 50 | /// or 51 | /// 52 | /// ```{.mlir} 53 | /// view<0xf32> 54 | /// ``` 55 | /// 56 | /// for 0-D views (a.k.a pointer to a scalar value). 57 | static void print(linalg::ViewType rt, raw_ostream &os) { 58 | os << "view<"; 59 | if (rt.getRank() > 0) { 60 | for (unsigned i = 0, e = rt.getRank(); i < e; ++i) { 61 | os << rt.getElementType() << ((i == e - 1) ? "" : "x"); 62 | } 63 | } else { 64 | os << "0x" << rt.getElementType(); 65 | } 66 | os << ">"; 67 | } 68 | 69 | void LinalgDialect::printType(Type type, raw_ostream &os) const { 70 | switch (type.getKind()) { 71 | default: 72 | llvm_unreachable("Unhandled linalg type"); 73 | case LinalgTypes::Range: 74 | print(type.cast(), os); 75 | break; 76 | case linalg::LinalgTypes::View: 77 | print(type.cast(), os); 78 | break; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /include/mlir/Support/MathExtras.h: -------------------------------------------------------------------------------- 1 | //===- MathExtras.h - Math functions relevant to MLIR -----------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file contains math functions relevant to MLIR. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_SUPPORT_MATHEXTRAS_H_ 23 | #define MLIR_SUPPORT_MATHEXTRAS_H_ 24 | 25 | #include "mlir/Support/LLVM.h" 26 | #include "llvm/ADT/APInt.h" 27 | 28 | namespace mlir { 29 | 30 | /// Returns the result of MLIR's ceildiv operation on constants. The RHS is 31 | /// expected to be positive. 32 | inline int64_t ceilDiv(int64_t lhs, int64_t rhs) { 33 | assert(rhs >= 1); 34 | // C/C++'s integer division rounds towards 0. 35 | return lhs % rhs > 0 ? lhs / rhs + 1 : lhs / rhs; 36 | } 37 | 38 | /// Returns the result of MLIR's floordiv operation on constants. The RHS is 39 | /// expected to be positive. 40 | inline int64_t floorDiv(int64_t lhs, int64_t rhs) { 41 | assert(rhs >= 1); 42 | // C/C++'s integer division rounds towards 0. 43 | return lhs % rhs < 0 ? lhs / rhs - 1 : lhs / rhs; 44 | } 45 | 46 | /// Returns MLIR's mod operation on constants. MLIR's mod operation yields the 47 | /// remainder of the Euclidean division of 'lhs' by 'rhs', and is therefore not 48 | /// C's % operator. The RHS is always expected to be positive, and the result 49 | /// is always non-negative. 50 | inline int64_t mod(int64_t lhs, int64_t rhs) { 51 | assert(rhs >= 1); 52 | return lhs % rhs < 0 ? lhs % rhs + rhs : lhs % rhs; 53 | } 54 | 55 | /// Returns the least common multiple of 'a' and 'b'. 56 | inline int64_t lcm(int64_t a, int64_t b) { 57 | uint64_t x = std::abs(a); 58 | uint64_t y = std::abs(b); 59 | int64_t lcm = (x * y) / llvm::GreatestCommonDivisor64(x, y); 60 | assert((lcm >= a && lcm >= b) && "LCM overflow"); 61 | return lcm; 62 | } 63 | } // end namespace mlir 64 | 65 | #endif // MLIR_SUPPORT_MATHEXTRAS_H_ 66 | -------------------------------------------------------------------------------- /test/mlir-tblgen/op-attribute.td: -------------------------------------------------------------------------------- 1 | // RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s 2 | 3 | include "mlir/IR/OpBase.td" 4 | 5 | def SomeAttr : Attr, "some attribute kind"> { 6 | let storageType = "some-attr-kind"; 7 | let returnType = "some-return-type"; 8 | let convertFromStorage = "{0}.some-convert-from-storage()"; 9 | let constBuilderCall = "some-const-builder-call({0}, {1})"; 10 | } 11 | 12 | def AOp : Op<"a_op", []> { 13 | let arguments = (ins 14 | SomeAttr:$aAttr, 15 | DefaultValuedAttr:$bAttr, 16 | OptionalAttr:$cAttr 17 | ); 18 | } 19 | 20 | // CHECK-LABEL: AOp definitions 21 | 22 | // Test getter methods 23 | // --- 24 | 25 | // CHECK: some-return-type AOp::aAttr() { 26 | // CHECK-NEXT: auto attr = this->getAttr("aAttr").dyn_cast_or_null(); 27 | // CHECK-NEXT: return attr.some-convert-from-storage(); 28 | 29 | // CHECK: some-return-type AOp::bAttr() { 30 | // CHECK-NEXT: auto attr = this->getAttr("bAttr").dyn_cast_or_null(); 31 | // CHECK-NEXT: if (!attr) 32 | // CHECK-NEXT: return some-const-builder-call(mlir::Builder(this->getContext()), 4.2).some-convert-from-storage(); 33 | // CHECK-NEXT: return attr.some-convert-from-storage(); 34 | 35 | // CHECK: Optional AOp::cAttr() { 36 | // CHECK-NEXT: auto attr = this->getAttr("cAttr").dyn_cast_or_null(); 37 | // CHECK-NEXT: return attr ? Optional(attr.some-convert-from-storage()) : (llvm::None); 38 | 39 | // Test build methods 40 | // --- 41 | 42 | // CHECK: void AOp::build( 43 | // CHECK: tblgen_state->addAttribute("aAttr", aAttr); 44 | // CHECK: tblgen_state->addAttribute("bAttr", bAttr); 45 | // CHECK: if (cAttr) { 46 | // CHECK-NEXT: tblgen_state->addAttribute("cAttr", cAttr); 47 | 48 | // CHECK: void AOp::build( 49 | // CHECK-SAME: ArrayRef attributes 50 | // CHECK: for (const auto& pair : attributes) 51 | // CHECK-NEXT: tblgen_state->addAttribute(pair.first, pair.second); 52 | 53 | def MixOperandsAndAttrs : Op<"mix_operands_and_attrs", []> { 54 | let arguments = (ins F32Attr:$attr, F32:$operand, F32Attr:$otherAttr, F32:$otherArg); 55 | } 56 | 57 | // CHECK-LABEL: MixOperandsAndAttrs definitions 58 | // CHECK-DAG: Value *MixOperandsAndAttrs::operand() 59 | // CHECK-DAG: Value *MixOperandsAndAttrs::otherArg() 60 | // CHECK-DAG: void MixOperandsAndAttrs::build(Builder *, OperationState *tblgen_state, FloatAttr attr, Value *operand, FloatAttr otherAttr, Value *otherArg) 61 | // CHECK-DAG: APFloat MixOperandsAndAttrs::attr() 62 | // CHECK-DAG: APFloat MixOperandsAndAttrs::otherAttr() 63 | -------------------------------------------------------------------------------- /lib/IR/IntegerSet.cpp: -------------------------------------------------------------------------------- 1 | //===- IntegerSet.cpp - MLIR Integer Set class ----------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #include "mlir/IR/IntegerSet.h" 19 | #include "IntegerSetDetail.h" 20 | #include "mlir/IR/AffineExpr.h" 21 | 22 | using namespace mlir; 23 | using namespace mlir::detail; 24 | 25 | unsigned IntegerSet::getNumDims() const { return set->dimCount; } 26 | unsigned IntegerSet::getNumSymbols() const { return set->symbolCount; } 27 | unsigned IntegerSet::getNumOperands() const { 28 | return set->dimCount + set->symbolCount; 29 | } 30 | 31 | unsigned IntegerSet::getNumConstraints() const { 32 | return set->constraints.size(); 33 | } 34 | 35 | unsigned IntegerSet::getNumEqualities() const { 36 | unsigned numEqualities = 0; 37 | for (unsigned i = 0, e = getNumConstraints(); i < e; i++) 38 | if (isEq(i)) 39 | ++numEqualities; 40 | return numEqualities; 41 | } 42 | 43 | unsigned IntegerSet::getNumInequalities() const { 44 | return getNumConstraints() - getNumEqualities(); 45 | } 46 | 47 | bool IntegerSet::isEmptyIntegerSet() const { 48 | // This will only work if uniqui'ing is on. 49 | static_assert(kUniquingThreshold >= 1, 50 | "uniquing threshold should be at least one"); 51 | return *this == getEmptySet(set->dimCount, set->symbolCount, getContext()); 52 | } 53 | 54 | ArrayRef IntegerSet::getConstraints() const { 55 | return set->constraints; 56 | } 57 | 58 | AffineExpr IntegerSet::getConstraint(unsigned idx) const { 59 | return getConstraints()[idx]; 60 | } 61 | 62 | /// Returns the equality bits, which specify whether each of the constraints 63 | /// is an equality or inequality. 64 | ArrayRef IntegerSet::getEqFlags() const { return set->eqFlags; } 65 | 66 | /// Returns true if the idx^th constraint is an equality, false if it is an 67 | /// inequality. 68 | bool IntegerSet::isEq(unsigned idx) const { return getEqFlags()[idx]; } 69 | 70 | MLIRContext *IntegerSet::getContext() const { 71 | return getConstraint(0).getContext(); 72 | } 73 | -------------------------------------------------------------------------------- /lib/Parser/Lexer.h: -------------------------------------------------------------------------------- 1 | //===- Lexer.h - MLIR Lexer Interface ---------------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file declares the MLIR Lexer class. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #ifndef MLIR_LIB_PARSER_LEXER_H 23 | #define MLIR_LIB_PARSER_LEXER_H 24 | 25 | #include "mlir/Parser.h" 26 | #include "Token.h" 27 | 28 | namespace mlir { 29 | class Location; 30 | 31 | /// This class breaks up the current file into a token stream. 32 | class Lexer { 33 | public: 34 | explicit Lexer(const llvm::SourceMgr &sourceMgr, MLIRContext *context); 35 | 36 | const llvm::SourceMgr &getSourceMgr() { return sourceMgr; } 37 | 38 | Token lexToken(); 39 | 40 | /// Encode the specified source location information into a Location object 41 | /// for attachment to the IR or error reporting. 42 | Location getEncodedSourceLocation(llvm::SMLoc loc); 43 | 44 | /// Change the position of the lexer cursor. The next token we lex will start 45 | /// at the designated point in the input. 46 | void resetPointer(const char *newPointer) { curPtr = newPointer; } 47 | 48 | private: 49 | // Helpers. 50 | Token formToken(Token::Kind kind, const char *tokStart) { 51 | return Token(kind, StringRef(tokStart, curPtr-tokStart)); 52 | } 53 | 54 | Token emitError(const char *loc, const Twine &message); 55 | 56 | // Lexer implementation methods. 57 | Token lexComment(); 58 | Token lexBareIdentifierOrKeyword(const char *tokStart); 59 | Token lexAtIdentifier(const char *tokStart); 60 | Token lexPrefixedIdentifier(const char *tokStart); 61 | Token lexNumber(const char *tokStart); 62 | Token lexString(const char *tokStart); 63 | 64 | const llvm::SourceMgr &sourceMgr; 65 | MLIRContext *context; 66 | 67 | StringRef curBuffer; 68 | const char *curPtr; 69 | 70 | Lexer(const Lexer &) = delete; 71 | void operator=(const Lexer &) = delete; 72 | }; 73 | 74 | } // end namespace mlir 75 | 76 | #endif // MLIR_LIB_PARSER_LEXER_H 77 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/TestHarness.h: -------------------------------------------------------------------------------- 1 | //===- TestHarness.h - Minimal test harness for exercising the linalg API -===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | 18 | #ifndef LINALG1_TEST_HARNESS_H 19 | #define LINALG1_TEST_HARNESS_H 20 | 21 | #include 22 | #include 23 | 24 | namespace test_detail { 25 | // Returns a mutable list of known test functions. Used internally by test 26 | // macros to add and run tests. This function is static to ensure it creates a 27 | // new list in each test file. 28 | static std::vector> &tests() { 29 | static std::vector> list; 30 | return list; 31 | } 32 | 33 | // Test registration class. Used internally by test macros to register tests 34 | // during static allocation. 35 | struct TestRegistration { 36 | explicit TestRegistration(std::function func) { 37 | test_detail::tests().push_back(func); 38 | } 39 | }; 40 | } // end namespace test_detail 41 | 42 | /// Declares a test function with the given name and adds it to the list of 43 | /// known tests. The body of the function must follow immediately. Example: 44 | /// 45 | /// TEST_FUNC(mytest) { 46 | /// // CHECK: expected-output-here 47 | /// emitSomethingToStdOut(); 48 | /// } 49 | /// 50 | #define TEST_FUNC(name) \ 51 | void name(); \ 52 | static test_detail::TestRegistration name##Registration(name); \ 53 | void name() 54 | 55 | /// Runs all registered tests. Example: 56 | /// 57 | /// int main() { 58 | /// RUN_TESTS(); 59 | /// return 0; 60 | /// } 61 | #define RUN_TESTS \ 62 | []() { \ 63 | for (auto f : test_detail::tests()) \ 64 | f(); \ 65 | } 66 | 67 | #endif // LINALG1_TEST_HARNESS_H 68 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg3/lib/Analysis.cpp: -------------------------------------------------------------------------------- 1 | //===- Analysis.cpp - Implementation of analysis functions for Linalg -----===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements a simple IR operation to create a new RangeType in the 19 | // linalg dialect. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #include "linalg3/Analysis.h" 24 | #include "mlir/IR/AffineExpr.h" 25 | #include "mlir/IR/AffineMap.h" 26 | #include "mlir/IR/StandardTypes.h" 27 | 28 | using llvm::SmallVector; 29 | using namespace mlir; 30 | 31 | // Compute an inverse map (only works with permutations for now). 32 | // Note that the mapping is generally non-full rank, so this returns the first 33 | // seen entry for each dim. 34 | static AffineMap inversePermutationMap(AffineMap map) { 35 | SmallVector exprs(map.getNumDims()); 36 | for (auto en : llvm::enumerate(map.getResults())) { 37 | auto expr = en.value(); 38 | auto d = expr.dyn_cast(); 39 | assert(d && "permutation map expected"); 40 | if (exprs[d.getPosition()]) 41 | continue; 42 | exprs[d.getPosition()] = getAffineDimExpr(en.index(), d.getContext()); 43 | } 44 | SmallVector seenExprs; 45 | seenExprs.reserve(map.getNumDims()); 46 | for (auto expr : exprs) 47 | if (expr) 48 | seenExprs.push_back(expr); 49 | assert(map.getNumSymbols() == 0 && "expected map without symbols"); 50 | assert(seenExprs.size() == map.getNumInputs() && "map is not invertible"); 51 | return AffineMap::get(map.getNumResults(), 0, seenExprs, {}); 52 | } 53 | 54 | mlir::AffineMap linalg::inverseSubMap(AffineMap map, unsigned beginResult, 55 | unsigned endResult) { 56 | if (beginResult == 0 && endResult == 0) 57 | endResult = map.getNumResults(); 58 | auto subMap = AffineMap::get( 59 | map.getNumDims(), map.getNumSymbols(), 60 | map.getResults().slice(beginResult, endResult - beginResult), {}); 61 | return inversePermutationMap(subMap); 62 | } 63 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/lib/Common.cpp: -------------------------------------------------------------------------------- 1 | //===- Common.cpp - Implementation of common supporting functions ---------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements a simple IR operation to create a new RangeType in the 19 | // linalg dialect. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #include "linalg1/Common.h" 24 | #include "linalg1/Ops.h" 25 | #include "linalg1/Types.h" 26 | #include "mlir/EDSC/Intrinsics.h" 27 | #include "mlir/StandardOps/Ops.h" 28 | 29 | using llvm::ArrayRef; 30 | using mlir::ConstantIndexOp; 31 | using mlir::edsc::CapturableHandle; 32 | using mlir::edsc::ValueHandle; 33 | using mlir::edsc::intrinsics::alloc; 34 | using mlir::edsc::intrinsics::ret; 35 | 36 | using namespace linalg; 37 | 38 | linalg::common::LoopNestRangeBuilder::LoopNestRangeBuilder( 39 | llvm::ArrayRef ivs, llvm::ArrayRef indexings) { 40 | assert(ivs.size() == indexings.size()); 41 | for (unsigned i = 0, e = indexings.size(); i < e; ++i) { 42 | auto rangeOp = 43 | indexings[i].getValue()->getDefiningOp()->dyn_cast(); 44 | if (!rangeOp) { 45 | continue; 46 | } 47 | auto lb = rangeOp.getMin(); 48 | auto ub = rangeOp.getMax(); 49 | // This must be a constexpr index until we relax the affine.for constraint 50 | auto step = 51 | rangeOp.getStep()->getDefiningOp()->cast().getValue(); 52 | loops.emplace_back(ivs[i], ValueHandle(lb), ValueHandle(ub), step); 53 | } 54 | } 55 | 56 | linalg::common::LoopNestRangeBuilder::LoopNestRangeBuilder( 57 | llvm::ArrayRef ivs, llvm::ArrayRef indexings) 58 | : LoopNestRangeBuilder(ivs, llvm::SmallVector( 59 | indexings.begin(), indexings.end())) {} 60 | 61 | ValueHandle linalg::common::LoopNestRangeBuilder::operator()( 62 | llvm::ArrayRef stmts) { 63 | for (auto &lit : llvm::reverse(loops)) { 64 | lit({}); 65 | } 66 | return ValueHandle::null(); 67 | } 68 | -------------------------------------------------------------------------------- /examples/Linalg/Linalg1/lib/RangeOp.cpp: -------------------------------------------------------------------------------- 1 | //===- RangeOp.cpp - Implementation of the linalg RangeOp operation -------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements a simple IR operation to create a new RangeType in the 19 | // linalg dialect. 20 | // 21 | //===----------------------------------------------------------------------===// 22 | 23 | #include "linalg1/Ops.h" 24 | #include "linalg1/Types.h" 25 | #include "mlir/IR/Builders.h" 26 | #include "mlir/IR/OpImplementation.h" 27 | #include "mlir/IR/StandardTypes.h" 28 | 29 | using mlir::Builder; 30 | using mlir::IndexType; 31 | using mlir::OpAsmParser; 32 | using mlir::OpAsmPrinter; 33 | using mlir::OperationState; 34 | using mlir::Value; 35 | 36 | // Minimal example for a new RangeOp operating on RangeType. 37 | void linalg::RangeOp::build(Builder *b, OperationState *result, Value *min, 38 | Value *max, Value *step) { 39 | result->addOperands({min, max, step}); 40 | result->addTypes({linalg::RangeType::get(b->getContext())}); 41 | } 42 | 43 | // Verification is simply that a RangeOp takes 3 index ssa-value. 44 | mlir::LogicalResult linalg::RangeOp::verify() { 45 | if (!getMin() || !getMin()->getType().isa()) 46 | return emitOpError("first operand should be of type index"); 47 | if (!getMax() || !getMax()->getType().isa()) 48 | return emitOpError("second operand should be of type index"); 49 | if (!getStep() || !getStep()->getType().isa()) 50 | return emitOpError("third operand should be of type index"); 51 | return mlir::success(); 52 | } 53 | 54 | // Parsing of the linalg dialect is not supported in this tutorial. 55 | bool linalg::RangeOp::parse(OpAsmParser *parser, OperationState *result) { 56 | llvm_unreachable("Parsing linalg dialect is not supported in this tutorial"); 57 | } 58 | 59 | // A RangeOp prints as: 60 | // 61 | // ```{.mlir} 62 | // linalg.range %arg0:%arg1:%c42 : !linalg<"range"> 63 | // ``` 64 | void linalg::RangeOp::print(OpAsmPrinter *p) { 65 | *p << getOperationName() << " " << *getMin() << ":" << *getMax() << ":" 66 | << *getStep() << " : " << getType(); 67 | } 68 | -------------------------------------------------------------------------------- /examples/toy/Ch1/toyc.cpp: -------------------------------------------------------------------------------- 1 | //===- toyc.cpp - The Toy Compiler ----------------------------------------===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // This file implements the entry point for the Toy compiler. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | 22 | #include "toy/Parser.h" 23 | 24 | #include "llvm/ADT/StringRef.h" 25 | #include "llvm/Support/CommandLine.h" 26 | #include "llvm/Support/ErrorOr.h" 27 | #include "llvm/Support/MemoryBuffer.h" 28 | #include "llvm/Support/raw_ostream.h" 29 | 30 | using namespace toy; 31 | namespace cl = llvm::cl; 32 | 33 | static cl::opt InputFilename(cl::Positional, 34 | cl::desc(""), 35 | cl::init("-"), 36 | cl::value_desc("filename")); 37 | namespace { 38 | enum Action { None, DumpAST }; 39 | } 40 | 41 | static cl::opt 42 | emitAction("emit", cl::desc("Select the kind of output desired"), 43 | cl::values(clEnumValN(DumpAST, "ast", "output the AST dump"))); 44 | 45 | /// Returns a Toy AST resulting from parsing the file or a nullptr on error. 46 | std::unique_ptr parseInputFile(llvm::StringRef filename) { 47 | llvm::ErrorOr> FileOrErr = 48 | llvm::MemoryBuffer::getFileOrSTDIN(filename); 49 | if (std::error_code EC = FileOrErr.getError()) { 50 | llvm::errs() << "Could not open input file: " << EC.message() << "\n"; 51 | return nullptr; 52 | } 53 | auto buffer = FileOrErr.get()->getBuffer(); 54 | LexerBuffer lexer(buffer.begin(), buffer.end(), filename); 55 | Parser parser(lexer); 56 | return parser.ParseModule(); 57 | } 58 | 59 | int main(int argc, char **argv) { 60 | cl::ParseCommandLineOptions(argc, argv, "toy compiler\n"); 61 | 62 | auto moduleAST = parseInputFile(InputFilename); 63 | if (!moduleAST) 64 | return 1; 65 | 66 | switch (emitAction) { 67 | case Action::DumpAST: 68 | dump(*moduleAST); 69 | return 0; 70 | default: 71 | llvm::errs() << "No action specified (parsing only?), use -emit=\n"; 72 | } 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /include/mlir/Translation.h: -------------------------------------------------------------------------------- 1 | //===- Translation.h - Translation registry ---------------------*- C++ -*-===// 2 | // 3 | // Copyright 2019 The MLIR Authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ============================================================================= 17 | // 18 | // Registry for user-provided translations. 19 | // 20 | //===----------------------------------------------------------------------===// 21 | #ifndef MLIR_TRANSLATION_H 22 | #define MLIR_TRANSLATION_H 23 | 24 | #include "llvm/ADT/StringMap.h" 25 | #include "llvm/ADT/StringRef.h" 26 | 27 | namespace mlir { 28 | class MLIRContext; 29 | class Module; 30 | 31 | /// Interface of the function that translates a file to MLIR. The 32 | /// implementation should create a new MLIR Module in the given context and 33 | /// return a pointer to it, or a nullptr in case of any error. 34 | using TranslateToMLIRFunction = 35 | std::function(llvm::StringRef, MLIRContext *)>; 36 | /// Interface of the function that translates MLIR to a different format and 37 | /// outputs the result to a file. The implementation should return "true" on 38 | /// error and "false" otherwise. It is allowed to modify the module. 39 | using TranslateFromMLIRFunction = 40 | std::function; 41 | 42 | /// Use Translate[To|From]MLIRRegistration as a global initialiser that 43 | /// registers a function and associates it with name. This requires that a 44 | /// translation has not been registered to a given name. 45 | /// 46 | /// Usage: 47 | /// 48 | /// // At namespace scope. 49 | /// static TranslateToMLIRRegistration Unused(&MySubCommand, [] { ... }); 50 | /// 51 | /// \{ 52 | struct TranslateToMLIRRegistration { 53 | TranslateToMLIRRegistration(llvm::StringRef name, 54 | const TranslateToMLIRFunction &function); 55 | }; 56 | 57 | struct TranslateFromMLIRRegistration { 58 | TranslateFromMLIRRegistration(llvm::StringRef name, 59 | const TranslateFromMLIRFunction &function); 60 | }; 61 | /// \} 62 | 63 | /// Get a read-only reference to the translator registry. 64 | const llvm::StringMap &getTranslationToMLIRRegistry(); 65 | const llvm::StringMap & 66 | getTranslationFromMLIRRegistry(); 67 | 68 | } // namespace mlir 69 | 70 | #endif // MLIR_TRANSLATION_H 71 | --------------------------------------------------------------------------------