[llvm] 8eabb5b - [ModRef] Move ModRefInfo and FunctionModRefBehavior into IR (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 13 03:11:15 PDT 2022


Author: Nikita Popov
Date: 2022-10-13T12:11:04+02:00
New Revision: 8eabb5b9f5461c4dcfc5b15fe0263481ca0b9ec7

URL: https://github.com/llvm/llvm-project/commit/8eabb5b9f5461c4dcfc5b15fe0263481ca0b9ec7
DIFF: https://github.com/llvm/llvm-project/commit/8eabb5b9f5461c4dcfc5b15fe0263481ca0b9ec7.diff

LOG: [ModRef] Move ModRefInfo and FunctionModRefBehavior into IR (NFC)

This is in preparation for
https://discourse.llvm.org/t/rfc-unify-memory-effect-attributes/65579.
FunctionModRefBehavior will be used by attributes, and as such has
to be available in IR, not just Analysis.

Differential Revision: https://reviews.llvm.org/D135589

Added: 
    llvm/include/llvm/IR/ModRef.h

Modified: 
    llvm/include/llvm/Analysis/AliasAnalysis.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h
index fcbf88d2574e..51d4b2185e5e 100644
--- a/llvm/include/llvm/Analysis/AliasAnalysis.h
+++ b/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -42,6 +42,7 @@
 #include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/IR/ModRef.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Pass.h"
 #include <cstdint>
@@ -140,226 +141,6 @@ static_assert(sizeof(AliasResult) == 4,
 /// << operator for AliasResult.
 raw_ostream &operator<<(raw_ostream &OS, AliasResult AR);
 
-/// Flags indicating whether a memory access modifies or references memory.
-///
-/// This is no access at all, a modification, a reference, or both
-/// a modification and a reference.
-enum class ModRefInfo : uint8_t {
-  /// The access neither references nor modifies the value stored in memory.
-  NoModRef = 0,
-  /// The access may reference the value stored in memory.
-  Ref = 1,
-  /// The access may modify the value stored in memory.
-  Mod = 2,
-  /// The access may reference and may modify the value stored in memory.
-  ModRef = Ref | Mod,
-  LLVM_MARK_AS_BITMASK_ENUM(ModRef),
-};
-
-[[nodiscard]] inline bool isNoModRef(const ModRefInfo MRI) {
-  return MRI == ModRefInfo::NoModRef;
-}
-[[nodiscard]] inline bool isModOrRefSet(const ModRefInfo MRI) {
-  return MRI != ModRefInfo::NoModRef;
-}
-[[nodiscard]] inline bool isModAndRefSet(const ModRefInfo MRI) {
-  return MRI == ModRefInfo::ModRef;
-}
-[[nodiscard]] inline bool isModSet(const ModRefInfo MRI) {
-  return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod);
-}
-[[nodiscard]] inline bool isRefSet(const ModRefInfo MRI) {
-  return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref);
-}
-
-/// Debug print ModRefInfo.
-raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
-
-/// Summary of how a function affects memory in the program.
-///
-/// Loads from constant globals are not considered memory accesses for this
-/// interface. Also, functions may freely modify stack space local to their
-/// invocation without having to report it through these interfaces.
-class FunctionModRefBehavior {
-public:
-  /// The locations at which a function might access memory.
-  enum Location {
-    /// Access to memory via argument pointers.
-    ArgMem = 0,
-    /// Memory that is inaccessible via LLVM IR.
-    InaccessibleMem = 1,
-    /// Any other memory.
-    Other = 2,
-  };
-
-private:
-  uint32_t Data = 0;
-
-  static constexpr uint32_t BitsPerLoc = 2;
-  static constexpr uint32_t LocMask = (1 << BitsPerLoc) - 1;
-
-  static uint32_t getLocationPos(Location Loc) {
-    return (uint32_t)Loc * BitsPerLoc;
-  }
-
-  static auto locations() {
-    return enum_seq_inclusive(Location::ArgMem, Location::Other,
-                              force_iteration_on_noniterable_enum);
-  }
-
-  FunctionModRefBehavior(uint32_t Data) : Data(Data) {}
-
-  void setModRef(Location Loc, ModRefInfo MR) {
-    Data &= ~(LocMask << getLocationPos(Loc));
-    Data |= static_cast<uint32_t>(MR) << getLocationPos(Loc);
-  }
-
-  friend raw_ostream &operator<<(raw_ostream &OS, FunctionModRefBehavior RMRB);
-
-public:
-  /// Create FunctionModRefBehavior that can access only the given location
-  /// with the given ModRefInfo.
-  FunctionModRefBehavior(Location Loc, ModRefInfo MR) { setModRef(Loc, MR); }
-
-  /// Create FunctionModRefBehavior that can access any location with the
-  /// given ModRefInfo.
-  explicit FunctionModRefBehavior(ModRefInfo MR) {
-    for (Location Loc : locations())
-      setModRef(Loc, MR);
-  }
-
-  /// Create FunctionModRefBehavior that can read and write any memory.
-  static FunctionModRefBehavior unknown() {
-    return FunctionModRefBehavior(ModRefInfo::ModRef);
-  }
-
-  /// Create FunctionModRefBehavior that cannot read or write any memory.
-  static FunctionModRefBehavior none() {
-    return FunctionModRefBehavior(ModRefInfo::NoModRef);
-  }
-
-  /// Create FunctionModRefBehavior that can read any memory.
-  static FunctionModRefBehavior readOnly() {
-    return FunctionModRefBehavior(ModRefInfo::Ref);
-  }
-
-  /// Create FunctionModRefBehavior that can write any memory.
-  static FunctionModRefBehavior writeOnly() {
-    return FunctionModRefBehavior(ModRefInfo::Mod);
-  }
-
-  /// Create FunctionModRefBehavior that can only access argument memory.
-  static FunctionModRefBehavior argMemOnly(ModRefInfo MR) {
-    return FunctionModRefBehavior(ArgMem, MR);
-  }
-
-  /// Create FunctionModRefBehavior that can only access inaccessible memory.
-  static FunctionModRefBehavior inaccessibleMemOnly(ModRefInfo MR) {
-    return FunctionModRefBehavior(InaccessibleMem, MR);
-  }
-
-  /// Create FunctionModRefBehavior that can only access inaccessible or
-  /// argument memory.
-  static FunctionModRefBehavior inaccessibleOrArgMemOnly(ModRefInfo MR) {
-    FunctionModRefBehavior FRMB = none();
-    FRMB.setModRef(ArgMem, MR);
-    FRMB.setModRef(InaccessibleMem, MR);
-    return FRMB;
-  }
-
-  /// Get ModRefInfo for the given Location.
-  ModRefInfo getModRef(Location Loc) const {
-    return ModRefInfo((Data >> getLocationPos(Loc)) & LocMask);
-  }
-
-  /// Get new FunctionModRefBehavior with modified ModRefInfo for Loc.
-  FunctionModRefBehavior getWithModRef(Location Loc, ModRefInfo MR) const {
-    FunctionModRefBehavior FMRB = *this;
-    FMRB.setModRef(Loc, MR);
-    return FMRB;
-  }
-
-  /// Get new FunctionModRefBehavior with NoModRef on the given Loc.
-  FunctionModRefBehavior getWithoutLoc(Location Loc) const {
-    FunctionModRefBehavior FMRB = *this;
-    FMRB.setModRef(Loc, ModRefInfo::NoModRef);
-    return FMRB;
-  }
-
-  /// Get ModRefInfo for any location.
-  ModRefInfo getModRef() const {
-    ModRefInfo MR = ModRefInfo::NoModRef;
-    for (Location Loc : locations())
-      MR |= getModRef(Loc);
-    return MR;
-  }
-
-  /// Whether this function accesses no memory.
-  bool doesNotAccessMemory() const { return Data == 0; }
-
-  /// Whether this function only (at most) reads memory.
-  bool onlyReadsMemory() const { return !isModSet(getModRef()); }
-
-  /// Whether this function only (at most) writes memory.
-  bool onlyWritesMemory() const { return !isRefSet(getModRef()); }
-
-  /// Whether this function only (at most) accesses argument memory.
-  bool onlyAccessesArgPointees() const {
-    return getWithoutLoc(ArgMem).doesNotAccessMemory();
-  }
-
-  /// Whether this function may access argument memory.
-  bool doesAccessArgPointees() const {
-    return isModOrRefSet(getModRef(ArgMem));
-  }
-
-  /// Whether this function only (at most) accesses inaccessible memory.
-  bool onlyAccessesInaccessibleMem() const {
-    return getWithoutLoc(InaccessibleMem).doesNotAccessMemory();
-  }
-
-  /// Whether this function only (at most) accesses argument and inaccessible
-  /// memory.
-  bool onlyAccessesInaccessibleOrArgMem() const {
-    return isNoModRef(getModRef(Other));
-  }
-
-  /// Intersect with another FunctionModRefBehavior.
-  FunctionModRefBehavior operator&(FunctionModRefBehavior Other) const {
-    return FunctionModRefBehavior(Data & Other.Data);
-  }
-
-  /// Intersect (in-place) with another FunctionModRefBehavior.
-  FunctionModRefBehavior &operator&=(FunctionModRefBehavior Other) {
-    Data &= Other.Data;
-    return *this;
-  }
-
-  /// Union with another FunctionModRefBehavior.
-  FunctionModRefBehavior operator|(FunctionModRefBehavior Other) const {
-    return FunctionModRefBehavior(Data | Other.Data);
-  }
-
-  /// Union (in-place) with another FunctionModRefBehavior.
-  FunctionModRefBehavior &operator|=(FunctionModRefBehavior Other) {
-    Data |= Other.Data;
-    return *this;
-  }
-
-  /// Check whether this is the same as another FunctionModRefBehavior.
-  bool operator==(FunctionModRefBehavior Other) const {
-    return Data == Other.Data;
-  }
-
-  /// Check whether this is 
diff erent from another FunctionModRefBehavior.
-  bool operator!=(FunctionModRefBehavior Other) const {
-    return !operator==(Other);
-  }
-};
-
-/// Debug print FunctionModRefBehavior.
-raw_ostream &operator<<(raw_ostream &OS, FunctionModRefBehavior RMRB);
-
 /// Virtual base class for providers of capture information.
 struct CaptureInfo {
   virtual ~CaptureInfo() = 0;

diff  --git a/llvm/include/llvm/IR/ModRef.h b/llvm/include/llvm/IR/ModRef.h
new file mode 100644
index 000000000000..1e314272e05c
--- /dev/null
+++ b/llvm/include/llvm/IR/ModRef.h
@@ -0,0 +1,243 @@
+//===--- ModRef.h - Memory effect modelling ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Definitions of ModRefInfo and FunctionModRefBehavior, which are used to
+// describe the memory effects of instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_MODREF_H
+#define LLVM_IR_MODREF_H
+
+#include "llvm/ADT/BitmaskEnum.h"
+
+namespace llvm {
+
+/// Flags indicating whether a memory access modifies or references memory.
+///
+/// This is no access at all, a modification, a reference, or both
+/// a modification and a reference.
+enum class ModRefInfo : uint8_t {
+  /// The access neither references nor modifies the value stored in memory.
+  NoModRef = 0,
+  /// The access may reference the value stored in memory.
+  Ref = 1,
+  /// The access may modify the value stored in memory.
+  Mod = 2,
+  /// The access may reference and may modify the value stored in memory.
+  ModRef = Ref | Mod,
+  LLVM_MARK_AS_BITMASK_ENUM(ModRef),
+};
+
+[[nodiscard]] inline bool isNoModRef(const ModRefInfo MRI) {
+  return MRI == ModRefInfo::NoModRef;
+}
+[[nodiscard]] inline bool isModOrRefSet(const ModRefInfo MRI) {
+  return MRI != ModRefInfo::NoModRef;
+}
+[[nodiscard]] inline bool isModAndRefSet(const ModRefInfo MRI) {
+  return MRI == ModRefInfo::ModRef;
+}
+[[nodiscard]] inline bool isModSet(const ModRefInfo MRI) {
+  return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod);
+}
+[[nodiscard]] inline bool isRefSet(const ModRefInfo MRI) {
+  return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref);
+}
+
+/// Debug print ModRefInfo.
+raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
+
+/// Summary of how a function affects memory in the program.
+///
+/// Loads from constant globals are not considered memory accesses for this
+/// interface. Also, functions may freely modify stack space local to their
+/// invocation without having to report it through these interfaces.
+class FunctionModRefBehavior {
+public:
+  /// The locations at which a function might access memory.
+  enum Location {
+    /// Access to memory via argument pointers.
+    ArgMem = 0,
+    /// Memory that is inaccessible via LLVM IR.
+    InaccessibleMem = 1,
+    /// Any other memory.
+    Other = 2,
+  };
+
+private:
+  uint32_t Data = 0;
+
+  static constexpr uint32_t BitsPerLoc = 2;
+  static constexpr uint32_t LocMask = (1 << BitsPerLoc) - 1;
+
+  static uint32_t getLocationPos(Location Loc) {
+    return (uint32_t)Loc * BitsPerLoc;
+  }
+
+  static auto locations() {
+    return enum_seq_inclusive(Location::ArgMem, Location::Other,
+                              force_iteration_on_noniterable_enum);
+  }
+
+  FunctionModRefBehavior(uint32_t Data) : Data(Data) {}
+
+  void setModRef(Location Loc, ModRefInfo MR) {
+    Data &= ~(LocMask << getLocationPos(Loc));
+    Data |= static_cast<uint32_t>(MR) << getLocationPos(Loc);
+  }
+
+  friend raw_ostream &operator<<(raw_ostream &OS, FunctionModRefBehavior RMRB);
+
+public:
+  /// Create FunctionModRefBehavior that can access only the given location
+  /// with the given ModRefInfo.
+  FunctionModRefBehavior(Location Loc, ModRefInfo MR) { setModRef(Loc, MR); }
+
+  /// Create FunctionModRefBehavior that can access any location with the
+  /// given ModRefInfo.
+  explicit FunctionModRefBehavior(ModRefInfo MR) {
+    for (Location Loc : locations())
+      setModRef(Loc, MR);
+  }
+
+  /// Create FunctionModRefBehavior that can read and write any memory.
+  static FunctionModRefBehavior unknown() {
+    return FunctionModRefBehavior(ModRefInfo::ModRef);
+  }
+
+  /// Create FunctionModRefBehavior that cannot read or write any memory.
+  static FunctionModRefBehavior none() {
+    return FunctionModRefBehavior(ModRefInfo::NoModRef);
+  }
+
+  /// Create FunctionModRefBehavior that can read any memory.
+  static FunctionModRefBehavior readOnly() {
+    return FunctionModRefBehavior(ModRefInfo::Ref);
+  }
+
+  /// Create FunctionModRefBehavior that can write any memory.
+  static FunctionModRefBehavior writeOnly() {
+    return FunctionModRefBehavior(ModRefInfo::Mod);
+  }
+
+  /// Create FunctionModRefBehavior that can only access argument memory.
+  static FunctionModRefBehavior argMemOnly(ModRefInfo MR) {
+    return FunctionModRefBehavior(ArgMem, MR);
+  }
+
+  /// Create FunctionModRefBehavior that can only access inaccessible memory.
+  static FunctionModRefBehavior inaccessibleMemOnly(ModRefInfo MR) {
+    return FunctionModRefBehavior(InaccessibleMem, MR);
+  }
+
+  /// Create FunctionModRefBehavior that can only access inaccessible or
+  /// argument memory.
+  static FunctionModRefBehavior inaccessibleOrArgMemOnly(ModRefInfo MR) {
+    FunctionModRefBehavior FRMB = none();
+    FRMB.setModRef(ArgMem, MR);
+    FRMB.setModRef(InaccessibleMem, MR);
+    return FRMB;
+  }
+
+  /// Get ModRefInfo for the given Location.
+  ModRefInfo getModRef(Location Loc) const {
+    return ModRefInfo((Data >> getLocationPos(Loc)) & LocMask);
+  }
+
+  /// Get new FunctionModRefBehavior with modified ModRefInfo for Loc.
+  FunctionModRefBehavior getWithModRef(Location Loc, ModRefInfo MR) const {
+    FunctionModRefBehavior FMRB = *this;
+    FMRB.setModRef(Loc, MR);
+    return FMRB;
+  }
+
+  /// Get new FunctionModRefBehavior with NoModRef on the given Loc.
+  FunctionModRefBehavior getWithoutLoc(Location Loc) const {
+    FunctionModRefBehavior FMRB = *this;
+    FMRB.setModRef(Loc, ModRefInfo::NoModRef);
+    return FMRB;
+  }
+
+  /// Get ModRefInfo for any location.
+  ModRefInfo getModRef() const {
+    ModRefInfo MR = ModRefInfo::NoModRef;
+    for (Location Loc : locations())
+      MR |= getModRef(Loc);
+    return MR;
+  }
+
+  /// Whether this function accesses no memory.
+  bool doesNotAccessMemory() const { return Data == 0; }
+
+  /// Whether this function only (at most) reads memory.
+  bool onlyReadsMemory() const { return !isModSet(getModRef()); }
+
+  /// Whether this function only (at most) writes memory.
+  bool onlyWritesMemory() const { return !isRefSet(getModRef()); }
+
+  /// Whether this function only (at most) accesses argument memory.
+  bool onlyAccessesArgPointees() const {
+    return getWithoutLoc(ArgMem).doesNotAccessMemory();
+  }
+
+  /// Whether this function may access argument memory.
+  bool doesAccessArgPointees() const {
+    return isModOrRefSet(getModRef(ArgMem));
+  }
+
+  /// Whether this function only (at most) accesses inaccessible memory.
+  bool onlyAccessesInaccessibleMem() const {
+    return getWithoutLoc(InaccessibleMem).doesNotAccessMemory();
+  }
+
+  /// Whether this function only (at most) accesses argument and inaccessible
+  /// memory.
+  bool onlyAccessesInaccessibleOrArgMem() const {
+    return isNoModRef(getModRef(Other));
+  }
+
+  /// Intersect with another FunctionModRefBehavior.
+  FunctionModRefBehavior operator&(FunctionModRefBehavior Other) const {
+    return FunctionModRefBehavior(Data & Other.Data);
+  }
+
+  /// Intersect (in-place) with another FunctionModRefBehavior.
+  FunctionModRefBehavior &operator&=(FunctionModRefBehavior Other) {
+    Data &= Other.Data;
+    return *this;
+  }
+
+  /// Union with another FunctionModRefBehavior.
+  FunctionModRefBehavior operator|(FunctionModRefBehavior Other) const {
+    return FunctionModRefBehavior(Data | Other.Data);
+  }
+
+  /// Union (in-place) with another FunctionModRefBehavior.
+  FunctionModRefBehavior &operator|=(FunctionModRefBehavior Other) {
+    Data |= Other.Data;
+    return *this;
+  }
+
+  /// Check whether this is the same as another FunctionModRefBehavior.
+  bool operator==(FunctionModRefBehavior Other) const {
+    return Data == Other.Data;
+  }
+
+  /// Check whether this is 
diff erent from another FunctionModRefBehavior.
+  bool operator!=(FunctionModRefBehavior Other) const {
+    return !operator==(Other);
+  }
+};
+
+/// Debug print FunctionModRefBehavior.
+raw_ostream &operator<<(raw_ostream &OS, FunctionModRefBehavior RMRB);
+
+} // namespace llvm
+
+#endif


        


More information about the llvm-commits mailing list