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