| //===- MemoryLocation.cpp - Memory location descriptions -------------------==// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Analysis/MemoryLocation.h" | |
| #include "llvm/Analysis/TargetLibraryInfo.h" | |
| #include "llvm/IR/BasicBlock.h" | |
| #include "llvm/IR/DataLayout.h" | |
| #include "llvm/IR/Instructions.h" | |
| #include "llvm/IR/IntrinsicInst.h" | |
| #include "llvm/IR/LLVMContext.h" | |
| #include "llvm/IR/Module.h" | |
| #include "llvm/IR/Type.h" | |
| using namespace llvm; | |
| MemoryLocation MemoryLocation::get(const LoadInst *LI) { | |
| AAMDNodes AATags; | |
| LI->getAAMetadata(AATags); | |
| const auto &DL = LI->getModule()->getDataLayout(); | |
| return MemoryLocation(LI->getPointerOperand(), | |
| DL.getTypeStoreSize(LI->getType()), AATags); | |
| } | |
| MemoryLocation MemoryLocation::get(const StoreInst *SI) { | |
| AAMDNodes AATags; | |
| SI->getAAMetadata(AATags); | |
| const auto &DL = SI->getModule()->getDataLayout(); | |
| return MemoryLocation(SI->getPointerOperand(), | |
| DL.getTypeStoreSize(SI->getValueOperand()->getType()), | |
| AATags); | |
| } | |
| MemoryLocation MemoryLocation::get(const VAArgInst *VI) { | |
| AAMDNodes AATags; | |
| VI->getAAMetadata(AATags); | |
| return MemoryLocation(VI->getPointerOperand(), UnknownSize, AATags); | |
| } | |
| MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) { | |
| AAMDNodes AATags; | |
| CXI->getAAMetadata(AATags); | |
| const auto &DL = CXI->getModule()->getDataLayout(); | |
| return MemoryLocation( | |
| CXI->getPointerOperand(), | |
| DL.getTypeStoreSize(CXI->getCompareOperand()->getType()), AATags); | |
| } | |
| MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { | |
| AAMDNodes AATags; | |
| RMWI->getAAMetadata(AATags); | |
| const auto &DL = RMWI->getModule()->getDataLayout(); | |
| return MemoryLocation(RMWI->getPointerOperand(), | |
| DL.getTypeStoreSize(RMWI->getValOperand()->getType()), | |
| AATags); | |
| } | |
| MemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) { | |
| return getForSource(cast<AnyMemTransferInst>(MTI)); | |
| } | |
| MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) { | |
| return getForSource(cast<AnyMemTransferInst>(MTI)); | |
| } | |
| MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) { | |
| uint64_t Size = UnknownSize; | |
| if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength())) | |
| Size = C->getValue().getZExtValue(); | |
| // memcpy/memmove can have AA tags. For memcpy, they apply | |
| // to both the source and the destination. | |
| AAMDNodes AATags; | |
| MTI->getAAMetadata(AATags); | |
| return MemoryLocation(MTI->getRawSource(), Size, AATags); | |
| } | |
| MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MI) { | |
| return getForDest(cast<AnyMemIntrinsic>(MI)); | |
| } | |
| MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) { | |
| return getForDest(cast<AnyMemIntrinsic>(MI)); | |
| } | |
| MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { | |
| uint64_t Size = UnknownSize; | |
| if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength())) | |
| Size = C->getValue().getZExtValue(); | |
| // memcpy/memmove can have AA tags. For memcpy, they apply | |
| // to both the source and the destination. | |
| AAMDNodes AATags; | |
| MI->getAAMetadata(AATags); | |
| return MemoryLocation(MI->getRawDest(), Size, AATags); | |
| } | |
| MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, | |
| unsigned ArgIdx, | |
| const TargetLibraryInfo &TLI) { | |
| AAMDNodes AATags; | |
| CS->getAAMetadata(AATags); | |
| const Value *Arg = CS.getArgument(ArgIdx); | |
| // We may be able to produce an exact size for known intrinsics. | |
| if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) { | |
| const DataLayout &DL = II->getModule()->getDataLayout(); | |
| switch (II->getIntrinsicID()) { | |
| default: | |
| break; | |
| case Intrinsic::memset: | |
| case Intrinsic::memcpy: | |
| case Intrinsic::memmove: | |
| assert((ArgIdx == 0 || ArgIdx == 1) && | |
| "Invalid argument index for memory intrinsic"); | |
| if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) | |
| return MemoryLocation(Arg, LenCI->getZExtValue(), AATags); | |
| break; | |
| case Intrinsic::lifetime_start: | |
| case Intrinsic::lifetime_end: | |
| case Intrinsic::invariant_start: | |
| assert(ArgIdx == 1 && "Invalid argument index"); | |
| return MemoryLocation( | |
| Arg, cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AATags); | |
| case Intrinsic::invariant_end: | |
| assert(ArgIdx == 2 && "Invalid argument index"); | |
| return MemoryLocation( | |
| Arg, cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AATags); | |
| case Intrinsic::arm_neon_vld1: | |
| assert(ArgIdx == 0 && "Invalid argument index"); | |
| // LLVM's vld1 and vst1 intrinsics currently only support a single | |
| // vector register. | |
| return MemoryLocation(Arg, DL.getTypeStoreSize(II->getType()), AATags); | |
| case Intrinsic::arm_neon_vst1: | |
| assert(ArgIdx == 0 && "Invalid argument index"); | |
| return MemoryLocation( | |
| Arg, DL.getTypeStoreSize(II->getArgOperand(1)->getType()), AATags); | |
| } | |
| } | |
| // We can bound the aliasing properties of memset_pattern16 just as we can | |
| // for memcpy/memset. This is particularly important because the | |
| // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 | |
| // whenever possible. | |
| LibFunc F; | |
| if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && | |
| F == LibFunc_memset_pattern16 && TLI.has(F)) { | |
| assert((ArgIdx == 0 || ArgIdx == 1) && | |
| "Invalid argument index for memset_pattern16"); | |
| if (ArgIdx == 1) | |
| return MemoryLocation(Arg, 16, AATags); | |
| if (const ConstantInt *LenCI = dyn_cast<ConstantInt>(CS.getArgument(2))) | |
| return MemoryLocation(Arg, LenCI->getZExtValue(), AATags); | |
| } | |
| // FIXME: Handle memset_pattern4 and memset_pattern8 also. | |
| return MemoryLocation(CS.getArgument(ArgIdx), UnknownSize, AATags); | |
| } |