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   uint64_t Size = UnknownSize;
     69   if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
     70     Size = C->getValue().getZExtValue();
     71 
     72   // memcpy/memmove can have AA tags. For memcpy, they apply
     73   // to both the source and the destination.
     74   AAMDNodes AATags;
     75   MTI->getAAMetadata(AATags);
     76 
     77   return MemoryLocation(MTI->getRawSource(), Size, AATags);
     78 }
     79 
     80 MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MTI) {
     81   uint64_t Size = UnknownSize;
     82   if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
     83     Size = C->getValue().getZExtValue();
     84 
     85   // memcpy/memmove can have AA tags. For memcpy, they apply
     86   // to both the source and the destination.
     87   AAMDNodes AATags;
     88   MTI->getAAMetadata(AATags);
     89 
     90   return MemoryLocation(MTI->getRawDest(), Size, AATags);
     91 }
     92 
     93 // FIXME: This code is duplicated with BasicAliasAnalysis and should be hoisted
     94 // to some common utility location.
     95 static bool isMemsetPattern16(const Function *MS,
     96                               const TargetLibraryInfo &TLI) {
     97   if (TLI.has(LibFunc::memset_pattern16) &&
     98       MS->getName() == "memset_pattern16") {
     99     FunctionType *MemsetType = MS->getFunctionType();
    100     if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 &&
    101         isa<PointerType>(MemsetType->getParamType(0)) &&
    102         isa<PointerType>(MemsetType->getParamType(1)) &&
    103         isa<IntegerType>(MemsetType->getParamType(2)))
    104       return true;
    105   }
    106 
    107   return false;
    108 }
    109 
    110 MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,
    111                                               unsigned ArgIdx,
    112                                               const TargetLibraryInfo &TLI) {
    113   AAMDNodes AATags;
    114   CS->getAAMetadata(AATags);
    115   const Value *Arg = CS.getArgument(ArgIdx);
    116 
    117   // We may be able to produce an exact size for known intrinsics.
    118   if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
    119     const DataLayout &DL = II->getModule()->getDataLayout();
    120 
    121     switch (II->getIntrinsicID()) {
    122     default:
    123       break;
    124     case Intrinsic::memset:
    125     case Intrinsic::memcpy:
    126     case Intrinsic::memmove:
    127       assert((ArgIdx == 0 || ArgIdx == 1) &&
    128              "Invalid argument index for memory intrinsic");
    129       if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
    130         return MemoryLocation(Arg, LenCI->getZExtValue(), AATags);
    131       break;
    132 
    133     case Intrinsic::lifetime_start:
    134     case Intrinsic::lifetime_end:
    135     case Intrinsic::invariant_start:
    136       assert(ArgIdx == 1 && "Invalid argument index");
    137       return MemoryLocation(
    138           Arg, cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AATags);
    139 
    140     case Intrinsic::invariant_end:
    141       assert(ArgIdx == 2 && "Invalid argument index");
    142       return MemoryLocation(
    143           Arg, cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AATags);
    144 
    145     case Intrinsic::arm_neon_vld1:
    146       assert(ArgIdx == 0 && "Invalid argument index");
    147       // LLVM's vld1 and vst1 intrinsics currently only support a single
    148       // vector register.
    149       return MemoryLocation(Arg, DL.getTypeStoreSize(II->getType()), AATags);
    150 
    151     case Intrinsic::arm_neon_vst1:
    152       assert(ArgIdx == 0 && "Invalid argument index");
    153       return MemoryLocation(
    154           Arg, DL.getTypeStoreSize(II->getArgOperand(1)->getType()), AATags);
    155     }
    156   }
    157 
    158   // We can bound the aliasing properties of memset_pattern16 just as we can
    159   // for memcpy/memset.  This is particularly important because the
    160   // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
    161   // whenever possible.
    162   if (CS.getCalledFunction() &&
    163       isMemsetPattern16(CS.getCalledFunction(), TLI)) {
    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