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