1 //===- MemoryLocation.cpp - Memory location descriptions -------------------==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Analysis/MemoryLocation.h"
11 #include "llvm/Analysis/TargetLibraryInfo.h"
12 #include "llvm/IR/BasicBlock.h"
13 #include "llvm/IR/DataLayout.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/IntrinsicInst.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/Type.h"
21 void LocationSize::print(raw_ostream
&OS
) const {
22 OS
<< "LocationSize::";
23 if (*this == unknown())
25 else if (*this == mapEmpty())
27 else if (*this == mapTombstone())
30 OS
<< "precise(" << getValue() << ')';
32 OS
<< "upperBound(" << getValue() << ')';
35 MemoryLocation
MemoryLocation::get(const LoadInst
*LI
) {
37 LI
->getAAMetadata(AATags
);
38 const auto &DL
= LI
->getModule()->getDataLayout();
40 return MemoryLocation(LI
->getPointerOperand(),
41 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 DL
.getTypeStoreSize(SI
->getValueOperand()->getType()),
54 MemoryLocation
MemoryLocation::get(const VAArgInst
*VI
) {
56 VI
->getAAMetadata(AATags
);
58 return MemoryLocation(VI
->getPointerOperand(), UnknownSize
, AATags
);
61 MemoryLocation
MemoryLocation::get(const AtomicCmpXchgInst
*CXI
) {
63 CXI
->getAAMetadata(AATags
);
64 const auto &DL
= CXI
->getModule()->getDataLayout();
66 return MemoryLocation(
67 CXI
->getPointerOperand(),
68 DL
.getTypeStoreSize(CXI
->getCompareOperand()->getType()), AATags
);
71 MemoryLocation
MemoryLocation::get(const AtomicRMWInst
*RMWI
) {
73 RMWI
->getAAMetadata(AATags
);
74 const auto &DL
= RMWI
->getModule()->getDataLayout();
76 return MemoryLocation(RMWI
->getPointerOperand(),
77 DL
.getTypeStoreSize(RMWI
->getValOperand()->getType()),
81 MemoryLocation
MemoryLocation::getForSource(const MemTransferInst
*MTI
) {
82 return getForSource(cast
<AnyMemTransferInst
>(MTI
));
85 MemoryLocation
MemoryLocation::getForSource(const AtomicMemTransferInst
*MTI
) {
86 return getForSource(cast
<AnyMemTransferInst
>(MTI
));
89 MemoryLocation
MemoryLocation::getForSource(const AnyMemTransferInst
*MTI
) {
90 uint64_t Size
= UnknownSize
;
91 if (ConstantInt
*C
= dyn_cast
<ConstantInt
>(MTI
->getLength()))
92 Size
= C
->getValue().getZExtValue();
94 // memcpy/memmove can have AA tags. For memcpy, they apply
95 // to both the source and the destination.
97 MTI
->getAAMetadata(AATags
);
99 return MemoryLocation(MTI
->getRawSource(), Size
, AATags
);
102 MemoryLocation
MemoryLocation::getForDest(const MemIntrinsic
*MI
) {
103 return getForDest(cast
<AnyMemIntrinsic
>(MI
));
106 MemoryLocation
MemoryLocation::getForDest(const AtomicMemIntrinsic
*MI
) {
107 return getForDest(cast
<AnyMemIntrinsic
>(MI
));
110 MemoryLocation
MemoryLocation::getForDest(const AnyMemIntrinsic
*MI
) {
111 uint64_t Size
= UnknownSize
;
112 if (ConstantInt
*C
= dyn_cast
<ConstantInt
>(MI
->getLength()))
113 Size
= C
->getValue().getZExtValue();
115 // memcpy/memmove can have AA tags. For memcpy, they apply
116 // to both the source and the destination.
118 MI
->getAAMetadata(AATags
);
120 return MemoryLocation(MI
->getRawDest(), Size
, AATags
);
123 MemoryLocation
MemoryLocation::getForArgument(ImmutableCallSite CS
,
125 const TargetLibraryInfo
*TLI
) {
127 CS
->getAAMetadata(AATags
);
128 const Value
*Arg
= CS
.getArgument(ArgIdx
);
130 // We may be able to produce an exact size for known intrinsics.
131 if (const IntrinsicInst
*II
= dyn_cast
<IntrinsicInst
>(CS
.getInstruction())) {
132 const DataLayout
&DL
= II
->getModule()->getDataLayout();
134 switch (II
->getIntrinsicID()) {
137 case Intrinsic::memset
:
138 case Intrinsic::memcpy
:
139 case Intrinsic::memmove
:
140 assert((ArgIdx
== 0 || ArgIdx
== 1) &&
141 "Invalid argument index for memory intrinsic");
142 if (ConstantInt
*LenCI
= dyn_cast
<ConstantInt
>(II
->getArgOperand(2)))
143 return MemoryLocation(Arg
, LenCI
->getZExtValue(), AATags
);
146 case Intrinsic::lifetime_start
:
147 case Intrinsic::lifetime_end
:
148 case Intrinsic::invariant_start
:
149 assert(ArgIdx
== 1 && "Invalid argument index");
150 return MemoryLocation(
151 Arg
, cast
<ConstantInt
>(II
->getArgOperand(0))->getZExtValue(), AATags
);
153 case Intrinsic::invariant_end
:
154 // The first argument to an invariant.end is a "descriptor" type (e.g. a
155 // pointer to a empty struct) which is never actually dereferenced.
157 return MemoryLocation(Arg
, 0, AATags
);
158 assert(ArgIdx
== 2 && "Invalid argument index");
159 return MemoryLocation(
160 Arg
, cast
<ConstantInt
>(II
->getArgOperand(1))->getZExtValue(), AATags
);
162 case Intrinsic::arm_neon_vld1
:
163 assert(ArgIdx
== 0 && "Invalid argument index");
164 // LLVM's vld1 and vst1 intrinsics currently only support a single
166 return MemoryLocation(Arg
, DL
.getTypeStoreSize(II
->getType()), AATags
);
168 case Intrinsic::arm_neon_vst1
:
169 assert(ArgIdx
== 0 && "Invalid argument index");
170 return MemoryLocation(
171 Arg
, DL
.getTypeStoreSize(II
->getArgOperand(1)->getType()), AATags
);
175 // We can bound the aliasing properties of memset_pattern16 just as we can
176 // for memcpy/memset. This is particularly important because the
177 // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
178 // whenever possible.
180 if (TLI
&& CS
.getCalledFunction() &&
181 TLI
->getLibFunc(*CS
.getCalledFunction(), F
) &&
182 F
== LibFunc_memset_pattern16
&& TLI
->has(F
)) {
183 assert((ArgIdx
== 0 || ArgIdx
== 1) &&
184 "Invalid argument index for memset_pattern16");
186 return MemoryLocation(Arg
, 16, AATags
);
187 if (const ConstantInt
*LenCI
= dyn_cast
<ConstantInt
>(CS
.getArgument(2)))
188 return MemoryLocation(Arg
, LenCI
->getZExtValue(), AATags
);
190 // FIXME: Handle memset_pattern4 and memset_pattern8 also.
192 return MemoryLocation(CS
.getArgument(ArgIdx
), UnknownSize
, AATags
);