Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===--- ModRef.h - Memory effect modelling ---------------------*- 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
// Definitions of ModRefInfo and MemoryEffects, which are used to
10
// describe the memory effects of instructions.
11
//
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_IR_MODREF_H
15
#define LLVM_IR_MODREF_H
16
 
17
#include "llvm/ADT/BitmaskEnum.h"
18
#include "llvm/ADT/Sequence.h"
19
#include "llvm/Support/raw_ostream.h"
20
 
21
namespace llvm {
22
 
23
/// Flags indicating whether a memory access modifies or references memory.
24
///
25
/// This is no access at all, a modification, a reference, or both
26
/// a modification and a reference.
27
enum class ModRefInfo : uint8_t {
28
  /// The access neither references nor modifies the value stored in memory.
29
  NoModRef = 0,
30
  /// The access may reference the value stored in memory.
31
  Ref = 1,
32
  /// The access may modify the value stored in memory.
33
  Mod = 2,
34
  /// The access may reference and may modify the value stored in memory.
35
  ModRef = Ref | Mod,
36
  LLVM_MARK_AS_BITMASK_ENUM(ModRef),
37
};
38
 
39
[[nodiscard]] inline bool isNoModRef(const ModRefInfo MRI) {
40
  return MRI == ModRefInfo::NoModRef;
41
}
42
[[nodiscard]] inline bool isModOrRefSet(const ModRefInfo MRI) {
43
  return MRI != ModRefInfo::NoModRef;
44
}
45
[[nodiscard]] inline bool isModAndRefSet(const ModRefInfo MRI) {
46
  return MRI == ModRefInfo::ModRef;
47
}
48
[[nodiscard]] inline bool isModSet(const ModRefInfo MRI) {
49
  return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod);
50
}
51
[[nodiscard]] inline bool isRefSet(const ModRefInfo MRI) {
52
  return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref);
53
}
54
 
55
/// Debug print ModRefInfo.
56
raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
57
 
58
/// Summary of how a function affects memory in the program.
59
///
60
/// Loads from constant globals are not considered memory accesses for this
61
/// interface. Also, functions may freely modify stack space local to their
62
/// invocation without having to report it through these interfaces.
63
class MemoryEffects {
64
public:
65
  /// The locations at which a function might access memory.
66
  enum Location {
67
    /// Access to memory via argument pointers.
68
    ArgMem = 0,
69
    /// Memory that is inaccessible via LLVM IR.
70
    InaccessibleMem = 1,
71
    /// Any other memory.
72
    Other = 2,
73
  };
74
 
75
private:
76
  uint32_t Data = 0;
77
 
78
  static constexpr uint32_t BitsPerLoc = 2;
79
  static constexpr uint32_t LocMask = (1 << BitsPerLoc) - 1;
80
 
81
  static uint32_t getLocationPos(Location Loc) {
82
    return (uint32_t)Loc * BitsPerLoc;
83
  }
84
 
85
  MemoryEffects(uint32_t Data) : Data(Data) {}
86
 
87
  void setModRef(Location Loc, ModRefInfo MR) {
88
    Data &= ~(LocMask << getLocationPos(Loc));
89
    Data |= static_cast<uint32_t>(MR) << getLocationPos(Loc);
90
  }
91
 
92
  friend raw_ostream &operator<<(raw_ostream &OS, MemoryEffects RMRB);
93
 
94
public:
95
  /// Returns iterator over all supported location kinds.
96
  static auto locations() {
97
    return enum_seq_inclusive(Location::ArgMem, Location::Other,
98
                              force_iteration_on_noniterable_enum);
99
  }
100
 
101
  /// Create MemoryEffects that can access only the given location with the
102
  /// given ModRefInfo.
103
  MemoryEffects(Location Loc, ModRefInfo MR) { setModRef(Loc, MR); }
104
 
105
  /// Create MemoryEffects that can access any location with the given
106
  /// ModRefInfo.
107
  explicit MemoryEffects(ModRefInfo MR) {
108
    for (Location Loc : locations())
109
      setModRef(Loc, MR);
110
  }
111
 
112
  /// Create MemoryEffects that can read and write any memory.
113
  static MemoryEffects unknown() {
114
    return MemoryEffects(ModRefInfo::ModRef);
115
  }
116
 
117
  /// Create MemoryEffects that cannot read or write any memory.
118
  static MemoryEffects none() {
119
    return MemoryEffects(ModRefInfo::NoModRef);
120
  }
121
 
122
  /// Create MemoryEffects that can read any memory.
123
  static MemoryEffects readOnly() {
124
    return MemoryEffects(ModRefInfo::Ref);
125
  }
126
 
127
  /// Create MemoryEffects that can write any memory.
128
  static MemoryEffects writeOnly() {
129
    return MemoryEffects(ModRefInfo::Mod);
130
  }
131
 
132
  /// Create MemoryEffects that can only access argument memory.
133
  static MemoryEffects argMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
134
    return MemoryEffects(ArgMem, MR);
135
  }
