xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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