#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "mlir/IR/FunctionInterfaces.h" #include "mlir/IR/MLIRContext.h" #include "mlir/IR/OpDefinition.h" #include "mlir/IR/Operation.h" #include "mlir/IR/PatternMatch.h" #include "mlir/IR/SymbolTable.h" #include "mlir/Interfaces/CallInterfaces.h" #include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Interfaces/SideEffectInterfaces.h" #include "revng/Clift/CliftAttributes.h" #include "revng/Clift/CliftDialect.h" #include "revng/Clift/CliftEnums.h" #include "revng/Clift/CliftInterfaces.h" #include "revng/Clift/CliftOpInterfaces.h" #include "revng/Clift/CliftOpTraits.h" #include "revng/Clift/CliftTypes.h" namespace clift { namespace impl { inline constexpr llvm::StringRef LoopLabelMaskAttrName = "label_mask"; inline constexpr unsigned BreakLabelFlag = 1 << 0; inline constexpr unsigned ContinueLabelFlag = 1 << 1; bool verifyStatementRegion(mlir::Region &R); bool verifyExpressionRegion(mlir::Region &R, bool Required); unsigned getPointerArithmeticPointerOperandIndex(mlir::Operation *Op); unsigned getPointerArithmeticOffsetOperandIndex(mlir::Operation *Op); mlir::LogicalResult verifyUnaryIntegerMutationOp(mlir::Operation *Op); } // namespace impl class AttrDictView { mlir::DictionaryAttr Underlying; public: explicit AttrDictView(mlir::DictionaryAttr Underlying) : Underlying(Underlying) {} [[nodiscard]] mlir::DictionaryAttr getDictionaryAttr() const { return Underlying; } [[nodiscard]] mlir::Attribute get(llvm::StringRef Name) const { return Underlying.get(Name); } template DefaultT> [[nodiscard]] mlir::Attribute get(llvm::StringRef Name, DefaultT &&Default) const { if (mlir::Attribute Attr = Underlying.get(Name)) return Attr; return std::forward(Default); } template [[nodiscard]] AttrT getOfType(llvm::StringRef Name) const { return mlir::dyn_cast_or_null(Underlying.get(Name)); } template DefaultT> [[nodiscard]] AttrT getOfType(llvm::StringRef Name, DefaultT &&Default) const { if (AttrT Attr = mlir::dyn_cast_or_null(Underlying.get(Name))) return Attr; return std::forward(Default); } [[nodiscard]] llvm::StringRef getString(llvm::StringRef Name) const { auto Attr = getOfType(Name); revng_assert(Attr); return Attr.getValue(); } [[nodiscard]] llvm::StringRef getString(llvm::StringRef Name, llvm::StringRef Default) const { auto Attr = getOfType(Name); return Attr ? Attr.getValue() : Default; } [[nodiscard]] llvm::StringRef getStringOrEmpty(llvm::StringRef Name) const { return getString(Name, llvm::StringRef()); } }; } // namespace clift // This include should stay here for correct build procedure #define GET_OP_CLASSES #include "revng/Clift/Clift.h.inc" namespace clift { /// Creates a new MLIR context with the Clift dialect pre-loaded. std::unique_ptr makeContext(); /// Creates a new Clift module. mlir::OwningOpRef makeModule(mlir::MLIRContext &Context); /// Returns true if the module has a Clift module attribute. bool isCliftModule(mlir::ModuleOp Module); /// Returns the data model for the specified module. /// \note The module must have an associated data model. const CDataModel &getDataModel(mlir::ModuleOp Module); /// Returns the data model for the specified function. /// \note The function must be contained within a module, and that module must /// have an associated data model. const CDataModel &getDataModel(FunctionOp Function); /// Assigns the module data model. void setDataModel(mlir::ModuleOp Module, const CDataModel &DataModel); /// Returns the terminating YieldOp of the expression represented by the region, /// or a operation if the region is not a valid expression region. YieldOp getExpressionYieldOp(mlir::Region &R); /// Returns the value of the expression represented by the region region, or a /// null value if the region is not a valid expression region. mlir::Value getExpressionValue(mlir::Region &R); /// Returns the type of the expression represented by the region, or a null type /// if region is not a valid expression region. mlir::Type getExpressionType(mlir::Region &R); } // namespace clift