LCOV - code coverage report
Current view: top level - include/llvm/CodeGen - MachineMemOperand.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 40 97.5 %
Date: 2017-09-14 15:23:50 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //==- llvm/CodeGen/MachineMemOperand.h - MachineMemOperand class -*- C++ -*-==//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file contains the declaration of the MachineMemOperand class, which is a
      11             : // description of a memory reference. It is used to help track dependencies
      12             : // in the backend.
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #ifndef LLVM_CODEGEN_MACHINEMEMOPERAND_H
      17             : #define LLVM_CODEGEN_MACHINEMEMOPERAND_H
      18             : 
      19             : #include "llvm/ADT/BitmaskEnum.h"
      20             : #include "llvm/ADT/PointerUnion.h"
      21             : #include "llvm/CodeGen/PseudoSourceValue.h"
      22             : #include "llvm/IR/Instructions.h"
      23             : #include "llvm/IR/Metadata.h"
      24             : #include "llvm/IR/Value.h" // PointerLikeTypeTraits<Value*>
      25             : #include "llvm/Support/AtomicOrdering.h"
      26             : #include "llvm/Support/DataTypes.h"
      27             : 
      28             : namespace llvm {
      29             : 
      30             : class FoldingSetNodeID;
      31             : class MDNode;
      32             : class raw_ostream;
      33             : class MachineFunction;
      34             : class ModuleSlotTracker;
      35             : 
      36             : /// This class contains a discriminated union of information about pointers in
      37             : /// memory operands, relating them back to LLVM IR or to virtual locations (such
      38             : /// as frame indices) that are exposed during codegen.
      39             : struct MachinePointerInfo {
      40             :   /// This is the IR pointer value for the access, or it is null if unknown.
      41             :   /// If this is null, then the access is to a pointer in the default address
      42             :   /// space.
      43             :   PointerUnion<const Value *, const PseudoSourceValue *> V;
      44             : 
      45             :   /// Offset - This is an offset from the base Value*.
      46             :   int64_t Offset;
      47             : 
      48             :   uint8_t StackID;
      49             : 
      50             :   explicit MachinePointerInfo(const Value *v = nullptr, int64_t offset = 0,
      51             :                               uint8_t ID = 0)
      52     1864796 :     : V(v), Offset(offset), StackID(ID) {}
      53             : 
      54             :   explicit MachinePointerInfo(const PseudoSourceValue *v,
      55             :                               int64_t offset = 0,
      56             :                               uint8_t ID = 0)
      57      677230 :     : V(v), Offset(offset), StackID(ID) {}
      58             : 
      59             :   MachinePointerInfo getWithOffset(int64_t O) const {
      60      474334 :     if (V.isNull()) return MachinePointerInfo();
      61      460304 :     if (V.is<const Value*>())
      62      410440 :       return MachinePointerInfo(V.get<const Value*>(), Offset+O, StackID);
      63       23531 :     return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset+O,
      64       73395 :                               StackID);
      65             :   }
      66             : 
      67             :   /// Return true if memory region [V, V+Offset+Size) is known to be
      68             :   /// dereferenceable.
      69             :   bool isDereferenceable(unsigned Size, LLVMContext &C,
      70             :                          const DataLayout &DL) const;
      71             : 
      72             :   /// Return the LLVM IR address space number that this pointer points into.
      73             :   unsigned getAddrSpace() const;
      74             : 
      75             :   /// Return a MachinePointerInfo record that refers to the constant pool.
      76             :   static MachinePointerInfo getConstantPool(MachineFunction &MF);
      77             : 
      78             :   /// Return a MachinePointerInfo record that refers to the specified
      79             :   /// FrameIndex.
      80             :   static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI,
      81             :                                           int64_t Offset = 0);
      82             : 
      83             :   /// Return a MachinePointerInfo record that refers to a jump table entry.
      84             :   static MachinePointerInfo getJumpTable(MachineFunction &MF);
      85             : 
      86             :   /// Return a MachinePointerInfo record that refers to a GOT entry.
      87             :   static MachinePointerInfo getGOT(MachineFunction &MF);
      88             : 
      89             :   /// Stack pointer relative access.
      90             :   static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset,
      91             :                                      uint8_t ID = 0);
      92             : };
      93             : 
      94             : 
      95             : //===----------------------------------------------------------------------===//
      96             : /// A description of a memory reference used in the backend.
      97             : /// Instead of holding a StoreInst or LoadInst, this class holds the address
      98             : /// Value of the reference along with a byte size and offset. This allows it
      99             : /// to describe lowered loads and stores. Also, the special PseudoSourceValue
     100             : /// objects can be used to represent loads and stores to memory locations
     101             : /// that aren't explicit in the regular LLVM IR.
     102             : ///
     103             : class MachineMemOperand {
     104             : public:
     105             :   /// Flags values. These may be or'd together.
     106             :   enum Flags : uint16_t {
     107             :     // No flags set.
     108             :     MONone = 0,
     109             :     /// The memory access reads data.
     110             :     MOLoad = 1u << 0,
     111             :     /// The memory access writes data.
     112             :     MOStore = 1u << 1,
     113             :     /// The memory access is volatile.
     114             :     MOVolatile = 1u << 2,
     115             :     /// The memory access is non-temporal.
     116             :     MONonTemporal = 1u << 3,
     117             :     /// The memory access is dereferenceable (i.e., doesn't trap).
     118             :     MODereferenceable = 1u << 4,
     119             :     /// The memory access always returns the same value (or traps).
     120             :     MOInvariant = 1u << 5,
     121             : 
     122             :     // Reserved for use by target-specific passes.
     123             :     // Targets may override getSerializableMachineMemOperandTargetFlags() to
     124             :     // enable MIR serialization/parsing of these flags.  If more of these flags
     125             :     // are added, the MIR printing/parsing code will need to be updated as well.
     126             :     MOTargetFlag1 = 1u << 6,
     127             :     MOTargetFlag2 = 1u << 7,
     128             :     MOTargetFlag3 = 1u << 8,
     129             : 
     130             :     LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ MOTargetFlag3)
     131             :   };
     132             : 
     133             : private:
     134             :   /// Atomic information for this memory operation.
     135             :   struct MachineAtomicInfo {
     136             :     /// Synchronization scope ID for this memory operation.
     137             :     unsigned SSID : 8;            // SyncScope::ID
     138             :     /// Atomic ordering requirements for this memory operation. For cmpxchg
     139             :     /// atomic operations, atomic ordering requirements when store occurs.
     140             :     unsigned Ordering : 4;        // enum AtomicOrdering
     141             :     /// For cmpxchg atomic operations, atomic ordering requirements when store
     142             :     /// does not occur.
     143             :     unsigned FailureOrdering : 4; // enum AtomicOrdering
     144             :   };
     145             : 
     146             :   MachinePointerInfo PtrInfo;
     147             :   uint64_t Size;
     148             :   Flags FlagVals;
     149             :   uint16_t BaseAlignLog2; // log_2(base_alignment) + 1
     150             :   MachineAtomicInfo AtomicInfo;
     151             :   AAMDNodes AAInfo;
     152             :   const MDNode *Ranges;
     153             : 
     154             : public:
     155             :   /// Construct a MachineMemOperand object with the specified PtrInfo, flags,
     156             :   /// size, and base alignment. For atomic operations the synchronization scope
     157             :   /// and atomic ordering requirements must also be specified. For cmpxchg
     158             :   /// atomic operations the atomic ordering requirements when store does not
     159             :   /// occur must also be specified.
     160             :   MachineMemOperand(MachinePointerInfo PtrInfo, Flags flags, uint64_t s,
     161             :                     unsigned base_alignment,
     162             :                     const AAMDNodes &AAInfo = AAMDNodes(),
     163             :                     const MDNode *Ranges = nullptr,
     164             :                     SyncScope::ID SSID = SyncScope::System,
     165             :                     AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
     166             :                     AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
     167             : 
     168    13302364 :   const MachinePointerInfo &getPointerInfo() const { return PtrInfo; }
     169             : 
     170             :   /// Return the base address of the memory access. This may either be a normal
     171             :   /// LLVM IR Value, or one of the special values used in CodeGen.
     172             :   /// Special values are those obtained via
     173             :   /// PseudoSourceValue::getFixedStack(int), PseudoSourceValue::getStack, and
     174             :   /// other PseudoSourceValue member functions which return objects which stand
     175             :   /// for frame/stack pointer relative references and other special references
     176             :   /// which are not representable in the high-level IR.
     177    16831917 :   const Value *getValue() const { return PtrInfo.V.dyn_cast<const Value*>(); }
     178             : 
     179             :   const PseudoSourceValue *getPseudoValue() const {
     180    13384195 :     return PtrInfo.V.dyn_cast<const PseudoSourceValue*>();
     181             :   }
     182             : 
     183           0 :   const void *getOpaqueValue() const { return PtrInfo.V.getOpaqueValue(); }
     184             : 
     185             :   /// Return the raw flags of the source value, \see Flags.
     186             :   Flags getFlags() const { return FlagVals; }
     187             : 
     188             :   /// Bitwise OR the current flags with the given flags.
     189          22 :   void setFlags(Flags f) { FlagVals |= f; }
     190             : 
     191             :   /// For normal values, this is a byte offset added to the base address.
     192             :   /// For PseudoSourceValue::FPRel values, this is the FrameIndex number.
     193             :   int64_t getOffset() const { return PtrInfo.Offset; }
     194             : 
     195      159799 :   unsigned getAddrSpace() const { return PtrInfo.getAddrSpace(); }
     196             : 
     197             :   /// Return the size in bytes of the memory reference.
     198             :   uint64_t getSize() const { return Size; }
     199             : 
     200             :   /// Return the minimum known alignment in bytes of the actual memory
     201             :   /// reference.
     202             :   uint64_t getAlignment() const;
     203             : 
     204             :   /// Return the minimum known alignment in bytes of the base address, without
     205             :   /// the offset.
     206    16382170 :   uint64_t getBaseAlignment() const { return (1u << BaseAlignLog2) >> 1; }
     207             : 
     208             :   /// Return the AA tags for the memory reference.
     209     4489394 :   AAMDNodes getAAInfo() const { return AAInfo; }
     210             : 
     211             :   /// Return the range tag for the memory reference.
     212             :   const MDNode *getRanges() const { return Ranges; }
     213             : 
     214             :   /// Returns the synchronization scope ID for this memory operation.
     215             :   SyncScope::ID getSyncScopeID() const {
     216      117093 :     return static_cast<SyncScope::ID>(AtomicInfo.SSID);
     217             :   }
     218             : 
     219             :   /// Return the atomic ordering requirements for this memory operation. For
     220             :   /// cmpxchg atomic operations, return the atomic ordering requirements when
     221             :   /// store occurs.
     222             :   AtomicOrdering getOrdering() const {
     223       82780 :     return static_cast<AtomicOrdering>(AtomicInfo.Ordering);
     224             :   }
     225             : 
     226             :   /// For cmpxchg atomic operations, return the atomic ordering requirements
     227             :   /// when store does not occur.
     228             :   AtomicOrdering getFailureOrdering() const {
     229       73272 :     return static_cast<AtomicOrdering>(AtomicInfo.FailureOrdering);
     230             :   }
     231             : 
     232     6213357 :   bool isLoad() const { return FlagVals & MOLoad; }
     233     7364818 :   bool isStore() const { return FlagVals & MOStore; }
     234    13394902 :   bool isVolatile() const { return FlagVals & MOVolatile; }
     235     3639574 :   bool isNonTemporal() const { return FlagVals & MONonTemporal; }
     236     3872191 :   bool isDereferenceable() const { return FlagVals & MODereferenceable; }
     237     5585789 :   bool isInvariant() const { return FlagVals & MOInvariant; }
     238             : 
     239             :   /// Returns true if this operation has an atomic ordering requirement of
     240             :   /// unordered or higher, false otherwise.
     241         755 :   bool isAtomic() const { return getOrdering() != AtomicOrdering::NotAtomic; }
     242             : 
     243             :   /// Returns true if this memory operation doesn't have any ordering
     244             :   /// constraints other than normal aliasing. Volatile and atomic memory
     245             :   /// operations can't be reordered.
     246             :   ///
     247             :   /// Currently, we don't model the difference between volatile and atomic
     248             :   /// operations. They should retain their ordering relative to all memory
     249             :   /// operations.
     250     6416258 :   bool isUnordered() const { return !isVolatile(); }
     251             : 
     252             :   /// Update this MachineMemOperand to reflect the alignment of MMO, if it has a
     253             :   /// greater alignment. This must only be used when the new alignment applies
     254             :   /// to all users of this MachineMemOperand.
     255             :   void refineAlignment(const MachineMemOperand *MMO);
     256             : 
     257             :   /// Change the SourceValue for this MachineMemOperand. This should only be
     258             :   /// used when an object is being relocated and all references to it are being
     259             :   /// updated.
     260        7570 :   void setValue(const Value *NewSV) { PtrInfo.V = NewSV; }
     261       53654 :   void setValue(const PseudoSourceValue *NewSV) { PtrInfo.V = NewSV; }
     262             :   void setOffset(int64_t NewOffset) { PtrInfo.Offset = NewOffset; }
     263             : 
     264             :   /// Profile - Gather unique data for the object.
     265             :   ///
     266             :   void Profile(FoldingSetNodeID &ID) const;
     267             : 
     268             :   /// Support for operator<<.
     269             :   /// @{
     270             :   void print(raw_ostream &OS) const;
     271             :   void print(raw_ostream &OS, ModuleSlotTracker &MST) const;
     272             :   /// @}
     273             : 
     274       19608 :   friend bool operator==(const MachineMemOperand &LHS,
     275             :                          const MachineMemOperand &RHS) {
     276       57257 :     return LHS.getValue() == RHS.getValue() &&
     277       53927 :            LHS.getPseudoValue() == RHS.getPseudoValue() &&
     278       35690 :            LHS.getSize() == RHS.getSize() &&
     279       33648 :            LHS.getOffset() == RHS.getOffset() &&
     280       15803 :            LHS.getFlags() == RHS.getFlags() &&
     281       63196 :            LHS.getAAInfo() == RHS.getAAInfo() &&
     282       31590 :            LHS.getRanges() == RHS.getRanges() &&
     283       51179 :            LHS.getAlignment() == RHS.getAlignment() &&
     284       51160 :            LHS.getAddrSpace() == RHS.getAddrSpace();
     285             :   }
     286             : 
     287             :   friend bool operator!=(const MachineMemOperand &LHS,
     288             :                          const MachineMemOperand &RHS) {
     289       19608 :     return !(LHS == RHS);
     290             :   }
     291             : };
     292             : 
     293             : inline raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO) {
     294           3 :   MRO.print(OS);
     295             :   return OS;
     296             : }
     297             : 
     298             : } // End llvm namespace
     299             : 
     300             : #endif

Generated by: LCOV version 1.13