├── .swift-format ├── Tools ├── GitHub Workflows ├── llvm-commit ├── MLIRSwiftSupport │ ├── MLIRSwiftSupport.cpp │ ├── MLIRSwiftSupport.h │ └── CMakeLists.txt ├── SwiftFormat │ ├── .gitignore │ ├── README.md │ ├── .swiftpm │ │ └── xcode │ │ │ └── package.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── Package.swift │ └── Package.resolved ├── BoilerplateGenerator │ ├── .gitignore │ ├── README.md │ ├── .swiftpm │ │ └── xcode │ │ │ └── package.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── Sources │ │ ├── Utilities │ │ │ └── Utilities.swift │ │ ├── GenerateBlockOperationsAppend │ │ │ └── main.swift │ │ ├── GenerateBlockInitializers │ │ │ └── main.swift │ │ └── GenerateOperationExtensions │ │ │ └── main.swift │ └── Package.swift ├── generate-boilerplate ├── swift-format ├── Docker │ └── Dockerfile ├── swift-format-spec └── build-dependencies ├── .clang-format ├── Sources ├── CDialects │ ├── CDialects.h │ └── module.modulemap ├── Dialects │ ├── SCF.swift │ ├── Standard.swift │ ├── Attributes.swift │ └── Operations.swift ├── MLIR │ ├── Builtins │ │ ├── Builtin Passes.swift │ │ ├── Builtin Operations.swift │ │ ├── Builtin Named Attributes.swift │ │ ├── Builtin Attributes.swift │ │ └── Builtin Types.swift │ ├── Passes │ │ ├── Pass.swift │ │ └── Pass Manager.swift │ ├── Infrastructure │ │ ├── Dialect.swift │ │ ├── Module.swift │ │ ├── Context.swift │ │ └── Location.swift │ ├── Helpers │ │ ├── String.swift │ │ ├── Linked List Index.swift │ │ ├── Parsing.swift │ │ ├── MLIR Representable.swift │ │ └── Text Output Stream.swift │ ├── IR │ │ ├── Region.swift │ │ ├── Value.swift │ │ ├── Identifier.swift │ │ ├── Type.swift │ │ ├── Block Operations Append (Generated).swift │ │ ├── Block.swift │ │ ├── Attribute.swift │ │ ├── Block Initializers (Generated).swift │ │ ├── Operation.swift │ │ └── Operation Extensions (Generated).swift │ └── Diagnostics │ │ ├── Collect Diagnostics.swift │ │ └── Diagnostics.swift └── CMLIR │ ├── CMLIR.h │ └── module.modulemap ├── .gitignore ├── Package.swift ├── Tests ├── MLIRTests │ ├── Type Tests.swift │ ├── Diagnostic Tests.swift │ └── Attribute Tests.swift └── DialectTests │ └── Module Tests.swift ├── README.md ├── .github └── workflows │ └── buildAndTest.yml └── LICENSE.txt /.swift-format: -------------------------------------------------------------------------------- 1 | Tools/swift-format-spec -------------------------------------------------------------------------------- /Tools/GitHub Workflows: -------------------------------------------------------------------------------- 1 | ../.github/workflows -------------------------------------------------------------------------------- /Tools/llvm-commit: -------------------------------------------------------------------------------- 1 | c68b560be381e831fd72c6b8b8909427e4e2ff36 -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | AlwaysBreakTemplateDeclarations: Yes 3 | -------------------------------------------------------------------------------- /Tools/MLIRSwiftSupport/MLIRSwiftSupport.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MLIRSwiftSupport.h" 3 | -------------------------------------------------------------------------------- /Tools/SwiftFormat/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | -------------------------------------------------------------------------------- /Sources/CDialects/CDialects.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.swiftpm 3 | /.build 4 | /Packages 5 | /*.xcodeproj 6 | xcuserdata/ 7 | .dependencies 8 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/README.md: -------------------------------------------------------------------------------- 1 | # BoilerplateGenerator 2 | 3 | Generates boilerplate for MLIR Swift Bindings 4 | -------------------------------------------------------------------------------- /Sources/Dialects/SCF.swift: -------------------------------------------------------------------------------- 1 | import CDialects 2 | import MLIR 3 | 4 | extension Dialect { 5 | public static let scf = Dialect(mlirGetDialectHandle__scf__()) 6 | } 7 | -------------------------------------------------------------------------------- /Sources/Dialects/Standard.swift: -------------------------------------------------------------------------------- 1 | import CDialects 2 | import MLIR 3 | 4 | extension Dialect { 5 | public static let std = Dialect(mlirGetDialectHandle__std__()) 6 | } 7 | -------------------------------------------------------------------------------- /Sources/MLIR/Builtins/Builtin Passes.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | extension Pass { 4 | public static let canonicalization = Pass(createdBy: mlirCreateTransformsCanonicalizer) 5 | } 6 | -------------------------------------------------------------------------------- /Tools/SwiftFormat/README.md: -------------------------------------------------------------------------------- 1 | # SwiftFormat 2 | 3 | This package is simply a helper package so we can pin a version of [swift-format](https://github.com/apple/swift-format) with this repo. 4 | -------------------------------------------------------------------------------- /Tools/SwiftFormat/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tools/MLIRSwiftSupport/MLIRSwiftSupport.h: -------------------------------------------------------------------------------- 1 | #ifndef MLIRSwiftSupport_h 2 | #define MLIRSwiftSupport_h 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #ifdef __cplusplus 9 | } 10 | #endif 11 | 12 | #endif /* MLIRSwiftSupport_h */ 13 | -------------------------------------------------------------------------------- /Sources/CMLIR/CMLIR.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | -------------------------------------------------------------------------------- /Tools/SwiftFormat/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "SwiftFormat", 7 | dependencies: [ 8 | .package(url: "https://github.com/apple/swift-format", .branch("swift-5.3-branch")) 9 | ], 10 | targets: [] 11 | ) 12 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/Sources/Utilities/Utilities.swift: -------------------------------------------------------------------------------- 1 | 2 | import Foundation 3 | 4 | let preamble: Void = { 5 | let executable = URL(fileURLWithPath: CommandLine.arguments[0]).lastPathComponent 6 | print(""" 7 | 8 | /** 9 | This file was autogenerated by running `Tools/generate-boilerplate` 10 | */ 11 | 12 | """) 13 | }() 14 | 15 | prefix operator << 16 | public prefix func <<(_ next: String) { 17 | preamble 18 | print(next) 19 | } 20 | -------------------------------------------------------------------------------- /Sources/Dialects/Attributes.swift: -------------------------------------------------------------------------------- 1 | import CDialects 2 | import MLIR 3 | 4 | extension Attribute { 5 | 6 | } 7 | 8 | public struct ValueNamedAttribute: ContextualNamedAttributeProtocol { 9 | public let attribute: ContextualAttribute 10 | public func `in`(_ context: Context) -> NamedAttribute { 11 | NamedAttribute(name: "value", attribute: attribute.in(context)) 12 | } 13 | } 14 | extension ContextualNamedAttributeProtocol where Self == ValueNamedAttribute { 15 | public static func value(_ attribute: Attribute) -> Self { 16 | ValueNamedAttribute(attribute: attribute) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/Sources/GenerateBlockOperationsAppend/main.swift: -------------------------------------------------------------------------------- 1 | 2 | import Utilities 3 | 4 | let maxNumArguments = 10 5 | 6 | <<""" 7 | extension Block.Operations { 8 | 9 | """ 10 | for numArguments in 1...maxNumArguments { 11 | let range = 0..) -> (\(values)) { 19 | append(operation.typeErased) 20 | return operation.results 21 | } 22 | 23 | """ 24 | } 25 | <<"}" 26 | -------------------------------------------------------------------------------- /Tools/generate-boilerplate: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TOOLS_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 4 | PROJECT_ROOT=${PROJECT_ROOT:-$(cd "$TOOLS_ROOT" && cd $(git rev-parse --show-toplevel) && pwd)} 5 | 6 | function swift-format() { 7 | "$PROJECT_ROOT/.dependencies/installed/tools/swift-format" --mode format $@ 8 | } 9 | 10 | function generate() { 11 | swift run --package-path $TOOLS_ROOT/BoilerplateGenerator Generate$(echo $@ | tr -d ' ') | 12 | swift-format > "$PROJECT_ROOT/Sources/MLIR/IR/$(echo $@) (Generated).swift" 13 | } 14 | 15 | generate Operation Extensions 16 | generate Block Initializers 17 | generate Block Operations Append 18 | -------------------------------------------------------------------------------- /Sources/Dialects/Operations.swift: -------------------------------------------------------------------------------- 1 | import MLIR 2 | 3 | extension Operation { 4 | 5 | public static func constant( 6 | _ value: Attribute, 7 | of type: Type, 8 | at location: Location 9 | ) -> Self 10 | where 11 | Results == (Value) 12 | { 13 | Self( 14 | .std, "constant", 15 | attributes: [ 16 | ValueNamedAttribute.value(value) 17 | ], 18 | resultType: type, 19 | location: location) 20 | } 21 | 22 | public static func `return`(_ values: Value..., at location: Location) -> Self 23 | where 24 | Results == () 25 | { 26 | Self( 27 | .std, "return", 28 | operands: values, 29 | location: location) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Sources/MLIR/Passes/Pass.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | An MLIR pass 5 | */ 6 | public struct Pass { 7 | 8 | /** 9 | We use a closure rather than an `MlirPass` because passes end up owned by `PassManager`, so it is invalid to register the same pass with multiple `PassManager`s. This way, we can create the pass on `PassManager` initialization and immediately transfer ownership. 10 | */ 11 | public init(createdBy builder: @escaping () -> MlirPass) { 12 | self.builder = builder 13 | } 14 | 15 | func build() -> MlirPass { 16 | builder() 17 | } 18 | 19 | /// Suppress synthesized initializer 20 | private init() { fatalError() } 21 | 22 | private let builder: () -> MlirPass 23 | } 24 | -------------------------------------------------------------------------------- /Sources/MLIR/Passes/Pass Manager.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | An object which manages a pass pipeline 5 | */ 6 | public final class PassManager { 7 | public convenience init(context: Context, passes: Pass...) { 8 | self.init(context: context, passes: Array(passes)) 9 | } 10 | public init(context: Context, passes: [Pass]) { 11 | mlir = mlirPassManagerCreate(context.mlir) 12 | for pass in passes { 13 | mlirPassManagerAddOwnedPass(mlir, pass.build()) 14 | } 15 | } 16 | deinit { 17 | mlirPassManagerDestroy(mlir) 18 | } 19 | 20 | public func runPasses(on module: Module) { 21 | mlirPassManagerRun(mlir, module.mlir) 22 | } 23 | 24 | let mlir: MlirPassManager 25 | } 26 | -------------------------------------------------------------------------------- /Tools/swift-format: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script requires that `swift-format` is installed using `build-dependendencies`. It also standardizes which files are processed for formatting. 4 | 5 | PROJECT_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd "$(git rev-parse --show-toplevel)" && pwd )" 6 | 7 | function swift-format() { 8 | # TODO: Add --parallel once Swift 5.4 is released 9 | "$PROJECT_ROOT/.dependencies/installed/tools/swift-format" $@ 10 | } 11 | 12 | if [[ "$1" == "--ci" ]]; then 13 | if [[ "$#" != "1" ]]; then 14 | echo "--ci cannot be used with any other arguments" 1>&2 15 | exit 1 16 | fi 17 | swift-format --mode format --in-place --recursive Sources 18 | else 19 | swift-format $@ 20 | fi 21 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "BoilerplateGenerator", 7 | products: [ 8 | .executable( 9 | name: "GenerateOperationExtensions", 10 | targets: ["GenerateOperationExtensions"]), 11 | .executable( 12 | name: "GenerateBlockInitializers", 13 | targets: ["GenerateBlockInitializers"]), 14 | .executable( 15 | name: "GenerateBlockOperationsAppend", 16 | targets: ["GenerateBlockOperationsAppend"]), 17 | ], 18 | targets: [ 19 | .target(name: "Utilities"), 20 | .target(name: "GenerateOperationExtensions", dependencies: ["Utilities"]), 21 | .target(name: "GenerateBlockInitializers", dependencies: ["Utilities"]), 22 | .target(name: "GenerateBlockOperationsAppend", dependencies: ["Utilities"]), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /Tools/Docker/Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | # Builds a docker image which can be used to test this project on Linux 3 | # Example use: 4 | # $ docker build -t mlir-swift Tools/Docker 5 | # $ docker run --rm -ti -v $(pwd):/project -w /project mlir-swift 6 | 7 | # You can also build an image with the nightly toolchain like so: 8 | # $ docker build -t mlir-swift Tools/Docker --build-arg image=swiftlang/swift:nightly-focal 9 | 10 | ARG image=swift:focal 11 | FROM $image 12 | 13 | RUN apt-get update && apt-get upgrade -y 14 | ARG DEBIAN_FRONTEND=noninteractive 15 | RUN apt-get install -y git 16 | RUN apt-get install -y libncurses5-dev libncursesw5-dev 17 | RUN apt-get install -y cmake ninja-build python3 18 | ENV DEPENDENCIES_ROOT="/project/.dependencies/linux" 19 | ENV LLVM_REPO_PATH="/project/.dependencies/llvm-repo" 20 | ENV PKG_CONFIG_PATH="$DEPENDENCIES_ROOT/installed" 21 | RUN swift --version 22 | -------------------------------------------------------------------------------- /Tools/MLIRSwiftSupport/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This project is meant to compile as part of the LLVM build using LLVM_EXTERNAL_PROJECTS 2 | # See `build-dependencies` for more details 3 | 4 | cmake_minimum_required(VERSION 3.13.4) 5 | 6 | include_directories(${MLIR_INCLUDE_DIRS}) 7 | include_directories(${LLVM_INCLUDE_DIRS}) 8 | 9 | # Sources 10 | file(GLOB sources *.cpp) 11 | add_llvm_library(MLIRSwiftSupport 12 | ${sources} 13 | LINK_LIBS PUBLIC 14 | MLIRCAPI) 15 | 16 | # Headers 17 | add_custom_target(MLIRSwiftSupport-headers) 18 | install( 19 | FILES 20 | # Headers listed here will be installed 21 | MLIRSwiftSupport.h 22 | 23 | DESTINATION include/MLIRSwiftSupport 24 | COMPONENT MLIRSwiftSupport-headers) 25 | add_llvm_install_targets(install-MLIRSwiftSupport-headers 26 | DEPENDS MLIRSwiftSupport-headers 27 | COMPONENT MLIRSwiftSupport-headers) -------------------------------------------------------------------------------- /Sources/MLIR/Infrastructure/Dialect.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | The Swift representation of an MLIR dialect 5 | */ 6 | public struct Dialect { 7 | 8 | /** 9 | Creates a `Dialect` from an `MlirDialectHandle` 10 | 11 | - note: While MLIR does have an `MlirDialect` type, we find that type is not particularly useful, so we choose not to provide a Swift analog. This frees up the name `Dialect` to be used as an analog to `MlirDialectHandle`. If it is needed in the future, we can create a Swift analog for `MlirDialect` with a name like `Dialect.Instance`. 12 | */ 13 | public init(_ handle: MlirDialectHandle) { 14 | self.mlir = handle 15 | } 16 | 17 | /** 18 | The namespace associated with this dialect 19 | */ 20 | public var namespace: String { 21 | mlirDialectHandleGetNamespace(mlir).string 22 | } 23 | 24 | let mlir: MlirDialectHandle 25 | } 26 | -------------------------------------------------------------------------------- /Sources/CDialects/module.modulemap: -------------------------------------------------------------------------------- 1 | module CDialects [system] { 2 | header "CDialects.h" 3 | 4 | // CAPI 5 | link "MLIRCAPISCF" 6 | link "MLIRCAPIStandard" 7 | 8 | // Dependencies 9 | link "LLVMBinaryFormat" 10 | link "LLVMBitstreamReader" 11 | link "LLVMCore" 12 | link "LLVMDemangle" 13 | link "LLVMRemarks" 14 | link "LLVMSupport" 15 | link "MLIRAffine" 16 | link "MLIRAnalysis" 17 | link "MLIRCAPIIR" 18 | link "MLIRCallInterfaces" 19 | link "MLIRCastInterfaces" 20 | link "MLIRControlFlowInterfaces" 21 | link "MLIREDSC" 22 | link "MLIRIR" 23 | link "MLIRInferTypeOpInterface" 24 | link "MLIRLinalg" 25 | link "MLIRLoopLikeInterface" 26 | link "MLIRParser" 27 | link "MLIRPass" 28 | link "MLIRSCF" 29 | link "MLIRSideEffectInterfaces" 30 | link "MLIRStandard" 31 | link "MLIRSupport" 32 | link "MLIRTensor" 33 | link "MLIRVectorInterfaces" 34 | link "MLIRViewLikeInterface" 35 | } 36 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "MLIR", 6 | platforms: [ 7 | .macOS(.v10_15) 8 | ], 9 | products: [ 10 | .library( 11 | name: "MLIR", 12 | targets: ["MLIR"]), 13 | .library( 14 | name: "MLIRDialects", 15 | targets: ["Dialects"]), 16 | ], 17 | targets: [ 18 | .systemLibrary( 19 | name: "CMLIR", 20 | pkgConfig: "LLVM-for-Swift"), 21 | .target( 22 | name: "MLIR", 23 | dependencies: ["CMLIR"]), 24 | .testTarget( 25 | name: "MLIRTests", 26 | dependencies: ["MLIR"]), 27 | 28 | .systemLibrary( 29 | name: "CDialects", 30 | pkgConfig: "LLVM-for-Swift"), 31 | .target( 32 | name: "Dialects", 33 | dependencies: ["CDialects", "MLIR"]), 34 | .testTarget( 35 | name: "DialectTests", 36 | dependencies: ["Dialects"]), 37 | ] 38 | ) 39 | -------------------------------------------------------------------------------- /Sources/MLIR/Helpers/String.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | import Foundation 3 | 4 | extension MlirStringRef { 5 | var buffer: UnsafeBufferPointer { 6 | UnsafeBufferPointer(start: data, count: length) 7 | } 8 | var string: String { 9 | buffer.withMemoryRebound(to: UInt8.self) { 10 | String(bytes: $0, encoding: .utf8)! 11 | } 12 | } 13 | } 14 | 15 | extension String { 16 | func withUnsafeMlirStringRef(_ body: (MlirStringRef) throws -> T) rethrows -> T { 17 | var string = self 18 | return try string.withUTF8 { 19 | try $0.withMemoryRebound(to: Int8.self) { 20 | try body(mlirStringRefCreate($0.baseAddress, $0.count)) 21 | } 22 | } 23 | } 24 | 25 | } 26 | 27 | extension StaticString { 28 | func withUnsafeMlirStringRef(_ body: (MlirStringRef) -> T) -> T { 29 | return withUTF8Buffer { 30 | $0.withMemoryRebound(to: Int8.self) { 31 | body(mlirStringRefCreate($0.baseAddress, $0.count)) 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Tests/MLIRTests/Type Tests.swift: -------------------------------------------------------------------------------- 1 | 2 | import XCTest 3 | @testable import MLIR 4 | 5 | final class TypeTests: XCTestCase { 6 | func testInteger() { 7 | let context = MLIR.OwnedContext() 8 | 9 | func test( 10 | _ source: String, 11 | parsesAs type: ContextualType, 12 | file: StaticString = #filePath, line: UInt = #line 13 | ) { 14 | do { 15 | let parsed = try context.parse(source, as: Type.self) 16 | XCTAssertEqual(parsed, type.in(context), file: file, line: line) 17 | } catch { 18 | XCTFail(file: file, line: line) 19 | } 20 | } 21 | 22 | test("i1", parsesAs: IntegerType.integer(bitWidth: 1)) 23 | test("si1", parsesAs: IntegerType.integer(.signed, bitWidth: 1)) 24 | test("ui1", parsesAs: IntegerType.integer(.unsigned, bitWidth: 1)) 25 | test("memref", parsesAs: MemoryReferenceType.memoryReference(to: Float32Type.float32, withDimensions: [.dynamic], inMemorySpace: IntegerAttribute.integer(type: .integer(bitWidth: 64), value: 0))) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/MLIR/Builtins/Builtin Operations.swift: -------------------------------------------------------------------------------- 1 | extension Operation where Results == () { 2 | /** 3 | - precondition: `blocks` must contain at least one block 4 | */ 5 | public static func function( 6 | _ name: String, 7 | returnTypes: [ContextualType] = [], 8 | attributes: [ContextualNamedAttributeProtocol] = [], 9 | blocks: [Block], 10 | at location: Location 11 | ) -> Self { 12 | let entryBlock = blocks.first! 13 | 14 | var attributes = attributes 15 | 16 | /// These will hopefully be able to use dot syntax as Swift 5.4 matures 17 | attributes.append(ContextualNamedAttribute.symbolName(name)) 18 | attributes.append( 19 | ContextualNamedAttribute.type( 20 | FunctionType.function(of: entryBlock.arguments.map(\.type), to: returnTypes))) 21 | 22 | return Self( 23 | builtin: "func", 24 | attributes: attributes, 25 | operands: [], 26 | resultTypes: [], 27 | ownedRegions: [ 28 | Region(ownedBlocks: blocks) 29 | ], 30 | location: location) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tools/SwiftFormat/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "swift-argument-parser", 6 | "repositoryURL": "https://github.com/apple/swift-argument-parser.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "9564d61b08a5335ae0a36f789a7d71493eacadfc", 10 | "version": "0.3.2" 11 | } 12 | }, 13 | { 14 | "package": "swift-format", 15 | "repositoryURL": "https://github.com/apple/swift-format", 16 | "state": { 17 | "branch": "swift-5.3-branch", 18 | "revision": "12089179aa1668a2478b2b2111d98fa37f3531e3", 19 | "version": null 20 | } 21 | }, 22 | { 23 | "package": "SwiftSyntax", 24 | "repositoryURL": "https://github.com/apple/swift-syntax", 25 | "state": { 26 | "branch": null, 27 | "revision": "844574d683f53d0737a9c6d706c3ef31ed2955eb", 28 | "version": "0.50300.0" 29 | } 30 | } 31 | ] 32 | }, 33 | "version": 1 34 | } 35 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Region.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | An IR node containing blocks 5 | */ 6 | public struct Region: MlirRepresentable { 7 | 8 | public init(_ mlir: MlirRegion) { 9 | self.init(mlir: mlir) 10 | } 11 | public let mlir: MlirRegion 12 | 13 | /** 14 | Creates an owned region 15 | */ 16 | public init(ownedBlocks: [Block] = []) { 17 | self.init(mlirRegionCreate()) 18 | ownedBlocks.forEach(blocks.append) 19 | } 20 | 21 | public struct Blocks: Collection { 22 | public typealias Index = LinkedListIndex 23 | public typealias Element = Block 24 | public var startIndex: Index { .starting(with: mlirRegionGetFirstBlock(region)) } 25 | public var endIndex: Index { .end } 26 | public func index(after i: Index) -> Index { 27 | i.successor(using: mlirBlockGetNextInRegion) 28 | } 29 | 30 | public func append(_ ownedBlock: Block) { 31 | mlirRegionAppendOwnedBlock(region, ownedBlock.mlir) 32 | } 33 | 34 | fileprivate let region: MlirRegion 35 | } 36 | public var blocks: Blocks { Blocks(region: mlir) } 37 | } 38 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Value.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | public struct Value: MlirRepresentable { 4 | 5 | public init(_ mlir: MlirValue) { 6 | self.init(mlir: mlir) 7 | } 8 | public let mlir: MlirValue 9 | 10 | public var type: MLIR.`Type` { 11 | Type(mlirValueGetType(mlir)) 12 | } 13 | public var context: UnownedContext { 14 | type.context 15 | } 16 | 17 | public enum Kind { 18 | case argument(of: Block) 19 | case result(of: AnyOperation) 20 | } 21 | public var kind: Kind { 22 | if mlirValueIsABlockArgument(mlir) { 23 | return .argument(of: Block(mlirBlockArgumentGetOwner(mlir))) 24 | } else if mlirValueIsAOpResult(mlir) { 25 | return .result(of: AnyOperation(mlirOpResultGetOwner(mlir))) 26 | } else { 27 | fatalError() 28 | } 29 | } 30 | 31 | public var block: Block? { 32 | switch kind { 33 | case .argument(of: let block): return block 34 | case .result(of: let operation): return operation.owningBlock 35 | } 36 | } 37 | 38 | /// Suppress initializer synthesis 39 | private init() { fatalError() } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/MLIR/Infrastructure/Module.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | The top-level object which owns an IR graph 5 | 6 | This module, along with any IR it owns, is destroyed on deinitialization. 7 | */ 8 | public final class Module { 9 | 10 | /** 11 | Creates an empty module with at the specified location 12 | */ 13 | public convenience init(location: Location) { 14 | self.init(assumingOwnershipOf: mlirModuleCreateEmpty(location.mlir)) 15 | } 16 | 17 | /** 18 | Assumes ownership of an MLIR module, meaning that module will be destroyed when `self` is deinitialized 19 | */ 20 | public init(assumingOwnershipOf mlir: MlirModule) { 21 | precondition(!mlirModuleIsNull(mlir)) 22 | self.mlir = mlir 23 | } 24 | deinit { 25 | mlirModuleDestroy(mlir) 26 | } 27 | 28 | public let mlir: MlirModule 29 | 30 | /** 31 | The body of this module 32 | */ 33 | public var body: Block { 34 | Block(mlirModuleGetBody(mlir)) 35 | } 36 | 37 | /** 38 | Returns this module as an operation 39 | */ 40 | public var operation: AnyOperation { 41 | Operation(mlirModuleGetOperation(mlir)) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/MLIRTests/Diagnostic Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import MLIR 3 | 4 | import CMLIR 5 | 6 | final class DiagnosticTests: XCTestCase { 7 | func testDiagnosticSeverity() { 8 | XCTAssertGreaterThan(Diagnostic.Severity.error, Diagnostic.Severity.warning) 9 | XCTAssertGreaterThan(Diagnostic.Severity.warning, Diagnostic.Severity.note) 10 | XCTAssertGreaterThan(Diagnostic.Severity.note, Diagnostic.Severity.remark) 11 | XCTAssertLessThan(Diagnostic.Severity.warning, Diagnostic.Severity.error) 12 | XCTAssertLessThan(Diagnostic.Severity.note, Diagnostic.Severity.warning) 13 | XCTAssertLessThan(Diagnostic.Severity.remark, Diagnostic.Severity.note) 14 | } 15 | func testDiagnosticHandling() { 16 | let context = MLIR.OwnedContext() 17 | let message = "Test Diagnostic" 18 | let diagnostics = context.collectDiagnostics { 19 | message.withCString { 20 | mlirEmitError(mlirLocationUnknownGet(context.mlir), $0) 21 | } 22 | } 23 | XCTAssertEqual(diagnostics.count, 1) 24 | let diagnostic = diagnostics[0] 25 | XCTAssertEqual(diagnostic.severity, .error) 26 | XCTAssertEqual(diagnostic.message, message) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Identifier.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | Swift represention of an `MlirIdentifier` 5 | */ 6 | public struct Identifier: MlirRepresentable { 7 | 8 | /** 9 | Creates an identifier from a string 10 | */ 11 | public init(_ string: String, in context: Context) { 12 | self.init( 13 | string.withUnsafeMlirStringRef { 14 | mlirIdentifierGet(context.mlir, $0) 15 | }) 16 | } 17 | 18 | public init(_ mlir: MlirIdentifier) { 19 | self.init(mlir: mlir) 20 | } 21 | public let mlir: MlirIdentifier 22 | 23 | public static func == (lhs: Self, rhs: Self) -> Bool { 24 | mlirIdentifierEqual(lhs.mlir, rhs.mlir) 25 | } 26 | 27 | /** 28 | The context that owns this identifier 29 | */ 30 | public var context: UnownedContext { 31 | UnownedContext(mlirIdentifierGetContext(mlir)) 32 | } 33 | 34 | /** 35 | A String representation of this identifier 36 | */ 37 | public var stringValue: String { 38 | mlirIdentifierStr(mlir).string 39 | } 40 | 41 | } 42 | 43 | // MARK: - Printing 44 | 45 | extension Identifier: CustomStringConvertible { 46 | public var description: String { 47 | stringValue 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Tests/MLIRTests/Attribute Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import MLIR 3 | 4 | import CMLIR 5 | 6 | final class AttributeTests: XCTestCase { 7 | func testAttributes() throws { 8 | let context = MLIR.OwnedContext() 9 | 10 | func test( 11 | _ source: String, 12 | parsesAs attribute: ContextualAttribute, 13 | file: StaticString = #filePath, line: UInt = #line 14 | ) { 15 | do { 16 | let parsed = try context.parse(source, as: Attribute.self) 17 | XCTAssertEqual(parsed, attribute.in(context), file: file, line: line) 18 | } catch { 19 | XCTFail(file: file, line: line) 20 | } 21 | } 22 | 23 | test(#""foo""#, parsesAs: StringAttribute.string("foo")) 24 | 25 | test(#"["foo", "bar"]"#, parsesAs: ArrayAttribute.array([.string("foo"), StringAttribute.string("bar")])) 26 | /// When Swift 5.4 is released, we will be able to do the following: 27 | // test(#"["foo", "bar"]"#, parsesAs: .array([.string("foo"), .string("bar")])) 28 | 29 | test(#"{foo = "bar"}"#, parsesAs: DictionaryAttribute.dictionary(["foo": StringAttribute.string("bar")])) 30 | /// When Swift 5.4 is released, we will be able to do the following: 31 | // test(#"{foo = "bar"}"#, parsesAs: .dictionary(["foo": StringAttribute.string("bar")])) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/CMLIR/module.modulemap: -------------------------------------------------------------------------------- 1 | module CMLIR [system] { 2 | header "CMLIR.h" 3 | 4 | /// For now, we link the entire contents of lib 5 | link "LLVMBinaryFormat" 6 | link "LLVMBitstreamReader" 7 | link "LLVMCore" 8 | link "LLVMDemangle" 9 | link "LLVMRemarks" 10 | link "LLVMSupport" 11 | link "MLIRAffine" 12 | link "MLIRAffineEDSC" 13 | link "MLIRAnalysis" 14 | link "MLIRCAPIIR" 15 | link "MLIRCAPISCF" 16 | link "MLIRCAPIStandard" 17 | link "MLIRCAPITransforms" 18 | link "MLIRCallInterfaces" 19 | link "MLIRCastInterfaces" 20 | link "MLIRControlFlowInterfaces" 21 | link "MLIRCopyOpInterface" 22 | link "MLIRDialectUtils" 23 | link "MLIREDSC" 24 | link "MLIRIR" 25 | link "MLIRInferTypeOpInterface" 26 | link "MLIRLinalg" 27 | link "MLIRLoopAnalysis" 28 | link "MLIRLoopLikeInterface" 29 | link "MLIRPDL" 30 | link "MLIRPDLInterp" 31 | link "MLIRPDLToPDLInterp" 32 | link "MLIRParser" 33 | link "MLIRPass" 34 | link "MLIRPresburger" 35 | link "MLIRRewrite" 36 | link "MLIRSCF" 37 | link "MLIRSideEffectInterfaces" 38 | link "MLIRStandard" 39 | link "MLIRSupport" 40 | link "MLIRSwiftSupport" 41 | link "MLIRTensor" 42 | link "MLIRTransformUtils" 43 | link "MLIRTransforms" 44 | link "MLIRVector" 45 | link "MLIRVectorInterfaces" 46 | link "MLIRViewLikeInterface" 47 | } 48 | -------------------------------------------------------------------------------- /Sources/MLIR/Infrastructure/Context.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | An object which owns simpler objects like `Type` and `Location`. Objects **must not** be used after the owning context is destroyed (this will result in undefined behavior). 5 | 6 | The main difference between the two types of context (`OwnedContext` and `UnownedContext`) is that `OwnedContext` is a class which destroys the context on deinitialization. 7 | */ 8 | public protocol Context { 9 | var mlir: MlirContext { get } 10 | } 11 | 12 | public func == (lhs: Context, rhs: Context) -> Bool { 13 | mlirContextEqual(lhs.mlir, rhs.mlir) 14 | } 15 | 16 | /** 17 | A context which destroys itself on deinitialization. 18 | */ 19 | public final class OwnedContext: Context { 20 | 21 | /** 22 | Creates a context loaded with the specified dialects 23 | */ 24 | public init(dialects: Dialect...) { 25 | mlir = mlirContextCreate() 26 | for dialect in dialects { 27 | _ = mlirDialectHandleLoadDialect(dialect.mlir, mlir) 28 | } 29 | } 30 | deinit { 31 | mlirContextDestroy(mlir) 32 | } 33 | 34 | public var mlir: MlirContext 35 | } 36 | 37 | /** 38 | A context which is owned by MLIR 39 | */ 40 | public struct UnownedContext: Context, MlirRepresentable { 41 | 42 | public init(_ mlir: MlirContext) { 43 | self.init(mlir: mlir) 44 | } 45 | public var mlir: MlirContext 46 | 47 | /// Suppress synthesized initializer 48 | private init() { fatalError() } 49 | } 50 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/Sources/GenerateBlockInitializers/main.swift: -------------------------------------------------------------------------------- 1 | 2 | import Utilities 3 | 4 | let maxNumArguments = 10 5 | <<""" 6 | 7 | extension Block { 8 | 9 | /// 0 arguments 10 | public init( 11 | buildOperations: (Block.Operations) throws -> Void 12 | ) rethrows { 13 | self.init(argumentTypes: []) 14 | try buildOperations(operations) 15 | } 16 | 17 | """ 18 | 19 | for numArguments in 1...maxNumArguments { 20 | let range = 0.. Void 27 | ) rethrows { 28 | self.init(argumentTypes: [\(names.joined(separator: ", "))]) 29 | try buildOperations(operations, \(range.map { "arguments[\($0)]" }.joined(separator: ", "))) 30 | } 31 | 32 | /// \(numArguments) arguments, contentual types 33 | public init( 34 | \(names.map { "_ \($0): ContextualType" }.joined(separator: ", ")), 35 | in context: Context, 36 | buildOperations: (Block.Operations, \(range.map { _ in "Value" }.joined(separator: ", "))) throws -> Void 37 | ) rethrows { 38 | self.init(argumentTypes: [\(names.joined(separator: ", "))], in: context) 39 | try buildOperations(operations, \(range.map { "arguments[\($0)]" }.joined(separator: ", "))) 40 | } 41 | 42 | """ 43 | } 44 | <<"}" 45 | -------------------------------------------------------------------------------- /Sources/MLIR/Builtins/Builtin Named Attributes.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | // MARK: - Arguments and Results 4 | 5 | public extension ContextualNamedAttributeProtocol where Self == ContextualNamedAttribute { 6 | static func argument( 7 | _ index: Int, 8 | attributes: [ContextualNamedAttributeProtocol] 9 | ) -> Self { 10 | Self(name: "arg\(index)", attribute: DictionaryAttribute.dictionary(attributes)) 11 | } 12 | static func argument( 13 | _ index: Int, 14 | attributes: ContextualNamedAttributeProtocol... 15 | ) -> Self { 16 | .argument(index, attributes: attributes) 17 | } 18 | static func result( 19 | _ index: Int, 20 | attributes: [ContextualNamedAttributeProtocol] 21 | ) -> Self { 22 | Self(name: "result\(index)", attribute: DictionaryAttribute.dictionary(attributes)) 23 | } 24 | static func result( 25 | _ index: Int, 26 | attributes: ContextualNamedAttributeProtocol... 27 | ) -> Self { 28 | .result(index, attributes: attributes) 29 | } 30 | } 31 | 32 | // MARK: - Symbol Name 33 | 34 | public extension ContextualNamedAttributeProtocol where Self == ContextualNamedAttribute { 35 | static func symbolName(_ name: String) -> Self { 36 | ContextualNamedAttribute( 37 | name: "sym_name", 38 | attribute: StringAttribute.string(name)) 39 | } 40 | } 41 | 42 | // MARK: - Type Attribute 43 | 44 | public extension ContextualNamedAttributeProtocol where Self == ContextualNamedAttribute { 45 | static func type(_ type: ContextualType) -> Self { 46 | ContextualNamedAttribute( 47 | name: "type", 48 | attribute: TypeAttribute.type(type)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Sources/MLIR/Helpers/Linked List Index.swift: -------------------------------------------------------------------------------- 1 | extension Collection where Index == LinkedListIndex { 2 | public subscript(position: Index) -> Element { 3 | position.value!.element 4 | } 5 | } 6 | 7 | /** 8 | An index for linked-list-style MLIR collections 9 | */ 10 | public struct LinkedListIndex: Comparable { 11 | public static func < (lhs: Self, rhs: Self) -> Bool { 12 | switch (lhs.value, rhs.value) { 13 | case (.none, .none): return false 14 | case (.none, .some): return false 15 | case (.some, .none): return true 16 | case let (lhs?, rhs?): return lhs.offset < rhs.offset 17 | } 18 | } 19 | public static func == (lhs: Self, rhs: Self) -> Bool { 20 | lhs.value?.offset == rhs.value?.offset 21 | } 22 | fileprivate let value: (offset: Int, element: Collection.Element)? 23 | } 24 | 25 | extension LinkedListIndex 26 | where 27 | Collection.Element: MlirRepresentable 28 | { 29 | typealias MlirElement = Collection.Element.MlirRepresentation 30 | static func starting(with element: MlirElement) -> Self { 31 | guard let element = Collection.Element(checkingForNull: element) else { 32 | return .end 33 | } 34 | return Self(value: (0, element)) 35 | } 36 | static var end: Self { Self(value: nil) } 37 | func successor(using fn: (MlirElement) -> MlirElement) -> Self { 38 | guard let value = value else { 39 | assertionFailure() 40 | return Self(value: nil) 41 | } 42 | guard let element = Collection.Element(checkingForNull: fn(value.element.mlir)) else { 43 | return .end 44 | } 45 | let offset = value.offset + 1 46 | return Self(value: (offset, element)) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tools/BoilerplateGenerator/Sources/GenerateOperationExtensions/main.swift: -------------------------------------------------------------------------------- 1 | 2 | import Utilities 3 | 4 | let maxNumResults = 10 5 | 6 | for numResults in 2...maxNumResults { 7 | let range = 0.. Location 10 | { 11 | file.withUnsafeMlirStringRef { 12 | Location( 13 | mlirLocationFileLineColGet( 14 | context.mlir, 15 | $0, 16 | UInt32(line), 17 | UInt32(column))) 18 | } 19 | } 20 | 21 | /** 22 | Creates an unknown location owned by the provided context 23 | */ 24 | public static func unknown(in context: Context) -> Location { 25 | Location(mlirLocationUnknownGet(context.mlir)) 26 | } 27 | 28 | /** 29 | Creates a call site location with `self` as the callee and `callSite` as the caller 30 | */ 31 | public func called(from callSite: Location) -> Location { 32 | Location(mlirLocationCallSiteGet(mlir, callSite.mlir)) 33 | } 34 | 35 | /** 36 | Creates a call site location with `self` as the callee and the current source location as the caller 37 | */ 38 | public func viaCallsite( 39 | file: StaticString = #fileID, line: UInt = #line, column: UInt = #column 40 | ) -> Location { 41 | Location.file(file, line: line, column: column, in: context) 42 | .called(from: self) 43 | } 44 | 45 | /** 46 | The `context` associated with this location 47 | */ 48 | public var context: UnownedContext { 49 | UnownedContext(mlirLocationGetContext(mlir)) 50 | } 51 | 52 | public init(_ mlir: MlirLocation) { 53 | self.init(mlir: mlir) 54 | } 55 | public let mlir: MlirLocation 56 | } 57 | 58 | /// For some reason, declaring this conformance in `Text Output Stream.swift` (like all the others) crashes the Swift 5.3 compiler. 59 | extension Location: Printable { 60 | static let print = mlirLocationPrint 61 | } 62 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Type.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | A representation of an MLIR type that is independent of a context 5 | */ 6 | public protocol ContextualType { 7 | func `in`(_ context: Context) -> Type 8 | } 9 | 10 | /** 11 | Swift representation of an `MlirType` 12 | 13 | - note: The type-name `Type` is awkward because it conflicts with Swift's built-in `Type` type which represent the metatype of a given type. This can be disambiguated with backtics, which we think is preferrable to calling this type something else (like `MLIRType`). 14 | */ 15 | public struct Type: ContextualType, MlirRepresentable { 16 | 17 | public init(_ mlir: MlirType) { 18 | self.init(mlir: mlir) 19 | } 20 | public let mlir: MlirType 21 | 22 | /** 23 | Type implements `ContextualType`, but requires that `context`be the context owning this type. 24 | */ 25 | public func `in`(_ context: Context) -> Type { 26 | precondition(context == self.context) 27 | return self 28 | } 29 | 30 | /** 31 | The context which owns this type 32 | */ 33 | public var context: UnownedContext { 34 | UnownedContext(mlirTypeGetContext(mlir)) 35 | } 36 | 37 | /// Suppress synthesized initializer 38 | private init() { fatalError() } 39 | } 40 | 41 | // MARK: - Equality 42 | 43 | extension Type: Equatable { 44 | public static func == (lhs: Self, rhs: Self) -> Bool { 45 | mlirTypeEqual(lhs.mlir, rhs.mlir) 46 | } 47 | } 48 | 49 | /** 50 | Types can be equated with contextual types 51 | 52 | - note: This operation is defined on optionals so we get optional comparisons as well 53 | */ 54 | public func == (lhs: ContextualType?, rhs: Type?) -> Bool { 55 | switch (lhs, rhs) { 56 | case (.none, .none): return true 57 | case (.some, .none), (.none, .some): return false 58 | case let (lhs?, rhs?): 59 | return lhs.in(rhs.context) == rhs 60 | } 61 | } 62 | 63 | public func == (lhs: Type?, rhs: ContextualType?) -> Bool { 64 | rhs == lhs 65 | } 66 | -------------------------------------------------------------------------------- /Tools/swift-format-spec: -------------------------------------------------------------------------------- 1 | { 2 | "version" : 1, 3 | "lineLength" : 100, 4 | "indentation" : { 5 | "spaces" : 2 6 | }, 7 | "tabWidth" : 8, 8 | "maximumBlankLines" : 1, 9 | "respectsExistingLineBreaks" : true, 10 | 11 | "fileScopedDeclarationPrivacy" : { 12 | "accessLevel" : "private" 13 | }, 14 | "indentConditionalCompilationBlocks" : true, 15 | "indentSwitchCaseLabels" : false, 16 | "lineBreakAroundMultilineExpressionChainComponents" : false, 17 | "lineBreakBeforeControlFlowKeywords" : false, 18 | "lineBreakBeforeEachArgument" : false, 19 | "lineBreakBeforeEachGenericRequirement" : false, 20 | "prioritizeKeepingFunctionOutputTogether" : false, 21 | "rules" : { 22 | "AllPublicDeclarationsHaveDocumentation" : false, 23 | "AlwaysUseLowerCamelCase" : true, 24 | "AmbiguousTrailingClosureOverload" : true, 25 | "BeginDocumentationCommentWithOneLineSummary" : false, 26 | "DoNotUseSemicolons" : true, 27 | "DontRepeatTypeInStaticProperties" : true, 28 | "FileScopedDeclarationPrivacy" : true, 29 | "FullyIndirectEnum" : true, 30 | "GroupNumericLiterals" : true, 31 | "IdentifiersMustBeASCII" : true, 32 | "NeverForceUnwrap" : false, 33 | "NeverUseForceTry" : false, 34 | "NeverUseImplicitlyUnwrappedOptionals" : false, 35 | "NoAccessLevelOnExtensionDeclaration" : false, 36 | "NoBlockComments" : false, 37 | "NoCasesWithOnlyFallthrough" : true, 38 | "NoEmptyTrailingClosureParentheses" : true, 39 | "NoLabelsInCasePatterns" : true, 40 | "NoLeadingUnderscores" : false, 41 | "NoParensAroundConditions" : true, 42 | "NoVoidReturnOnFunctionSignature" : true, 43 | "OneCasePerLine" : true, 44 | "OneVariableDeclarationPerLine" : true, 45 | "OnlyOneTrailingClosureArgument" : true, 46 | "OrderedImports" : true, 47 | "ReturnVoidInsteadOfEmptyTuple" : true, 48 | "UseLetInEveryBoundCaseVariable" : false, 49 | "UseShorthandTypeNames" : false, 50 | "UseSingleLinePropertyGetter" : true, 51 | "UseSynthesizedInitializer" : true, 52 | "UseTripleSlashForDocumentationComments" : false, 53 | "ValidateDocumentationComments" : false 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This project has moved to https://github.com/circt/MLIRSwift 2 | 3 | # MLIR Bindings for Swift 4 | 5 | This project intends to make MLIR APIs accessible from Swift via the MLIR C Bindings. 6 | 7 | **DISCLAIMER:** This project is a work in progress. Currently, it is more of a proof-of-concept, so expect things to be incomplete and to change without notice. 8 | 9 | ## Usage 10 | 11 | The best reference for how to use this package will always be the tests ([Module Tests](Tests/DialectTests/Module%20Tests.swift) is probably the most interesting), and I recommend consulting them for more details. 12 | 13 | ## MLIR 14 | 15 | ### Installation 16 | 17 | MLIR is build using the LLVM build infrastructure which uses `cmake`. This is incompatible with Swift Package Manager, so for now developers will need to install MLIR separately in order for this project to work. Once the MLIR C API settles and Swift Package Manager get better support for binary targets on Linux, we will likely make this dependency available as a precompiled binary. 18 | 19 | In the meantime, you can manually install MLIR using the `Tools/build-dependencies` script 20 | 21 | ### Updating 22 | 23 | We do not include MLIR (llvm) as a submodule, because this would cause Swift Pacakge Manager to pull in all of LLVM in any project depending on MLIRSwift. Instead, we store the hash we care about in `Tools/llvm-commit` file, update this file to a new commit to update MLIR. Note that this file _must_ be a hash and not a branch like `main`, since the contents of this file is used to cache the LLVM build on GitHub Actions. 24 | 25 | ### Using an external MLIR checkout 26 | 27 | You can point use your own local version of MLIR in a number of ways, the most flexible is simply to install a custom "LLVM-for-Swift.pc" file that points to your locally built version (consult `Tools/build-dependencies` for an example). A simpler option may be to run `Tools/build-dependencies` with the environment variable `LLVM_REPO` set to `"local"`, and `LLVM_REPO_PATH` set to the path to the repo you want to use. There are a number of other knobs you can turn in `Tools/build-dependencies` to customize this approach. 28 | 29 | 30 | -------------------------------------------------------------------------------- /Sources/MLIR/Diagnostics/Collect Diagnostics.swift: -------------------------------------------------------------------------------- 1 | extension Context { 2 | /** 3 | This method captures diagnostics of at least a certain severity level emitted during `body` (and stops them from being forwarded to other registered handlers). 4 | - parameter minimumSeverity: Diagnostics with severity lower than this value will not be collected and instead be forwarded to the existing handler chain 5 | */ 6 | public func collectDiagnostics( 7 | minimumSeverity: Diagnostic.Severity = .remark, _ body: () -> T 8 | ) -> (value: T, diagnostics: [Diagnostic]) { 9 | _collectDiagnostics(minimumSeverity: minimumSeverity, body) 10 | } 11 | 12 | /** 13 | This method captures diagnostics of at least a certain severity level emitted during `body` (and stops them from being forwarded to other registered handlers). 14 | - parameter minimumSeverity: Diagnostics with severity lower than this value will not be collected and instead be forwarded to the existing handler chain 15 | */ 16 | public func collectDiagnostics( 17 | minimumSeverity: Diagnostic.Severity = .remark, _ body: () -> Void 18 | ) -> [Diagnostic] { 19 | _collectDiagnostics(minimumSeverity: minimumSeverity, body).diagnostics 20 | } 21 | 22 | private func _collectDiagnostics(minimumSeverity: Diagnostic.Severity, _ body: () -> T) 23 | -> (value: T, diagnostics: [Diagnostic]) 24 | { 25 | let collector = DiagnosticCollector(minimumSeverity: minimumSeverity) 26 | let registration = register(collector) 27 | let value = body() 28 | unregister(registration) 29 | return (value, collector.diagnostics) 30 | } 31 | } 32 | 33 | // MARK: - Private 34 | 35 | private final class DiagnosticCollector: DiagnosticHandler { 36 | init(minimumSeverity: Diagnostic.Severity) { 37 | self.minimumSeverity = minimumSeverity 38 | } 39 | let minimumSeverity: Diagnostic.Severity 40 | var diagnostics: [Diagnostic] = [] 41 | func handle(_ unsafeDiagnostic: UnsafeDiagnostic) -> DiagnosticHandlingDirective { 42 | guard unsafeDiagnostic.severity >= minimumSeverity else { return .continue } 43 | diagnostics.append(Diagnostic(unsafeDiagnostic)) 44 | return .stop 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/MLIR/Helpers/Parsing.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | extension Context { 4 | 5 | /** 6 | Attempts to parse `source` as a module 7 | */ 8 | public func parse( 9 | _ source: String, 10 | as type: Module.Type = Module.self 11 | ) throws -> Module { 12 | try parse( 13 | source, 14 | parse: mlirModuleCreateParse, 15 | isNull: mlirModuleIsNull, 16 | init: Module.init) 17 | } 18 | /** 19 | Attempts to parse `source` as an attribute 20 | */ 21 | public func parse( 22 | _ source: String, 23 | as type: Attribute.Type = Attribute.self 24 | ) throws -> Attribute { 25 | try parse( 26 | source, 27 | parse: mlirAttributeParseGet, 28 | isNull: mlirAttributeIsNull, 29 | init: Attribute.init) 30 | } 31 | 32 | /** 33 | Attempts to parse `source` as a type 34 | */ 35 | public func parse( 36 | _ source: String, 37 | as type: Type.Type = Type.self 38 | ) throws -> Type { 39 | try parse( 40 | source, 41 | parse: mlirTypeParseGet, 42 | isNull: mlirTypeIsNull, 43 | init: Type.init) 44 | } 45 | 46 | private func parse( 47 | _ source: String, 48 | parse: (MlirContext, MlirStringRef) -> T, 49 | isNull: (T) -> Bool, 50 | init: (T) -> U 51 | ) throws -> U { 52 | let pair = collectDiagnostics(minimumSeverity: .error) { 53 | source.withUnsafeMlirStringRef { 54 | parse(mlir, $0) 55 | } 56 | } 57 | guard pair.diagnostics.isEmpty else { 58 | throw ParsingError(diagnostics: pair.diagnostics) 59 | } 60 | guard !isNull(pair.value) else { 61 | throw ParsingError(diagnostics: []) 62 | } 63 | return `init`(pair.value) 64 | } 65 | } 66 | 67 | public struct ParsingError: Swift.Error, CustomStringConvertible { 68 | public let diagnostics: [Diagnostic] 69 | 70 | public var description: String { 71 | switch diagnostics.count { 72 | case 0: 73 | return "Unknown Error" 74 | case 1: 75 | return diagnostics[0].message 76 | default: 77 | return """ 78 | \(diagnostics.count) errors: 79 | \(diagnostics.map { " - \($0.message)" }.joined(separator: "\n")) 80 | """ 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Sources/MLIR/Helpers/MLIR Representable.swift: -------------------------------------------------------------------------------- 1 | /** 2 | A Swift struct which is memory-layout-compatible with an MLIR type represented by a single pointer. 3 | */ 4 | protocol MlirRepresentable { 5 | associatedtype MlirRepresentation 6 | var mlir: MlirRepresentation { get } 7 | } 8 | 9 | extension MlirRepresentable { 10 | /** 11 | Initializes this type by casting directly from its MLIR representation. 12 | 13 | - precondition: `mlir` must not be `nil` 14 | */ 15 | init(mlir: MlirRepresentation) { 16 | self.init(checkingForNull: mlir)! 17 | } 18 | 19 | /** 20 | Initializes this type by casting directly from its MLIR representation if non-`nil` 21 | */ 22 | init?(checkingForNull mlir: MlirRepresentation) { 23 | Self.validateMemoryLayout() 24 | let optionalValue = withUnsafePointer(to: mlir) { pointer -> Self? in 25 | let raw = UnsafeRawPointer(pointer) 26 | if raw.assumingMemoryBound(to: MlirPointer.self).pointee == nil { 27 | return nil 28 | } else { 29 | return raw.assumingMemoryBound(to: Self.self).pointee 30 | } 31 | } 32 | guard let value = optionalValue else { return nil } 33 | self = value 34 | } 35 | } 36 | 37 | extension Array where Element: MlirRepresentable { 38 | func withUnsafeMlirRepresentation( 39 | _ body: (UnsafeBufferPointer) throws -> R 40 | ) rethrows -> R { 41 | Element.validateMemoryLayout() 42 | return try withUnsafeBufferPointer { buffer in 43 | try buffer.withMemoryRebound(to: Element.MlirRepresentation.self, body) 44 | } 45 | } 46 | } 47 | 48 | // MARK: - Private 49 | 50 | extension MlirRepresentable { 51 | fileprivate static func validateMemoryLayout() { 52 | precondition(isMemoryLayoutCompatible(with: MlirRepresentation.self)) 53 | precondition(isMemoryLayoutCompatible(with: MlirPointer.self)) 54 | precondition(!(Self.self is AnyObject.Type)) 55 | } 56 | } 57 | 58 | private extension MlirRepresentable { 59 | private static func isMemoryLayoutCompatible(with other: T.Type) -> Bool { 60 | [ 61 | (MemoryLayout.size, MemoryLayout.size), 62 | (MemoryLayout.stride, MemoryLayout.stride), 63 | (MemoryLayout.alignment, MemoryLayout.alignment), 64 | ] 65 | .allSatisfy(==) 66 | } 67 | } 68 | 69 | private typealias MlirPointer = UnsafeMutableRawPointer? 70 | -------------------------------------------------------------------------------- /Sources/MLIR/Helpers/Text Output Stream.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | import Foundation 3 | 4 | // MARK: - Public 5 | 6 | extension TextOutputStream { 7 | 8 | /** 9 | Writes to `self` using MLIR-style string callbacks 10 | 11 | - parameter body: A block taking arguments suitable for use with MLIR printing APIs such as `mlirOperationPrint`. The callback passed to this closure is `@escaping` because the MLIR C APIs take optionals (which must be `@escaping`), but it is very much not safe for the callback to escape the body of the closure. 12 | */ 13 | public mutating func write(_ body: (MlirStringCallback?, UnsafeMutableRawPointer) -> Void) { 14 | withUnsafeMutablePointer(to: &self) { targetRef in 15 | typealias StringCallback = (MlirStringRef) -> Void 16 | let stringCallback: StringCallback = { 17 | targetRef.pointee.write($0.string) 18 | } 19 | withUnsafePointer(to: stringCallback) { stringCallbackRef in 20 | body( 21 | // callback 22 | { mlirString, stringCallbackRef in 23 | stringCallbackRef! 24 | .assumingMemoryBound(to: StringCallback.self) 25 | .pointee(mlirString) 26 | }, 27 | // userData 28 | UnsafeMutableRawPointer(mutating: stringCallbackRef)) 29 | } 30 | } 31 | } 32 | } 33 | 34 | // MARK: - Printing 35 | 36 | protocol Printable: TextOutputStreamable, CustomStringConvertible, CustomDebugStringConvertible { 37 | associatedtype MlirRepresentation 38 | var mlir: MlirRepresentation { get } 39 | static var print: PrintCallback { get } 40 | } 41 | 42 | extension Printable { 43 | public func write(to target: inout Target) { 44 | target.write { Self.print(mlir, $0, $1) } 45 | } 46 | public var description: String { 47 | "\(self)" 48 | } 49 | public var debugDescription: String { 50 | "\(Self.self)(\(self))" 51 | } 52 | 53 | typealias PrintCallback = (MlirRepresentation, MlirStringCallback?, UnsafeMutableRawPointer?) -> 54 | Void 55 | } 56 | 57 | extension Attribute: Printable { 58 | static let print = mlirAttributePrint 59 | } 60 | extension Operation: Printable { 61 | static var print: PrintCallback { mlirOperationPrint } 62 | } 63 | extension Type: Printable { 64 | static let print = mlirTypePrint 65 | } 66 | extension Value: Printable { 67 | static let print = mlirValuePrint 68 | } 69 | extension UnsafeDiagnostic: Printable { 70 | static let print = mlirDiagnosticPrint 71 | } 72 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Block Operations Append (Generated).swift: -------------------------------------------------------------------------------- 1 | /// This file was autogenerated by running `Tools/generate-boilerplate` 2 | 3 | extension Block.Operations { 4 | 5 | /** 6 | Appends an operation with 1 results and returns the results 7 | */ 8 | public func append(_ operation: Operation<(Value)>) -> (Value) { 9 | append(operation.typeErased) 10 | return operation.results 11 | } 12 | 13 | /** 14 | Appends an operation with 2 results and returns the results 15 | */ 16 | public func append(_ operation: Operation<(Value, Value)>) -> (Value, Value) { 17 | append(operation.typeErased) 18 | return operation.results 19 | } 20 | 21 | /** 22 | Appends an operation with 3 results and returns the results 23 | */ 24 | public func append(_ operation: Operation<(Value, Value, Value)>) -> (Value, Value, Value) { 25 | append(operation.typeErased) 26 | return operation.results 27 | } 28 | 29 | /** 30 | Appends an operation with 4 results and returns the results 31 | */ 32 | public func append(_ operation: Operation<(Value, Value, Value, Value)>) -> ( 33 | Value, Value, Value, Value 34 | ) { 35 | append(operation.typeErased) 36 | return operation.results 37 | } 38 | 39 | /** 40 | Appends an operation with 5 results and returns the results 41 | */ 42 | public func append(_ operation: Operation<(Value, Value, Value, Value, Value)>) -> ( 43 | Value, Value, Value, Value, Value 44 | ) { 45 | append(operation.typeErased) 46 | return operation.results 47 | } 48 | 49 | /** 50 | Appends an operation with 6 results and returns the results 51 | */ 52 | public func append(_ operation: Operation<(Value, Value, Value, Value, Value, Value)>) -> ( 53 | Value, Value, Value, Value, Value, Value 54 | ) { 55 | append(operation.typeErased) 56 | return operation.results 57 | } 58 | 59 | /** 60 | Appends an operation with 7 results and returns the results 61 | */ 62 | public func append(_ operation: Operation<(Value, Value, Value, Value, Value, Value, Value)>) -> ( 63 | Value, Value, Value, Value, Value, Value, Value 64 | ) { 65 | append(operation.typeErased) 66 | return operation.results 67 | } 68 | 69 | /** 70 | Appends an operation with 8 results and returns the results 71 | */ 72 | public func append( 73 | _ operation: Operation<(Value, Value, Value, Value, Value, Value, Value, Value)> 74 | ) -> (Value, Value, Value, Value, Value, Value, Value, Value) { 75 | append(operation.typeErased) 76 | return operation.results 77 | } 78 | 79 | /** 80 | Appends an operation with 9 results and returns the results 81 | */ 82 | public func append( 83 | _ operation: Operation<(Value, Value, Value, Value, Value, Value, Value, Value, Value)> 84 | ) -> (Value, Value, Value, Value, Value, Value, Value, Value, Value) { 85 | append(operation.typeErased) 86 | return operation.results 87 | } 88 | 89 | /** 90 | Appends an operation with 10 results and returns the results 91 | */ 92 | public func append( 93 | _ operation: Operation<(Value, Value, Value, Value, Value, Value, Value, Value, Value, Value)> 94 | ) -> (Value, Value, Value, Value, Value, Value, Value, Value, Value, Value) { 95 | append(operation.typeErased) 96 | return operation.results 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /.github/workflows/buildAndTest.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | types: [assigned, opened, synchronize, reopened] 9 | workflow_dispatch: 10 | 11 | # This workflow has two jobs: `build-dependencies` and `build-and-test`. `build-dependencies` is a subset of `build-and-test`. This allows us to cache the LLVM build (which took almost 1.5 hours at the time of writing) even if the subsequent tests fail, which is helpful when trying to get a new version of llvm through CI. 12 | # WARNING: Edit this file with caution. If the two sections that build LLVM end up out of sync it might cause some nasty bugs. 13 | # See also: 14 | # - https://stackoverflow.com/questions/60491837/saving-cache-on-job-failure-in-github-actions 15 | jobs: 16 | build-dependencies: 17 | name: Build Dependencies 18 | strategy: 19 | matrix: 20 | os: [macos-latest, ubuntu-latest] 21 | runs-on: ${{ matrix.os }} 22 | steps: 23 | # This sequence of steps must match the sequence below in the validate job 24 | - name: Checkout Repo 25 | uses: actions/checkout@v2 26 | - name: Cache Dependencies 27 | id: cache-dependencies 28 | uses: actions/cache@v2 29 | with: 30 | path: .dependencies/installed 31 | key: ${{ runner.os }}-dependencies-v1-${{ hashFiles('Tools/llvm-commit', 'Tools/build-dependencies', 'Sources/*/module.modulemap', 'Tools/SwiftFormat/Package.swift') }} 32 | - name: Install Ninja 33 | if: steps.cache-dependencies.outputs.cache-hit != 'true' 34 | uses: seanmiddleditch/gha-setup-ninja@master 35 | - name: Clone, Build and Install Dependencies 36 | if: steps.cache-dependencies.outputs.cache-hit != 'true' 37 | run: | 38 | PKG_CONFIG_PATH=.dependencies/installed NO_INTERACTION=true Tools/build-dependencies 39 | 40 | # Validate this commit 41 | validate: 42 | name: Validate Commit 43 | needs: build-dependencies 44 | strategy: 45 | matrix: 46 | os: [macos-latest, ubuntu-latest] 47 | runs-on: ${{ matrix.os }} 48 | steps: 49 | # The following sequence of steps must match the sequence above in build-dependencies 50 | - name: Checkout Repo 51 | uses: actions/checkout@v2 52 | - name: Cache Dependencies 53 | id: cache-dependencies 54 | uses: actions/cache@v2 55 | with: 56 | path: .dependencies/installed 57 | key: ${{ runner.os }}-dependencies-v1-${{ hashFiles('Tools/llvm-commit', 'Tools/build-dependencies', 'Sources/*/module.modulemap', 'Tools/SwiftFormat/Package.swift') }} 58 | - name: Install Ninja 59 | if: steps.cache-dependencies.outputs.cache-hit != 'true' 60 | uses: seanmiddleditch/gha-setup-ninja@master 61 | - name: Clone, Build and Install Dependencies 62 | if: steps.cache-dependencies.outputs.cache-hit != 'true' 63 | run: | 64 | PKG_CONFIG_PATH=.dependencies/installed NO_INTERACTION=true Tools/build-dependencies 65 | 66 | # Actually validate this commit 67 | 68 | - name: Validate Generated Code 69 | run: | 70 | Tools/generate-boilerplate 71 | git diff 72 | git diff-index --quiet HEAD -- 73 | 74 | - name: Format 75 | run: | 76 | Tools/swift-format --ci 77 | git diff 78 | git diff-index --quiet HEAD -- 79 | 80 | - name: Run tests 81 | run: | 82 | PKG_CONFIG_PATH=$PWD/.dependencies/installed swift test --enable-test-discovery 83 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Block.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | An IR node which can have arguments and holds operations 5 | */ 6 | public struct Block: MlirRepresentable, Equatable { 7 | 8 | /** 9 | Creates a block with the specified argument types 10 | */ 11 | public init(argumentTypes: [Type] = []) { 12 | self = argumentTypes.withUnsafeMlirRepresentation { 13 | Self(mlirBlockCreate($0.count, $0.baseAddress)) 14 | } 15 | } 16 | 17 | /** 18 | Creates a block with the specified argument types 19 | */ 20 | public init(argumentTypes: [ContextualType], in context: Context) { 21 | self.init(argumentTypes: argumentTypes.map { $0.in(context) }) 22 | } 23 | 24 | public init(_ mlir: MlirBlock) { 25 | precondition(!mlirBlockIsNull(mlir)) 26 | self.mlir = mlir 27 | } 28 | public let mlir: MlirBlock 29 | 30 | /** 31 | Destroys this block 32 | 33 | This block **must not** be used after `destroy` returns, doing so will lead to undefined behavior 34 | */ 35 | public func destroy() { 36 | mlirBlockDestroy(mlir) 37 | } 38 | 39 | /** 40 | The arguments to this block 41 | */ 42 | public var arguments: Arguments { 43 | Arguments(block: mlir) 44 | } 45 | 46 | /** 47 | The operations in this block 48 | */ 49 | public var operations: Operations { 50 | Operations(block: mlir) 51 | } 52 | 53 | /** 54 | The operation that owns this block 55 | */ 56 | public var owningOperation: AnyOperation? { 57 | Operation(checkingForNull: mlirBlockGetParentOperation(mlir)) 58 | } 59 | 60 | public static func == (lhs: Self, rhs: Self) -> Bool { 61 | mlirBlockEqual(lhs.mlir, rhs.mlir) 62 | } 63 | 64 | } 65 | 66 | // MARK: - Arguments 67 | 68 | extension Block { 69 | public struct Arguments: RandomAccessCollection { 70 | public let startIndex = 0 71 | public var endIndex: Int { mlirBlockGetNumArguments(block) } 72 | public subscript(position: Int) -> MLIR.Value { 73 | Value(mlirBlockGetArgument(block, position)) 74 | } 75 | public func append(_ type: MLIR.`Type`) -> MLIR.Value { 76 | Value(mlirBlockAddArgument(block, type.mlir)) 77 | } 78 | fileprivate let block: MlirBlock 79 | } 80 | } 81 | 82 | // MARK: - Operations 83 | 84 | extension Block { 85 | public struct Operations: Collection { 86 | public typealias Index = LinkedListIndex 87 | public typealias Element = AnyOperation 88 | public var startIndex: Index { .starting(with: mlirBlockGetFirstOperation(block)) } 89 | public var endIndex: Index { .end } 90 | public func index(after i: Index) -> Index { 91 | i.successor(using: mlirOperationGetNextInBlock) 92 | } 93 | 94 | /** 95 | Takes ownership of an operation and appends it to this block 96 | */ 97 | public func append(_ ownedOperation: AnyOperation) { 98 | /** 99 | If present, the module terminator must always be at the end. 100 | If there is no terminator, `mlirBlockGetTerminator` returns null which causes `mlirBlockInsertOwnedOperationBefore` to act like `mlirBlockAppendOwnedOperation`. 101 | */ 102 | mlirBlockInsertOwnedOperationBefore(block, mlirBlockGetTerminator(block), ownedOperation.mlir) 103 | } 104 | 105 | /** 106 | Appends an operation with 0 results 107 | */ 108 | public func append(_ operation: Operation<()>) { 109 | let operation = operation.typeErased 110 | precondition(operation.results.count == 0) 111 | append(operation) 112 | } 113 | 114 | public let block: MlirBlock 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Tests/DialectTests/Module Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Dialects 4 | import MLIR 5 | 6 | final class ModuleTests: XCTestCase { 7 | func testCanonicalization() throws { 8 | let context = MLIR.OwnedContext(dialects: .std) 9 | let passManager = PassManager(context: context, passes: .canonicalization) 10 | let module: Module = try context.parse(""" 11 | module { 12 | func @swap(%arg0: i1, %arg1: i1) -> (i1, i1) { 13 | %0 = "std.addi"(%arg0, %arg0) : (i1, i1) -> i1 14 | return %arg1, %arg0 : i1, i1 15 | } 16 | } 17 | 18 | """) 19 | passManager.runPasses(on: module) 20 | XCTAssertEqual( 21 | "\(module.operation)", """ 22 | module { 23 | func @swap(%arg0: i1, %arg1: i1) -> (i1, i1) { 24 | return %arg1, %arg0 : i1, i1 25 | } 26 | } 27 | 28 | """) 29 | } 30 | 31 | func testCanonicalization2() throws { 32 | let context = MLIR.OwnedContext(dialects: .std) 33 | let passManager = PassManager(context: context, passes: .canonicalization) 34 | let module: Module = try context.parse(""" 35 | module { 36 | func @swap(%arg0: i1, %arg1: i1) -> (i1, i1) { 37 | %0 = "std.addi"(%arg0, %arg0) : (i1, i1) -> i1 38 | return %arg1, %arg0 : i1, i1 39 | } 40 | } 41 | 42 | """) 43 | passManager.runPasses(on: module) 44 | XCTAssertEqual( 45 | "\(module.operation)", """ 46 | module { 47 | func @swap(%arg0: i1, %arg1: i1) -> (i1, i1) { 48 | return %arg1, %arg0 : i1, i1 49 | } 50 | } 51 | 52 | """) 53 | } 54 | 55 | func testModule() throws { 56 | let context = MLIR.OwnedContext(dialects: .std) 57 | let reference = """ 58 | module { 59 | func @swap(%arg0: i1, %arg1: i1) -> (i1, i1) { 60 | return %arg1, %arg0 : i1, i1 61 | } 62 | } 63 | 64 | """ 65 | let generic = """ 66 | "module"() ( { 67 | "func"() ( { 68 | ^bb0(%arg0: i1, %arg1: i1): // no predecessors 69 | "std.return"(%arg1, %arg0) : (i1, i1) -> () 70 | }) {sym_name = "swap", type = (i1, i1) -> (i1, i1)} : () -> () 71 | "module_terminator"() : () -> () 72 | }) : () -> () 73 | 74 | """ 75 | 76 | let location: Location = .unknown(in: context) 77 | 78 | let constructed = Module(location: location) 79 | constructed.body.operations.append( 80 | .function( 81 | "swap", 82 | returnTypes: [IntegerType.integer(bitWidth: 1), .integer(bitWidth: 1)], 83 | blocks: [ 84 | Block(IntegerType.integer(bitWidth: 1), IntegerType.integer(bitWidth: 1), in: context) { ops, a, b in 85 | ops.append(.return(b, a, at: location.viaCallsite())) 86 | } 87 | ], 88 | at: location.viaCallsite())) 89 | XCTAssertTrue(constructed.body.operations.map(\.isValid).reduce(true, { $0 && $1 })) 90 | XCTAssertTrue(constructed.operation.isValid) 91 | 92 | let parsed: Module = try context.parse(reference) 93 | 94 | XCTAssertEqual(parsed.body.operations.count, 2) /// Includes the module terminator 95 | XCTAssertEqual(parsed.operation.regions.count, 1) 96 | XCTAssertEqual(parsed.operation.regions.first?.blocks.count, 1) 97 | 98 | XCTAssertEqual( 99 | generic, 100 | "\(constructed.operation.withPrintingOptions(alwaysPrintInGenericForm: true))") 101 | XCTAssertEqual( 102 | generic, 103 | "\(parsed.operation.withPrintingOptions(alwaysPrintInGenericForm: true))") 104 | 105 | XCTAssertEqual(reference, "\(constructed.operation)") 106 | XCTAssertEqual(reference, "\(parsed.operation)") 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Sources/MLIR/Builtins/Builtin Attributes.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | // MARK: - String 4 | 5 | public struct StringAttribute: ContextualAttribute { 6 | public let value: String 7 | public func `in`(_ context: Context) -> Attribute { 8 | Attribute( 9 | value.withUnsafeMlirStringRef { 10 | mlirStringAttrGet(context.mlir, $0) 11 | }) 12 | } 13 | } 14 | extension ContextualAttribute where Self == StringAttribute { 15 | public static func string(_ value: String) -> Self { 16 | StringAttribute(value: value) 17 | } 18 | } 19 | 20 | // MARK: - Integer 21 | 22 | public struct IntegerAttribute: ContextualAttribute { 23 | public let type: IntegerType 24 | public let value: Int 25 | public func `in`(_ context: Context) -> Attribute { 26 | Attribute(mlirIntegerAttrGet(type.in(context).mlir, Int64(value))) 27 | } 28 | } 29 | extension ContextualAttribute where Self == IntegerAttribute { 30 | public static func integer( 31 | type: IntegerType, 32 | value: Int 33 | ) -> Self { 34 | IntegerAttribute(type: type, value: value) 35 | } 36 | } 37 | 38 | // MARK: - Type 39 | 40 | public struct TypeAttribute: ContextualAttribute { 41 | public let type: ContextualType 42 | public func `in`(_ context: Context) -> Attribute { 43 | Attribute(mlirTypeAttrGet(type.in(context).mlir)) 44 | } 45 | } 46 | public extension ContextualAttribute where Self == TypeAttribute { 47 | static func type(_ type: ContextualType) -> Self { 48 | TypeAttribute(type: type) 49 | } 50 | } 51 | 52 | // MARK: - Array 53 | 54 | public struct ArrayAttribute: ContextualAttribute { 55 | public let elements: [ContextualAttribute] 56 | public func `in`(_ context: Context) -> Attribute { 57 | elements 58 | .map { $0.in(context) } 59 | .withUnsafeMlirRepresentation { elements in 60 | Attribute(mlirArrayAttrGet(context.mlir, elements.count, elements.baseAddress)) 61 | } 62 | } 63 | } 64 | public extension ContextualAttribute where Self == ArrayAttribute { 65 | static func array(_ elements: [ContextualAttribute]) -> Self { 66 | ArrayAttribute(elements: elements) 67 | } 68 | static func array(_ elements: ContextualAttribute...) -> Self { 69 | ArrayAttribute(elements: elements) 70 | } 71 | } 72 | 73 | // MARK: - Dictionary 74 | 75 | public struct DictionaryAttribute: ContextualAttribute { 76 | public let elements: [ContextualNamedAttributeProtocol] 77 | public func `in`(_ context: Context) -> Attribute { 78 | elements 79 | .map { $0.in(context) } 80 | .withUnsafeMlirRepresentation { elements in 81 | Attribute(mlirDictionaryAttrGet(context.mlir, elements.count, elements.baseAddress)) 82 | } 83 | } 84 | } 85 | public extension ContextualAttribute where Self == DictionaryAttribute { 86 | static func dictionary(_ elements: [ContextualNamedAttributeProtocol]) -> Self { 87 | DictionaryAttribute(elements: elements) 88 | } 89 | static func dictionary(_ elements: ContextualNamedAttributeProtocol...) -> Self { 90 | DictionaryAttribute(elements: elements) 91 | } 92 | static func dictionary(_ pairs: Pairs) -> Self 93 | where 94 | Pairs.Element == (key: String, value: ContextualAttribute) 95 | { 96 | .dictionary(pairs.map(NameContextualAttributePair.init)) 97 | } 98 | } 99 | 100 | private struct NameContextualAttributePair: ContextualNamedAttributeProtocol { 101 | let name: String 102 | let attribute: ContextualAttribute 103 | func `in`(_ context: Context) -> NamedAttribute { 104 | NamedAttribute(name: name, attribute: attribute.in(context)) 105 | } 106 | } 107 | 108 | // MARK: - Flat Symbol Reference 109 | 110 | public struct FlatSymbolReferenceAttribute: ContextualAttribute { 111 | public let name: String 112 | public func `in`(_ context: Context) -> Attribute { 113 | name.withUnsafeMlirStringRef { 114 | Attribute(mlirFlatSymbolRefAttrGet(context.mlir, $0)) 115 | } 116 | } 117 | } 118 | public extension 119 | ContextualAttribute where Self == FlatSymbolReferenceAttribute 120 | { 121 | static func flatSymbolReference(_ name: String) -> Self { 122 | FlatSymbolReferenceAttribute(name: name) 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Sources/MLIR/Diagnostics/Diagnostics.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | // MARK: - Public 4 | 5 | public struct Diagnostic: Swift.Error { 6 | public enum Severity: Comparable { 7 | case remark, note, warning, error 8 | } 9 | 10 | public let location: Location 11 | public let severity: Severity 12 | public let notes: [Diagnostic] 13 | public let message: String 14 | 15 | init(_ unsafeDiagnostic: UnsafeDiagnostic) { 16 | self.location = unsafeDiagnostic.location 17 | self.severity = unsafeDiagnostic.severity 18 | self.notes = unsafeDiagnostic.notes.map(Diagnostic.init) 19 | self.message = "\(unsafeDiagnostic)" 20 | } 21 | } 22 | 23 | // MARK: - Internal 24 | 25 | struct UnsafeDiagnostic { 26 | 27 | struct Notes: Sequence { 28 | func makeIterator() -> Iterator { 29 | return Iterator(parent: parent) 30 | } 31 | struct Iterator: IteratorProtocol { 32 | init(parent: MlirDiagnostic) { 33 | self.parent = parent 34 | self.count = mlirDiagnosticGetNumNotes(parent) 35 | } 36 | mutating func next() -> UnsafeDiagnostic? { 37 | guard index < count else { return nil } 38 | let diagnostic = UnsafeDiagnostic(mlir: mlirDiagnosticGetNote(parent, index)) 39 | index += 1 40 | return diagnostic 41 | } 42 | private let parent: MlirDiagnostic 43 | private let count: Int 44 | private var index = 0 45 | } 46 | fileprivate let parent: MlirDiagnostic 47 | } 48 | 49 | var location: Location { Location(mlirDiagnosticGetLocation(mlir)) } 50 | var severity: Diagnostic.Severity { 51 | Diagnostic.Severity(c: mlirDiagnosticGetSeverity(mlir)) 52 | } 53 | var notes: Notes { Notes(parent: mlir) } 54 | 55 | let mlir: MlirDiagnostic 56 | 57 | } 58 | 59 | enum DiagnosticHandlingDirective { 60 | case stop 61 | case `continue` 62 | 63 | fileprivate var logicalResult: MlirLogicalResult { 64 | switch self { 65 | case .stop: 66 | return mlirLogicalResultSuccess() 67 | case .continue: 68 | return mlirLogicalResultFailure() 69 | } 70 | } 71 | } 72 | 73 | /** 74 | - note: This type is named `Registration`, unlike the wrapped C type, so it would be more consistent with other Swift APIs and not be confused with `ID` from the `Identifiable` protocol (which means something different). 75 | */ 76 | struct DiagnosticHandlerRegistration { 77 | fileprivate let id: MlirDiagnosticHandlerID 78 | } 79 | 80 | protocol DiagnosticHandler: AnyObject { 81 | /** 82 | - parameter unsafeDiagnostic: A `Diagnostic` which, along with any derived values such as `notes`, will only be valid for the duration of the call to `handle`. 83 | */ 84 | func handle(_ unsafeDiagnostic: UnsafeDiagnostic) -> DiagnosticHandlingDirective 85 | } 86 | 87 | extension Context { 88 | func register(_ handler: DiagnosticHandler) -> DiagnosticHandlerRegistration { 89 | let userData = UnsafeMutableRawPointer(Unmanaged.passRetained(handler as AnyObject).toOpaque()) 90 | let id = mlirContextAttachDiagnosticHandler( 91 | mlir, 92 | mlirDiagnosticHandler, 93 | userData, 94 | mlirDeleteUserData) 95 | return DiagnosticHandlerRegistration(id: id) 96 | } 97 | func unregister(_ registration: DiagnosticHandlerRegistration) { 98 | mlirContextDetachDiagnosticHandler(mlir, registration.id) 99 | } 100 | } 101 | 102 | // MARK: - Private 103 | 104 | extension Diagnostic.Severity { 105 | fileprivate var c: MlirDiagnosticSeverity { 106 | switch self { 107 | case .error: return MlirDiagnosticError 108 | case .warning: return MlirDiagnosticWarning 109 | case .note: return MlirDiagnosticNote 110 | case .remark: return MlirDiagnosticRemark 111 | } 112 | } 113 | fileprivate init(c: MlirDiagnosticSeverity) { 114 | switch c { 115 | case MlirDiagnosticError: self = .error 116 | case MlirDiagnosticWarning: self = .warning 117 | case MlirDiagnosticNote: self = .note 118 | case MlirDiagnosticRemark: self = .remark 119 | 120 | /// We do not expect MLIR to return us diagnostics with invalid severities 121 | default: fatalError() 122 | } 123 | } 124 | } 125 | 126 | private func mlirDiagnosticHandler( 127 | mlirDiagnostic: MlirDiagnostic, userData: UnsafeMutableRawPointer! 128 | ) -> MlirLogicalResult { 129 | let handler = 130 | Unmanaged.fromOpaque(userData).takeUnretainedValue() as! DiagnosticHandler 131 | return handler.handle(UnsafeDiagnostic(mlir: mlirDiagnostic)).logicalResult 132 | } 133 | 134 | private func mlirDeleteUserData(userData: UnsafeMutableRawPointer!) { 135 | Unmanaged.fromOpaque(userData).release() 136 | } 137 | -------------------------------------------------------------------------------- /Sources/MLIR/Builtins/Builtin Types.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | // MARK: - Index 4 | 5 | public struct IndexType: ContextualType { 6 | public func `in`(_ context: Context) -> Type { 7 | Type(mlirIndexTypeGet(context.mlir)) 8 | } 9 | } 10 | extension ContextualType where Self == IndexType { 11 | public static var index: Self { IndexType() } 12 | } 13 | extension Type { 14 | public var isIndex: Bool { mlirTypeIsAIndex(mlir) } 15 | } 16 | 17 | // MARK: - Float 18 | 19 | public struct Float32Type: ContextualType { 20 | public func `in`(_ context: Context) -> Type { 21 | Type(mlirF32TypeGet(context.mlir)) 22 | } 23 | } 24 | extension ContextualType where Self == Float32Type { 25 | public static var float32: Self { Float32Type() } 26 | } 27 | extension Type { 28 | public var isFloat32: Bool { mlirTypeIsAF32(mlir) } 29 | } 30 | 31 | // MARK: - Integer 32 | 33 | public struct IntegerType: ContextualType { 34 | 35 | public enum Signedness { 36 | case signed, unsigned 37 | } 38 | public let signedness: Signedness? 39 | 40 | public let bitWidth: Int 41 | 42 | public func `in`(_ context: Context) -> Type { 43 | precondition(bitWidth > 0) 44 | let c: MlirType 45 | switch signedness { 46 | case .signed: 47 | c = mlirIntegerTypeSignedGet(context.mlir, UInt32(bitWidth)) 48 | case .unsigned: 49 | c = mlirIntegerTypeUnsignedGet(context.mlir, UInt32(bitWidth)) 50 | case .none: 51 | c = mlirIntegerTypeGet(context.mlir, UInt32(bitWidth)) 52 | } 53 | return Type(c) 54 | } 55 | } 56 | extension ContextualType where Self == IntegerType { 57 | public static func integer(_ signedness: IntegerType.Signedness? = nil, bitWidth: Int) 58 | -> Self 59 | { 60 | IntegerType(signedness: signedness, bitWidth: bitWidth) 61 | } 62 | } 63 | extension Type { 64 | public func asIntegerType() -> IntegerType? { 65 | guard mlirTypeIsAInteger(mlir) else { return nil } 66 | let signedness: IntegerType.Signedness? 67 | if mlirIntegerTypeIsSignless(mlir) { 68 | signedness = nil 69 | } else if mlirIntegerTypeIsSigned(mlir) { 70 | signedness = .signed 71 | } else if mlirIntegerTypeIsUnsigned(mlir) { 72 | signedness = .unsigned 73 | } else { 74 | fatalError() 75 | } 76 | return IntegerType(signedness: signedness, bitWidth: Int(mlirIntegerTypeGetWidth(mlir))) 77 | } 78 | } 79 | 80 | // MARK: - Memory Reference 81 | 82 | public struct MemoryReferenceType: ContextualType { 83 | 84 | public struct Size: ExpressibleByIntegerLiteral { 85 | public init(integerLiteral value: Int64) { 86 | precondition(value >= 0) 87 | self.value = value 88 | } 89 | 90 | public static var dynamic: Self { Self(value: -1) } 91 | 92 | fileprivate let value: Int64 93 | fileprivate init(value: Int64) { 94 | self.value = value 95 | } 96 | } 97 | public let dimensions: [Size] 98 | public let element: ContextualType 99 | public let memorySpace: IntegerAttribute 100 | 101 | public func `in`(_ context: Context) -> Type { 102 | precondition(MemoryLayout.size == MemoryLayout.size) 103 | precondition(MemoryLayout.stride == MemoryLayout.stride) 104 | return dimensions.withUnsafeBufferPointer { dimensions in 105 | dimensions.withMemoryRebound(to: Int64.self) { dimensions in 106 | let unsafeMutable = UnsafeMutablePointer(mutating: dimensions.baseAddress) 107 | return Type( 108 | mlirMemRefTypeContiguousGet( 109 | element.in(context).mlir, 110 | dimensions.count, 111 | unsafeMutable, 112 | memorySpace.in(context).mlir)) 113 | } 114 | } 115 | } 116 | } 117 | extension ContextualType where Self == MemoryReferenceType { 118 | public static func memoryReference( 119 | to element: ContextualType, 120 | withDimensions dimensions: [MemoryReferenceType.Size], 121 | inMemorySpace memorySpace: IntegerAttribute 122 | ) 123 | -> Self 124 | { 125 | MemoryReferenceType(dimensions: dimensions, element: element, memorySpace: memorySpace) 126 | } 127 | } 128 | 129 | // MARK: - Function 130 | 131 | public struct FunctionType: ContextualType { 132 | public let inputs, results: [ContextualType] 133 | 134 | public func `in`(_ context: Context) -> Type { 135 | let c: MlirType = 136 | inputs 137 | .map { $0.in(context) } 138 | .withUnsafeMlirRepresentation { inputs in 139 | results 140 | .map { $0.in(context) } 141 | .withUnsafeMlirRepresentation { results in 142 | mlirFunctionTypeGet( 143 | context.mlir, 144 | inputs.count, inputs.baseAddress, 145 | results.count, results.baseAddress) 146 | } 147 | } 148 | return Type(c) 149 | } 150 | } 151 | extension ContextualType where Self == FunctionType { 152 | public static func function( 153 | of inputs: Inputs, 154 | to results: Results 155 | ) -> Self 156 | where 157 | Inputs: Sequence, 158 | Inputs.Element == ContextualType, 159 | Results: Sequence, 160 | Results.Element == ContextualType 161 | { 162 | FunctionType(inputs: Array(inputs), results: Array(results)) 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Attribute.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | // MARK: - Attribute 4 | 5 | /** 6 | A representation of an MLIR attribute that is independent of a context 7 | */ 8 | public protocol ContextualAttribute { 9 | func `in`(_ context: Context) -> Attribute 10 | } 11 | 12 | /** 13 | A Swift representation of an MLIR attribute 14 | */ 15 | public struct Attribute: ContextualAttribute, MlirRepresentable { 16 | 17 | public init(_ mlir: MlirAttribute) { 18 | self.init(mlir: mlir) 19 | } 20 | public let mlir: MlirAttribute 21 | 22 | /** 23 | Attribute implements `ContextualAttribute`, but requires that `context`be the context owning this type. 24 | */ 25 | public func `in`(_ context: Context) -> Attribute { 26 | precondition(context == self.context) 27 | return self 28 | } 29 | 30 | /** 31 | The context which owns this attribute 32 | */ 33 | public var context: UnownedContext { 34 | UnownedContext(mlirAttributeGetContext(mlir)) 35 | } 36 | 37 | /// Suppress synthesized initializer 38 | private init() { fatalError() } 39 | 40 | } 41 | 42 | // MARK: Equality 43 | 44 | extension Attribute: Equatable { 45 | public static func == (lhs: Attribute, rhs: Attribute) -> Bool { 46 | mlirAttributeEqual(lhs.mlir, rhs.mlir) 47 | } 48 | } 49 | 50 | /** 51 | Attributes can be equated with contextual attributes 52 | 53 | - note: This operation is defined on optionals so we get optional comparisons as well 54 | */ 55 | public func == (lhs: ContextualAttribute?, rhs: Attribute?) -> Bool { 56 | switch (lhs, rhs) { 57 | case (.none, .none): return true 58 | case (.some, .none), (.none, .some): return false 59 | case let (lhs?, rhs?): 60 | return lhs.in(rhs.context) == rhs 61 | } 62 | } 63 | 64 | public func == (lhs: Attribute?, rhs: ContextualAttribute?) -> Bool { 65 | rhs == lhs 66 | } 67 | 68 | // MARK: - Named Attribute 69 | 70 | /** 71 | A representation of an MLIR named attribute that is independent of a context 72 | 73 | - note: Unlike `ContextualType` and `ContextualAttribute`, named attributes are most often just the union of an identifier and an attribute, so we provide a concrete `ContextualNamedAttribute` type to simplify the common case. 74 | */ 75 | public protocol ContextualNamedAttributeProtocol { 76 | func `in`(_ context: Context) -> NamedAttribute 77 | } 78 | 79 | /** 80 | A concrete type for the common case of contextual named attributes 81 | */ 82 | public struct ContextualNamedAttribute: ContextualNamedAttributeProtocol { 83 | public init(name: String, attribute: ContextualAttribute) { 84 | self.name = name 85 | self.attribute = attribute 86 | } 87 | public func `in`(_ context: Context) -> NamedAttribute { 88 | NamedAttribute(name: name, attribute: attribute.in(context)) 89 | } 90 | let name: String 91 | let attribute: ContextualAttribute 92 | } 93 | 94 | /** 95 | Represent an identifier-attribute pair. 96 | 97 | - note: We model this as its own type, and collections of named attributes as arrays of `NamedAttribute`, because often the type of an attribute can be inferred from the identifier which we would not have access to if we represented the collection as a dictionary of attributes. 98 | */ 99 | public struct NamedAttribute: ContextualNamedAttributeProtocol { 100 | 101 | /** 102 | Creates a named attribute from an identifier and an attribute 103 | */ 104 | public init(name: Identifier, attribute: Attribute) { 105 | self.init(mlirNamedAttributeGet(name.mlir, attribute.mlir)) 106 | } 107 | 108 | /** 109 | Creates a named attribute from a string and an attribute 110 | */ 111 | public init(name: String, attribute: Attribute) { 112 | self.init( 113 | name: Identifier(name, in: attribute.context), 114 | attribute: attribute) 115 | } 116 | 117 | /** 118 | Creates a named attribute from an `MlirNamedAttribute` 119 | 120 | - precondition: The attribute must not be null 121 | - precondition: `name` and `attribute` must be in the same context 122 | */ 123 | public init(_ mlir: MlirNamedAttribute) { 124 | precondition(!mlirAttributeIsNull(mlir.attribute)) 125 | self.mlir = mlir 126 | precondition(name.context == attribute.context) 127 | } 128 | public let mlir: MlirNamedAttribute 129 | 130 | /** 131 | - precondition: `context` must be equal to the context which owns this named attribute 132 | */ 133 | public func `in`(_ context: Context) -> NamedAttribute { 134 | precondition(context == self.context) 135 | return self 136 | } 137 | 138 | /** 139 | The context which owns the identifier and attribute comprising `self` 140 | */ 141 | public var context: UnownedContext { 142 | /// This is ensured during initialization 143 | assert(name.context == attribute.context) 144 | return name.context 145 | } 146 | 147 | /** 148 | The name of this named attribute 149 | */ 150 | public var name: Identifier { 151 | Identifier(mlir.name) 152 | } 153 | 154 | /** 155 | The attribute of this named attribute 156 | */ 157 | public var attribute: Attribute { 158 | Attribute(mlir.attribute) 159 | } 160 | } 161 | 162 | extension Array where Element == NamedAttribute { 163 | func withUnsafeMlirRepresentation( 164 | _ body: (UnsafeBufferPointer) throws -> R 165 | ) rethrows -> R { 166 | precondition(MemoryLayout.size == MemoryLayout.size) 167 | precondition(MemoryLayout.stride == MemoryLayout.stride) 168 | precondition( 169 | MemoryLayout.alignment == MemoryLayout.alignment) 170 | return try withUnsafeBufferPointer { buffer in 171 | try buffer.withMemoryRebound(to: MlirNamedAttribute.self, body) 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /Tools/build-dependencies: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ "$VERBOSE" == "true" ]]; then 6 | set -x 7 | fi 8 | 9 | function check_executable { 10 | if ! which "$1" > /dev/null; then 11 | echo "$1 not installed." 12 | exit 1 13 | fi 14 | } 15 | 16 | check_executable git 17 | check_executable cmake 18 | check_executable ninja 19 | 20 | # Configuration 21 | TOOLS_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 22 | PROJECT_ROOT=${PROJECT_ROOT:-$(cd "$TOOLS_ROOT" && cd "$(git rev-parse --show-toplevel)" && pwd)} 23 | DEPENDENCIES_ROOT=${DEPENDENCIES_ROOT:-$PROJECT_ROOT/.dependencies} 24 | INSTALL_PATH=${INSTALL_PATH:-$DEPENDENCIES_ROOT/installed} 25 | LLVM_COMMIT=${LLVM_COMMIT:-$(cat "$TOOLS_ROOT/llvm-commit")} 26 | LLVM_REPO=${LLVM_REPO:-https://github.com/llvm/llvm-project} 27 | LLVM_REPO_PATH=${LLVM_REPO_PATH:-$DEPENDENCIES_ROOT/llvm-repo} 28 | LLVM_PATH_IN_REPO=${LLVM_PATH_IN_REPO:-""} 29 | LLVM_ROOT="$LLVM_REPO_PATH/$LLVM_PATH_IN_REPO" 30 | LLVM_BUILD_ROOT="$DEPENDENCIES_ROOT/llvm-build" 31 | IFS=" " read -r -a LLVM_ADDITIONAL_CMAKE_ARGS_ARRAY <<< "$LLVM_ADDITIONAL_CMAKE_ARGS" 32 | LLVM_SYSTEM_LIBRARY_TARGETS=" 33 | $PROJECT_ROOT/Sources/CDialects 34 | $PROJECT_ROOT/Sources/CMLIR 35 | $LLVM_ADDITIONAL_SYSTEM_LIBRARY_TARGETS" 36 | TOOLS_INSTALL_PATH="$DEPENDENCIES_ROOT/installed/tools" 37 | PKG_CONFIG_PATH=${PKG_CONFIG_PATH:-/usr/local/lib/pkgconfig} 38 | PKG_CONFIG_FILE_PATH="$PKG_CONFIG_PATH/LLVM-for-Swift.pc" 39 | PKG_CONFIG=$(cat << EOF 40 | prefix=$INSTALL_PATH 41 | 42 | Name: LLVM for Swift 43 | Description: LLVM, potentially with additional projects. Installed using Tools/build-dependencies in MLIRSwift. 44 | Version: local 45 | Cflags: -I\${prefix}/include 46 | Libs: -lcurses $( 47 | # For some reason, linking the C++ standard libary is different on Linux and macOS 48 | [[ "$OSTYPE" == "darwin"* ]] && echo "-lc++" || echo "-lstdc++" 49 | ) -L\${prefix}/lib 50 | EOF 51 | ) 52 | 53 | # Create a comma-separated list of external projects 54 | LLVM_EXTERNAL_PROJECTS=$( 55 | delim="" 56 | for TARGET in $(echo " 57 | MLIRSwiftSupport 58 | $LLVM_ADDITIONAL_EXTERNAL_PROJECTS") 59 | do 60 | printf "%s" "$delim$TARGET" 61 | delim="," 62 | done 63 | ) 64 | 65 | # Create a list of install targets with some extra ceremony so they up as a bash array 66 | LLVM_INSTALL_TARGETS=() 67 | for TARGET in $(echo "$( 68 | for SYSTEM_LIBRARY_TARGET in $LLVM_SYSTEM_LIBRARY_TARGETS; do 69 | sed -n 's/link "\(.*\)"/install-\1/p' < "$SYSTEM_LIBRARY_TARGET/module.modulemap" 70 | done; 71 | echo " 72 | install-MLIRSwiftSupport-headers 73 | install-llvm-headers 74 | install-mlir-headers 75 | $LLVM_ADDITIONAL_TARGETS" 76 | )" | xargs | tr ' ' '\n' | sort -u) 77 | do 78 | LLVM_INSTALL_TARGETS+=("$TARGET") 79 | done 80 | 81 | # If shell is interactive, prompt for comfirmation 82 | echo "This script will perform the following tasks:" 83 | if [[ "$LLVM_REPO" != "local" ]]; then 84 | # Invoke with LLVM_REPO="" to skip any repo-management logic 85 | echo " - Checkout commit ${LLVM_COMMIT} from ${LLVM_REPO} to ${LLVM_REPO_PATH}" 86 | fi 87 | echo " - Build LLVM from ${LLVM_ROOT}" 88 | echo " - The following targets will be built:" 89 | for TARGET in "${LLVM_INSTALL_TARGETS[@]}"; do 90 | echo " $TARGET" 91 | done 92 | if [[ ! ${#LLVM_ADDITIONAL_CMAKE_ARGS_ARRAY[@]} -eq 0 ]]; then 93 | echo " - Additional cmake arguments:" 94 | for ARG in "${LLVM_ADDITIONAL_CMAKE_ARGS_ARRAY[@]}"; do 95 | echo " $ARG" 96 | done 97 | fi 98 | echo " - Built products will be placed in ${LLVM_BUILD_ROOT}" 99 | echo " - Install all available LLVM projects to ${INSTALL_PATH}" 100 | echo " - Install necessary tools to ${TOOLS_INSTALL_PATH}" 101 | echo " - Update ${PKG_CONFIG_FILE_PATH} to point to ${INSTALL_PATH}" 102 | echo "" 103 | 104 | if [[ "$NO_INTERACTION" != "true" ]]; then 105 | echo "Press enter to continue." 106 | read -r 107 | fi 108 | 109 | # Clone/checkout LLVM or other another project that includes LLVM 110 | if [[ "$LLVM_REPO" != "local" ]]; then 111 | if [[ ! -d "$LLVM_REPO_PATH/.git" ]]; then 112 | echo "Setting up \"$LLVM_REPO\"" 113 | # Set up repo without cloning 114 | mkdir -p "$LLVM_REPO_PATH" 115 | pushd "$LLVM_REPO_PATH" > /dev/null 116 | git init 117 | git remote add origin "$LLVM_REPO" 118 | popd > /dev/null 119 | fi 120 | # Checkout specified commit 121 | echo "Checking out \"$LLVM_COMMIT\"" 122 | pushd "$LLVM_REPO_PATH" > /dev/null 123 | git fetch origin "$LLVM_COMMIT" 124 | git checkout -f "$LLVM_COMMIT" 125 | # This tool is meant to support repos which include LLVM as a submodule 126 | git submodule update --init 127 | popd > /dev/null 128 | fi 129 | 130 | CMAKE_OSX_DEPLOYMENT_TARGET="" 131 | [[ "$OSTYPE" == "darwin"* ]] && CMAKE_OSX_DEPLOYMENT_TARGET="10.15" 132 | 133 | # Build LLVM 134 | (set -x; cmake \ 135 | -S "$LLVM_ROOT/llvm" \ 136 | -B "$LLVM_BUILD_ROOT" \ 137 | -G Ninja \ 138 | -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" \ 139 | ${CMAKE_OSX_DEPLOYMENT_TARGET:+ "-DCMAKE_OSX_DEPLOYMENT_TARGET=$CMAKE_OSX_DEPLOYMENT_TARGET"} \ 140 | -DCMAKE_C_COMPILER=clang \ 141 | -DCMAKE_CXX_COMPILER=clang++ \ 142 | -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" \ 143 | -DLLVM_BUILD_EXAMPLES=OFF \ 144 | -DLLVM_INSTALL_UTILS=OFF \ 145 | -DLLVM_BUILD_TOOLS=OFF \ 146 | -DLLVM_TARGETS_TO_BUILD=host \ 147 | -DLLVM_ENABLE_PROJECTS=mlir \ 148 | -DLLVM_ENABLE_OCAMLDOC=OFF \ 149 | -DLLVM_ENABLE_BINDINGS=OFF \ 150 | -DLLVM_ENABLE_ASSERTIONS=ON \ 151 | -DLLVM_EXTERNAL_PROJECTS="$LLVM_EXTERNAL_PROJECTS" \ 152 | -DLLVM_EXTERNAL_MLIRSWIFTSUPPORT_SOURCE_DIR="${TOOLS_ROOT}/MLIRSwiftSupport" \ 153 | "${LLVM_ADDITIONAL_CMAKE_ARGS_ARRAY[@]}") 154 | (set -x; cmake \ 155 | --build "$LLVM_BUILD_ROOT" \ 156 | --target "${LLVM_INSTALL_TARGETS[@]}") 157 | 158 | # Install the LLVM package config 159 | if [[ -n "$PKG_CONFIG_FILE_PATH" ]]; then 160 | echo "Writing pkg-config file to $PKG_CONFIG_FILE_PATH" 161 | if ! echo "$PKG_CONFIG" > "$PKG_CONFIG_FILE_PATH"; then 162 | echo "Could not create pkg-config file, please ensure $PKG_CONFIG_FILE_PATH is writable." 163 | exit 1 164 | fi 165 | fi 166 | 167 | # Install swift-format 168 | if [[ ! -f "$TOOLS_INSTALL_PATH/swift-format" ]]; then 169 | echo "Installing swift-format" 170 | # `swift build` doesn't seem to actually build the swift-format executable (likely because it is a dependency), so we use `swift run`. Also, the first invocatin of this fails for some reason in dependent projects. 171 | swift run --package-path "$TOOLS_ROOT/SwiftFormat" -c release swift-format --version || \ 172 | swift run --package-path "$TOOLS_ROOT/SwiftFormat" -c release swift-format --version 173 | mkdir -p "$TOOLS_INSTALL_PATH" 174 | cp "$(swift build --package-path "$TOOLS_ROOT/SwiftFormat" -c release --show-bin-path)/swift-format" "$TOOLS_INSTALL_PATH" 175 | fi 176 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Block Initializers (Generated).swift: -------------------------------------------------------------------------------- 1 | /// This file was autogenerated by running `Tools/generate-boilerplate` 2 | 3 | extension Block { 4 | 5 | /// 0 arguments 6 | public init( 7 | buildOperations: (Block.Operations) throws -> Void 8 | ) rethrows { 9 | self.init(argumentTypes: []) 10 | try buildOperations(operations) 11 | } 12 | 13 | /// 1 arguments 14 | public init( 15 | _ t0: Type, 16 | buildOperations: (Block.Operations, Value) throws -> Void 17 | ) rethrows { 18 | self.init(argumentTypes: [t0]) 19 | try buildOperations(operations, arguments[0]) 20 | } 21 | 22 | /// 1 arguments, contentual types 23 | public init( 24 | _ t0: ContextualType, 25 | in context: Context, 26 | buildOperations: (Block.Operations, Value) throws -> Void 27 | ) rethrows { 28 | self.init(argumentTypes: [t0], in: context) 29 | try buildOperations(operations, arguments[0]) 30 | } 31 | 32 | /// 2 arguments 33 | public init( 34 | _ t0: Type, _ t1: Type, 35 | buildOperations: (Block.Operations, Value, Value) throws -> Void 36 | ) rethrows { 37 | self.init(argumentTypes: [t0, t1]) 38 | try buildOperations(operations, arguments[0], arguments[1]) 39 | } 40 | 41 | /// 2 arguments, contentual types 42 | public init( 43 | _ t0: ContextualType, _ t1: ContextualType, 44 | in context: Context, 45 | buildOperations: (Block.Operations, Value, Value) throws -> Void 46 | ) rethrows { 47 | self.init(argumentTypes: [t0, t1], in: context) 48 | try buildOperations(operations, arguments[0], arguments[1]) 49 | } 50 | 51 | /// 3 arguments 52 | public init( 53 | _ t0: Type, _ t1: Type, _ t2: Type, 54 | buildOperations: (Block.Operations, Value, Value, Value) throws -> Void 55 | ) rethrows { 56 | self.init(argumentTypes: [t0, t1, t2]) 57 | try buildOperations(operations, arguments[0], arguments[1], arguments[2]) 58 | } 59 | 60 | /// 3 arguments, contentual types 61 | public init( 62 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 63 | in context: Context, 64 | buildOperations: (Block.Operations, Value, Value, Value) throws -> Void 65 | ) rethrows { 66 | self.init(argumentTypes: [t0, t1, t2], in: context) 67 | try buildOperations(operations, arguments[0], arguments[1], arguments[2]) 68 | } 69 | 70 | /// 4 arguments 71 | public init( 72 | _ t0: Type, _ t1: Type, _ t2: Type, _ t3: Type, 73 | buildOperations: (Block.Operations, Value, Value, Value, Value) throws -> Void 74 | ) rethrows { 75 | self.init(argumentTypes: [t0, t1, t2, t3]) 76 | try buildOperations(operations, arguments[0], arguments[1], arguments[2], arguments[3]) 77 | } 78 | 79 | /// 4 arguments, contentual types 80 | public init( 81 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, _ t3: ContextualType, 82 | in context: Context, 83 | buildOperations: (Block.Operations, Value, Value, Value, Value) throws -> Void 84 | ) rethrows { 85 | self.init(argumentTypes: [t0, t1, t2, t3], in: context) 86 | try buildOperations(operations, arguments[0], arguments[1], arguments[2], arguments[3]) 87 | } 88 | 89 | /// 5 arguments 90 | public init( 91 | _ t0: Type, _ t1: Type, _ t2: Type, _ t3: Type, _ t4: Type, 92 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value) throws -> Void 93 | ) rethrows { 94 | self.init(argumentTypes: [t0, t1, t2, t3, t4]) 95 | try buildOperations( 96 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]) 97 | } 98 | 99 | /// 5 arguments, contentual types 100 | public init( 101 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, _ t3: ContextualType, 102 | _ t4: ContextualType, 103 | in context: Context, 104 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value) throws -> Void 105 | ) rethrows { 106 | self.init(argumentTypes: [t0, t1, t2, t3, t4], in: context) 107 | try buildOperations( 108 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]) 109 | } 110 | 111 | /// 6 arguments 112 | public init( 113 | _ t0: Type, _ t1: Type, _ t2: Type, _ t3: Type, _ t4: Type, _ t5: Type, 114 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value, Value) throws -> Void 115 | ) rethrows { 116 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5]) 117 | try buildOperations( 118 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5] 119 | ) 120 | } 121 | 122 | /// 6 arguments, contentual types 123 | public init( 124 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, _ t3: ContextualType, 125 | _ t4: ContextualType, _ t5: ContextualType, 126 | in context: Context, 127 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value, Value) throws -> Void 128 | ) rethrows { 129 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5], in: context) 130 | try buildOperations( 131 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5] 132 | ) 133 | } 134 | 135 | /// 7 arguments 136 | public init( 137 | _ t0: Type, _ t1: Type, _ t2: Type, _ t3: Type, _ t4: Type, _ t5: Type, _ t6: Type, 138 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value, Value, Value) throws -> 139 | Void 140 | ) rethrows { 141 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6]) 142 | try buildOperations( 143 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 144 | arguments[5], arguments[6]) 145 | } 146 | 147 | /// 7 arguments, contentual types 148 | public init( 149 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, _ t3: ContextualType, 150 | _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, 151 | in context: Context, 152 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value, Value, Value) throws -> 153 | Void 154 | ) rethrows { 155 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6], in: context) 156 | try buildOperations( 157 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 158 | arguments[5], arguments[6]) 159 | } 160 | 161 | /// 8 arguments 162 | public init( 163 | _ t0: Type, _ t1: Type, _ t2: Type, _ t3: Type, _ t4: Type, _ t5: Type, _ t6: Type, _ t7: Type, 164 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value, Value, Value, Value) 165 | throws -> Void 166 | ) rethrows { 167 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6, t7]) 168 | try buildOperations( 169 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 170 | arguments[5], arguments[6], arguments[7]) 171 | } 172 | 173 | /// 8 arguments, contentual types 174 | public init( 175 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, _ t3: ContextualType, 176 | _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, _ t7: ContextualType, 177 | in context: Context, 178 | buildOperations: (Block.Operations, Value, Value, Value, Value, Value, Value, Value, Value) 179 | throws -> Void 180 | ) rethrows { 181 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6, t7], in: context) 182 | try buildOperations( 183 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 184 | arguments[5], arguments[6], arguments[7]) 185 | } 186 | 187 | /// 9 arguments 188 | public init( 189 | _ t0: Type, _ t1: Type, _ t2: Type, _ t3: Type, _ t4: Type, _ t5: Type, _ t6: Type, _ t7: Type, 190 | _ t8: Type, 191 | buildOperations: ( 192 | Block.Operations, Value, Value, Value, Value, Value, Value, Value, Value, Value 193 | ) throws -> Void 194 | ) rethrows { 195 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6, t7, t8]) 196 | try buildOperations( 197 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 198 | arguments[5], arguments[6], arguments[7], arguments[8]) 199 | } 200 | 201 | /// 9 arguments, contentual types 202 | public init( 203 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, _ t3: ContextualType, 204 | _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, _ t7: ContextualType, 205 | _ t8: ContextualType, 206 | in context: Context, 207 | buildOperations: ( 208 | Block.Operations, Value, Value, Value, Value, Value, Value, Value, Value, Value 209 | ) throws -> Void 210 | ) rethrows { 211 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6, t7, t8], in: context) 212 | try buildOperations( 213 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 214 | arguments[5], arguments[6], arguments[7], arguments[8]) 215 | } 216 | 217 | /// 10 arguments 218 | public init( 219 | _ t0: Type, _ t1: Type, _ t2: Type, _ t3: Type, _ t4: Type, _ t5: Type, _ t6: Type, _ t7: Type, 220 | _ t8: Type, _ t9: Type, 221 | buildOperations: ( 222 | Block.Operations, Value, Value, Value, Value, Value, Value, Value, Value, Value, Value 223 | ) throws -> Void 224 | ) rethrows { 225 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9]) 226 | try buildOperations( 227 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 228 | arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]) 229 | } 230 | 231 | /// 10 arguments, contentual types 232 | public init( 233 | _ t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, _ t3: ContextualType, 234 | _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, _ t7: ContextualType, 235 | _ t8: ContextualType, _ t9: ContextualType, 236 | in context: Context, 237 | buildOperations: ( 238 | Block.Operations, Value, Value, Value, Value, Value, Value, Value, Value, Value, Value 239 | ) throws -> Void 240 | ) rethrows { 241 | self.init(argumentTypes: [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9], in: context) 242 | try buildOperations( 243 | operations, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 244 | arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]) 245 | } 246 | 247 | } 248 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Operation.swift: -------------------------------------------------------------------------------- 1 | import CMLIR 2 | 3 | /** 4 | An operation which has no constraints on its results 5 | */ 6 | public typealias AnyOperation = Operation 7 | 8 | /** 9 | Swift representation of an MLIR Operation 10 | 11 | The generic argument `Results` indicates how the operation should treat its results. 12 | */ 13 | public struct Operation: MlirRepresentable { 14 | 15 | public init(_ mlir: MlirOperation) { 16 | self.init(mlir: mlir) 17 | } 18 | public let mlir: MlirOperation 19 | 20 | /** 21 | - parameter resultTypes: `nil` implies type inference 22 | */ 23 | public init( 24 | _ dialect: Dialect, _ name: String, 25 | attributes: [ContextualNamedAttributeProtocol] = [], 26 | operands: [Value] = [], 27 | resultTypes: [ContextualType]? = [], 28 | ownedRegions: [Region] = [], 29 | location: Location 30 | ) { 31 | self.init( 32 | dialect: dialect as Dialect?, 33 | name: name, 34 | attributes: attributes, 35 | operands: operands, 36 | resultTypes: resultTypes, 37 | ownedRegions: ownedRegions, 38 | location: location) 39 | } 40 | 41 | /** 42 | - parameter resultTypes: `nil` implies type inference 43 | */ 44 | public init( 45 | builtin name: String, 46 | attributes: [ContextualNamedAttributeProtocol] = [], 47 | operands: [Value] = [], 48 | resultTypes: [ContextualType]? = [], 49 | ownedRegions: [Region] = [], 50 | location: Location 51 | ) { 52 | self.init( 53 | dialect: nil, 54 | name: name, 55 | attributes: attributes, 56 | operands: operands, 57 | resultTypes: resultTypes, 58 | ownedRegions: ownedRegions, 59 | location: location) 60 | } 61 | 62 | /** 63 | Returns a new operation with the result type erased 64 | */ 65 | public var typeErased: AnyOperation { 66 | AnyOperation(mlir) 67 | } 68 | 69 | /** 70 | Returns `true` if verification of this operation is successful 71 | */ 72 | public var isValid: Bool { 73 | mlirOperationVerify(mlir) 74 | } 75 | 76 | /** 77 | Returns the operation that owns this operation, if one exists 78 | */ 79 | public var owningOperation: Operation? { 80 | Operation(mlirOperationGetParentOperation(mlir)) 81 | } 82 | 83 | /** 84 | Returns the block that contains this operation, if one exists 85 | */ 86 | public var owningBlock: Block? { 87 | Block(mlirOperationGetBlock(mlir)) 88 | } 89 | 90 | /** 91 | Returns the context associated with this operation 92 | */ 93 | public var context: UnownedContext { 94 | UnownedContext(mlirOperationGetContext(mlir)) 95 | } 96 | 97 | private init( 98 | dialect: Dialect? = nil, 99 | name: String, 100 | attributes: [ContextualNamedAttributeProtocol], 101 | operands: [Value], 102 | resultTypes: [ContextualType]?, 103 | ownedRegions: [Region], 104 | location: Location 105 | ) { 106 | let context = location.context 107 | let qualifiedName: String 108 | if let dialect = dialect { 109 | qualifiedName = "\(dialect.namespace).\(name)" 110 | } else { 111 | qualifiedName = name 112 | } 113 | self.init( 114 | qualifiedName.withUnsafeMlirStringRef { name in 115 | operands.withUnsafeMlirRepresentation { operands in 116 | attributes.map { $0.in(context) }.withUnsafeMlirRepresentation { attributes in 117 | ownedRegions.withUnsafeMlirRepresentation { ownedRegions in 118 | var state = mlirOperationStateGet(name, location.mlir) 119 | mlirOperationStateAddOperands(&state, operands.count, operands.baseAddress) 120 | mlirOperationStateAddAttributes(&state, attributes.count, attributes.baseAddress) 121 | mlirOperationStateAddOwnedRegions( 122 | &state, ownedRegions.count, ownedRegions.baseAddress) 123 | if let resultTypes = resultTypes { 124 | return 125 | resultTypes 126 | .map { $0.in(context) } 127 | .withUnsafeMlirRepresentation { resultTypes in 128 | mlirOperationStateAddResults(&state, resultTypes.count, resultTypes.baseAddress) 129 | return mlirOperationCreate(&state) 130 | } 131 | } else { 132 | mlirOperationStateEnableResultTypeInference(&state) 133 | return mlirOperationCreate(&state) 134 | } 135 | } 136 | } 137 | } 138 | }) 139 | } 140 | } 141 | 142 | // MARK: Attributes 143 | 144 | extension Operation { 145 | public typealias Attributes = _OperationAttributes 146 | public var attributes: Attributes { 147 | Attributes(mlir: mlir) 148 | } 149 | } 150 | 151 | public struct _OperationAttributes { 152 | public subscript(_ name: String) -> Attribute? { 153 | get { 154 | Attribute(name.withUnsafeMlirStringRef { mlirOperationGetAttributeByName(mlir, $0) }) 155 | } 156 | nonmutating set { 157 | name.withUnsafeMlirStringRef { 158 | if let newValue = newValue { 159 | mlirOperationSetAttributeByName(mlir, $0, newValue.mlir) 160 | } else { 161 | mlirOperationRemoveAttributeByName(mlir, $0) 162 | } 163 | } 164 | } 165 | } 166 | public func set(_ namedAttribute: NamedAttribute) { 167 | /// Eventually we may want to expose API in MLIR to do this less circuitously 168 | self[namedAttribute.name.stringValue] = namedAttribute.attribute 169 | } 170 | fileprivate let mlir: MlirOperation 171 | } 172 | 173 | // MARK: Regions 174 | 175 | extension Operation { 176 | public typealias Regions = _OperationRegions 177 | public var regions: Regions { 178 | Regions(mlir: mlir) 179 | } 180 | } 181 | 182 | public struct _OperationRegions: RandomAccessCollection { 183 | public let startIndex = 0 184 | public var endIndex: Int { mlirOperationGetNumRegions(mlir) } 185 | public subscript(position: Int) -> Region { 186 | Region(mlirOperationGetRegion(mlir, position)) 187 | } 188 | fileprivate let mlir: MlirOperation 189 | } 190 | 191 | // MARK: Results 192 | 193 | public struct OperationResults: RandomAccessCollection { 194 | public let startIndex = 0 195 | public var endIndex: Int { mlirOperationGetNumResults(mlir) } 196 | public subscript(position: Int) -> Value { 197 | Value(mlirOperationGetResult(mlir, position)) 198 | } 199 | fileprivate let mlir: MlirOperation 200 | } 201 | 202 | extension AnyOperation { 203 | public var results: Results { 204 | Results(mlir: mlir) 205 | } 206 | } 207 | 208 | public extension Operation { 209 | typealias InferredResultType = _OperationInferredResultType 210 | } 211 | public struct _OperationInferredResultType { 212 | public static let inferred = Self() 213 | 214 | /** 215 | If it becomes interesting, we can implement the following function so we could do partial inference like so: `OperationDefinition(resultTypes: .inferred, .inferred(expecting: .integer(bitWidth: 1))` 216 | ``` 217 | public static func inferred(expecting type: MLIR.`Type`) -> Self { 218 | 219 | } 220 | ``` 221 | */ 222 | } 223 | 224 | // MARK: - Printing with Options 225 | 226 | public enum _OperationDebugInfoStyle: ExpressibleByNilLiteral { 227 | case none 228 | case standard 229 | case pretty 230 | 231 | public init(nilLiteral: ()) { 232 | self = .none 233 | } 234 | } 235 | 236 | extension Operation { 237 | 238 | public typealias DebugInfoStyle = _OperationDebugInfoStyle 239 | 240 | public func withPrintingOptions( 241 | elideElementsAttributesLargerThan: Bool? = nil, 242 | debugInformationStyle: DebugInfoStyle = nil, 243 | alwaysPrintInGenericForm: Bool = false, 244 | useLocalScope: Bool = false 245 | ) -> TextOutputStreamable & CustomStringConvertible { 246 | return OperationWithPrintingOptions( 247 | operation: mlir, 248 | options: .init( 249 | elideElementsAttributesLargerThan: elideElementsAttributesLargerThan, 250 | debugInformationStyle: debugInformationStyle, 251 | alwaysPrintInGenericForm: alwaysPrintInGenericForm, 252 | useLocalScope: useLocalScope)) 253 | } 254 | } 255 | 256 | private struct OperationWithPrintingOptions: TextOutputStreamable, CustomStringConvertible { 257 | 258 | struct PrintingOptions { 259 | var elideElementsAttributesLargerThan: Bool? = nil 260 | var debugInformationStyle: Operation.DebugInfoStyle = nil 261 | var alwaysPrintInGenericForm: Bool = false 262 | var useLocalScope: Bool = false 263 | 264 | func withUnsafeMlirOpPrintingFlags(_ body: (MlirOpPrintingFlags) -> Void) { 265 | let c = mlirOpPrintingFlagsCreate() 266 | if let value = elideElementsAttributesLargerThan { 267 | mlirOpPrintingFlagsEnableDebugInfo(c, value) 268 | } 269 | switch debugInformationStyle { 270 | case .none: 271 | break 272 | case .standard: 273 | mlirOpPrintingFlagsEnableDebugInfo(c, false) 274 | case .pretty: 275 | mlirOpPrintingFlagsEnableDebugInfo(c, true) 276 | } 277 | if alwaysPrintInGenericForm { 278 | mlirOpPrintingFlagsPrintGenericOpForm(c) 279 | } 280 | if useLocalScope { 281 | mlirOpPrintingFlagsUseLocalScope(c) 282 | } 283 | body(c) 284 | mlirOpPrintingFlagsDestroy(c) 285 | } 286 | } 287 | 288 | func write(to target: inout Target) { 289 | options.withUnsafeMlirOpPrintingFlags { flags in 290 | target.write { mlirOperationPrintWithFlags(operation, flags, $0, $1) } 291 | } 292 | } 293 | var description: String { 294 | "\(self)" 295 | } 296 | 297 | fileprivate let operation: MlirOperation 298 | fileprivate let options: PrintingOptions 299 | } 300 | 301 | // MARK: - Zero Result Operations 302 | 303 | extension Operation where Results == () { 304 | 305 | public init( 306 | _ dialect: Dialect, _ name: String, 307 | attributes: [ContextualNamedAttributeProtocol] = [], 308 | operands: [Value] = [], 309 | ownedRegions: [Region] = [], 310 | location: Location 311 | ) { 312 | self.init( 313 | dialect: dialect, 314 | name: name, 315 | attributes: attributes, 316 | operands: operands, 317 | resultTypes: [], 318 | ownedRegions: ownedRegions, 319 | location: location) 320 | } 321 | 322 | } 323 | 324 | // MARK: - Single Result Operations 325 | 326 | extension Operation where Results == (Value) { 327 | 328 | public init( 329 | _ dialect: Dialect, _ name: String, 330 | attributes: [ContextualNamedAttributeProtocol] = [], 331 | operands: [Value] = [], 332 | resultType type: ContextualType, 333 | ownedRegions: [Region] = [], 334 | location: Location 335 | ) { 336 | self.init( 337 | dialect: dialect, 338 | name: name, 339 | attributes: attributes, 340 | operands: operands, 341 | resultTypes: [type], 342 | ownedRegions: ownedRegions, 343 | location: location) 344 | } 345 | 346 | public init( 347 | _ dialect: Dialect, _ name: String, 348 | attributes: [ContextualNamedAttributeProtocol] = [], 349 | operands: [Value] = [], 350 | resultType _: Self.InferredResultType, 351 | ownedRegions: [Region] = [], 352 | location: Location 353 | ) { 354 | self.init( 355 | dialect: dialect, 356 | name: name, 357 | attributes: attributes, 358 | operands: operands, 359 | resultTypes: nil, 360 | ownedRegions: ownedRegions, 361 | location: location) 362 | } 363 | 364 | public var results: Results { 365 | let results = typeErased.results 366 | precondition(results.count == 1) 367 | return results[0] 368 | } 369 | 370 | } 371 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | MLIRSwift is under the Apache License v2.0 with LLVM Exceptions: 3 | ============================================================================== 4 | 5 | Apache License 6 | Version 2.0, January 2004 7 | http://www.apache.org/licenses/ 8 | 9 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 10 | 11 | 1. Definitions. 12 | 13 | "License" shall mean the terms and conditions for use, reproduction, 14 | and distribution as defined by Sections 1 through 9 of this document. 15 | 16 | "Licensor" shall mean the copyright owner or entity authorized by 17 | the copyright owner that is granting the License. 18 | 19 | "Legal Entity" shall mean the union of the acting entity and all 20 | other entities that control, are controlled by, or are under common 21 | control with that entity. For the purposes of this definition, 22 | "control" means (i) the power, direct or indirect, to cause the 23 | direction or management of such entity, whether by contract or 24 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 25 | outstanding shares, or (iii) beneficial ownership of such entity. 26 | 27 | "You" (or "Your") shall mean an individual or Legal Entity 28 | exercising permissions granted by this License. 29 | 30 | "Source" form shall mean the preferred form for making modifications, 31 | including but not limited to software source code, documentation 32 | source, and configuration files. 33 | 34 | "Object" form shall mean any form resulting from mechanical 35 | transformation or translation of a Source form, including but 36 | not limited to compiled object code, generated documentation, 37 | and conversions to other media types. 38 | 39 | "Work" shall mean the work of authorship, whether in Source or 40 | Object form, made available under the License, as indicated by a 41 | copyright notice that is included in or attached to the work 42 | (an example is provided in the Appendix below). 43 | 44 | "Derivative Works" shall mean any work, whether in Source or Object 45 | form, that is based on (or derived from) the Work and for which the 46 | editorial revisions, annotations, elaborations, or other modifications 47 | represent, as a whole, an original work of authorship. For the purposes 48 | of this License, Derivative Works shall not include works that remain 49 | separable from, or merely link (or bind by name) to the interfaces of, 50 | the Work and Derivative Works thereof. 51 | 52 | "Contribution" shall mean any work of authorship, including 53 | the original version of the Work and any modifications or additions 54 | to that Work or Derivative Works thereof, that is intentionally 55 | submitted to Licensor for inclusion in the Work by the copyright owner 56 | or by an individual or Legal Entity authorized to submit on behalf of 57 | the copyright owner. For the purposes of this definition, "submitted" 58 | means any form of electronic, verbal, or written communication sent 59 | to the Licensor or its representatives, including but not limited to 60 | communication on electronic mailing lists, source code control systems, 61 | and issue tracking systems that are managed by, or on behalf of, the 62 | Licensor for the purpose of discussing and improving the Work, but 63 | excluding communication that is conspicuously marked or otherwise 64 | designated in writing by the copyright owner as "Not a Contribution." 65 | 66 | "Contributor" shall mean Licensor and any individual or Legal Entity 67 | on behalf of whom a Contribution has been received by Licensor and 68 | subsequently incorporated within the Work. 69 | 70 | 2. Grant of Copyright License. Subject to the terms and conditions of 71 | this License, each Contributor hereby grants to You a perpetual, 72 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 73 | copyright license to reproduce, prepare Derivative Works of, 74 | publicly display, publicly perform, sublicense, and distribute the 75 | Work and such Derivative Works in Source or Object form. 76 | 77 | 3. Grant of Patent License. Subject to the terms and conditions of 78 | this License, each Contributor hereby grants to You a perpetual, 79 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 80 | (except as stated in this section) patent license to make, have made, 81 | use, offer to sell, sell, import, and otherwise transfer the Work, 82 | where such license applies only to those patent claims licensable 83 | by such Contributor that are necessarily infringed by their 84 | Contribution(s) alone or by combination of their Contribution(s) 85 | with the Work to which such Contribution(s) was submitted. If You 86 | institute patent litigation against any entity (including a 87 | cross-claim or counterclaim in a lawsuit) alleging that the Work 88 | or a Contribution incorporated within the Work constitutes direct 89 | or contributory patent infringement, then any patent licenses 90 | granted to You under this License for that Work shall terminate 91 | as of the date such litigation is filed. 92 | 93 | 4. Redistribution. You may reproduce and distribute copies of the 94 | Work or Derivative Works thereof in any medium, with or without 95 | modifications, and in Source or Object form, provided that You 96 | meet the following conditions: 97 | 98 | (a) You must give any other recipients of the Work or 99 | Derivative Works a copy of this License; and 100 | 101 | (b) You must cause any modified files to carry prominent notices 102 | stating that You changed the files; and 103 | 104 | (c) You must retain, in the Source form of any Derivative Works 105 | that You distribute, all copyright, patent, trademark, and 106 | attribution notices from the Source form of the Work, 107 | excluding those notices that do not pertain to any part of 108 | the Derivative Works; and 109 | 110 | (d) If the Work includes a "NOTICE" text file as part of its 111 | distribution, then any Derivative Works that You distribute must 112 | include a readable copy of the attribution notices contained 113 | within such NOTICE file, excluding those notices that do not 114 | pertain to any part of the Derivative Works, in at least one 115 | of the following places: within a NOTICE text file distributed 116 | as part of the Derivative Works; within the Source form or 117 | documentation, if provided along with the Derivative Works; or, 118 | within a display generated by the Derivative Works, if and 119 | wherever such third-party notices normally appear. The contents 120 | of the NOTICE file are for informational purposes only and 121 | do not modify the License. You may add Your own attribution 122 | notices within Derivative Works that You distribute, alongside 123 | or as an addendum to the NOTICE text from the Work, provided 124 | that such additional attribution notices cannot be construed 125 | as modifying the License. 126 | 127 | You may add Your own copyright statement to Your modifications and 128 | may provide additional or different license terms and conditions 129 | for use, reproduction, or distribution of Your modifications, or 130 | for any such Derivative Works as a whole, provided Your use, 131 | reproduction, and distribution of the Work otherwise complies with 132 | the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, 135 | any Contribution intentionally submitted for inclusion in the Work 136 | by You to the Licensor shall be under the terms and conditions of 137 | this License, without any additional terms or conditions. 138 | Notwithstanding the above, nothing herein shall supersede or modify 139 | the terms of any separate license agreement you may have executed 140 | with Licensor regarding such Contributions. 141 | 142 | 6. Trademarks. This License does not grant permission to use the trade 143 | names, trademarks, service marks, or product names of the Licensor, 144 | except as required for reasonable and customary use in describing the 145 | origin of the Work and reproducing the content of the NOTICE file. 146 | 147 | 7. Disclaimer of Warranty. Unless required by applicable law or 148 | agreed to in writing, Licensor provides the Work (and each 149 | Contributor provides its Contributions) on an "AS IS" BASIS, 150 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 151 | implied, including, without limitation, any warranties or conditions 152 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 153 | PARTICULAR PURPOSE. You are solely responsible for determining the 154 | appropriateness of using or redistributing the Work and assume any 155 | risks associated with Your exercise of permissions under this License. 156 | 157 | 8. Limitation of Liability. In no event and under no legal theory, 158 | whether in tort (including negligence), contract, or otherwise, 159 | unless required by applicable law (such as deliberate and grossly 160 | negligent acts) or agreed to in writing, shall any Contributor be 161 | liable to You for damages, including any direct, indirect, special, 162 | incidental, or consequential damages of any character arising as a 163 | result of this License or out of the use or inability to use the 164 | Work (including but not limited to damages for loss of goodwill, 165 | work stoppage, computer failure or malfunction, or any and all 166 | other commercial damages or losses), even if such Contributor 167 | has been advised of the possibility of such damages. 168 | 169 | 9. Accepting Warranty or Additional Liability. While redistributing 170 | the Work or Derivative Works thereof, You may choose to offer, 171 | and charge a fee for, acceptance of support, warranty, indemnity, 172 | or other liability obligations and/or rights consistent with this 173 | License. However, in accepting such obligations, You may act only 174 | on Your own behalf and on Your sole responsibility, not on behalf 175 | of any other Contributor, and only if You agree to indemnify, 176 | defend, and hold each Contributor harmless for any liability 177 | incurred by, or claims asserted against, such Contributor by reason 178 | of your accepting any such warranty or additional liability. 179 | 180 | END OF TERMS AND CONDITIONS 181 | 182 | APPENDIX: How to apply the Apache License to your work. 183 | 184 | To apply the Apache License to your work, attach the following 185 | boilerplate notice, with the fields enclosed by brackets "[]" 186 | replaced with your own identifying information. (Don't include 187 | the brackets!) The text should be enclosed in the appropriate 188 | comment syntax for the file format. We also recommend that a 189 | file or class name and description of purpose be included on the 190 | same "printed page" as the copyright notice for easier 191 | identification within third-party archives. 192 | 193 | Copyright 2021 SiFive 194 | 195 | Licensed under the Apache License, Version 2.0 (the "License"); 196 | you may not use this file except in compliance with the License. 197 | You may obtain a copy of the License at 198 | 199 | http://www.apache.org/licenses/LICENSE-2.0 200 | 201 | Unless required by applicable law or agreed to in writing, software 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 204 | See the License for the specific language governing permissions and 205 | limitations under the License. 206 | 207 | 208 | ---- LLVM Exceptions to the Apache 2.0 License ---- 209 | 210 | As an exception, if, as a result of your compiling your source code, portions 211 | of this Software are embedded into an Object form of such source code, you 212 | may redistribute such embedded portions in such Object form without complying 213 | with the conditions of Sections 4(a), 4(b) and 4(d) of the License. 214 | 215 | In addition, if you combine or link compiled forms of this Software with 216 | software that is licensed under the GPLv2 ("Combined Software") and if a 217 | court of competent jurisdiction determines that the patent provision (Section 218 | 3), the indemnity provision (Section 9) or other Section of the License 219 | conflicts with the conditions of the GPLv2, you may retroactively and 220 | prospectively choose to deem waived or otherwise exclude such Section(s) of 221 | the License, but only in their entirety and only with respect to the Combined 222 | Software. 223 | -------------------------------------------------------------------------------- /Sources/MLIR/IR/Operation Extensions (Generated).swift: -------------------------------------------------------------------------------- 1 | /// This file was autogenerated by running `Tools/generate-boilerplate` 2 | 3 | // 2 results 4 | extension Operation where Results == (Value, Value) { 5 | 6 | public init( 7 | _ dialect: Dialect, _ name: String, 8 | attributes: [NamedAttribute] = [], 9 | operands: [Value] = [], 10 | resultTypes t0: ContextualType, _ t1: ContextualType, 11 | ownedRegions: [Region] = [], 12 | location: Location 13 | ) { 14 | self.init( 15 | dialect, name, 16 | attributes: attributes, 17 | operands: operands, 18 | resultTypes: [t0, t1], 19 | ownedRegions: ownedRegions, 20 | location: location) 21 | } 22 | 23 | public init( 24 | _ dialect: Dialect, _ name: String, 25 | attributes: [NamedAttribute] = [], 26 | operands: [Value] = [], 27 | resultTypes _: InferredResultType, _: InferredResultType, 28 | ownedRegions: [Region] = [], 29 | location: Location 30 | ) { 31 | self.init( 32 | dialect, name, 33 | attributes: attributes, 34 | operands: operands, 35 | resultTypes: nil, 36 | ownedRegions: ownedRegions, 37 | location: location) 38 | } 39 | 40 | public var results: Results { 41 | let results = typeErased.results 42 | precondition(results.count == 2) 43 | return (results[0], results[1]) 44 | } 45 | 46 | } 47 | 48 | // 3 results 49 | extension Operation where Results == (Value, Value, Value) { 50 | 51 | public init( 52 | _ dialect: Dialect, _ name: String, 53 | attributes: [NamedAttribute] = [], 54 | operands: [Value] = [], 55 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 56 | ownedRegions: [Region] = [], 57 | location: Location 58 | ) { 59 | self.init( 60 | dialect, name, 61 | attributes: attributes, 62 | operands: operands, 63 | resultTypes: [t0, t1, t2], 64 | ownedRegions: ownedRegions, 65 | location: location) 66 | } 67 | 68 | public init( 69 | _ dialect: Dialect, _ name: String, 70 | attributes: [NamedAttribute] = [], 71 | operands: [Value] = [], 72 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 73 | ownedRegions: [Region] = [], 74 | location: Location 75 | ) { 76 | self.init( 77 | dialect, name, 78 | attributes: attributes, 79 | operands: operands, 80 | resultTypes: nil, 81 | ownedRegions: ownedRegions, 82 | location: location) 83 | } 84 | 85 | public var results: Results { 86 | let results = typeErased.results 87 | precondition(results.count == 3) 88 | return (results[0], results[1], results[2]) 89 | } 90 | 91 | } 92 | 93 | // 4 results 94 | extension Operation where Results == (Value, Value, Value, Value) { 95 | 96 | public init( 97 | _ dialect: Dialect, _ name: String, 98 | attributes: [NamedAttribute] = [], 99 | operands: [Value] = [], 100 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 101 | _ t3: ContextualType, 102 | ownedRegions: [Region] = [], 103 | location: Location 104 | ) { 105 | self.init( 106 | dialect, name, 107 | attributes: attributes, 108 | operands: operands, 109 | resultTypes: [t0, t1, t2, t3], 110 | ownedRegions: ownedRegions, 111 | location: location) 112 | } 113 | 114 | public init( 115 | _ dialect: Dialect, _ name: String, 116 | attributes: [NamedAttribute] = [], 117 | operands: [Value] = [], 118 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 119 | _: InferredResultType, 120 | ownedRegions: [Region] = [], 121 | location: Location 122 | ) { 123 | self.init( 124 | dialect, name, 125 | attributes: attributes, 126 | operands: operands, 127 | resultTypes: nil, 128 | ownedRegions: ownedRegions, 129 | location: location) 130 | } 131 | 132 | public var results: Results { 133 | let results = typeErased.results 134 | precondition(results.count == 4) 135 | return (results[0], results[1], results[2], results[3]) 136 | } 137 | 138 | } 139 | 140 | // 5 results 141 | extension Operation where Results == (Value, Value, Value, Value, Value) { 142 | 143 | public init( 144 | _ dialect: Dialect, _ name: String, 145 | attributes: [NamedAttribute] = [], 146 | operands: [Value] = [], 147 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 148 | _ t3: ContextualType, _ t4: ContextualType, 149 | ownedRegions: [Region] = [], 150 | location: Location 151 | ) { 152 | self.init( 153 | dialect, name, 154 | attributes: attributes, 155 | operands: operands, 156 | resultTypes: [t0, t1, t2, t3, t4], 157 | ownedRegions: ownedRegions, 158 | location: location) 159 | } 160 | 161 | public init( 162 | _ dialect: Dialect, _ name: String, 163 | attributes: [NamedAttribute] = [], 164 | operands: [Value] = [], 165 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 166 | _: InferredResultType, _: InferredResultType, 167 | ownedRegions: [Region] = [], 168 | location: Location 169 | ) { 170 | self.init( 171 | dialect, name, 172 | attributes: attributes, 173 | operands: operands, 174 | resultTypes: nil, 175 | ownedRegions: ownedRegions, 176 | location: location) 177 | } 178 | 179 | public var results: Results { 180 | let results = typeErased.results 181 | precondition(results.count == 5) 182 | return (results[0], results[1], results[2], results[3], results[4]) 183 | } 184 | 185 | } 186 | 187 | // 6 results 188 | extension Operation where Results == (Value, Value, Value, Value, Value, Value) { 189 | 190 | public init( 191 | _ dialect: Dialect, _ name: String, 192 | attributes: [NamedAttribute] = [], 193 | operands: [Value] = [], 194 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 195 | _ t3: ContextualType, _ t4: ContextualType, _ t5: ContextualType, 196 | ownedRegions: [Region] = [], 197 | location: Location 198 | ) { 199 | self.init( 200 | dialect, name, 201 | attributes: attributes, 202 | operands: operands, 203 | resultTypes: [t0, t1, t2, t3, t4, t5], 204 | ownedRegions: ownedRegions, 205 | location: location) 206 | } 207 | 208 | public init( 209 | _ dialect: Dialect, _ name: String, 210 | attributes: [NamedAttribute] = [], 211 | operands: [Value] = [], 212 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 213 | _: InferredResultType, _: InferredResultType, _: InferredResultType, 214 | ownedRegions: [Region] = [], 215 | location: Location 216 | ) { 217 | self.init( 218 | dialect, name, 219 | attributes: attributes, 220 | operands: operands, 221 | resultTypes: nil, 222 | ownedRegions: ownedRegions, 223 | location: location) 224 | } 225 | 226 | public var results: Results { 227 | let results = typeErased.results 228 | precondition(results.count == 6) 229 | return (results[0], results[1], results[2], results[3], results[4], results[5]) 230 | } 231 | 232 | } 233 | 234 | // 7 results 235 | extension Operation where Results == (Value, Value, Value, Value, Value, Value, Value) { 236 | 237 | public init( 238 | _ dialect: Dialect, _ name: String, 239 | attributes: [NamedAttribute] = [], 240 | operands: [Value] = [], 241 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 242 | _ t3: ContextualType, _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, 243 | ownedRegions: [Region] = [], 244 | location: Location 245 | ) { 246 | self.init( 247 | dialect, name, 248 | attributes: attributes, 249 | operands: operands, 250 | resultTypes: [t0, t1, t2, t3, t4, t5, t6], 251 | ownedRegions: ownedRegions, 252 | location: location) 253 | } 254 | 255 | public init( 256 | _ dialect: Dialect, _ name: String, 257 | attributes: [NamedAttribute] = [], 258 | operands: [Value] = [], 259 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 260 | _: InferredResultType, _: InferredResultType, _: InferredResultType, _: InferredResultType, 261 | ownedRegions: [Region] = [], 262 | location: Location 263 | ) { 264 | self.init( 265 | dialect, name, 266 | attributes: attributes, 267 | operands: operands, 268 | resultTypes: nil, 269 | ownedRegions: ownedRegions, 270 | location: location) 271 | } 272 | 273 | public var results: Results { 274 | let results = typeErased.results 275 | precondition(results.count == 7) 276 | return (results[0], results[1], results[2], results[3], results[4], results[5], results[6]) 277 | } 278 | 279 | } 280 | 281 | // 8 results 282 | extension Operation where Results == (Value, Value, Value, Value, Value, Value, Value, Value) { 283 | 284 | public init( 285 | _ dialect: Dialect, _ name: String, 286 | attributes: [NamedAttribute] = [], 287 | operands: [Value] = [], 288 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 289 | _ t3: ContextualType, _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, 290 | _ t7: ContextualType, 291 | ownedRegions: [Region] = [], 292 | location: Location 293 | ) { 294 | self.init( 295 | dialect, name, 296 | attributes: attributes, 297 | operands: operands, 298 | resultTypes: [t0, t1, t2, t3, t4, t5, t6, t7], 299 | ownedRegions: ownedRegions, 300 | location: location) 301 | } 302 | 303 | public init( 304 | _ dialect: Dialect, _ name: String, 305 | attributes: [NamedAttribute] = [], 306 | operands: [Value] = [], 307 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 308 | _: InferredResultType, _: InferredResultType, _: InferredResultType, _: InferredResultType, 309 | _: InferredResultType, 310 | ownedRegions: [Region] = [], 311 | location: Location 312 | ) { 313 | self.init( 314 | dialect, name, 315 | attributes: attributes, 316 | operands: operands, 317 | resultTypes: nil, 318 | ownedRegions: ownedRegions, 319 | location: location) 320 | } 321 | 322 | public var results: Results { 323 | let results = typeErased.results 324 | precondition(results.count == 8) 325 | return ( 326 | results[0], results[1], results[2], results[3], results[4], results[5], results[6], results[7] 327 | ) 328 | } 329 | 330 | } 331 | 332 | // 9 results 333 | extension Operation 334 | where Results == (Value, Value, Value, Value, Value, Value, Value, Value, Value) { 335 | 336 | public init( 337 | _ dialect: Dialect, _ name: String, 338 | attributes: [NamedAttribute] = [], 339 | operands: [Value] = [], 340 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 341 | _ t3: ContextualType, _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, 342 | _ t7: ContextualType, _ t8: ContextualType, 343 | ownedRegions: [Region] = [], 344 | location: Location 345 | ) { 346 | self.init( 347 | dialect, name, 348 | attributes: attributes, 349 | operands: operands, 350 | resultTypes: [t0, t1, t2, t3, t4, t5, t6, t7, t8], 351 | ownedRegions: ownedRegions, 352 | location: location) 353 | } 354 | 355 | public init( 356 | _ dialect: Dialect, _ name: String, 357 | attributes: [NamedAttribute] = [], 358 | operands: [Value] = [], 359 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 360 | _: InferredResultType, _: InferredResultType, _: InferredResultType, _: InferredResultType, 361 | _: InferredResultType, _: InferredResultType, 362 | ownedRegions: [Region] = [], 363 | location: Location 364 | ) { 365 | self.init( 366 | dialect, name, 367 | attributes: attributes, 368 | operands: operands, 369 | resultTypes: nil, 370 | ownedRegions: ownedRegions, 371 | location: location) 372 | } 373 | 374 | public var results: Results { 375 | let results = typeErased.results 376 | precondition(results.count == 9) 377 | return ( 378 | results[0], results[1], results[2], results[3], results[4], results[5], results[6], 379 | results[7], results[8] 380 | ) 381 | } 382 | 383 | } 384 | 385 | // 10 results 386 | extension Operation 387 | where Results == (Value, Value, Value, Value, Value, Value, Value, Value, Value, Value) { 388 | 389 | public init( 390 | _ dialect: Dialect, _ name: String, 391 | attributes: [NamedAttribute] = [], 392 | operands: [Value] = [], 393 | resultTypes t0: ContextualType, _ t1: ContextualType, _ t2: ContextualType, 394 | _ t3: ContextualType, _ t4: ContextualType, _ t5: ContextualType, _ t6: ContextualType, 395 | _ t7: ContextualType, _ t8: ContextualType, _ t9: ContextualType, 396 | ownedRegions: [Region] = [], 397 | location: Location 398 | ) { 399 | self.init( 400 | dialect, name, 401 | attributes: attributes, 402 | operands: operands, 403 | resultTypes: [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9], 404 | ownedRegions: ownedRegions, 405 | location: location) 406 | } 407 | 408 | public init( 409 | _ dialect: Dialect, _ name: String, 410 | attributes: [NamedAttribute] = [], 411 | operands: [Value] = [], 412 | resultTypes _: InferredResultType, _: InferredResultType, _: InferredResultType, 413 | _: InferredResultType, _: InferredResultType, _: InferredResultType, _: InferredResultType, 414 | _: InferredResultType, _: InferredResultType, _: InferredResultType, 415 | ownedRegions: [Region] = [], 416 | location: Location 417 | ) { 418 | self.init( 419 | dialect, name, 420 | attributes: attributes, 421 | operands: operands, 422 | resultTypes: nil, 423 | ownedRegions: ownedRegions, 424 | location: location) 425 | } 426 | 427 | public var results: Results { 428 | let results = typeErased.results 429 | precondition(results.count == 10) 430 | return ( 431 | results[0], results[1], results[2], results[3], results[4], results[5], results[6], 432 | results[7], results[8], results[9] 433 | ) 434 | } 435 | 436 | } 437 | --------------------------------------------------------------------------------