1 //===- MemoryLocation.cpp - Memory location descriptions -------------------==//
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
7 //===----------------------------------------------------------------------===//
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/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/Type.h"
20 void LocationSize::print(raw_ostream
&OS
) const {
21 OS
<< "LocationSize::";
22 if (*this == unknown())
24 else if (*this == mapEmpty())
26 else if (*this == mapTombstone())
29 OS
<< "precise(" << getValue() << ')';
31 OS
<< "upperBound(" << getValue() << ')';
34 MemoryLocation
MemoryLocation::get(const LoadInst
*LI
) {
36 LI
->getAAMetadata(AATags
);
37 const auto &DL
= LI
->getModule()->getDataLayout();
39 return MemoryLocation(
40 LI
->getPointerOperand(),
41 LocationSize::precise(DL
.getTypeStoreSize(LI
->getType())), AATags
);
44 MemoryLocation
MemoryLocation::get(const StoreInst
*SI
) {
46 SI
->getAAMetadata(AATags
);
47 const auto &DL
= SI
->getModule()->getDataLayout();
49 return MemoryLocation(SI
->getPointerOperand(),
50 LocationSize::precise(DL
.getTypeStoreSize(
51 SI
->getValueOperand()->getType())),
55 MemoryLocation
MemoryLocation::get(const VAArgInst
*VI
) {
57 VI
->getAAMetadata(AATags
);
59 return MemoryLocation(VI
->getPointerOperand(), LocationSize::unknown(),
63 MemoryLocation
MemoryLocation::get(const AtomicCmpXchgInst
*CXI
) {
65 CXI
->getAAMetadata(AATags
);
66 const auto &DL
= CXI
->getModule()->getDataLayout();
68 return MemoryLocation(CXI
->getPointerOperand(),
69 LocationSize::precise(DL
.getTypeStoreSize(
70 CXI
->getCompareOperand()->getType())),
74 MemoryLocation
MemoryLocation::get(const AtomicRMWInst
*RMWI
) {
76 RMWI
->getAAMetadata(AATags
);
77 const auto &DL
= RMWI
->getModule()->getDataLayout();
79 return MemoryLocation(RMWI
->getPointerOperand(),
80 LocationSize::precise(DL
.getTypeStoreSize(
81 RMWI
->getValOperand()->getType())),
85 MemoryLocation
MemoryLocation::getForSource(const MemTransferInst
*MTI
) {
86 return getForSource(cast
<AnyMemTransferInst
>(MTI
));
89 MemoryLocation
MemoryLocation::getForSource(const AtomicMemTransferInst
*MTI
) {
90 return getForSource(cast
<AnyMemTransferInst
>(MTI
));
93 MemoryLocation
MemoryLocation::getForSource(const AnyMemTransferInst
*MTI
) {
94 auto Size
= LocationSize::unknown();
95 if (ConstantInt
*C
= dyn_cast
<ConstantInt
>(MTI
->getLength()))
96 Size
= LocationSize::precise(C
->getValue().getZExtValue());
98 // memcpy/memmove can have AA tags. For memcpy, they apply
99 // to both the source and the destination.
101 MTI
->getAAMetadata(AATags
);
103 return MemoryLocation(MTI
->getRawSource(), Size
, AATags
);
106 MemoryLocation
MemoryLocation::getForDest(const MemIntrinsic
*MI
) {
107 return getForDest(cast
<AnyMemIntrinsic
>(MI
));
110 MemoryLocation
MemoryLocation::getForDest(const AtomicMemIntrinsic
*MI
) {
111 return getForDest(cast
<AnyMemIntrinsic
>(MI
));
114 MemoryLocation
MemoryLocation::getForDest(const AnyMemIntrinsic
*MI
) {
115 auto Size
= LocationSize::unknown();
116 if (ConstantInt
*C
= dyn_cast
<ConstantInt
>(MI
->getLength()))
117 Size
= LocationSize::precise(C
->getValue().getZExtValue());
119 // memcpy/memmove can have AA tags. For memcpy, they apply
120 // to both the source and the destination.
122 MI
->getAAMetadata(AATags
);
124 return MemoryLocation(MI
->getRawDest(), Size
, AATags
);
127 MemoryLocation
MemoryLocation::getForArgument(const CallBase
*Call
,
129 const TargetLibraryInfo
*TLI
) {
131 Call
->getAAMetadata(AATags
);
132 const Value
*Arg
= Call
->getArgOperand(ArgIdx
);
134 // We may be able to produce an exact size for known intrinsics.
135 if (const IntrinsicInst
*II
= dyn_cast
<IntrinsicInst
>(Call
)) {
136 const DataLayout
&DL
= II
->getModule()->getDataLayout();
138 switch (II
->getIntrinsicID()) {
141 case Intrinsic::memset
:
142 case Intrinsic::memcpy
:
143 case Intrinsic::memmove
:
144 assert((ArgIdx
== 0 || ArgIdx
== 1) &&
145 "Invalid argument index for memory intrinsic");
146 if (ConstantInt
*LenCI
= dyn_cast
<ConstantInt
>(II
->getArgOperand(2)))
147 return MemoryLocation(Arg
, LocationSize::precise(LenCI
->getZExtValue()),
151 case Intrinsic::lifetime_start
:
152 case Intrinsic::lifetime_end
:
153 case Intrinsic::invariant_start
:
154 assert(ArgIdx
== 1 && "Invalid argument index");
155 return MemoryLocation(
157 LocationSize::precise(
158 cast
<ConstantInt
>(II
->getArgOperand(0))->getZExtValue()),
161 case Intrinsic::invariant_end
:
162 // The first argument to an invariant.end is a "descriptor" type (e.g. a
163 // pointer to a empty struct) which is never actually dereferenced.
165 return MemoryLocation(Arg
, LocationSize::precise(0), AATags
);
166 assert(ArgIdx
== 2 && "Invalid argument index");
167 return MemoryLocation(
169 LocationSize::precise(
170 cast
<ConstantInt
>(II
->getArgOperand(1))->getZExtValue()),
173 case Intrinsic::arm_neon_vld1
:
174 assert(ArgIdx
== 0 && "Invalid argument index");
175 // LLVM's vld1 and vst1 intrinsics currently only support a single
177 return MemoryLocation(
178 Arg
, LocationSize::precise(DL
.getTypeStoreSize(II
->getType())),
181 case Intrinsic::arm_neon_vst1
:
182 assert(ArgIdx
== 0 && "Invalid argument index");
183 return MemoryLocation(Arg
,
184 LocationSize::precise(DL
.getTypeStoreSize(
185 II
->getArgOperand(1)->getType())),
190 // We can bound the aliasing properties of memset_pattern16 just as we can
191 // for memcpy/memset. This is particularly important because the
192 // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
193 // whenever possible.
195 if (TLI
&& Call
->getCalledFunction() &&
196 TLI
->getLibFunc(*Call
->getCalledFunction(), F
) &&
197 F
== LibFunc_memset_pattern16
&& TLI
->has(F
)) {
198 assert((ArgIdx
== 0 || ArgIdx
== 1) &&
199 "Invalid argument index for memset_pattern16");
201 return MemoryLocation(Arg
, LocationSize::precise(16), AATags
);
202 if (const ConstantInt
*LenCI
=
203 dyn_cast
<ConstantInt
>(Call
->getArgOperand(2)))
204 return MemoryLocation(Arg
, LocationSize::precise(LenCI
->getZExtValue()),
207 // FIXME: Handle memset_pattern4 and memset_pattern8 also.
209 return MemoryLocation(Call
->getArgOperand(ArgIdx
), LocationSize::unknown(),