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