Alex Zinenko 3ba14fa0ce [mlir] Introduce data layout modeling subsystem
Data layout information allows to answer questions about the size and alignment
properties of a type. It enables, among others, the generation of various
linear memory addressing schemes for containers of abstract types and deeper
reasoning about vectors. This introduces the subsystem for modeling data
layouts in MLIR.

The data layout subsystem is designed to scale to MLIR's open type and
operation system. At the top level, it consists of attribute interfaces that
can be implemented by concrete data layout specifications; type interfaces that
should be implemented by types subject to data layout; operation interfaces
that must be implemented by operations that can serve as data layout scopes
(e.g., modules); and dialect interfaces for data layout properties unrelated to
specific types. Built-in types are handled specially to decrease the overall
query cost.

A concrete default implementation of these interfaces is provided in the new
Target dialect. Defaults for built-in types that match the current behavior are
also provided.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D97067
2021-03-11 16:54:47 +01:00

173 lines
5.8 KiB
MLIR

// RUN: mlir-opt --test-data-layout-query %s | FileCheck %s
// CHECK-LABEL: @no_layout_builtin
func @no_layout_builtin() {
// CHECK: alignment = 4
// CHECK: preferred = 4
// CHECK: size = 4
"test.data_layout_query"() : () -> i32
// CHECK: alignment = 8
// CHECK: preferred = 8
// CHECK: size = 8
"test.data_layout_query"() : () -> f64
return
}
// CHECK-LABEL: @no_layout_custom
func @no_layout_custom() {
// CHECK: alignment = 1
// CHECK: preferred = 1
// CHECK: size = 1
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
return
}
// CHECK-LABEL: @layout_op_no_layout
func @layout_op_no_layout() {
"test.op_with_data_layout"() ({
// CHECK: alignment = 1
// CHECK: preferred = 1
// CHECK: size = 1
"test.data_layout_query"() : () -> !test.test_type_with_layout<1000>
"test.maybe_terminator"() : () -> ()
}) : () -> ()
return
}
// CHECK-LABEL: @layout_op
func @layout_op() {
"test.op_with_data_layout"() ({
// CHECK: alignment = 20
// CHECK: preferred = 1
// CHECK: size = 10
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 10]>,
#dlti.dl_entry<!test.test_type_with_layout<20>, ["alignment", 20]>
>} : () -> ()
return
}
// Make sure the outer op with layout may be missing the spec.
// CHECK-LABEL: @nested_inner_only
func @nested_inner_only() {
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
// CHECK: alignment = 20
// CHECK: preferred = 1
// CHECK: size = 10
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 10]>,
#dlti.dl_entry<!test.test_type_with_layout<20>, ["alignment", 20]>
>} : () -> ()
"test.maybe_terminator"() : () -> ()
}) : () -> ()
return
}
// Make sure the inner op with layout may be missing the spec.
// CHECK-LABEL: @nested_outer_only
func @nested_outer_only() {
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
// CHECK: alignment = 20
// CHECK: preferred = 1
// CHECK: size = 10
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) : () -> ()
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 10]>,
#dlti.dl_entry<!test.test_type_with_layout<20>, ["alignment", 20]>
>} : () -> ()
return
}
// CHECK-LABEL: @nested_middle_only
func @nested_middle_only() {
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
// CHECK: alignment = 20
// CHECK: preferred = 1
// CHECK: size = 10
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) : () -> ()
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 10]>,
#dlti.dl_entry<!test.test_type_with_layout<20>, ["alignment", 20]>
>} : () -> ()
"test.maybe_terminator"() : () -> ()
}) : () -> ()
return
}
// CHECK-LABEL: @nested_combine_with_missing
func @nested_combine_with_missing() {
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
// CHECK: alignment = 20
// CHECK: preferred = 30
// CHECK: size = 10
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) : () -> ()
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 10]>,
#dlti.dl_entry<!test.test_type_with_layout<20>, ["alignment", 20]>
>} : () -> ()
// CHECK: alignment = 1
// CHECK: preferred = 30
// CHECK: size = 42
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 42]>,
#dlti.dl_entry<!test.test_type_with_layout<30>, ["preferred", 30]>
>}: () -> ()
return
}
// CHECK-LABEL: @nested_combine_all
func @nested_combine_all() {
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
"test.op_with_data_layout"() ({
// CHECK: alignment = 20
// CHECK: preferred = 30
// CHECK: size = 3
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 3]>,
#dlti.dl_entry<!test.test_type_with_layout<30>, ["preferred", 30]>
>} : () -> ()
// CHECK: alignment = 20
// CHECK: preferred = 30
// CHECK: size = 10
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 10]>,
#dlti.dl_entry<!test.test_type_with_layout<20>, ["alignment", 20]>
>} : () -> ()
// CHECK: alignment = 1
// CHECK: preferred = 30
// CHECK: size = 42
"test.data_layout_query"() : () -> !test.test_type_with_layout<10>
"test.maybe_terminator"() : () -> ()
}) { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<!test.test_type_with_layout<10>, ["size", 42]>,
#dlti.dl_entry<!test.test_type_with_layout<30>, ["preferred", 30]>
>}: () -> ()
return
}