Home | History | Annotate | Download | only in Analysis
      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 MemoryLocation MemoryLocation::get(const LoadInst *LI) {
     22   AAMDNodes AATags;
     23   LI->getAAMetadata(AATags);
     24   const auto &DL = LI->getModule()->getDataLayout();
     25 
     26   return MemoryLocation(LI->getPointerOperand(),
     27                         DL.getTypeStoreSize(LI->getType()), AATags);
     28 }
     29 
     30 MemoryLocation MemoryLocation::get(const StoreInst *SI) {
     31   AAMDNodes AATags;
     32   SI->getAAMetadata(AATags);
     33   const auto &DL = SI->getModule()->getDataLayout();
     34 
     35   return MemoryLocation(SI->getPointerOperand(),
     36                         DL.getTypeStoreSize(SI->getValueOperand()->getType()),
     37                         AATags);
     38 }
     39 
     40 MemoryLocation MemoryLocation::get(const VAArgInst *VI) {
     41   AAMDNodes AATags;
     42   VI->getAAMetadata(AATags);
     43 
     44   return MemoryLocation(VI->getPointerOperand(), UnknownSize, AATags);
     45 }
     46 
     47 MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) {
     48   AAMDNodes AATags;
     49   CXI->getAAMetadata(AATags);
     50   const auto &DL = CXI->getModule()->getDataLayout();
     51 
     52   return MemoryLocation(
     53       CXI->getPointerOperand(),
     54       DL.getTypeStoreSize(CXI->getCompareOperand()->getType()), AATags);
     55 }
     56 
     57 MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) {
     58   AAMDNodes AATags;
     59   RMWI->getAAMetadata(AATags);
     60   const auto &DL = RMWI->getModule()->getDataLayout();
     61 
     62   return MemoryLocation(RMWI->getPointerOperand(),
     63                         DL.getTypeStoreSize(RMWI->getValOperand()->getType()),
     64                         AATags);
     65 }
     66 
     67 MemoryLocation MemoryLocation::getForSource(const MemTransferInst *MTI) {
     68   return getForSource(cast<AnyMemTransferInst>(MTI));
     69 }
     70 
     71 MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) {
     72   return getForSource(cast<AnyMemTransferInst>(MTI));
     73 }
     74 
     75 MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) {
     76   uint64_t Size = UnknownSize;
     77   if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
     78     Size = C->getValue().getZExtValue();
     79 
     80   // memcpy/memmove can have AA tags. For memcpy, they apply
     81   // to both the source and the destination.
     82   AAMDNodes AATags;
     83   MTI->getAAMetadata(AATags);
     84 
     85   return MemoryLocation(MTI->getRawSource(), Size, AATags);
     86 }
     87 
     88 MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MI) {
     89   return getForDest(cast<AnyMemIntrinsic>(MI));
     90 }
     91 
     92 MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) {
     93   return getForDest(cast<AnyMemIntrinsic>(MI));
     94 }
     95 
     96 MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) {
     97   uint64_t Size = UnknownSize;
     98   if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength()))
     99     Size = C->getValue().getZExtValue();
    100 
    101   // memcpy/memmove can have AA tags. For memcpy, they apply
    102   // to both the source and the destination.
    103   AAMDNodes AATags;
    104   MI->getAAMetadata(AATags);
    105 
    106   return MemoryLocation(MI->getRawDest(), Size, AATags);
    107 }
    108 
    109 MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,
    110                                               unsigned ArgIdx,
    111                                               const TargetLibraryInfo &TLI) {
    112   AAMDNodes AATags;
    113   CS->getAAMetadata(AATags);
    114   const Value *Arg = CS.getArgument(ArgIdx);
    115 
    116   // We may be able to produce an exact size for known intrinsics.
    117   if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
    118     const DataLayout &DL = II->getModule()->getDataLayout();
    119 
    120     switch (II->getIntrinsicID()) {
    121     default:
    122       break;
    123     case Intrinsic::memset:
    124     case Intrinsic::memcpy:
    125     case Intrinsic::memmove:
    126       assert((ArgIdx == 0 || ArgIdx == 1) &&
    127              "Invalid argument index for memory intrinsic");
    128       if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
    129         return MemoryLocation(Arg, LenCI->getZExtValue(), AATags);
    130       break;
    131 
    132     case Intrinsic::lifetime_start:
    133     case Intrinsic::lifetime_end:
    134     case Intrinsic::invariant_start:
    135       assert(ArgIdx == 1 && "Invalid argument index");
    136       return MemoryLocation(
    137           Arg, cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AATags);
    138 
    139     case Intrinsic::invariant_end:
    140       assert(ArgIdx == 2 && "Invalid argument index");
    141       return MemoryLocation(
    142           Arg, cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AATags);
    143 
    144     case Intrinsic::arm_neon_vld1:
    145       assert(ArgIdx == 0 && "Invalid argument index");
    146       // LLVM's vld1 and vst1 intrinsics currently only support a single
    147       // vector register.
    148       return MemoryLocation(Arg, DL.getTypeStoreSize(II->getType()), AATags);
    149 
    150     case Intrinsic::arm_neon_vst1:
    151       assert(ArgIdx == 0 && "Invalid argument index");
    152       return MemoryLocation(
    153           Arg, DL.getTypeStoreSize(II->getArgOperand(1)->getType()), AATags);
    154     }
    155   }
    156 
    157   // We can bound the aliasing properties of memset_pattern16 just as we can
    158   // for memcpy/memset.  This is particularly important because the
    159   // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
    160   // whenever possible.
    161   LibFunc F;
    162   if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) &&
    163       F == LibFunc_memset_pattern16 && TLI.has(F)) {
    164     assert((ArgIdx == 0 || ArgIdx == 1) &&
    165            "Invalid argument index for memset_pattern16");
    166     if (ArgIdx == 1)
    167       return MemoryLocation(Arg, 16, AATags);
    168     if (const ConstantInt *LenCI = dyn_cast<ConstantInt>(CS.getArgument(2)))
    169       return MemoryLocation(Arg, LenCI->getZExtValue(), AATags);
    170   }
    171   // FIXME: Handle memset_pattern4 and memset_pattern8 also.
    172 
    173   return MemoryLocation(CS.getArgument(ArgIdx), UnknownSize, AATags);
    174 }
    175