1 //===- MemoryLocation.cpp - Memory location descriptions -------------------==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 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" 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(LI->getPointerOperand(), 41 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 DL.getTypeStoreSize(SI->getValueOperand()->getType()), 51 AATags); 52 } 53 54 MemoryLocation MemoryLocation::get(const VAArgInst *VI) { 55 AAMDNodes AATags; 56 VI->getAAMetadata(AATags); 57 58 return MemoryLocation(VI->getPointerOperand(), LocationSize::unknown(), 59 AATags); 60 } 61 62 MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) { 63 AAMDNodes AATags; 64 CXI->getAAMetadata(AATags); 65 const auto &DL = CXI->getModule()->getDataLayout(); 66 67 return MemoryLocation( 68 CXI->getPointerOperand(), 69 DL.getTypeStoreSize(CXI->getCompareOperand()->getType()), AATags); 70 } 71 72 MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { 73 AAMDNodes AATags; 74 RMWI->getAAMetadata(AATags); 75 const auto &DL = RMWI->getModule()->getDataLayout(); 76 77 return MemoryLocation(RMWI->getPointerOperand(), 78 DL.getTypeStoreSize(RMWI->getValOperand()->getType()), 79 AATags); 80 } 81 82 MemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) { 83 return getForSource(cast<AnyMemTransferInst>(MTI)); 84 } 85 86 MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) { 87 return getForSource(cast<AnyMemTransferInst>(MTI)); 88 } 89 90 MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) { 91 uint64_t Size = MemoryLocation::UnknownSize; 92 if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength())) 93 Size = C->getValue().getZExtValue(); 94 95 // memcpy/memmove can have AA tags. For memcpy, they apply 96 // to both the source and the destination. 97 AAMDNodes AATags; 98 MTI->getAAMetadata(AATags); 99 100 return MemoryLocation(MTI->getRawSource(), Size, AATags); 101 } 102 103 MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MI) { 104 return getForDest(cast<AnyMemIntrinsic>(MI)); 105 } 106 107 MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) { 108 return getForDest(cast<AnyMemIntrinsic>(MI)); 109 } 110 111 MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { 112 uint64_t Size = MemoryLocation::UnknownSize; 113 if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength())) 114 Size = 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 MI->getAAMetadata(AATags); 120 121 return MemoryLocation(MI->getRawDest(), Size, AATags); 122 } 123 124 MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, 125 unsigned ArgIdx, 126 const TargetLibraryInfo *TLI) { 127 AAMDNodes AATags; 128 CS->getAAMetadata(AATags); 129 const Value *Arg = CS.getArgument(ArgIdx); 130 131 // We may be able to produce an exact size for known intrinsics. 132 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) { 133 const DataLayout &DL = II->getModule()->getDataLayout(); 134 135 switch (II->getIntrinsicID()) { 136 default: 137 break; 138 case Intrinsic::memset: 139 case Intrinsic::memcpy: 140 case Intrinsic::memmove: 141 assert((ArgIdx == 0 || ArgIdx == 1) && 142 "Invalid argument index for memory intrinsic"); 143 if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) 144 return MemoryLocation(Arg, LenCI->getZExtValue(), AATags); 145 break; 146 147 case Intrinsic::lifetime_start: 148 case Intrinsic::lifetime_end: 149 case Intrinsic::invariant_start: 150 assert(ArgIdx == 1 && "Invalid argument index"); 151 return MemoryLocation( 152 Arg, cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AATags); 153 154 case Intrinsic::invariant_end: 155 // The first argument to an invariant.end is a "descriptor" type (e.g. a 156 // pointer to a empty struct) which is never actually dereferenced. 157 if (ArgIdx == 0) 158 return MemoryLocation(Arg, 0, AATags); 159 assert(ArgIdx == 2 && "Invalid argument index"); 160 return MemoryLocation( 161 Arg, cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AATags); 162 163 case Intrinsic::arm_neon_vld1: 164 assert(ArgIdx == 0 && "Invalid argument index"); 165 // LLVM's vld1 and vst1 intrinsics currently only support a single 166 // vector register. 167 return MemoryLocation(Arg, DL.getTypeStoreSize(II->getType()), AATags); 168 169 case Intrinsic::arm_neon_vst1: 170 assert(ArgIdx == 0 && "Invalid argument index"); 171 return MemoryLocation( 172 Arg, DL.getTypeStoreSize(II->getArgOperand(1)->getType()), AATags); 173 } 174 } 175 176 // We can bound the aliasing properties of memset_pattern16 just as we can 177 // for memcpy/memset. This is particularly important because the 178 // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 179 // whenever possible. 180 LibFunc F; 181 if (TLI && CS.getCalledFunction() && 182 TLI->getLibFunc(*CS.getCalledFunction(), F) && 183 F == LibFunc_memset_pattern16 && TLI->has(F)) { 184 assert((ArgIdx == 0 || ArgIdx == 1) && 185 "Invalid argument index for memset_pattern16"); 186 if (ArgIdx == 1) 187 return MemoryLocation(Arg, 16, AATags); 188 if (const ConstantInt *LenCI = dyn_cast<ConstantInt>(CS.getArgument(2))) 189 return MemoryLocation(Arg, LenCI->getZExtValue(), AATags); 190 } 191 // FIXME: Handle memset_pattern4 and memset_pattern8 also. 192 193 return MemoryLocation(CS.getArgument(ArgIdx), LocationSize::unknown(), 194 AATags); 195 } 196