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 
get(const LoadInst * LI)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 
get(const StoreInst * SI)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 
get(const VAArgInst * VI)40 MemoryLocation MemoryLocation::get(const VAArgInst *VI) {
41   AAMDNodes AATags;
42   VI->getAAMetadata(AATags);
43 
44   return MemoryLocation(VI->getPointerOperand(), UnknownSize, AATags);
45 }
46 
get(const AtomicCmpXchgInst * CXI)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 
get(const AtomicRMWInst * RMWI)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 
getForSource(const MemTransferInst * MTI)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 
getForDest(const MemIntrinsic * MTI)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.
isMemsetPattern16(const Function * MS,const TargetLibraryInfo & TLI)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 
getForArgument(ImmutableCallSite CS,unsigned ArgIdx,const TargetLibraryInfo & TLI)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