In this PR, the users of BufferPlacement can configure
BufferAssginmentTypeConverter. These new configurations would give the user more
freedom in the process of converting function signature, and return and call
operation conversions.
These are the new features:
- Accepting callback functions for decomposing types (i.e. 1 to N type conversion such as unpacking tuple types).
- Defining ResultConversionKind for specifying whether a function result with a certain type should be appended to the function arguments list or should be kept as function result. (Usage: converter.setResultConversionKind<MemRefType>(AppendToArgumentList))
- Accepting callback functions for composing or decomposing values (i.e. N to 1 and 1 to N value conversion).
Input:
func @test(%arg0: tuple<tensor<2xf32>,i1>) -> (tuple<tensor<2xf32>,i1>){ return %arg0 : tuple<tensor<2xf32>,i1> }
Output with [converter.setResultConversionKind<MemRefType>(AppendToArgumentList)]:
func @test(%arg0: memref<2xf32>, %arg1: i1, %arg2: memref<2xf32>) -> i1 { %0 = "test.make_tuple"(%arg0, %arg1) : (memref<2xf32>, i1) -> tuple<memref<2xf32>, i1> %1 = "test.get_tuple_element"(%0) {index = 0 : i32} : (tuple<memref<2xf32>, i1>) -> memref<2xf32> %2 = "test.get_tuple_element"(%0) {index = 1 : i32} : (tuple<memref<2xf32>, i1>) -> i1 linalg.copy(%1, %arg2) : memref<2xf32>, memref<2xf32> return %2 : i1 }
Output with [converter.setResultConversionKind<MemRefType>(KeepAsFunctionResult)]:
func @test(%arg0: memref<2xf32>, %arg1: i1) -> (memref<2xf32>, i1) { %0 = "test.make_tuple"(%arg0, %arg1) : (memref<2xf32>, i1) -> tuple<memref<2xf32>, i1> %1 = "test.get_tuple_element"(%0) {index = 0 : i32} : (tuple<memref<2xf32>, i1>) -> memref<2xf32> %2 = "test.get_tuple_element"(%0) {index = 1 : i32} : (tuple<memref<2xf32>, i1>) -> i1 return %1, %2 : memref<2xf32>, i1 }
Currently this could just be a map from Type to ResultConversionKind. Callbacks only help if the user can provide them and hence have some extra logic in them. Maybe by also passing the originating type?