| //===-- Optimizer/Dialect/FIRAttr.h -- FIR attributes -----------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef OPTIMIZER_DIALECT_FIRATTR_H |
| #define OPTIMIZER_DIALECT_FIRATTR_H |
| |
| #include "mlir/IR/BuiltinAttributes.h" |
| |
| namespace mlir { |
| class DialectAsmParser; |
| class DialectAsmPrinter; |
| } // namespace mlir |
| |
| namespace fir { |
| |
| class FIROpsDialect; |
| |
| namespace detail { |
| struct OpaqueAttributeStorage; |
| struct RealAttributeStorage; |
| struct TypeAttributeStorage; |
| } // namespace detail |
| |
| using KindTy = unsigned; |
| |
| class ExactTypeAttr |
| : public mlir::Attribute::AttrBase<ExactTypeAttr, mlir::Attribute, |
| detail::TypeAttributeStorage> { |
| public: |
| using Base::Base; |
| using ValueType = mlir::Type; |
| |
| static constexpr llvm::StringRef getAttrName() { return "instance"; } |
| static ExactTypeAttr get(mlir::Type value); |
| |
| mlir::Type getType() const; |
| }; |
| |
| class SubclassAttr |
| : public mlir::Attribute::AttrBase<SubclassAttr, mlir::Attribute, |
| detail::TypeAttributeStorage> { |
| public: |
| using Base::Base; |
| using ValueType = mlir::Type; |
| |
| static constexpr llvm::StringRef getAttrName() { return "subsumed"; } |
| static SubclassAttr get(mlir::Type value); |
| |
| mlir::Type getType() const; |
| }; |
| |
| // Attributes for building SELECT CASE multiway branches |
| |
| /// A closed interval (including the bound values) is an interval with both an |
| /// upper and lower bound as given as ssa-values. |
| /// A case selector of `CASE (n:m)` corresponds to any value from `n` to `m` and |
| /// is encoded as `#fir.interval, %n, %m`. |
| class ClosedIntervalAttr |
| : public mlir::Attribute::AttrBase<ClosedIntervalAttr, mlir::Attribute, |
| mlir::AttributeStorage> { |
| public: |
| using Base::Base; |
| |
| static constexpr llvm::StringRef getAttrName() { return "interval"; } |
| static ClosedIntervalAttr get(mlir::MLIRContext *ctxt); |
| }; |
| |
| /// An upper bound is an open interval (including the bound value) as given as |
| /// an ssa-value. |
| /// A case selector of `CASE (:m)` corresponds to any value up to and including |
| /// `m` and is encoded as `#fir.upper, %m`. |
| class UpperBoundAttr |
| : public mlir::Attribute::AttrBase<UpperBoundAttr, mlir::Attribute, |
| mlir::AttributeStorage> { |
| public: |
| using Base::Base; |
| |
| static constexpr llvm::StringRef getAttrName() { return "upper"; } |
| static UpperBoundAttr get(mlir::MLIRContext *ctxt); |
| }; |
| |
| /// A lower bound is an open interval (including the bound value) as given as |
| /// an ssa-value. |
| /// A case selector of `CASE (n:)` corresponds to any value down to and |
| /// including `n` and is encoded as `#fir.lower, %n`. |
| class LowerBoundAttr |
| : public mlir::Attribute::AttrBase<LowerBoundAttr, mlir::Attribute, |
| mlir::AttributeStorage> { |
| public: |
| using Base::Base; |
| |
| static constexpr llvm::StringRef getAttrName() { return "lower"; } |
| static LowerBoundAttr get(mlir::MLIRContext *ctxt); |
| }; |
| |
| /// A pointer interval is a closed interval as given as an ssa-value. The |
| /// interval contains exactly one value. |
| /// A case selector of `CASE (p)` corresponds to exactly the value `p` and is |
| /// encoded as `#fir.point, %p`. |
| class PointIntervalAttr |
| : public mlir::Attribute::AttrBase<PointIntervalAttr, mlir::Attribute, |
| mlir::AttributeStorage> { |
| public: |
| using Base::Base; |
| |
| static constexpr llvm::StringRef getAttrName() { return "point"; } |
| static PointIntervalAttr get(mlir::MLIRContext *ctxt); |
| }; |
| |
| /// A real attribute is used to workaround MLIR's default parsing of a real |
| /// constant. |
| /// `#fir.real<10, 3.14>` is used to introduce a real constant of value `3.14` |
| /// with a kind of `10`. |
| class RealAttr |
| : public mlir::Attribute::AttrBase<RealAttr, mlir::Attribute, |
| detail::RealAttributeStorage> { |
| public: |
| using Base::Base; |
| using ValueType = std::pair<int, llvm::APFloat>; |
| |
| static constexpr llvm::StringRef getAttrName() { return "real"; } |
| static RealAttr get(mlir::MLIRContext *ctxt, const ValueType &key); |
| |
| KindTy getFKind() const; |
| llvm::APFloat getValue() const; |
| }; |
| |
| /// An opaque attribute is used to provide dictionary lookups of pointers. The |
| /// underlying type of the pointee object is left up to the client. Opaque |
| /// attributes are always constructed as null pointers when parsing. Clearly, |
| /// opaque attributes come with restrictions and must be used with care. |
| /// 1. An opaque attribute should not refer to information of semantic |
| /// significance, since the pointed-to object will not be a part of |
| /// round-tripping the IR. |
| /// 2. The lifetime of the pointed-to object must outlive any possible uses |
| /// via the opaque attribute. |
| class OpaqueAttr |
| : public mlir::Attribute::AttrBase<OpaqueAttr, mlir::Attribute, |
| detail::OpaqueAttributeStorage> { |
| public: |
| using Base::Base; |
| |
| static constexpr llvm::StringRef getAttrName() { return "opaque"; } |
| static OpaqueAttr get(mlir::MLIRContext *ctxt, void *pointer); |
| |
| void *getPointer() const; |
| }; |
| |
| mlir::Attribute parseFirAttribute(FIROpsDialect *dialect, |
| mlir::DialectAsmParser &parser, |
| mlir::Type type); |
| |
| void printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr, |
| mlir::DialectAsmPrinter &p); |
| |
| } // namespace fir |
| |
| #endif // OPTIMIZER_DIALECT_FIRATTR_H |