LLVM  16.0.0git
MemoryLocation.cpp
Go to the documentation of this file.
1 //===- MemoryLocation.cpp - Memory location descriptions -------------------==//
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 
11 #include "llvm/IR/DataLayout.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/IntrinsicInst.h"
14 #include "llvm/IR/IntrinsicsARM.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/IR/Type.h"
17 #include <optional>
18 using namespace llvm;
19 
21  OS << "LocationSize::";
22  if (*this == beforeOrAfterPointer())
23  OS << "beforeOrAfterPointer";
24  else if (*this == afterPointer())
25  OS << "afterPointer";
26  else if (*this == mapEmpty())
27  OS << "mapEmpty";
28  else if (*this == mapTombstone())
29  OS << "mapTombstone";
30  else if (isPrecise())
31  OS << "precise(" << getValue() << ')';
32  else
33  OS << "upperBound(" << getValue() << ')';
34 }
35 
37  const auto &DL = LI->getModule()->getDataLayout();
38 
39  return MemoryLocation(
40  LI->getPointerOperand(),
41  LocationSize::precise(DL.getTypeStoreSize(LI->getType())),
42  LI->getAAMetadata());
43 }
44 
46  const auto &DL = SI->getModule()->getDataLayout();
47 
48  return MemoryLocation(SI->getPointerOperand(),
49  LocationSize::precise(DL.getTypeStoreSize(
50  SI->getValueOperand()->getType())),
51  SI->getAAMetadata());
52 }
53 
55  return MemoryLocation(VI->getPointerOperand(),
56  LocationSize::afterPointer(), VI->getAAMetadata());
57 }
58 
60  const auto &DL = CXI->getModule()->getDataLayout();
61 
62  return MemoryLocation(CXI->getPointerOperand(),
63  LocationSize::precise(DL.getTypeStoreSize(
64  CXI->getCompareOperand()->getType())),
65  CXI->getAAMetadata());
66 }
67 
69  const auto &DL = RMWI->getModule()->getDataLayout();
70 
71  return MemoryLocation(RMWI->getPointerOperand(),
72  LocationSize::precise(DL.getTypeStoreSize(
73  RMWI->getValOperand()->getType())),
74  RMWI->getAAMetadata());
75 }
76 
77 std::optional<MemoryLocation>
79  switch (Inst->getOpcode()) {
80  case Instruction::Load:
81  return get(cast<LoadInst>(Inst));
82  case Instruction::Store:
83  return get(cast<StoreInst>(Inst));
84  case Instruction::VAArg:
85  return get(cast<VAArgInst>(Inst));
86  case Instruction::AtomicCmpXchg:
87  return get(cast<AtomicCmpXchgInst>(Inst));
88  case Instruction::AtomicRMW:
89  return get(cast<AtomicRMWInst>(Inst));
90  default:
91  return std::nullopt;
92  }
93 }
94 
96  return getForSource(cast<AnyMemTransferInst>(MTI));
97 }
98 
100  return getForSource(cast<AnyMemTransferInst>(MTI));
101 }
102 
104  assert(MTI->getRawSource() == MTI->getArgOperand(1));
105  return getForArgument(MTI, 1, nullptr);
106 }
107 
109  return getForDest(cast<AnyMemIntrinsic>(MI));
110 }
111 
113  return getForDest(cast<AnyMemIntrinsic>(MI));
114 }
115 
117  assert(MI->getRawDest() == MI->getArgOperand(0));
118  return getForArgument(MI, 0, nullptr);
119 }
120 
121 std::optional<MemoryLocation>
123  if (!CB->onlyAccessesArgMemory())
124  return std::nullopt;
125 
126  if (CB->hasOperandBundles())
127  // TODO: remove implementation restriction
128  return std::nullopt;
129 
130  Value *UsedV = nullptr;
131  std::optional<unsigned> UsedIdx;
132  for (unsigned i = 0; i < CB->arg_size(); i++) {
133  if (!CB->getArgOperand(i)->getType()->isPointerTy())
134  continue;
135  if (CB->onlyReadsMemory(i))
136  continue;
137  if (!UsedV) {
138  // First potentially writing parameter
139  UsedV = CB->getArgOperand(i);
140  UsedIdx = i;
141  continue;
142  }
143  UsedIdx = std::nullopt;
144  if (UsedV != CB->getArgOperand(i))
145  // Can't describe writing to two distinct locations.
146  // TODO: This results in an inprecision when two values derived from the
147  // same object are passed as arguments to the same function.
148  return std::nullopt;
149  }
150  if (!UsedV)
151  // We don't currently have a way to represent a "does not write" result
152  // and thus have to be conservative and return unknown.
153  return std::nullopt;
154 
155  if (UsedIdx)
156  return getForArgument(CB, *UsedIdx, &TLI);
157  return MemoryLocation::getBeforeOrAfter(UsedV, CB->getAAMetadata());
158 }
159 
161  unsigned ArgIdx,
162  const TargetLibraryInfo *TLI) {
163  AAMDNodes AATags = Call->getAAMetadata();
164  const Value *Arg = Call->getArgOperand(ArgIdx);
165 
166  // We may be able to produce an exact size for known intrinsics.
167  if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Call)) {
168  const DataLayout &DL = II->getModule()->getDataLayout();
169 
170  switch (II->getIntrinsicID()) {
171  default:
172  break;
173  case Intrinsic::memset:
174  case Intrinsic::memcpy:
175  case Intrinsic::memcpy_inline:
176  case Intrinsic::memmove:
177  case Intrinsic::memcpy_element_unordered_atomic:
178  case Intrinsic::memmove_element_unordered_atomic:
179  case Intrinsic::memset_element_unordered_atomic:
180  assert((ArgIdx == 0 || ArgIdx == 1) &&
181  "Invalid argument index for memory intrinsic");
182  if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
183  return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
184  AATags);
186 
187  case Intrinsic::lifetime_start:
188  case Intrinsic::lifetime_end:
189  case Intrinsic::invariant_start:
190  assert(ArgIdx == 1 && "Invalid argument index");
191  return MemoryLocation(
192  Arg,
194  cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()),
195  AATags);
196 
197  case Intrinsic::masked_load:
198  assert(ArgIdx == 0 && "Invalid argument index");
199  return MemoryLocation(
200  Arg,
201  LocationSize::upperBound(DL.getTypeStoreSize(II->getType())),
202  AATags);
203 
204  case Intrinsic::masked_store:
205  assert(ArgIdx == 1 && "Invalid argument index");
206  return MemoryLocation(
207  Arg,
209  DL.getTypeStoreSize(II->getArgOperand(0)->getType())),
210  AATags);
211 
212  case Intrinsic::invariant_end:
213  // The first argument to an invariant.end is a "descriptor" type (e.g. a
214  // pointer to a empty struct) which is never actually dereferenced.
215  if (ArgIdx == 0)
217  assert(ArgIdx == 2 && "Invalid argument index");
218  return MemoryLocation(
219  Arg,
221  cast<ConstantInt>(II->getArgOperand(1))->getZExtValue()),
222  AATags);
223 
224  case Intrinsic::arm_neon_vld1:
225  assert(ArgIdx == 0 && "Invalid argument index");
226  // LLVM's vld1 and vst1 intrinsics currently only support a single
227  // vector register.
228  return MemoryLocation(
229  Arg, LocationSize::precise(DL.getTypeStoreSize(II->getType())),
230  AATags);
231 
232  case Intrinsic::arm_neon_vst1:
233  assert(ArgIdx == 0 && "Invalid argument index");
234  return MemoryLocation(Arg,
235  LocationSize::precise(DL.getTypeStoreSize(
236  II->getArgOperand(1)->getType())),
237  AATags);
238  }
239 
240  assert(
241  !isa<AnyMemTransferInst>(II) &&
242  "all memory transfer intrinsics should be handled by the switch above");
243  }
244 
245  // We can bound the aliasing properties of memset_pattern16 just as we can
246  // for memcpy/memset. This is particularly important because the
247  // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
248  // whenever possible.
249  LibFunc F;
250  if (TLI && TLI->getLibFunc(*Call, F) && TLI->has(F)) {
251  switch (F) {
252  case LibFunc_strcpy:
253  case LibFunc_strcat:
254  case LibFunc_strncat:
255  assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for str function");
257 
258  case LibFunc_memset_chk:
259  assert(ArgIdx == 0 && "Invalid argument index for memset_chk");
261  case LibFunc_memcpy_chk: {
262  assert((ArgIdx == 0 || ArgIdx == 1) &&
263  "Invalid argument index for memcpy_chk");
265  if (const auto *Len = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
266  // memset_chk writes at most Len bytes, memcpy_chk reads/writes at most
267  // Len bytes. They may read/write less, if Len exceeds the specified max
268  // size and aborts.
269  Size = LocationSize::upperBound(Len->getZExtValue());
270  }
271  return MemoryLocation(Arg, Size, AATags);
272  }
273  case LibFunc_strncpy: {
274  assert((ArgIdx == 0 || ArgIdx == 1) &&
275  "Invalid argument index for strncpy");
277  if (const auto *Len = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
278  // strncpy is guaranteed to write Len bytes, but only reads up to Len
279  // bytes.
280  Size = ArgIdx == 0 ? LocationSize::precise(Len->getZExtValue())
281  : LocationSize::upperBound(Len->getZExtValue());
282  }
283  return MemoryLocation(Arg, Size, AATags);
284  }
285  case LibFunc_memset_pattern16:
286  case LibFunc_memset_pattern4:
287  case LibFunc_memset_pattern8:
288  assert((ArgIdx == 0 || ArgIdx == 1) &&
289  "Invalid argument index for memset_pattern16");
290  if (ArgIdx == 1) {
291  unsigned Size = 16;
292  if (F == LibFunc_memset_pattern4)
293  Size = 4;
294  else if (F == LibFunc_memset_pattern8)
295  Size = 8;
297  }
298  if (const ConstantInt *LenCI =
299  dyn_cast<ConstantInt>(Call->getArgOperand(2)))
300  return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
301  AATags);
303  case LibFunc_bcmp:
304  case LibFunc_memcmp:
305  assert((ArgIdx == 0 || ArgIdx == 1) &&
306  "Invalid argument index for memcmp/bcmp");
307  if (const ConstantInt *LenCI =
308  dyn_cast<ConstantInt>(Call->getArgOperand(2)))
309  return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
310  AATags);
312  case LibFunc_memchr:
313  assert((ArgIdx == 0) && "Invalid argument index for memchr");
314  if (const ConstantInt *LenCI =
315  dyn_cast<ConstantInt>(Call->getArgOperand(2)))
316  return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
317  AATags);
319  case LibFunc_memccpy:
320  assert((ArgIdx == 0 || ArgIdx == 1) &&
321  "Invalid argument index for memccpy");
322  // We only know an upper bound on the number of bytes read/written.
323  if (const ConstantInt *LenCI =
324  dyn_cast<ConstantInt>(Call->getArgOperand(3)))
325  return MemoryLocation(
326  Arg, LocationSize::upperBound(LenCI->getZExtValue()), AATags);
328  default:
329  break;
330  };
331  }
332 
333  return MemoryLocation::getBeforeOrAfter(Call->getArgOperand(ArgIdx), AATags);
334 }
i
i
Definition: README.txt:29
llvm::LocationSize::print
void print(raw_ostream &OS) const
Definition: MemoryLocation.cpp:20
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm::MemoryLocation::get
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
Definition: MemoryLocation.cpp:36
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::Instruction::getModule
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:69
llvm::VAArgInst
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
Definition: Instructions.h:1830
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::LocationSize::afterPointer
constexpr static LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
Definition: MemoryLocation.h:125
IntrinsicInst.h
llvm::Type::isPointerTy
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:237
llvm::MemTransferInst
This class wraps the llvm.memcpy/memmove intrinsics.
Definition: IntrinsicInst.h:1106
llvm::MemoryLocation::getOrNone
static std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
Definition: MemoryLocation.cpp:78
llvm::LocationSize::upperBound
static LocationSize upperBound(uint64_t Value)
Definition: MemoryLocation.h:109
llvm::AAMDNodes
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition: Metadata.h:652
llvm::MemoryLocation::Size
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
Definition: MemoryLocation.h:228
Module.h
llvm::MemIntrinsic
This is the common base class for memset/memcpy/memmove.
Definition: IntrinsicInst.h:1041
llvm::LoadInst::getPointerOperand
Value * getPointerOperand()
Definition: Instructions.h:261
llvm::LocationSize::isPrecise
bool isPrecise() const
Definition: MemoryLocation.h:167
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::AtomicRMWInst::getPointerOperand
Value * getPointerOperand()
Definition: Instructions.h:866
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::MemoryLocation::AATags
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
Definition: MemoryLocation.h:232
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::Instruction::getOpcode
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:169
llvm::LocationSize
Definition: MemoryLocation.h:67
llvm::LibFunc
LibFunc
Definition: TargetLibraryInfo.h:36
llvm::AtomicMemTransferInst
Definition: IntrinsicInst.h:1000
SI
@ SI
Definition: SIInstrInfo.cpp:7966
llvm::MemoryLocation::getForSource
static MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
Definition: MemoryLocation.cpp:95
llvm::MemTransferBase::getRawSource
Value * getRawSource() const
Return the arguments to the instruction.
Definition: IntrinsicInst.h:873
llvm::LocationSize::getValue
uint64_t getValue() const
Definition: MemoryLocation.h:160
TargetLibraryInfo.h
llvm::LocationSize::mapTombstone
constexpr static LocationSize mapTombstone()
Definition: MemoryLocation.h:136
llvm::TargetLibraryInfo::getLibFunc
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Definition: TargetLibraryInfo.h:298
llvm::Instruction
Definition: Instruction.h:42
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::LocationSize::precise
static LocationSize precise(uint64_t Value)
Definition: MemoryLocation.h:102
llvm::Instruction::getAAMetadata
AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
Definition: Metadata.cpp:1500
llvm::CallBase::onlyReadsMemory
bool onlyReadsMemory(unsigned OpNo) const
Definition: InstrTypes.h:1721
Type.h
llvm::AnyMemTransferInst
Definition: IntrinsicInst.h:1220
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:298
VI
@ VI
Definition: SIInstrInfo.cpp:7967
llvm::CallBase::onlyAccessesArgMemory
bool onlyAccessesArgMemory() const
Determine if the call can access memmory only using pointers based on its arguments.
Definition: Instructions.cpp:585
MemoryLocation.h
llvm::SPII::Store
@ Store
Definition: SparcInstrInfo.h:33
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MemoryLocation::getForArgument
static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
Definition: MemoryLocation.cpp:160
llvm::CallBase::hasOperandBundles
bool hasOperandBundles() const
Return true if this User has any operand bundles.
Definition: InstrTypes.h:1936
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::AtomicCmpXchgInst::getCompareOperand
Value * getCompareOperand()
Definition: Instructions.h:644
llvm::TargetLibraryInfo::has
bool has(LibFunc F) const
Tests whether a library function is available.
Definition: TargetLibraryInfo.h:332
DataLayout.h
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::LocationSize::mapEmpty
constexpr static LocationSize mapEmpty()
Definition: MemoryLocation.h:139
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:270
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:715
llvm::MemoryLocation::MemoryLocation
MemoryLocation()
Definition: MemoryLocation.h:289
llvm::LocationSize::beforeOrAfterPointer
constexpr static LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
Definition: MemoryLocation.h:131
llvm::CallBase::arg_size
unsigned arg_size() const
Definition: InstrTypes.h:1340
llvm::AtomicCmpXchgInst::getPointerOperand
Value * getPointerOperand()
Definition: Instructions.h:640
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:226
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:46
llvm::AtomicMemIntrinsic
Definition: IntrinsicInst.h:948
llvm::AtomicRMWInst::getValOperand
Value * getValOperand()
Definition: Instructions.h:870
Instructions.h
llvm::MemoryLocation::getAfter
static MemoryLocation getAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location after Ptr, while remaining within the underlying objec...
Definition: MemoryLocation.h:271
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1342
llvm::MemoryLocation::getBeforeOrAfter
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
Definition: MemoryLocation.h:279
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1175
llvm::Module::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:399
llvm::MemoryLocation::getForDest
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
Definition: MemoryLocation.cpp:108
llvm::AnyMemIntrinsic
Definition: IntrinsicInst.h:1168
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::AtomicCmpXchgInst
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:510
llvm::MemoryLocation
Representation for a specific memory location.
Definition: MemoryLocation.h:211