• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/Metadata.h"
23 #include "llvm/IR/Value.h"  // PointerLikeTypeTraits<Value*>
24 #include "llvm/Support/DataTypes.h"
25 
26 namespace llvm {
27 
28 class FoldingSetNodeID;
29 class MDNode;
30 class raw_ostream;
31 class MachineFunction;
32 class ModuleSlotTracker;
33 
34 /// This class contains a discriminated union of information about pointers in
35 /// memory operands, relating them back to LLVM IR or to virtual locations (such
36 /// as frame indices) that are exposed during codegen.
37 struct MachinePointerInfo {
38   /// This is the IR pointer value for the access, or it is null if unknown.
39   /// If this is null, then the access is to a pointer in the default address
40   /// space.
41   PointerUnion<const Value *, const PseudoSourceValue *> V;
42 
43   /// Offset - This is an offset from the base Value*.
44   int64_t Offset;
45 
46   explicit MachinePointerInfo(const Value *v = nullptr, int64_t offset = 0)
VMachinePointerInfo47     : V(v), Offset(offset) {}
48 
49   explicit MachinePointerInfo(const PseudoSourceValue *v,
50                               int64_t offset = 0)
VMachinePointerInfo51     : V(v), Offset(offset) {}
52 
getWithOffsetMachinePointerInfo53   MachinePointerInfo getWithOffset(int64_t O) const {
54     if (V.isNull()) return MachinePointerInfo();
55     if (V.is<const Value*>())
56       return MachinePointerInfo(V.get<const Value*>(), Offset+O);
57     return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset+O);
58   }
59 
60   /// Return the LLVM IR address space number that this pointer points into.
61   unsigned getAddrSpace() const;
62 
63   /// Return a MachinePointerInfo record that refers to the constant pool.
64   static MachinePointerInfo getConstantPool(MachineFunction &MF);
65 
66   /// Return a MachinePointerInfo record that refers to the specified
67   /// FrameIndex.
68   static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI,
69                                           int64_t Offset = 0);
70 
71   /// Return a MachinePointerInfo record that refers to a jump table entry.
72   static MachinePointerInfo getJumpTable(MachineFunction &MF);
73 
74   /// Return a MachinePointerInfo record that refers to a GOT entry.
75   static MachinePointerInfo getGOT(MachineFunction &MF);
76 
77   /// Stack pointer relative access.
78   static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset);
79 };
80 
81 
82 //===----------------------------------------------------------------------===//
83 /// A description of a memory reference used in the backend.
84 /// Instead of holding a StoreInst or LoadInst, this class holds the address
85 /// Value of the reference along with a byte size and offset. This allows it
86 /// to describe lowered loads and stores. Also, the special PseudoSourceValue
87 /// objects can be used to represent loads and stores to memory locations
88 /// that aren't explicit in the regular LLVM IR.
89 ///
90 class MachineMemOperand {
91 public:
92   /// Flags values. These may be or'd together.
93   enum Flags : uint16_t {
94     // No flags set.
95     MONone = 0,
96     /// The memory access reads data.
97     MOLoad = 1u << 0,
98     /// The memory access writes data.
99     MOStore = 1u << 1,
100     /// The memory access is volatile.
101     MOVolatile = 1u << 2,
102     /// The memory access is non-temporal.
103     MONonTemporal = 1u << 3,
104     /// The memory access is invariant.
105     MOInvariant = 1u << 4,
106 
107     // Reserved for use by target-specific passes.
108     MOTargetFlag1 = 1u << 5,
109     MOTargetFlag2 = 1u << 6,
110     MOTargetFlag3 = 1u << 7,
111 
112     LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ MOTargetFlag3)
113   };
114 
115 private:
116   MachinePointerInfo PtrInfo;
117   uint64_t Size;
118   Flags FlagVals;
119   uint16_t BaseAlignLog2; // log_2(base_alignment) + 1
120   AAMDNodes AAInfo;
121   const MDNode *Ranges;
122 
123 public:
124   /// Construct a MachineMemOperand object with the specified PtrInfo, flags,
125   /// size, and base alignment.
126   MachineMemOperand(MachinePointerInfo PtrInfo, Flags flags, uint64_t s,
127                     unsigned base_alignment,
128                     const AAMDNodes &AAInfo = AAMDNodes(),
129                     const MDNode *Ranges = nullptr);
130 
getPointerInfo()131   const MachinePointerInfo &getPointerInfo() const { return PtrInfo; }
132 
133   /// Return the base address of the memory access. This may either be a normal
134   /// LLVM IR Value, or one of the special values used in CodeGen.
135   /// Special values are those obtained via
136   /// PseudoSourceValue::getFixedStack(int), PseudoSourceValue::getStack, and
137   /// other PseudoSourceValue member functions which return objects which stand
138   /// for frame/stack pointer relative references and other special references
139   /// which are not representable in the high-level IR.
getValue()140   const Value *getValue() const { return PtrInfo.V.dyn_cast<const Value*>(); }
141 
getPseudoValue()142   const PseudoSourceValue *getPseudoValue() const {
143     return PtrInfo.V.dyn_cast<const PseudoSourceValue*>();
144   }
145 
getOpaqueValue()146   const void *getOpaqueValue() const { return PtrInfo.V.getOpaqueValue(); }
147 
148   /// Return the raw flags of the source value, \see Flags.
getFlags()149   Flags getFlags() const { return FlagVals; }
150 
151   /// Bitwise OR the current flags with the given flags.
setFlags(Flags f)152   void setFlags(Flags f) { FlagVals |= f; }
153 
154   /// For normal values, this is a byte offset added to the base address.
155   /// For PseudoSourceValue::FPRel values, this is the FrameIndex number.
getOffset()156   int64_t getOffset() const { return PtrInfo.Offset; }
157 
getAddrSpace()158   unsigned getAddrSpace() const { return PtrInfo.getAddrSpace(); }
159 
160   /// Return the size in bytes of the memory reference.
getSize()161   uint64_t getSize() const { return Size; }
162 
163   /// Return the minimum known alignment in bytes of the actual memory
164   /// reference.
165   uint64_t getAlignment() const;
166 
167   /// Return the minimum known alignment in bytes of the base address, without
168   /// the offset.
getBaseAlignment()169   uint64_t getBaseAlignment() const { return (1u << BaseAlignLog2) >> 1; }
170 
171   /// Return the AA tags for the memory reference.
getAAInfo()172   AAMDNodes getAAInfo() const { return AAInfo; }
173 
174   /// Return the range tag for the memory reference.
getRanges()175   const MDNode *getRanges() const { return Ranges; }
176 
isLoad()177   bool isLoad() const { return FlagVals & MOLoad; }
isStore()178   bool isStore() const { return FlagVals & MOStore; }
isVolatile()179   bool isVolatile() const { return FlagVals & MOVolatile; }
isNonTemporal()180   bool isNonTemporal() const { return FlagVals & MONonTemporal; }
isInvariant()181   bool isInvariant() const { return FlagVals & MOInvariant; }
182 
183   /// Returns true if this memory operation doesn't have any ordering
184   /// constraints other than normal aliasing. Volatile and atomic memory
185   /// operations can't be reordered.
186   ///
187   /// Currently, we don't model the difference between volatile and atomic
188   /// operations. They should retain their ordering relative to all memory
189   /// operations.
isUnordered()190   bool isUnordered() const { return !isVolatile(); }
191 
192   /// Update this MachineMemOperand to reflect the alignment of MMO, if it has a
193   /// greater alignment. This must only be used when the new alignment applies
194   /// to all users of this MachineMemOperand.
195   void refineAlignment(const MachineMemOperand *MMO);
196 
197   /// Change the SourceValue for this MachineMemOperand. This should only be
198   /// used when an object is being relocated and all references to it are being
199   /// updated.
setValue(const Value * NewSV)200   void setValue(const Value *NewSV) { PtrInfo.V = NewSV; }
setValue(const PseudoSourceValue * NewSV)201   void setValue(const PseudoSourceValue *NewSV) { PtrInfo.V = NewSV; }
setOffset(int64_t NewOffset)202   void setOffset(int64_t NewOffset) { PtrInfo.Offset = NewOffset; }
203 
204   /// Profile - Gather unique data for the object.
205   ///
206   void Profile(FoldingSetNodeID &ID) const;
207 
208   /// Support for operator<<.
209   /// @{
210   void print(raw_ostream &OS) const;
211   void print(raw_ostream &OS, ModuleSlotTracker &MST) const;
212   /// @}
213 
214   friend bool operator==(const MachineMemOperand &LHS,
215                          const MachineMemOperand &RHS) {
216     return LHS.getValue() == RHS.getValue() &&
217            LHS.getPseudoValue() == RHS.getPseudoValue() &&
218            LHS.getSize() == RHS.getSize() &&
219            LHS.getOffset() == RHS.getOffset() &&
220            LHS.getFlags() == RHS.getFlags() &&
221            LHS.getAAInfo() == RHS.getAAInfo() &&
222            LHS.getRanges() == RHS.getRanges() &&
223            LHS.getAlignment() == RHS.getAlignment() &&
224            LHS.getAddrSpace() == RHS.getAddrSpace();
225   }
226 
227   friend bool operator!=(const MachineMemOperand &LHS,
228                          const MachineMemOperand &RHS) {
229     return !(LHS == RHS);
230   }
231 };
232 
233 inline raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO) {
234   MRO.print(OS);
235   return OS;
236 }
237 
238 } // End llvm namespace
239 
240 #endif
241