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