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