1 | //===- TestDataLayoutQuery.cpp - Test Data Layout Queries -----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "TestOps.h" |
10 | #include "mlir/Analysis/DataLayoutAnalysis.h" |
11 | #include "mlir/Dialect/DLTI/DLTI.h" |
12 | #include "mlir/IR/BuiltinAttributes.h" |
13 | #include "mlir/Pass/Pass.h" |
14 | |
15 | using namespace mlir; |
16 | |
17 | namespace { |
18 | |
19 | /// A pass that finds "test.data_layout_query" operations and attaches to them |
20 | /// attributes containing the results of data layout queries for operation |
21 | /// result types. |
22 | struct TestDataLayoutQuery |
23 | : public PassWrapper<TestDataLayoutQuery, OperationPass<func::FuncOp>> { |
24 | MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDataLayoutQuery) |
25 | |
26 | StringRef getArgument() const final { return "test-data-layout-query" ; } |
27 | StringRef getDescription() const final { return "Test data layout queries" ; } |
28 | void runOnOperation() override { |
29 | func::FuncOp func = getOperation(); |
30 | Builder builder(func.getContext()); |
31 | const DataLayoutAnalysis &layouts = getAnalysis<DataLayoutAnalysis>(); |
32 | |
33 | func.walk([&](test::DataLayoutQueryOp op) { |
34 | // Skip the ops with already processed in a deeper call. |
35 | if (op->getDiscardableAttr("size" )) |
36 | return; |
37 | |
38 | const DataLayout &layout = layouts.getAbove(operation: op); |
39 | llvm::TypeSize size = layout.getTypeSize(t: op.getType()); |
40 | llvm::TypeSize bitsize = layout.getTypeSizeInBits(t: op.getType()); |
41 | uint64_t alignment = layout.getTypeABIAlignment(t: op.getType()); |
42 | uint64_t preferred = layout.getTypePreferredAlignment(t: op.getType()); |
43 | uint64_t index = layout.getTypeIndexBitwidth(t: op.getType()).value_or(0); |
44 | Attribute endianness = layout.getEndianness(); |
45 | Attribute defaultMemorySpace = layout.getDefaultMemorySpace(); |
46 | Attribute allocaMemorySpace = layout.getAllocaMemorySpace(); |
47 | Attribute manglingMode = layout.getManglingMode(); |
48 | Attribute programMemorySpace = layout.getProgramMemorySpace(); |
49 | Attribute globalMemorySpace = layout.getGlobalMemorySpace(); |
50 | uint64_t stackAlignment = layout.getStackAlignment(); |
51 | Attribute functionPointerAlignment = layout.getFunctionPointerAlignment(); |
52 | Attribute legalIntWidths = layout.getLegalIntWidths(); |
53 | |
54 | auto convertTypeSizeToAttr = [&](llvm::TypeSize typeSize) -> Attribute { |
55 | if (!typeSize.isScalable()) |
56 | return builder.getIndexAttr(typeSize); |
57 | |
58 | return builder.getDictionaryAttr({ |
59 | builder.getNamedAttr("scalable" , builder.getUnitAttr()), |
60 | builder.getNamedAttr( |
61 | "minimal_size" , |
62 | builder.getIndexAttr(typeSize.getKnownMinValue())), |
63 | }); |
64 | }; |
65 | |
66 | op->setAttrs( |
67 | {builder.getNamedAttr("size" , convertTypeSizeToAttr(size)), |
68 | builder.getNamedAttr("bitsize" , convertTypeSizeToAttr(bitsize)), |
69 | builder.getNamedAttr("alignment" , builder.getIndexAttr(alignment)), |
70 | builder.getNamedAttr("preferred" , builder.getIndexAttr(preferred)), |
71 | builder.getNamedAttr("index" , builder.getIndexAttr(index)), |
72 | builder.getNamedAttr("endianness" , endianness == Attribute() |
73 | ? builder.getStringAttr("" ) |
74 | : endianness), |
75 | builder.getNamedAttr("default_memory_space" , |
76 | defaultMemorySpace == Attribute() |
77 | ? builder.getUI32IntegerAttr(0) |
78 | : defaultMemorySpace), |
79 | builder.getNamedAttr("alloca_memory_space" , |
80 | allocaMemorySpace == Attribute() |
81 | ? builder.getUI32IntegerAttr(0) |
82 | : allocaMemorySpace), |
83 | builder.getNamedAttr("mangling_mode" , manglingMode == Attribute() |
84 | ? builder.getStringAttr("" ) |
85 | : manglingMode), |
86 | builder.getNamedAttr("program_memory_space" , |
87 | programMemorySpace == Attribute() |
88 | ? builder.getUI32IntegerAttr(0) |
89 | : programMemorySpace), |
90 | builder.getNamedAttr("global_memory_space" , |
91 | globalMemorySpace == Attribute() |
92 | ? builder.getUI32IntegerAttr(0) |
93 | : globalMemorySpace), |
94 | builder.getNamedAttr("stack_alignment" , |
95 | builder.getIndexAttr(stackAlignment)), |
96 | builder.getNamedAttr("function_pointer_alignment" , |
97 | functionPointerAlignment == Attribute() |
98 | ? FunctionPointerAlignmentAttr::get( |
99 | builder.getContext(), 0, |
100 | /*function_dependent=*/false) |
101 | : functionPointerAlignment), |
102 | builder.getNamedAttr("legal_int_widths" , |
103 | legalIntWidths == Attribute() |
104 | ? builder.getDenseI32ArrayAttr({}) |
105 | : legalIntWidths) |
106 | |
107 | }); |
108 | |
109 | }); |
110 | } |
111 | }; |
112 | } // namespace |
113 | |
114 | namespace mlir { |
115 | namespace test { |
116 | void registerTestDataLayoutQuery() { PassRegistration<TestDataLayoutQuery>(); } |
117 | } // namespace test |
118 | } // namespace mlir |
119 | |