1 //===- MemoryModelRelaxationAnnotations.h -----------------------*- 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 /// \file 10 /// This file provides utility for Memory Model Relaxation Annotations (MMRAs). 11 /// Those annotations are represented using Metadata. The MMRATagSet class 12 /// offers a simple API to parse the metadata and perform common operations on 13 /// it. The MMRAMetadata class is a simple tuple of MDNode that provides easy 14 /// access to all MMRA annotations on an instruction. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #ifndef LLVM_IR_MEMORYMODELRELAXATIONANNOTATIONS_H 19 #define LLVM_IR_MEMORYMODELRELAXATIONANNOTATIONS_H 20 21 #include "llvm/ADT/DenseSet.h" 22 #include "llvm/ADT/StringRef.h" 23 #include <tuple> // for std::pair 24 25 namespace llvm { 26 27 template <typename T> class ArrayRef; 28 29 class MDNode; 30 class MDTuple; 31 class Metadata; 32 class raw_ostream; 33 class LLVMContext; 34 class Instruction; 35 36 /// Helper class to manipulate `!mmra` metadata nodes. 37 /// 38 /// This can be visualized as a set of "tags", with each tag 39 /// representing a particular property of an instruction, as 40 /// explained in the MemoryModelRelaxationAnnotations docs. 41 /// 42 /// This class (and the optimizer in general) does not reason 43 /// about the exact nature of the tags and the properties they 44 /// imply. It just sees the metadata as a collection of tags, which 45 /// are a prefix/suffix pair of strings. 46 class MMRAMetadata { 47 public: 48 using TagT = std::pair<StringRef, StringRef>; 49 using SetT = DenseSet<TagT>; 50 using const_iterator = SetT::const_iterator; 51 52 /// \name Constructors 53 /// @{ 54 MMRAMetadata() = default; 55 MMRAMetadata(const Instruction &I); 56 MMRAMetadata(MDNode *MD); 57 /// @} 58 59 /// \name Metadata Helpers & Builders 60 /// @{ 61 62 /// Combines \p A and \p B according to MMRA semantics. 63 /// \returns !mmra metadata for the combined MMRAs. 64 static MDNode *combine(LLVMContext &Ctx, const MMRAMetadata &A, 65 const MMRAMetadata &B); 66 67 /// Creates !mmra metadata for a single tag. 68 /// 69 /// !mmra metadata can either be a single tag, or a MDTuple containing 70 /// multiple tags. 71 static MDTuple *getTagMD(LLVMContext &Ctx, StringRef Prefix, 72 StringRef Suffix); getTagMD(LLVMContext & Ctx,const TagT & T)73 static MDTuple *getTagMD(LLVMContext &Ctx, const TagT &T) { 74 return getTagMD(Ctx, T.first, T.second); 75 } 76 77 /// Creates !mmra metadata from \p Tags. 78 /// \returns nullptr or a MDTuple* from \p Tags. 79 static MDTuple *getMD(LLVMContext &Ctx, ArrayRef<TagT> Tags); 80 81 /// \returns true if \p MD is a well-formed MMRA tag. 82 static bool isTagMD(const Metadata *MD); 83 84 /// @} 85 86 /// \name Compatibility Helpers 87 /// @{ 88 89 /// \returns whether the MMRAs on \p A and \p B are compatible. checkCompatibility(const Instruction & A,const Instruction & B)90 static bool checkCompatibility(const Instruction &A, const Instruction &B) { 91 return MMRAMetadata(A).isCompatibleWith(B); 92 } 93 94 /// \returns whether this set of tags is compatible with \p Other. 95 bool isCompatibleWith(const MMRAMetadata &Other) const; 96 97 /// @} 98 99 /// \name Content Queries 100 /// @{ 101 102 bool hasTag(StringRef Prefix, StringRef Suffix) const; 103 bool hasTagWithPrefix(StringRef Prefix) const; 104 105 const_iterator begin() const; 106 const_iterator end() const; 107 bool empty() const; 108 unsigned size() const; 109 110 /// @} 111 112 void print(raw_ostream &OS) const; 113 void dump() const; 114 115 operator bool() const { return !Tags.empty(); } 116 bool operator==(const MMRAMetadata &Other) const { 117 return Tags == Other.Tags; 118 } 119 bool operator!=(const MMRAMetadata &Other) const { 120 return Tags != Other.Tags; 121 } 122 123 private: 124 SetT Tags; 125 }; 126 127 /// \returns true if \p I can have !mmra metadata. 128 bool canInstructionHaveMMRAs(const Instruction &I); 129 130 } // namespace llvm 131 132 #endif 133