1d80d3a35SRiver Riddle //===- TestBuiltinAttributeInterfaces.cpp ---------------------------------===//
2d80d3a35SRiver Riddle //
3d80d3a35SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d80d3a35SRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
5d80d3a35SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d80d3a35SRiver Riddle //
7d80d3a35SRiver Riddle //===----------------------------------------------------------------------===//
8d80d3a35SRiver Riddle 
9d80d3a35SRiver Riddle #include "TestAttributes.h"
1036d3efeaSRiver Riddle #include "mlir/IR/BuiltinOps.h"
11d80d3a35SRiver Riddle #include "mlir/Pass/Pass.h"
12d80d3a35SRiver Riddle #include "llvm/Support/FormatVariadic.h"
13d80d3a35SRiver Riddle 
14d80d3a35SRiver Riddle using namespace mlir;
15d80d3a35SRiver Riddle using namespace test;
16d80d3a35SRiver Riddle 
17*7faf75bbSMehdi Amini // Helper to print one scalar value, force int8_t to print as integer instead of
18*7faf75bbSMehdi Amini // char.
19*7faf75bbSMehdi Amini template <typename T>
printOneElement(InFlightDiagnostic & os,T value)20*7faf75bbSMehdi Amini static void printOneElement(InFlightDiagnostic &os, T value) {
21*7faf75bbSMehdi Amini   os << llvm::formatv("{0}", value).str();
22*7faf75bbSMehdi Amini }
23*7faf75bbSMehdi Amini template <>
printOneElement(InFlightDiagnostic & os,int8_t value)24*7faf75bbSMehdi Amini void printOneElement<int8_t>(InFlightDiagnostic &os, int8_t value) {
25*7faf75bbSMehdi Amini   os << llvm::formatv("{0}", static_cast<int64_t>(value)).str();
26*7faf75bbSMehdi Amini }
27*7faf75bbSMehdi Amini 
28d80d3a35SRiver Riddle namespace {
29d80d3a35SRiver Riddle struct TestElementsAttrInterface
30d80d3a35SRiver Riddle     : public PassWrapper<TestElementsAttrInterface, OperationPass<ModuleOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anon25b185410111::TestElementsAttrInterface315e50dd04SRiver Riddle   MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestElementsAttrInterface)
325e50dd04SRiver Riddle 
33d80d3a35SRiver Riddle   StringRef getArgument() const final { return "test-elements-attr-interface"; }
getDescription__anon25b185410111::TestElementsAttrInterface34d80d3a35SRiver Riddle   StringRef getDescription() const final {
35d80d3a35SRiver Riddle     return "Test ElementsAttr interface support.";
36d80d3a35SRiver Riddle   }
runOnOperation__anon25b185410111::TestElementsAttrInterface37d80d3a35SRiver Riddle   void runOnOperation() override {
38d80d3a35SRiver Riddle     getOperation().walk([&](Operation *op) {
39d80d3a35SRiver Riddle       for (NamedAttribute attr : op->getAttrs()) {
400c7890c8SRiver Riddle         auto elementsAttr = attr.getValue().dyn_cast<ElementsAttr>();
41d80d3a35SRiver Riddle         if (!elementsAttr)
42d80d3a35SRiver Riddle           continue;
43*7faf75bbSMehdi Amini         if (auto concreteAttr =
44*7faf75bbSMehdi Amini                 attr.getValue().dyn_cast<DenseArrayBaseAttr>()) {
45*7faf75bbSMehdi Amini           switch (concreteAttr.getElementType()) {
46*7faf75bbSMehdi Amini           case DenseArrayBaseAttr::EltType::I8:
47*7faf75bbSMehdi Amini             testElementsAttrIteration<int8_t>(op, elementsAttr, "int8_t");
48*7faf75bbSMehdi Amini             break;
49*7faf75bbSMehdi Amini           case DenseArrayBaseAttr::EltType::I16:
50*7faf75bbSMehdi Amini             testElementsAttrIteration<int16_t>(op, elementsAttr, "int16_t");
51*7faf75bbSMehdi Amini             break;
52*7faf75bbSMehdi Amini           case DenseArrayBaseAttr::EltType::I32:
53*7faf75bbSMehdi Amini             testElementsAttrIteration<int32_t>(op, elementsAttr, "int32_t");
54*7faf75bbSMehdi Amini             break;
55*7faf75bbSMehdi Amini           case DenseArrayBaseAttr::EltType::I64:
56*7faf75bbSMehdi Amini             testElementsAttrIteration<int64_t>(op, elementsAttr, "int64_t");
57*7faf75bbSMehdi Amini             break;
58*7faf75bbSMehdi Amini           case DenseArrayBaseAttr::EltType::F32:
59*7faf75bbSMehdi Amini             testElementsAttrIteration<float>(op, elementsAttr, "float");
60*7faf75bbSMehdi Amini             break;
61*7faf75bbSMehdi Amini           case DenseArrayBaseAttr::EltType::F64:
62*7faf75bbSMehdi Amini             testElementsAttrIteration<double>(op, elementsAttr, "double");
63*7faf75bbSMehdi Amini             break;
64*7faf75bbSMehdi Amini           }
65*7faf75bbSMehdi Amini           continue;
66*7faf75bbSMehdi Amini         }
67*7faf75bbSMehdi Amini         testElementsAttrIteration<int64_t>(op, elementsAttr, "int64_t");
68d80d3a35SRiver Riddle         testElementsAttrIteration<uint64_t>(op, elementsAttr, "uint64_t");
69d80d3a35SRiver Riddle         testElementsAttrIteration<APInt>(op, elementsAttr, "APInt");
70d80d3a35SRiver Riddle         testElementsAttrIteration<IntegerAttr>(op, elementsAttr, "IntegerAttr");
71d80d3a35SRiver Riddle       }
72d80d3a35SRiver Riddle     });
73d80d3a35SRiver Riddle   }
74d80d3a35SRiver Riddle 
75d80d3a35SRiver Riddle   template <typename T>
testElementsAttrIteration__anon25b185410111::TestElementsAttrInterface76d80d3a35SRiver Riddle   void testElementsAttrIteration(Operation *op, ElementsAttr attr,
77d80d3a35SRiver Riddle                                  StringRef type) {
78d80d3a35SRiver Riddle     InFlightDiagnostic diag = op->emitError()
79d80d3a35SRiver Riddle                               << "Test iterating `" << type << "`: ";
80d80d3a35SRiver Riddle 
81d80d3a35SRiver Riddle     auto values = attr.tryGetValues<T>();
82d80d3a35SRiver Riddle     if (!values) {
83d80d3a35SRiver Riddle       diag << "unable to iterate type";
84d80d3a35SRiver Riddle       return;
85d80d3a35SRiver Riddle     }
86d80d3a35SRiver Riddle 
87*7faf75bbSMehdi Amini     llvm::interleaveComma(*values, diag,
88*7faf75bbSMehdi Amini                           [&](T value) { printOneElement(diag, value); });
89d80d3a35SRiver Riddle   }
90d80d3a35SRiver Riddle };
91be0a7e9fSMehdi Amini } // namespace
92d80d3a35SRiver Riddle 
93d80d3a35SRiver Riddle namespace mlir {
94d80d3a35SRiver Riddle namespace test {
registerTestBuiltinAttributeInterfaces()95d80d3a35SRiver Riddle void registerTestBuiltinAttributeInterfaces() {
96d80d3a35SRiver Riddle   PassRegistration<TestElementsAttrInterface>();
97d80d3a35SRiver Riddle }
98d80d3a35SRiver Riddle } // namespace test
99d80d3a35SRiver Riddle } // namespace mlir
100