/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Analysis/MemoryLocation.cpp
Line | Count | Source (jump to first uncovered line) |
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/LLVMContext.h" |
16 | | #include "llvm/IR/Module.h" |
17 | | #include "llvm/IR/Type.h" |
18 | | using namespace llvm; |
19 | | |
20 | 368 | void LocationSize::print(raw_ostream &OS) const { |
21 | 368 | OS << "LocationSize::"; |
22 | 368 | if (*this == unknown()) |
23 | 0 | OS << "unknown"; |
24 | 368 | else if (*this == mapEmpty()) |
25 | 0 | OS << "mapEmpty"; |
26 | 368 | else if (*this == mapTombstone()) |
27 | 0 | OS << "mapTombstone"; |
28 | 368 | else if (isPrecise()) |
29 | 368 | OS << "precise(" << getValue() << ')'; |
30 | 0 | else |
31 | 0 | OS << "upperBound(" << getValue() << ')'; |
32 | 368 | } |
33 | | |
34 | 20.1M | MemoryLocation MemoryLocation::get(const LoadInst *LI) { |
35 | 20.1M | AAMDNodes AATags; |
36 | 20.1M | LI->getAAMetadata(AATags); |
37 | 20.1M | const auto &DL = LI->getModule()->getDataLayout(); |
38 | 20.1M | |
39 | 20.1M | return MemoryLocation( |
40 | 20.1M | LI->getPointerOperand(), |
41 | 20.1M | LocationSize::precise(DL.getTypeStoreSize(LI->getType())), AATags); |
42 | 20.1M | } |
43 | | |
44 | 21.7M | MemoryLocation MemoryLocation::get(const StoreInst *SI) { |
45 | 21.7M | AAMDNodes AATags; |
46 | 21.7M | SI->getAAMetadata(AATags); |
47 | 21.7M | const auto &DL = SI->getModule()->getDataLayout(); |
48 | 21.7M | |
49 | 21.7M | return MemoryLocation(SI->getPointerOperand(), |
50 | 21.7M | LocationSize::precise(DL.getTypeStoreSize( |
51 | 21.7M | SI->getValueOperand()->getType())), |
52 | 21.7M | AATags); |
53 | 21.7M | } |
54 | | |
55 | 1.31k | MemoryLocation MemoryLocation::get(const VAArgInst *VI) { |
56 | 1.31k | AAMDNodes AATags; |
57 | 1.31k | VI->getAAMetadata(AATags); |
58 | 1.31k | |
59 | 1.31k | return MemoryLocation(VI->getPointerOperand(), LocationSize::unknown(), |
60 | 1.31k | AATags); |
61 | 1.31k | } |
62 | | |
63 | 0 | MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) { |
64 | 0 | AAMDNodes AATags; |
65 | 0 | CXI->getAAMetadata(AATags); |
66 | 0 | const auto &DL = CXI->getModule()->getDataLayout(); |
67 | 0 |
|
68 | 0 | return MemoryLocation(CXI->getPointerOperand(), |
69 | 0 | LocationSize::precise(DL.getTypeStoreSize( |
70 | 0 | CXI->getCompareOperand()->getType())), |
71 | 0 | AATags); |
72 | 0 | } |
73 | | |
74 | 4.31k | MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { |
75 | 4.31k | AAMDNodes AATags; |
76 | 4.31k | RMWI->getAAMetadata(AATags); |
77 | 4.31k | const auto &DL = RMWI->getModule()->getDataLayout(); |
78 | 4.31k | |
79 | 4.31k | return MemoryLocation(RMWI->getPointerOperand(), |
80 | 4.31k | LocationSize::precise(DL.getTypeStoreSize( |
81 | 4.31k | RMWI->getValOperand()->getType())), |
82 | 4.31k | AATags); |
83 | 4.31k | } |
84 | | |
85 | 22.6k | MemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) { |
86 | 22.6k | return getForSource(cast<AnyMemTransferInst>(MTI)); |
87 | 22.6k | } |
88 | | |
89 | 0 | MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) { |
90 | 0 | return getForSource(cast<AnyMemTransferInst>(MTI)); |
91 | 0 | } |
92 | | |
93 | 314k | MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) { |
94 | 314k | auto Size = LocationSize::unknown(); |
95 | 314k | if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength())) |
96 | 300k | Size = LocationSize::precise(C->getValue().getZExtValue()); |
97 | 314k | |
98 | 314k | // memcpy/memmove can have AA tags. For memcpy, they apply |
99 | 314k | // to both the source and the destination. |
100 | 314k | AAMDNodes AATags; |
101 | 314k | MTI->getAAMetadata(AATags); |
102 | 314k | |
103 | 314k | return MemoryLocation(MTI->getRawSource(), Size, AATags); |
104 | 314k | } |
105 | | |
106 | 2.19k | MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MI) { |
107 | 2.19k | return getForDest(cast<AnyMemIntrinsic>(MI)); |
108 | 2.19k | } |
109 | | |
110 | 0 | MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) { |
111 | 0 | return getForDest(cast<AnyMemIntrinsic>(MI)); |
112 | 0 | } |
113 | | |
114 | 353k | MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { |
115 | 353k | auto Size = LocationSize::unknown(); |
116 | 353k | if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength())) |
117 | 337k | Size = LocationSize::precise(C->getValue().getZExtValue()); |
118 | 353k | |
119 | 353k | // memcpy/memmove can have AA tags. For memcpy, they apply |
120 | 353k | // to both the source and the destination. |
121 | 353k | AAMDNodes AATags; |
122 | 353k | MI->getAAMetadata(AATags); |
123 | 353k | |
124 | 353k | return MemoryLocation(MI->getRawDest(), Size, AATags); |
125 | 353k | } |
126 | | |
127 | | MemoryLocation MemoryLocation::getForArgument(const CallBase *Call, |
128 | | unsigned ArgIdx, |
129 | 1.55M | const TargetLibraryInfo *TLI) { |
130 | 1.55M | AAMDNodes AATags; |
131 | 1.55M | Call->getAAMetadata(AATags); |
132 | 1.55M | const Value *Arg = Call->getArgOperand(ArgIdx); |
133 | 1.55M | |
134 | 1.55M | // We may be able to produce an exact size for known intrinsics. |
135 | 1.55M | if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Call)) { |
136 | 1.52M | const DataLayout &DL = II->getModule()->getDataLayout(); |
137 | 1.52M | |
138 | 1.52M | switch (II->getIntrinsicID()) { |
139 | 1.52M | default: |
140 | 18.2k | break; |
141 | 1.52M | case Intrinsic::memset: |
142 | 707k | case Intrinsic::memcpy: |
143 | 707k | case Intrinsic::memmove: |
144 | 707k | assert((ArgIdx == 0 || ArgIdx == 1) && |
145 | 707k | "Invalid argument index for memory intrinsic"); |
146 | 707k | if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) |
147 | 646k | return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), |
148 | 646k | AATags); |
149 | 60.5k | break; |
150 | 60.5k | |
151 | 803k | case Intrinsic::lifetime_start: |
152 | 803k | case Intrinsic::lifetime_end: |
153 | 803k | case Intrinsic::invariant_start: |
154 | 803k | assert(ArgIdx == 1 && "Invalid argument index"); |
155 | 803k | return MemoryLocation( |
156 | 803k | Arg, |
157 | 803k | LocationSize::precise( |
158 | 803k | cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()), |
159 | 803k | AATags); |
160 | 803k | |
161 | 803k | case Intrinsic::invariant_end: |
162 | 8 | // The first argument to an invariant.end is a "descriptor" type (e.g. a |
163 | 8 | // pointer to a empty struct) which is never actually dereferenced. |
164 | 8 | if (ArgIdx == 0) |
165 | 4 | return MemoryLocation(Arg, LocationSize::precise(0), AATags); |
166 | 4 | assert(ArgIdx == 2 && "Invalid argument index"); |
167 | 4 | return MemoryLocation( |
168 | 4 | Arg, |
169 | 4 | LocationSize::precise( |
170 | 4 | cast<ConstantInt>(II->getArgOperand(1))->getZExtValue()), |
171 | 4 | AATags); |
172 | 4 | |
173 | 4 | case Intrinsic::arm_neon_vld1: |
174 | 4 | assert(ArgIdx == 0 && "Invalid argument index"); |
175 | 4 | // LLVM's vld1 and vst1 intrinsics currently only support a single |
176 | 4 | // vector register. |
177 | 4 | return MemoryLocation( |
178 | 4 | Arg, LocationSize::precise(DL.getTypeStoreSize(II->getType())), |
179 | 4 | AATags); |
180 | 4 | |
181 | 4 | case Intrinsic::arm_neon_vst1: |
182 | 4 | assert(ArgIdx == 0 && "Invalid argument index"); |
183 | 4 | return MemoryLocation(Arg, |
184 | 4 | LocationSize::precise(DL.getTypeStoreSize( |
185 | 4 | II->getArgOperand(1)->getType())), |
186 | 4 | AATags); |
187 | 109k | } |
188 | 109k | } |
189 | 109k | |
190 | 109k | // We can bound the aliasing properties of memset_pattern16 just as we can |
191 | 109k | // for memcpy/memset. This is particularly important because the |
192 | 109k | // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 |
193 | 109k | // whenever possible. |
194 | 109k | LibFunc F; |
195 | 109k | if (TLI && Call->getCalledFunction()102k && |
196 | 109k | TLI->getLibFunc(*Call->getCalledFunction(), F)102k && |
197 | 109k | F == LibFunc_memset_pattern1624.1k && TLI->has(F)3.90k ) { |
198 | 3.90k | assert((ArgIdx == 0 || ArgIdx == 1) && |
199 | 3.90k | "Invalid argument index for memset_pattern16"); |
200 | 3.90k | if (ArgIdx == 1) |
201 | 1.95k | return MemoryLocation(Arg, LocationSize::precise(16), AATags); |
202 | 1.95k | if (const ConstantInt *LenCI = |
203 | 1.63k | dyn_cast<ConstantInt>(Call->getArgOperand(2))) |
204 | 1.63k | return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), |
205 | 1.63k | AATags); |
206 | 105k | } |
207 | 105k | // FIXME: Handle memset_pattern4 and memset_pattern8 also. |
208 | 105k | |
209 | 105k | return MemoryLocation(Call->getArgOperand(ArgIdx), LocationSize::unknown(), |
210 | 105k | AATags); |
211 | 105k | } |