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 void LocationSize::print(raw_ostream &OS) const { 21 OS << "LocationSize::"; 22 if (*this == unknown()) 23 OS << "unknown"; 24 else if (*this == mapEmpty()) 25 OS << "mapEmpty"; 26 else if (*this == mapTombstone()) 27 OS << "mapTombstone"; 28 else if (isPrecise()) 29 OS << "precise(" << getValue() << ')'; 30 else 31 OS << "upperBound(" << getValue() << ')'; 32 } 33 34 MemoryLocation MemoryLocation::get(const LoadInst *LI) { 35 AAMDNodes AATags; 36 LI->getAAMetadata(AATags); 37 const auto &DL = LI->getModule()->getDataLayout(); 38 39 return MemoryLocation( 40 LI->getPointerOperand(), 41 LocationSize::precise(DL.getTypeStoreSize(LI->getType())), AATags); 42 } 43 44 MemoryLocation MemoryLocation::get(const StoreInst *SI) { 45 AAMDNodes AATags; 46 SI->getAAMetadata(AATags); 47 const auto &DL = SI->getModule()->getDataLayout(); 48 49 return MemoryLocation(SI->getPointerOperand(), 50 LocationSize::precise(DL.getTypeStoreSize( 51 SI->getValueOperand()->getType())), 52 AATags); 53 } 54 55 MemoryLocation MemoryLocation::get(const VAArgInst *VI) { 56 AAMDNodes AATags; 57 VI->getAAMetadata(AATags); 58 59 return MemoryLocation(VI->getPointerOperand(), LocationSize::unknown(), 60 AATags); 61 } 62 63 MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) { 64 AAMDNodes AATags; 65 CXI->getAAMetadata(AATags); 66 const auto &DL = CXI->getModule()->getDataLayout(); 67 68 return MemoryLocation(CXI->getPointerOperand(), 69 LocationSize::precise(DL.getTypeStoreSize( 70 CXI->getCompareOperand()->getType())), 71 AATags); 72 } 73 74 MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { 75 AAMDNodes AATags; 76 RMWI->getAAMetadata(AATags); 77 const auto &DL = RMWI->getModule()->getDataLayout(); 78 79 return MemoryLocation(RMWI->getPointerOperand(), 80 LocationSize::precise(DL.getTypeStoreSize( 81 RMWI->getValOperand()->getType())), 82 AATags); 83 } 84 85 MemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) { 86 return getForSource(cast<AnyMemTransferInst>(MTI)); 87 } 88 89 MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) { 90 return getForSource(cast<AnyMemTransferInst>(MTI)); 91 } 92 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()); 97 98 // memcpy/memmove can have AA tags. For memcpy, they apply 99 // to both the source and the destination. 100 AAMDNodes AATags; 101 MTI->getAAMetadata(AATags); 102 103 return MemoryLocation(MTI->getRawSource(), Size, AATags); 104 } 105 106 MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MI) { 107 return getForDest(cast<AnyMemIntrinsic>(MI)); 108 } 109 110 MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) { 111 return getForDest(cast<AnyMemIntrinsic>(MI)); 112 } 113 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()); 118 119 // memcpy/memmove can have AA tags. For memcpy, they apply 120 // to both the source and the destination. 121 AAMDNodes AATags; 122 MI->getAAMetadata(AATags); 123 124 return MemoryLocation(MI->getRawDest(), Size, AATags); 125 } 126 127 MemoryLocation MemoryLocation::getForArgument(const CallBase *Call, 128 unsigned ArgIdx, 129 const TargetLibraryInfo *TLI) { 130 AAMDNodes AATags; 131 Call->getAAMetadata(AATags); 132 const Value *Arg = Call->getArgOperand(ArgIdx); 133 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(); 137 138 switch (II->getIntrinsicID()) { 139 default: 140 break; 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()), 148 AATags); 149 break; 150 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( 156 Arg, 157 LocationSize::precise( 158 cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()), 159 AATags); 160 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. 164 if (ArgIdx == 0) 165 return MemoryLocation(Arg, LocationSize::precise(0), AATags); 166 assert(ArgIdx == 2 && "Invalid argument index"); 167 return MemoryLocation( 168 Arg, 169 LocationSize::precise( 170 cast<ConstantInt>(II->getArgOperand(1))->getZExtValue()), 171 AATags); 172 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 176 // vector register. 177 return MemoryLocation( 178 Arg, LocationSize::precise(DL.getTypeStoreSize(II->getType())), 179 AATags); 180 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())), 186 AATags); 187 } 188 } 189 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. 194 LibFunc F; 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"); 200 if (ArgIdx == 1) 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()), 205 AATags); 206 } 207 // FIXME: Handle memset_pattern4 and memset_pattern8 also. 208 209 return MemoryLocation(Call->getArgOperand(ArgIdx), LocationSize::unknown(), 210 AATags); 211 } 212