xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/MemoryLocation.cpp (revision 79ac3c12a714bcd3f2354c52d948aed9575c46d6)
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 
9 #include "llvm/Analysis/MemoryLocation.h"
10 #include "llvm/Analysis/TargetLibraryInfo.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/DataLayout.h"
13 #include "llvm/IR/Instructions.h"
14 #include "llvm/IR/IntrinsicInst.h"
15 #include "llvm/IR/IntrinsicsARM.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/Type.h"
19 using namespace llvm;
20 
21 void LocationSize::print(raw_ostream &OS) const {
22   OS << "LocationSize::";
23   if (*this == beforeOrAfterPointer())
24     OS << "beforeOrAfterPointer";
25   else if (*this == afterPointer())
26     OS << "afterPointer";
27   else if (*this == mapEmpty())
28     OS << "mapEmpty";
29   else if (*this == mapTombstone())
30     OS << "mapTombstone";
31   else if (isPrecise())
32     OS << "precise(" << getValue() << ')';
33   else
34     OS << "upperBound(" << getValue() << ')';
35 }
36 
37 MemoryLocation MemoryLocation::get(const LoadInst *LI) {
38   AAMDNodes AATags;
39   LI->getAAMetadata(AATags);
40   const auto &DL = LI->getModule()->getDataLayout();
41 
42   return MemoryLocation(
43       LI->getPointerOperand(),
44       LocationSize::precise(DL.getTypeStoreSize(LI->getType())), AATags);
45 }
46 
47 MemoryLocation MemoryLocation::get(const StoreInst *SI) {
48   AAMDNodes AATags;
49   SI->getAAMetadata(AATags);
50   const auto &DL = SI->getModule()->getDataLayout();
51 
52   return MemoryLocation(SI->getPointerOperand(),
53                         LocationSize::precise(DL.getTypeStoreSize(
54                             SI->getValueOperand()->getType())),
55                         AATags);
56 }
57 
58 MemoryLocation MemoryLocation::get(const VAArgInst *VI) {
59   AAMDNodes AATags;
60   VI->getAAMetadata(AATags);
61 
62   return MemoryLocation(VI->getPointerOperand(),
63                         LocationSize::afterPointer(), AATags);
64 }
65 
66 MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) {
67   AAMDNodes AATags;
68   CXI->getAAMetadata(AATags);
69   const auto &DL = CXI->getModule()->getDataLayout();
70 
71   return MemoryLocation(CXI->getPointerOperand(),
72                         LocationSize::precise(DL.getTypeStoreSize(
73                             CXI->getCompareOperand()->getType())),
74                         AATags);
75 }
76 
77 MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) {
78   AAMDNodes AATags;
79   RMWI->getAAMetadata(AATags);
80   const auto &DL = RMWI->getModule()->getDataLayout();
81 
82   return MemoryLocation(RMWI->getPointerOperand(),
83                         LocationSize::precise(DL.getTypeStoreSize(
84                             RMWI->getValOperand()->getType())),
85                         AATags);
86 }
87 
88 Optional<MemoryLocation> MemoryLocation::getOrNone(const Instruction *Inst) {
89   switch (Inst->getOpcode()) {
90   case Instruction::Load:
91     return get(cast<LoadInst>(Inst));
92   case Instruction::Store:
93     return get(cast<StoreInst>(Inst));
94   case Instruction::VAArg:
95     return get(cast<VAArgInst>(Inst));
96   case Instruction::AtomicCmpXchg:
97     return get(cast<AtomicCmpXchgInst>(Inst));
98   case Instruction::AtomicRMW:
99     return get(cast<AtomicRMWInst>(Inst));
100   default:
101     return None;
102   }
103 }
104 
105 MemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) {
106   return getForSource(cast<AnyMemTransferInst>(MTI));
107 }
108 
109 MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) {
110   return getForSource(cast<AnyMemTransferInst>(MTI));
111 }
112 
113 MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) {
114   auto Size = LocationSize::afterPointer();
115   if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
116     Size = LocationSize::precise(C->getValue().getZExtValue());
117 
118   // memcpy/memmove can have AA tags. For memcpy, they apply
119   // to both the source and the destination.
120   AAMDNodes AATags;
121   MTI->getAAMetadata(AATags);
122 
123   return MemoryLocation(MTI->getRawSource(), Size, AATags);
124 }
125 
126 MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MI) {
127   return getForDest(cast<AnyMemIntrinsic>(MI));
128 }
129 
130 MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) {
131   return getForDest(cast<AnyMemIntrinsic>(MI));
132 }
133 
134 MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) {
135   auto Size = LocationSize::afterPointer();
136   if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength()))
137     Size = LocationSize::precise(C->getValue().getZExtValue());
138 
139   // memcpy/memmove can have AA tags. For memcpy, they apply
140   // to both the source and the destination.
141   AAMDNodes AATags;
142   MI->getAAMetadata(AATags);
143 
144   return MemoryLocation(MI->getRawDest(), Size, AATags);
145 }
146 
147 MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
148                                               unsigned ArgIdx,
149                                               const TargetLibraryInfo *TLI) {
150   AAMDNodes AATags;
151   Call->getAAMetadata(AATags);
152   const Value *Arg = Call->getArgOperand(ArgIdx);
153 
154   // We may be able to produce an exact size for known intrinsics.
155   if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Call)) {
156     const DataLayout &DL = II->getModule()->getDataLayout();
157 
158     switch (II->getIntrinsicID()) {
159     default:
160       break;
161     case Intrinsic::memset:
162     case Intrinsic::memcpy:
163     case Intrinsic::memcpy_inline:
164     case Intrinsic::memmove:
165       assert((ArgIdx == 0 || ArgIdx == 1) &&
166              "Invalid argument index for memory intrinsic");
167       if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
168         return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
169                               AATags);
170       return MemoryLocation::getAfter(Arg, AATags);
171 
172     case Intrinsic::lifetime_start:
173     case Intrinsic::lifetime_end:
174     case Intrinsic::invariant_start:
175       assert(ArgIdx == 1 && "Invalid argument index");
176       return MemoryLocation(
177           Arg,
178           LocationSize::precise(
179               cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()),
180           AATags);
181 
182     case Intrinsic::masked_load:
183       assert(ArgIdx == 0 && "Invalid argument index");
184       return MemoryLocation(
185           Arg,
186           LocationSize::upperBound(DL.getTypeStoreSize(II->getType())),
187           AATags);
188 
189     case Intrinsic::masked_store:
190       assert(ArgIdx == 1 && "Invalid argument index");
191       return MemoryLocation(
192           Arg,
193           LocationSize::upperBound(
194               DL.getTypeStoreSize(II->getArgOperand(0)->getType())),
195           AATags);
196 
197     case Intrinsic::invariant_end:
198       // The first argument to an invariant.end is a "descriptor" type (e.g. a
199       // pointer to a empty struct) which is never actually dereferenced.
200       if (ArgIdx == 0)
201         return MemoryLocation(Arg, LocationSize::precise(0), AATags);
202       assert(ArgIdx == 2 && "Invalid argument index");
203       return MemoryLocation(
204           Arg,
205           LocationSize::precise(
206               cast<ConstantInt>(II->getArgOperand(1))->getZExtValue()),
207           AATags);
208 
209     case Intrinsic::arm_neon_vld1:
210       assert(ArgIdx == 0 && "Invalid argument index");
211       // LLVM's vld1 and vst1 intrinsics currently only support a single
212       // vector register.
213       return MemoryLocation(
214           Arg, LocationSize::precise(DL.getTypeStoreSize(II->getType())),
215           AATags);
216 
217     case Intrinsic::arm_neon_vst1:
218       assert(ArgIdx == 0 && "Invalid argument index");
219       return MemoryLocation(Arg,
220                             LocationSize::precise(DL.getTypeStoreSize(
221                                 II->getArgOperand(1)->getType())),
222                             AATags);
223     }
224   }
225 
226   // We can bound the aliasing properties of memset_pattern16 just as we can
227   // for memcpy/memset.  This is particularly important because the
228   // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
229   // whenever possible.
230   LibFunc F;
231   if (TLI && TLI->getLibFunc(*Call, F) && TLI->has(F)) {
232     switch (F) {
233     case LibFunc_memset_pattern16:
234       assert((ArgIdx == 0 || ArgIdx == 1) &&
235              "Invalid argument index for memset_pattern16");
236       if (ArgIdx == 1)
237         return MemoryLocation(Arg, LocationSize::precise(16), AATags);
238       if (const ConstantInt *LenCI =
239               dyn_cast<ConstantInt>(Call->getArgOperand(2)))
240         return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
241                               AATags);
242       return MemoryLocation::getAfter(Arg, AATags);
243     case LibFunc_bcmp:
244     case LibFunc_memcmp:
245       assert((ArgIdx == 0 || ArgIdx == 1) &&
246              "Invalid argument index for memcmp/bcmp");
247       if (const ConstantInt *LenCI =
248               dyn_cast<ConstantInt>(Call->getArgOperand(2)))
249         return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
250                               AATags);
251       return MemoryLocation::getAfter(Arg, AATags);
252     case LibFunc_memchr:
253       assert((ArgIdx == 0) && "Invalid argument index for memchr");
254       if (const ConstantInt *LenCI =
255               dyn_cast<ConstantInt>(Call->getArgOperand(2)))
256         return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
257                               AATags);
258       return MemoryLocation::getAfter(Arg, AATags);
259     case LibFunc_memccpy:
260       assert((ArgIdx == 0 || ArgIdx == 1) &&
261              "Invalid argument index for memccpy");
262       // We only know an upper bound on the number of bytes read/written.
263       if (const ConstantInt *LenCI =
264               dyn_cast<ConstantInt>(Call->getArgOperand(3)))
265         return MemoryLocation(
266             Arg, LocationSize::upperBound(LenCI->getZExtValue()), AATags);
267       return MemoryLocation::getAfter(Arg, AATags);
268     default:
269       break;
270     };
271   }
272   // FIXME: Handle memset_pattern4 and memset_pattern8 also.
273 
274   return MemoryLocation::getBeforeOrAfter(Call->getArgOperand(ArgIdx), AATags);
275 }
276