Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  262.