diff options
Diffstat (limited to 'lib/Analysis/MemoryLocation.cpp')
| -rw-r--r-- | lib/Analysis/MemoryLocation.cpp | 96 | 
1 files changed, 67 insertions, 29 deletions
diff --git a/lib/Analysis/MemoryLocation.cpp b/lib/Analysis/MemoryLocation.cpp index 55924db284ecf..27e8d72b8e898 100644 --- a/lib/Analysis/MemoryLocation.cpp +++ b/lib/Analysis/MemoryLocation.cpp @@ -18,13 +18,28 @@  #include "llvm/IR/Type.h"  using namespace llvm; +void LocationSize::print(raw_ostream &OS) const { +  OS << "LocationSize::"; +  if (*this == unknown()) +    OS << "unknown"; +  else if (*this == mapEmpty()) +    OS << "mapEmpty"; +  else if (*this == mapTombstone()) +    OS << "mapTombstone"; +  else if (isPrecise()) +    OS << "precise(" << getValue() << ')'; +  else +    OS << "upperBound(" << getValue() << ')'; +} +  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); +  return MemoryLocation( +      LI->getPointerOperand(), +      LocationSize::precise(DL.getTypeStoreSize(LI->getType())), AATags);  }  MemoryLocation MemoryLocation::get(const StoreInst *SI) { @@ -33,7 +48,8 @@ MemoryLocation MemoryLocation::get(const StoreInst *SI) {    const auto &DL = SI->getModule()->getDataLayout();    return MemoryLocation(SI->getPointerOperand(), -                        DL.getTypeStoreSize(SI->getValueOperand()->getType()), +                        LocationSize::precise(DL.getTypeStoreSize( +                            SI->getValueOperand()->getType())),                          AATags);  } @@ -41,7 +57,8 @@ MemoryLocation MemoryLocation::get(const VAArgInst *VI) {    AAMDNodes AATags;    VI->getAAMetadata(AATags); -  return MemoryLocation(VI->getPointerOperand(), UnknownSize, AATags); +  return MemoryLocation(VI->getPointerOperand(), LocationSize::unknown(), +                        AATags);  }  MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) { @@ -49,9 +66,10 @@ MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) {    CXI->getAAMetadata(AATags);    const auto &DL = CXI->getModule()->getDataLayout(); -  return MemoryLocation( -      CXI->getPointerOperand(), -      DL.getTypeStoreSize(CXI->getCompareOperand()->getType()), AATags); +  return MemoryLocation(CXI->getPointerOperand(), +                        LocationSize::precise(DL.getTypeStoreSize( +                            CXI->getCompareOperand()->getType())), +                        AATags);  }  MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { @@ -60,7 +78,8 @@ MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) {    const auto &DL = RMWI->getModule()->getDataLayout();    return MemoryLocation(RMWI->getPointerOperand(), -                        DL.getTypeStoreSize(RMWI->getValOperand()->getType()), +                        LocationSize::precise(DL.getTypeStoreSize( +                            RMWI->getValOperand()->getType())),                          AATags);  } @@ -73,9 +92,9 @@ MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) {  }  MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) { -  uint64_t Size = UnknownSize; +  auto Size = LocationSize::unknown();    if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength())) -    Size = C->getValue().getZExtValue(); +    Size = LocationSize::precise(C->getValue().getZExtValue());    // memcpy/memmove can have AA tags. For memcpy, they apply    // to both the source and the destination. @@ -94,9 +113,9 @@ MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) {  }  MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { -  uint64_t Size = UnknownSize; +  auto Size = LocationSize::unknown();    if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength())) -    Size = C->getValue().getZExtValue(); +    Size = LocationSize::precise(C->getValue().getZExtValue());    // memcpy/memmove can have AA tags. For memcpy, they apply    // to both the source and the destination. @@ -106,15 +125,15 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) {    return MemoryLocation(MI->getRawDest(), Size, AATags);  } -MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, +MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,                                                unsigned ArgIdx, -                                              const TargetLibraryInfo &TLI) { +                                              const TargetLibraryInfo *TLI) {    AAMDNodes AATags; -  CS->getAAMetadata(AATags); -  const Value *Arg = CS.getArgument(ArgIdx); +  Call->getAAMetadata(AATags); +  const Value *Arg = Call->getArgOperand(ArgIdx);    // We may be able to produce an exact size for known intrinsics. -  if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) { +  if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Call)) {      const DataLayout &DL = II->getModule()->getDataLayout();      switch (II->getIntrinsicID()) { @@ -126,7 +145,8 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,        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); +        return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), +                              AATags);        break;      case Intrinsic::lifetime_start: @@ -134,23 +154,37 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,      case Intrinsic::invariant_start:        assert(ArgIdx == 1 && "Invalid argument index");        return MemoryLocation( -          Arg, cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AATags); +          Arg, +          LocationSize::precise( +              cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()), +          AATags);      case Intrinsic::invariant_end: +      // The first argument to an invariant.end is a "descriptor" type (e.g. a +      // pointer to a empty struct) which is never actually dereferenced. +      if (ArgIdx == 0) +        return MemoryLocation(Arg, LocationSize::precise(0), AATags);        assert(ArgIdx == 2 && "Invalid argument index");        return MemoryLocation( -          Arg, cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AATags); +          Arg, +          LocationSize::precise( +              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); +      return MemoryLocation( +          Arg, LocationSize::precise(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); +      return MemoryLocation(Arg, +                            LocationSize::precise(DL.getTypeStoreSize( +                                II->getArgOperand(1)->getType())), +                            AATags);      }    } @@ -159,16 +193,20 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,    // 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)) { +  if (TLI && Call->getCalledFunction() && +      TLI->getLibFunc(*Call->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); +      return MemoryLocation(Arg, LocationSize::precise(16), AATags); +    if (const ConstantInt *LenCI = +            dyn_cast<ConstantInt>(Call->getArgOperand(2))) +      return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), +                            AATags);    }    // FIXME: Handle memset_pattern4 and memset_pattern8 also. -  return MemoryLocation(CS.getArgument(ArgIdx), UnknownSize, AATags); +  return MemoryLocation(Call->getArgOperand(ArgIdx), LocationSize::unknown(), +                        AATags);  }  | 
