xref: /llvm-project/flang/include/flang/Optimizer/Dialect/FIRAttr.h (revision 3dbac2c007c114a720300d2a4d79abe9ca1351e7)
1 //===-- Optimizer/Dialect/FIRAttr.h -- FIR attributes -----------*- C++ -*-===//
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 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef FORTRAN_OPTIMIZER_DIALECT_FIRATTR_H
14 #define FORTRAN_OPTIMIZER_DIALECT_FIRATTR_H
15 
16 #include "mlir/IR/BuiltinAttributes.h"
17 
18 namespace mlir {
19 class DialectAsmParser;
20 class DialectAsmPrinter;
21 } // namespace mlir
22 
23 namespace fir {
24 
25 class FIROpsDialect;
26 
27 namespace detail {
28 struct RealAttributeStorage;
29 struct TypeAttributeStorage;
30 } // namespace detail
31 
32 using KindTy = unsigned;
33 
34 class ExactTypeAttr
35     : public mlir::Attribute::AttrBase<ExactTypeAttr, mlir::Attribute,
36                                        detail::TypeAttributeStorage> {
37 public:
38   using Base::Base;
39   using ValueType = mlir::Type;
40 
41   static constexpr llvm::StringLiteral name = "fir.type_is";
getAttrName()42   static constexpr llvm::StringRef getAttrName() { return "type_is"; }
43   static ExactTypeAttr get(mlir::Type value);
44 
45   mlir::Type getType() const;
46 };
47 
48 class SubclassAttr
49     : public mlir::Attribute::AttrBase<SubclassAttr, mlir::Attribute,
50                                        detail::TypeAttributeStorage> {
51 public:
52   using Base::Base;
53   using ValueType = mlir::Type;
54 
55   static constexpr llvm::StringLiteral name = "fir.class_is";
getAttrName()56   static constexpr llvm::StringRef getAttrName() { return "class_is"; }
57   static SubclassAttr get(mlir::Type value);
58 
59   mlir::Type getType() const;
60 };
61 
62 /// Attribute which can be applied to a fir.allocmem operation, specifying that
63 /// the allocation may not be moved to the heap by passes
64 class MustBeHeapAttr : public mlir::BoolAttr {
65 public:
66   using BoolAttr::BoolAttr;
67 
68   static constexpr llvm::StringLiteral name = "fir.must_be_heap";
getAttrName()69   static constexpr llvm::StringRef getAttrName() { return "fir.must_be_heap"; }
70 };
71 
72 // Attributes for building SELECT CASE multiway branches
73 
74 /// A closed interval (including the bound values) is an interval with both an
75 /// upper and lower bound as given as ssa-values.
76 /// A case selector of `CASE (n:m)` corresponds to any value from `n` to `m` and
77 /// is encoded as `#fir.interval, %n, %m`.
78 class ClosedIntervalAttr
79     : public mlir::Attribute::AttrBase<ClosedIntervalAttr, mlir::Attribute,
80                                        mlir::AttributeStorage> {
81 public:
82   using Base::Base;
83 
84   static constexpr llvm::StringLiteral name = "fir.interval";
getAttrName()85   static constexpr llvm::StringRef getAttrName() { return "interval"; }
86   static ClosedIntervalAttr get(mlir::MLIRContext *ctxt);
87 };
88 
89 /// An upper bound is an open interval (including the bound value) as given as
90 /// an ssa-value.
91 /// A case selector of `CASE (:m)` corresponds to any value up to and including
92 /// `m` and is encoded as `#fir.upper, %m`.
93 class UpperBoundAttr
94     : public mlir::Attribute::AttrBase<UpperBoundAttr, mlir::Attribute,
95                                        mlir::AttributeStorage> {
96 public:
97   using Base::Base;
98 
99   static constexpr llvm::StringLiteral name = "fir.upper";
getAttrName()100   static constexpr llvm::StringRef getAttrName() { return "upper"; }
101   static UpperBoundAttr get(mlir::MLIRContext *ctxt);
102 };
103 
104 /// A lower bound is an open interval (including the bound value) as given as
105 /// an ssa-value.
106 /// A case selector of `CASE (n:)` corresponds to any value down to and
107 /// including `n` and is encoded as `#fir.lower, %n`.
108 class LowerBoundAttr
109     : public mlir::Attribute::AttrBase<LowerBoundAttr, mlir::Attribute,
110                                        mlir::AttributeStorage> {
111 public:
112   using Base::Base;
113 
114   static constexpr llvm::StringLiteral name = "fir.lower";
getAttrName()115   static constexpr llvm::StringRef getAttrName() { return "lower"; }
116   static LowerBoundAttr get(mlir::MLIRContext *ctxt);
117 };
118 
119 /// A pointer interval is a closed interval as given as an ssa-value. The
120 /// interval contains exactly one value.
121 /// A case selector of `CASE (p)` corresponds to exactly the value `p` and is
122 /// encoded as `#fir.point, %p`.
123 class PointIntervalAttr
124     : public mlir::Attribute::AttrBase<PointIntervalAttr, mlir::Attribute,
125                                        mlir::AttributeStorage> {
126 public:
127   using Base::Base;
128 
129   static constexpr llvm::StringLiteral name = "fir.point";
getAttrName()130   static constexpr llvm::StringRef getAttrName() { return "point"; }
131   static PointIntervalAttr get(mlir::MLIRContext *ctxt);
132 };
133 
134 /// A real attribute is used to workaround MLIR's default parsing of a real
135 /// constant.
136 /// `#fir.real<10, 3.14>` is used to introduce a real constant of value `3.14`
137 /// with a kind of `10`.
138 class RealAttr
139     : public mlir::Attribute::AttrBase<RealAttr, mlir::Attribute,
140                                        detail::RealAttributeStorage> {
141 public:
142   using Base::Base;
143   using ValueType = std::pair<int, llvm::APFloat>;
144 
145   static constexpr llvm::StringLiteral name = "fir.real";
getAttrName()146   static constexpr llvm::StringRef getAttrName() { return "real"; }
147   static RealAttr get(mlir::MLIRContext *ctxt, const ValueType &key);
148 
149   KindTy getFKind() const;
150   llvm::APFloat getValue() const;
151 };
152 
153 mlir::Attribute parseFirAttribute(FIROpsDialect *dialect,
154                                   mlir::DialectAsmParser &parser,
155                                   mlir::Type type);
156 
157 void printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr,
158                        mlir::DialectAsmPrinter &p);
159 
160 } // namespace fir
161 
162 #include "flang/Optimizer/Dialect/FIREnumAttr.h.inc"
163 
164 #define GET_ATTRDEF_CLASSES
165 #include "flang/Optimizer/Dialect/FIRAttr.h.inc"
166 
167 #endif // FORTRAN_OPTIMIZER_DIALECT_FIRATTR_H
168