Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:07

0001 //===- MemoryModelRelaxationAnnotations.h -----------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 /// \file
0010 /// This file provides utility for Memory Model Relaxation Annotations (MMRAs).
0011 /// Those annotations are represented using Metadata. The MMRATagSet class
0012 /// offers a simple API to parse the metadata and perform common operations on
0013 /// it. The MMRAMetadata class is a simple tuple of MDNode that provides easy
0014 /// access to all MMRA annotations on an instruction.
0015 //
0016 //===----------------------------------------------------------------------===//
0017 
0018 #ifndef LLVM_IR_MEMORYMODELRELAXATIONANNOTATIONS_H
0019 #define LLVM_IR_MEMORYMODELRELAXATIONANNOTATIONS_H
0020 
0021 #include "llvm/ADT/DenseSet.h"
0022 #include "llvm/ADT/StringRef.h"
0023 #include <tuple> // for std::pair
0024 
0025 namespace llvm {
0026 
0027 template <typename T> class ArrayRef;
0028 
0029 class MDNode;
0030 class MDTuple;
0031 class Metadata;
0032 class raw_ostream;
0033 class LLVMContext;
0034 class Instruction;
0035 
0036 /// Helper class to manipulate `!mmra` metadata nodes.
0037 ///
0038 /// This can be visualized as a set of "tags", with each tag
0039 /// representing a particular property of an instruction, as
0040 /// explained in the MemoryModelRelaxationAnnotations docs.
0041 ///
0042 /// This class (and the optimizer in general) does not reason
0043 /// about the exact nature of the tags and the properties they
0044 /// imply. It just sees the metadata as a collection of tags, which
0045 /// are a prefix/suffix pair of strings.
0046 class MMRAMetadata {
0047 public:
0048   using TagT = std::pair<StringRef, StringRef>;
0049   using SetT = DenseSet<TagT>;
0050   using const_iterator = SetT::const_iterator;
0051 
0052   /// \name Constructors
0053   /// @{
0054   MMRAMetadata() = default;
0055   MMRAMetadata(const Instruction &I);
0056   MMRAMetadata(MDNode *MD);
0057   /// @}
0058 
0059   /// \name Metadata Helpers & Builders
0060   /// @{
0061 
0062   /// Combines \p A and \p B according to MMRA semantics.
0063   /// \returns !mmra metadata for the combined MMRAs.
0064   static MDNode *combine(LLVMContext &Ctx, const MMRAMetadata &A,
0065                          const MMRAMetadata &B);
0066 
0067   /// Creates !mmra metadata for a single tag.
0068   ///
0069   /// !mmra metadata can either be a single tag, or a MDTuple containing
0070   /// multiple tags.
0071   static MDTuple *getTagMD(LLVMContext &Ctx, StringRef Prefix,
0072                            StringRef Suffix);
0073   static MDTuple *getTagMD(LLVMContext &Ctx, const TagT &T) {
0074     return getTagMD(Ctx, T.first, T.second);
0075   }
0076 
0077   /// Creates !mmra metadata from \p Tags.
0078   /// \returns nullptr or a MDTuple* from \p Tags.
0079   static MDTuple *getMD(LLVMContext &Ctx, ArrayRef<TagT> Tags);
0080 
0081   /// \returns true if \p MD is a well-formed MMRA tag.
0082   static bool isTagMD(const Metadata *MD);
0083 
0084   /// @}
0085 
0086   /// \name Compatibility Helpers
0087   /// @{
0088 
0089   /// \returns whether the MMRAs on \p A and \p B are compatible.
0090   static bool checkCompatibility(const Instruction &A, const Instruction &B) {
0091     return MMRAMetadata(A).isCompatibleWith(B);
0092   }
0093 
0094   /// \returns whether this set of tags is compatible with \p Other.
0095   bool isCompatibleWith(const MMRAMetadata &Other) const;
0096 
0097   /// @}
0098 
0099   /// \name Content Queries
0100   /// @{
0101 
0102   bool hasTag(StringRef Prefix, StringRef Suffix) const;
0103   bool hasTagWithPrefix(StringRef Prefix) const;
0104 
0105   const_iterator begin() const;
0106   const_iterator end() const;
0107   bool empty() const;
0108   unsigned size() const;
0109 
0110   /// @}
0111 
0112   void print(raw_ostream &OS) const;
0113   void dump() const;
0114 
0115   operator bool() const { return !Tags.empty(); }
0116   bool operator==(const MMRAMetadata &Other) const {
0117     return Tags == Other.Tags;
0118   }
0119   bool operator!=(const MMRAMetadata &Other) const {
0120     return Tags != Other.Tags;
0121   }
0122 
0123 private:
0124   SetT Tags;
0125 };
0126 
0127 /// \returns true if \p I can have !mmra metadata.
0128 bool canInstructionHaveMMRAs(const Instruction &I);
0129 
0130 } // namespace llvm
0131 
0132 #endif