Mercurial > hg > CbC > CbC_llvm
comparison mlir/docs/ConversionToLLVMDialect.md @ 173:0572611fdcc8 llvm10 llvm12
reorgnization done
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 11:55:54 +0900 |
parents | 1d019706d866 |
children | 2e18cbf3894f |
comparison
equal
deleted
inserted
replaced
172:9fbae9c8bf63 | 173:0572611fdcc8 |
---|---|
1 # Conversion to the LLVM Dialect | 1 # Conversion to the LLVM Dialect |
2 | 2 |
3 Conversion from the Standard to the [LLVM Dialect](Dialects/LLVM.md) can be | 3 Conversion from the Standard to the [LLVM Dialect](Dialects/LLVM.md) can be |
4 performed by the specialized dialect conversion pass by running | 4 performed by the specialized dialect conversion pass by running: |
5 | 5 |
6 ```shell | 6 ```shell |
7 mlir-opt -convert-std-to-llvm <filename.mlir> | 7 mlir-opt -convert-std-to-llvm <filename.mlir> |
8 ``` | 8 ``` |
9 | 9 |
17 ## Type Conversion | 17 ## Type Conversion |
18 | 18 |
19 ### Scalar Types | 19 ### Scalar Types |
20 | 20 |
21 Scalar types are converted to their LLVM counterparts if they exist. The | 21 Scalar types are converted to their LLVM counterparts if they exist. The |
22 following conversions are currently implemented. | 22 following conversions are currently implemented: |
23 | 23 |
24 - `i*` converts to `!llvm.i*` | 24 - `i*` converts to `!llvm.i*` |
25 - `f16` converts to `!llvm.half` | 25 - `f16` converts to `!llvm.half` |
26 - `f32` converts to `!llvm.float` | 26 - `f32` converts to `!llvm.float` |
27 - `f64` converts to `!llvm.double` | 27 - `f64` converts to `!llvm.double` |
50 | 50 |
51 ### Memref Types | 51 ### Memref Types |
52 | 52 |
53 Memref types in MLIR have both static and dynamic information associated with | 53 Memref types in MLIR have both static and dynamic information associated with |
54 them. The dynamic information comprises the buffer pointer as well as sizes and | 54 them. The dynamic information comprises the buffer pointer as well as sizes and |
55 strides of any dynamically sized dimensions. Memref types are normalized and | 55 strides of any dynamically-sized dimensions. Memref types are normalized and |
56 converted to a descriptor that is only dependent on the rank of the memref. The | 56 converted to a descriptor that is only dependent on the rank of the memref. The |
57 descriptor contains: | 57 descriptor contains: |
58 | 58 |
59 1. the pointer to the data buffer, followed by | 59 1. the pointer to the data buffer, followed by |
60 2. the pointer to properly aligned data payload that the memref indexes, | 60 2. the pointer to properly aligned data payload that the memref indexes, |
88 | 88 |
89 // Memref types can have vectors as element types | 89 // Memref types can have vectors as element types |
90 memref<1x? x vector<4xf32>> -> !llvm<"{ <4 x float>*, <4 x float>*, i64, [1 x i64], [1 x i64] }"> | 90 memref<1x? x vector<4xf32>> -> !llvm<"{ <4 x float>*, <4 x float>*, i64, [1 x i64], [1 x i64] }"> |
91 ``` | 91 ``` |
92 | 92 |
93 If the rank of the memref is unknown at compile time, the Memref is converted to | 93 If the rank of the memref is unknown at compile time, the memref is converted to |
94 an unranked descriptor that contains: | 94 an unranked descriptor that contains: |
95 | 95 |
96 1. a 64-bit integer representing the dynamic rank of the memref, followed by | 96 1. a 64-bit integer representing the dynamic rank of the memref, followed by |
97 2. a pointer to a ranked memref descriptor with the contents listed above. | 97 2. a pointer to a ranked memref descriptor with the contents listed above. |
98 | 98 |
126 individually according to these rules. The result types need to accommodate the | 126 individually according to these rules. The result types need to accommodate the |
127 fact that LLVM IR functions always have a return type, which may be a Void type. | 127 fact that LLVM IR functions always have a return type, which may be a Void type. |
128 The converted function always has a single result type. If the original function | 128 The converted function always has a single result type. If the original function |
129 type had no results, the converted function will have one result of the wrapped | 129 type had no results, the converted function will have one result of the wrapped |
130 `void` type. If the original function type had one result, the converted | 130 `void` type. If the original function type had one result, the converted |
131 function will have one result converted using these rules. Otherwise, the result | 131 function will also have one result converted using these rules. Otherwise, the result |
132 type will be a wrapped LLVM IR structure type where each element of the | 132 type will be a wrapped LLVM IR structure type where each element of the |
133 structure corresponds to one of the results of the original function, converted | 133 structure corresponds to one of the results of the original function, converted |
134 using these rules. In high-order functions, function-typed arguments and results | 134 using these rules. In high-order functions, function-typed arguments and results |
135 are converted to a wrapped LLVM IR function pointer type (since LLVM IR does not | 135 are converted to a wrapped LLVM IR function pointer type (since LLVM IR does not |
136 allow passing functions to functions without indirection) with the pointee type | 136 allow passing functions to functions without indirection) with the pointee type |
372 *This convention may or may not apply if the conversion of MemRef types is | 372 *This convention may or may not apply if the conversion of MemRef types is |
373 overridden by the user.* | 373 overridden by the user.* |
374 | 374 |
375 ### C-compatible wrapper emission | 375 ### C-compatible wrapper emission |
376 | 376 |
377 In practical cases, it may be desirable to have externally-facing functions | 377 In practical cases, it may be desirable to have externally-facing functions with |
378 with a single attribute corresponding to a MemRef argument. When interfacing | 378 a single attribute corresponding to a MemRef argument. When interfacing with |
379 with LLVM IR produced from C, the code needs to respect the corresponding | 379 LLVM IR produced from C, the code needs to respect the corresponding calling |
380 calling convention. The conversion to the LLVM dialect provides an option to | 380 convention. The conversion to the LLVM dialect provides an option to generate |
381 generate wrapper functions that take memref descriptors as pointers-to-struct | 381 wrapper functions that take memref descriptors as pointers-to-struct compatible |
382 compatible with data types produced by Clang when compiling C sources. | 382 with data types produced by Clang when compiling C sources. The generation of |
383 such wrapper functions can additionally be controlled at a function granularity | |
384 by setting the `llvm.emit_c_interface` unit attribute. | |
383 | 385 |
384 More specifically, a memref argument is converted into a pointer-to-struct | 386 More specifically, a memref argument is converted into a pointer-to-struct |
385 argument of type `{T*, T*, i64, i64[N], i64[N]}*` in the wrapper function, where | 387 argument of type `{T*, T*, i64, i64[N], i64[N]}*` in the wrapper function, where |
386 `T` is the converted element type and `N` is the memref rank. This type is | 388 `T` is the converted element type and `N` is the memref rank. This type is |
387 compatible with that produced by Clang for the following C++ structure template | 389 compatible with that produced by Clang for the following C++ structure template |
392 struct MemRefDescriptor { | 394 struct MemRefDescriptor { |
393 T *allocated; | 395 T *allocated; |
394 T *aligned; | 396 T *aligned; |
395 intptr_t offset; | 397 intptr_t offset; |
396 intptr_t sizes[N]; | 398 intptr_t sizes[N]; |
397 intptr_t stides[N]; | 399 intptr_t strides[N]; |
398 }; | 400 }; |
399 ``` | 401 ``` |
400 | 402 |
401 If enabled, the option will do the following. For _external_ functions declared | 403 If enabled, the option will do the following. For _external_ functions declared |
402 in the MLIR module. | 404 in the MLIR module. |
405 are converted to pointer-to-struct and the remaining arguments are converted | 407 are converted to pointer-to-struct and the remaining arguments are converted |
406 as usual. | 408 as usual. |
407 1. Add a body to the original function (making it non-external) that | 409 1. Add a body to the original function (making it non-external) that |
408 1. allocates a memref descriptor, | 410 1. allocates a memref descriptor, |
409 1. populates it, and | 411 1. populates it, and |
410 1. passes the pointer to it into the newly declared interface function | 412 1. passes the pointer to it into the newly declared interface function, then |
411 1. collects the result of the call and returns it to the caller. | 413 1. collects the result of the call and returns it to the caller. |
412 | 414 |
413 For (non-external) functions defined in the MLIR module. | 415 For (non-external) functions defined in the MLIR module. |
414 | 416 |
415 1. Define a new function `_mlir_ciface_<original name>` where memref arguments | 417 1. Define a new function `_mlir_ciface_<original name>` where memref arguments |
558 from the memref type. This descriptor holds all the necessary information to | 560 from the memref type. This descriptor holds all the necessary information to |
559 produce an address of a specific element. In particular, it holds dynamic values | 561 produce an address of a specific element. In particular, it holds dynamic values |
560 for static sizes, and they are expected to match at all times. | 562 for static sizes, and they are expected to match at all times. |
561 | 563 |
562 It is created by the allocation operation and is updated by the conversion | 564 It is created by the allocation operation and is updated by the conversion |
563 operations that may change static dimensions into dynamic and vice versa. | 565 operations that may change static dimensions into dynamic dimensions and vice versa. |
564 | 566 |
565 **Note**: LLVM IR conversion does not support `memref`s with layouts that are | 567 **Note**: LLVM IR conversion does not support `memref`s with layouts that are |
566 not amenable to the strided form. | 568 not amenable to the strided form. |
567 | 569 |
568 ### Index Linearization | 570 ### Index Linearization |