136
 
137
  /// Create MemoryEffects that can only access inaccessible memory.
138
  static MemoryEffects inaccessibleMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
139
    return MemoryEffects(InaccessibleMem, MR);
140
  }
141
 
142
  /// Create MemoryEffects that can only access inaccessible or argument memory.
143
  static MemoryEffects
144
  inaccessibleOrArgMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
145
    MemoryEffects FRMB = none();
146
    FRMB.setModRef(ArgMem, MR);
147
    FRMB.setModRef(InaccessibleMem, MR);
148
    return FRMB;
149
  }
150
 
151
  /// Create MemoryEffects from an encoded integer value (used by memory
152
  /// attribute).
153
  static MemoryEffects createFromIntValue(uint32_t Data) {
154
    return MemoryEffects(Data);
155
  }
156
 
157
  /// Convert MemoryEffects into an encoded integer value (used by memory
158
  /// attribute).
159
  uint32_t toIntValue() const {
160
    return Data;
161
  }
162
 
163
  /// Get ModRefInfo for the given Location.
164
  ModRefInfo getModRef(Location Loc) const {
165
    return ModRefInfo((Data >> getLocationPos(Loc)) & LocMask);
166
  }
167
 
168
  /// Get new MemoryEffects with modified ModRefInfo for Loc.
169
  MemoryEffects getWithModRef(Location Loc, ModRefInfo MR) const {
170
    MemoryEffects ME = *this;
171
    ME.setModRef(Loc, MR);
172
    return ME;
173
  }
174
 
175
  /// Get new MemoryEffects with NoModRef on the given Loc.
176
  MemoryEffects getWithoutLoc(Location Loc) const {
177
    MemoryEffects ME = *this;
178
    ME.setModRef(Loc, ModRefInfo::NoModRef);
179
    return ME;
180
  }
181
 
182
  /// Get ModRefInfo for any location.
183
  ModRefInfo getModRef() const {
184
    ModRefInfo MR = ModRefInfo::NoModRef;
185
    for (Location Loc : locations())
186
      MR |= getModRef(Loc);
187
    return MR;
188
  }
189
 
190
  /// Whether this function accesses no memory.
191
  bool doesNotAccessMemory() const { return Data == 0; }
192
 
193
  /// Whether this function only (at most) reads memory.
194
  bool onlyReadsMemory() const { return !isModSet(getModRef()); }
195
 
196
  /// Whether this function only (at most) writes memory.
197
  bool onlyWritesMemory() const { return !isRefSet(getModRef()); }
198
 
199
  /// Whether this function only (at most) accesses argument memory.
200
  bool onlyAccessesArgPointees() const {
201
    return getWithoutLoc(ArgMem).doesNotAccessMemory();
202
  }
203
 
204
  /// Whether this function may access argument memory.
205
  bool doesAccessArgPointees() const {
206
    return isModOrRefSet(getModRef(ArgMem));
207
  }
208
 
209
  /// Whether this function only (at most) accesses inaccessible memory.
210
  bool onlyAccessesInaccessibleMem() const {
211
    return getWithoutLoc(InaccessibleMem).doesNotAccessMemory();
212
  }
213
 
214
  /// Whether this function only (at most) accesses argument and inaccessible
215
  /// memory.
216
  bool onlyAccessesInaccessibleOrArgMem() const {
217
    return isNoModRef(getModRef(Other));
218
  }
219
 
220
  /// Intersect with other MemoryEffects.
221
  MemoryEffects operator&(MemoryEffects Other) const {
222
    return MemoryEffects(Data & Other.Data);
223
  }
224
 
225
  /// Intersect (in-place) with other MemoryEffects.
226
  MemoryEffects &operator&=(MemoryEffects Other) {
227
    Data &= Other.Data;
228
    return *this;
229
  }
230
 
231
  /// Union with other MemoryEffects.
232
  MemoryEffects operator|(MemoryEffects Other) const {
233
    return MemoryEffects(Data | Other.Data);
234
  }
235
 
236
  /// Union (in-place) with other MemoryEffects.
237
  MemoryEffects &operator|=(MemoryEffects Other) {
238
    Data |= Other.Data;
239
    return *this;
240
  }
241
 
242
  /// Check whether this is the same as other MemoryEffects.
243
  bool operator==(MemoryEffects Other) const {
244
    return Data == Other.Data;
245
  }
246
 
247
  /// Check whether this is different from other MemoryEffects.
248
  bool operator!=(MemoryEffects Other) const {
249
    return !operator==(Other);
250
  }
251
};
252
 
253
/// Debug print MemoryEffects.
254
raw_ostream &operator<<(raw_ostream &OS, MemoryEffects RMRB);
255
 
256
// Legacy alias.
257
using FunctionModRefBehavior = MemoryEffects;
258
 
259
} // namespace llvm
260
 
261
#endif