xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CGBuilder.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===-- CGBuilder.h - Choose IRBuilder implementation  ----------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick 
9e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
10e5dd7070Spatrick #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
11e5dd7070Spatrick 
12e5dd7070Spatrick #include "Address.h"
13e5dd7070Spatrick #include "CodeGenTypeCache.h"
14*12c85518Srobert #include "llvm/IR/DataLayout.h"
15*12c85518Srobert #include "llvm/IR/IRBuilder.h"
16*12c85518Srobert #include "llvm/IR/Type.h"
17e5dd7070Spatrick 
18e5dd7070Spatrick namespace clang {
19e5dd7070Spatrick namespace CodeGen {
20e5dd7070Spatrick 
21e5dd7070Spatrick class CodeGenFunction;
22e5dd7070Spatrick 
23e5dd7070Spatrick /// This is an IRBuilder insertion helper that forwards to
24e5dd7070Spatrick /// CodeGenFunction::InsertHelper, which adds necessary metadata to
25e5dd7070Spatrick /// instructions.
26ec727ea7Spatrick class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter {
27e5dd7070Spatrick public:
28e5dd7070Spatrick   CGBuilderInserter() = default;
CGBuilderInserter(CodeGenFunction * CGF)29e5dd7070Spatrick   explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
30e5dd7070Spatrick 
31e5dd7070Spatrick   /// This forwards to CodeGenFunction::InsertHelper.
32e5dd7070Spatrick   void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
33e5dd7070Spatrick                     llvm::BasicBlock *BB,
34ec727ea7Spatrick                     llvm::BasicBlock::iterator InsertPt) const override;
35*12c85518Srobert 
36e5dd7070Spatrick private:
37e5dd7070Spatrick   CodeGenFunction *CGF = nullptr;
38e5dd7070Spatrick };
39e5dd7070Spatrick 
40e5dd7070Spatrick typedef CGBuilderInserter CGBuilderInserterTy;
41e5dd7070Spatrick 
42e5dd7070Spatrick typedef llvm::IRBuilder<llvm::ConstantFolder, CGBuilderInserterTy>
43e5dd7070Spatrick     CGBuilderBaseTy;
44e5dd7070Spatrick 
45e5dd7070Spatrick class CGBuilderTy : public CGBuilderBaseTy {
46e5dd7070Spatrick   /// Storing a reference to the type cache here makes it a lot easier
47e5dd7070Spatrick   /// to build natural-feeling, target-specific IR.
48e5dd7070Spatrick   const CodeGenTypeCache &TypeCache;
49*12c85518Srobert 
50e5dd7070Spatrick public:
CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::LLVMContext & C)51e5dd7070Spatrick   CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C)
52e5dd7070Spatrick       : CGBuilderBaseTy(C), TypeCache(TypeCache) {}
CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::LLVMContext & C,const llvm::ConstantFolder & F,const CGBuilderInserterTy & Inserter)53*12c85518Srobert   CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C,
54*12c85518Srobert               const llvm::ConstantFolder &F,
55e5dd7070Spatrick               const CGBuilderInserterTy &Inserter)
56e5dd7070Spatrick       : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {}
CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::Instruction * I)57e5dd7070Spatrick   CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I)
58e5dd7070Spatrick       : CGBuilderBaseTy(I), TypeCache(TypeCache) {}
CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::BasicBlock * BB)59e5dd7070Spatrick   CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB)
60e5dd7070Spatrick       : CGBuilderBaseTy(BB), TypeCache(TypeCache) {}
61e5dd7070Spatrick 
getSize(CharUnits N)62e5dd7070Spatrick   llvm::ConstantInt *getSize(CharUnits N) {
63e5dd7070Spatrick     return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity());
64e5dd7070Spatrick   }
getSize(uint64_t N)65e5dd7070Spatrick   llvm::ConstantInt *getSize(uint64_t N) {
66e5dd7070Spatrick     return llvm::ConstantInt::get(TypeCache.SizeTy, N);
67e5dd7070Spatrick   }
68e5dd7070Spatrick 
69e5dd7070Spatrick   // Note that we intentionally hide the CreateLoad APIs that don't
70e5dd7070Spatrick   // take an alignment.
71e5dd7070Spatrick   llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") {
72a9ac8606Spatrick     return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
73ec727ea7Spatrick                              Addr.getAlignment().getAsAlign(), Name);
74e5dd7070Spatrick   }
CreateLoad(Address Addr,const char * Name)75e5dd7070Spatrick   llvm::LoadInst *CreateLoad(Address Addr, const char *Name) {
76e5dd7070Spatrick     // This overload is required to prevent string literals from
77e5dd7070Spatrick     // ending up in the IsVolatile overload.
78a9ac8606Spatrick     return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
79ec727ea7Spatrick                              Addr.getAlignment().getAsAlign(), Name);
80e5dd7070Spatrick   }
81e5dd7070Spatrick   llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile,
82e5dd7070Spatrick                              const llvm::Twine &Name = "") {
83a9ac8606Spatrick     return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
84a9ac8606Spatrick                              Addr.getAlignment().getAsAlign(), IsVolatile,
85a9ac8606Spatrick                              Name);
86e5dd7070Spatrick   }
87e5dd7070Spatrick 
88e5dd7070Spatrick   using CGBuilderBaseTy::CreateAlignedLoad;
89e5dd7070Spatrick   llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr,
90e5dd7070Spatrick                                     CharUnits Align,
91e5dd7070Spatrick                                     const llvm::Twine &Name = "") {
92*12c85518Srobert     assert(llvm::cast<llvm::PointerType>(Addr->getType())
93*12c85518Srobert                ->isOpaqueOrPointeeTypeMatches(Ty));
94a9ac8606Spatrick     return CreateAlignedLoad(Ty, Addr, Align.getAsAlign(), Name);
95e5dd7070Spatrick   }
96e5dd7070Spatrick 
97e5dd7070Spatrick   // Note that we intentionally hide the CreateStore APIs that don't
98e5dd7070Spatrick   // take an alignment.
99e5dd7070Spatrick   llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr,
100e5dd7070Spatrick                                bool IsVolatile = false) {
101e5dd7070Spatrick     return CreateAlignedStore(Val, Addr.getPointer(),
102e5dd7070Spatrick                               Addr.getAlignment().getAsAlign(), IsVolatile);
103e5dd7070Spatrick   }
104e5dd7070Spatrick 
105e5dd7070Spatrick   using CGBuilderBaseTy::CreateAlignedStore;
106e5dd7070Spatrick   llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr,
107*12c85518Srobert                                       CharUnits Align,
108*12c85518Srobert                                       bool IsVolatile = false) {
109ec727ea7Spatrick     return CreateAlignedStore(Val, Addr, Align.getAsAlign(), IsVolatile);
110e5dd7070Spatrick   }
111e5dd7070Spatrick 
112e5dd7070Spatrick   // FIXME: these "default-aligned" APIs should be removed,
113e5dd7070Spatrick   // but I don't feel like fixing all the builtin code right now.
114e5dd7070Spatrick   llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val,
115e5dd7070Spatrick                                              llvm::Value *Addr,
116e5dd7070Spatrick                                              bool IsVolatile = false) {
117e5dd7070Spatrick     return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile);
118e5dd7070Spatrick   }
119e5dd7070Spatrick 
120e5dd7070Spatrick   /// Emit a load from an i1 flag variable.
121e5dd7070Spatrick   llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr,
122e5dd7070Spatrick                                  const llvm::Twine &Name = "") {
123*12c85518Srobert     assert(llvm::cast<llvm::PointerType>(Addr->getType())
124*12c85518Srobert                ->isOpaqueOrPointeeTypeMatches(getInt1Ty()));
125e5dd7070Spatrick     return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name);
126e5dd7070Spatrick   }
127e5dd7070Spatrick 
128e5dd7070Spatrick   /// Emit a store to an i1 flag variable.
CreateFlagStore(bool Value,llvm::Value * Addr)129e5dd7070Spatrick   llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) {
130*12c85518Srobert     assert(llvm::cast<llvm::PointerType>(Addr->getType())
131*12c85518Srobert                ->isOpaqueOrPointeeTypeMatches(getInt1Ty()));
132e5dd7070Spatrick     return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One());
133e5dd7070Spatrick   }
134e5dd7070Spatrick 
135a9ac8606Spatrick   // Temporarily use old signature; clang will be updated to an Address overload
136a9ac8606Spatrick   // in a subsequent patch.
137a9ac8606Spatrick   llvm::AtomicCmpXchgInst *
138a9ac8606Spatrick   CreateAtomicCmpXchg(llvm::Value *Ptr, llvm::Value *Cmp, llvm::Value *New,
139a9ac8606Spatrick                       llvm::AtomicOrdering SuccessOrdering,
140a9ac8606Spatrick                       llvm::AtomicOrdering FailureOrdering,
141a9ac8606Spatrick                       llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
142a9ac8606Spatrick     return CGBuilderBaseTy::CreateAtomicCmpXchg(
143a9ac8606Spatrick         Ptr, Cmp, New, llvm::MaybeAlign(), SuccessOrdering, FailureOrdering,
144a9ac8606Spatrick         SSID);
145a9ac8606Spatrick   }
146a9ac8606Spatrick 
147a9ac8606Spatrick   // Temporarily use old signature; clang will be updated to an Address overload
148a9ac8606Spatrick   // in a subsequent patch.
149a9ac8606Spatrick   llvm::AtomicRMWInst *
150a9ac8606Spatrick   CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, llvm::Value *Ptr,
151a9ac8606Spatrick                   llvm::Value *Val, llvm::AtomicOrdering Ordering,
152a9ac8606Spatrick                   llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
153a9ac8606Spatrick     return CGBuilderBaseTy::CreateAtomicRMW(Op, Ptr, Val, llvm::MaybeAlign(),
154a9ac8606Spatrick                                             Ordering, SSID);
155a9ac8606Spatrick   }
156a9ac8606Spatrick 
157e5dd7070Spatrick   using CGBuilderBaseTy::CreateAddrSpaceCast;
158e5dd7070Spatrick   Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty,
159e5dd7070Spatrick                               const llvm::Twine &Name = "") {
160*12c85518Srobert     assert(cast<llvm::PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(
161*12c85518Srobert                Addr.getElementType()) &&
162*12c85518Srobert            "Should not change the element type");
163*12c85518Srobert     return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name));
164e5dd7070Spatrick   }
165e5dd7070Spatrick 
166e5dd7070Spatrick   /// Cast the element type of the given address to a different type,
167e5dd7070Spatrick   /// preserving information like the alignment and address space.
168e5dd7070Spatrick   Address CreateElementBitCast(Address Addr, llvm::Type *Ty,
169e5dd7070Spatrick                                const llvm::Twine &Name = "") {
170*12c85518Srobert     auto *PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
171*12c85518Srobert     return Address(CreateBitCast(Addr.getPointer(), PtrTy, Name), Ty,
172*12c85518Srobert                    Addr.getAlignment());
173e5dd7070Spatrick   }
174e5dd7070Spatrick 
175e5dd7070Spatrick   using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
176e5dd7070Spatrick   Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty,
177*12c85518Srobert                                               llvm::Type *ElementTy,
178e5dd7070Spatrick                                               const llvm::Twine &Name = "") {
179e5dd7070Spatrick     llvm::Value *Ptr =
180e5dd7070Spatrick         CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
181*12c85518Srobert     return Address(Ptr, ElementTy, Addr.getAlignment());
182e5dd7070Spatrick   }
183e5dd7070Spatrick 
184e5dd7070Spatrick   /// Given
185e5dd7070Spatrick   ///   %addr = {T1, T2...}* ...
186e5dd7070Spatrick   /// produce
187e5dd7070Spatrick   ///   %name = getelementptr inbounds %addr, i32 0, i32 index
188e5dd7070Spatrick   ///
189e5dd7070Spatrick   /// This API assumes that drilling into a struct like this is always an
190e5dd7070Spatrick   /// inbounds operation.
191e5dd7070Spatrick   using CGBuilderBaseTy::CreateStructGEP;
192e5dd7070Spatrick   Address CreateStructGEP(Address Addr, unsigned Index,
193e5dd7070Spatrick                           const llvm::Twine &Name = "") {
194e5dd7070Spatrick     llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
195e5dd7070Spatrick     const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
196e5dd7070Spatrick     const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
197e5dd7070Spatrick     auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
198e5dd7070Spatrick 
199*12c85518Srobert     return Address(
200*12c85518Srobert         CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
201*12c85518Srobert         ElTy->getElementType(Index),
202e5dd7070Spatrick         Addr.getAlignment().alignmentAtOffset(Offset));
203e5dd7070Spatrick   }
204e5dd7070Spatrick 
205e5dd7070Spatrick   /// Given
206e5dd7070Spatrick   ///   %addr = [n x T]* ...
207e5dd7070Spatrick   /// produce
208e5dd7070Spatrick   ///   %name = getelementptr inbounds %addr, i64 0, i64 index
209e5dd7070Spatrick   /// where i64 is actually the target word size.
210e5dd7070Spatrick   ///
211e5dd7070Spatrick   /// This API assumes that drilling into an array like this is always
212e5dd7070Spatrick   /// an inbounds operation.
213e5dd7070Spatrick   Address CreateConstArrayGEP(Address Addr, uint64_t Index,
214e5dd7070Spatrick                               const llvm::Twine &Name = "") {
215e5dd7070Spatrick     llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType());
216e5dd7070Spatrick     const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
217e5dd7070Spatrick     CharUnits EltSize =
218e5dd7070Spatrick         CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
219e5dd7070Spatrick 
220e5dd7070Spatrick     return Address(
221a9ac8606Spatrick         CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
222e5dd7070Spatrick                           {getSize(CharUnits::Zero()), getSize(Index)}, Name),
223*12c85518Srobert         ElTy->getElementType(),
224e5dd7070Spatrick         Addr.getAlignment().alignmentAtOffset(Index * EltSize));
225e5dd7070Spatrick   }
226e5dd7070Spatrick 
227e5dd7070Spatrick   /// Given
228e5dd7070Spatrick   ///   %addr = T* ...
229e5dd7070Spatrick   /// produce
230e5dd7070Spatrick   ///   %name = getelementptr inbounds %addr, i64 index
231e5dd7070Spatrick   /// where i64 is actually the target word size.
232e5dd7070Spatrick   Address CreateConstInBoundsGEP(Address Addr, uint64_t Index,
233e5dd7070Spatrick                                  const llvm::Twine &Name = "") {
234e5dd7070Spatrick     llvm::Type *ElTy = Addr.getElementType();
235e5dd7070Spatrick     const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
236e5dd7070Spatrick     CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
237e5dd7070Spatrick 
238e5dd7070Spatrick     return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
239e5dd7070Spatrick                                      getSize(Index), Name),
240*12c85518Srobert                    ElTy,
241e5dd7070Spatrick                    Addr.getAlignment().alignmentAtOffset(Index * EltSize));
242e5dd7070Spatrick   }
243e5dd7070Spatrick 
244e5dd7070Spatrick   /// Given
245e5dd7070Spatrick   ///   %addr = T* ...
246e5dd7070Spatrick   /// produce
247e5dd7070Spatrick   ///   %name = getelementptr inbounds %addr, i64 index
248e5dd7070Spatrick   /// where i64 is actually the target word size.
249e5dd7070Spatrick   Address CreateConstGEP(Address Addr, uint64_t Index,
250e5dd7070Spatrick                          const llvm::Twine &Name = "") {
251e5dd7070Spatrick     const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
252e5dd7070Spatrick     CharUnits EltSize =
253e5dd7070Spatrick         CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
254e5dd7070Spatrick 
255e5dd7070Spatrick     return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
256e5dd7070Spatrick                              getSize(Index), Name),
257*12c85518Srobert                    Addr.getElementType(),
258e5dd7070Spatrick                    Addr.getAlignment().alignmentAtOffset(Index * EltSize));
259e5dd7070Spatrick   }
260e5dd7070Spatrick 
261*12c85518Srobert   /// Create GEP with single dynamic index. The address alignment is reduced
262*12c85518Srobert   /// according to the element size.
263*12c85518Srobert   using CGBuilderBaseTy::CreateGEP;
264*12c85518Srobert   Address CreateGEP(Address Addr, llvm::Value *Index,
265*12c85518Srobert                     const llvm::Twine &Name = "") {
266*12c85518Srobert     const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
267*12c85518Srobert     CharUnits EltSize =
268*12c85518Srobert         CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
269*12c85518Srobert 
270*12c85518Srobert     return Address(
271*12c85518Srobert         CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
272*12c85518Srobert         Addr.getElementType(),
273*12c85518Srobert         Addr.getAlignment().alignmentOfArrayElement(EltSize));
274*12c85518Srobert   }
275*12c85518Srobert 
276e5dd7070Spatrick   /// Given a pointer to i8, adjust it by a given constant offset.
277e5dd7070Spatrick   Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
278e5dd7070Spatrick                                      const llvm::Twine &Name = "") {
279e5dd7070Spatrick     assert(Addr.getElementType() == TypeCache.Int8Ty);
280a9ac8606Spatrick     return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
281a9ac8606Spatrick                                      getSize(Offset), Name),
282*12c85518Srobert                    Addr.getElementType(),
283e5dd7070Spatrick                    Addr.getAlignment().alignmentAtOffset(Offset));
284e5dd7070Spatrick   }
285e5dd7070Spatrick   Address CreateConstByteGEP(Address Addr, CharUnits Offset,
286e5dd7070Spatrick                              const llvm::Twine &Name = "") {
287e5dd7070Spatrick     assert(Addr.getElementType() == TypeCache.Int8Ty);
288a9ac8606Spatrick     return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
289a9ac8606Spatrick                              getSize(Offset), Name),
290*12c85518Srobert                    Addr.getElementType(),
291e5dd7070Spatrick                    Addr.getAlignment().alignmentAtOffset(Offset));
292e5dd7070Spatrick   }
293e5dd7070Spatrick 
294e5dd7070Spatrick   using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
295e5dd7070Spatrick   Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1,
296e5dd7070Spatrick                                      const llvm::Twine &Name = "") {
297e5dd7070Spatrick     const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
298e5dd7070Spatrick 
299e5dd7070Spatrick     auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32(
300e5dd7070Spatrick         Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name));
301e5dd7070Spatrick     llvm::APInt Offset(
302e5dd7070Spatrick         DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0,
303e5dd7070Spatrick         /*isSigned=*/true);
304e5dd7070Spatrick     if (!GEP->accumulateConstantOffset(DL, Offset))
305e5dd7070Spatrick       llvm_unreachable("offset of GEP with constants is always computable");
306*12c85518Srobert     return Address(GEP, GEP->getResultElementType(),
307*12c85518Srobert                    Addr.getAlignment().alignmentAtOffset(
308e5dd7070Spatrick                        CharUnits::fromQuantity(Offset.getSExtValue())));
309e5dd7070Spatrick   }
310e5dd7070Spatrick 
311e5dd7070Spatrick   using CGBuilderBaseTy::CreateMemCpy;
312e5dd7070Spatrick   llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size,
313e5dd7070Spatrick                                bool IsVolatile = false) {
314e5dd7070Spatrick     return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
315e5dd7070Spatrick                         Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
316e5dd7070Spatrick                         IsVolatile);
317e5dd7070Spatrick   }
318e5dd7070Spatrick   llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size,
319e5dd7070Spatrick                                bool IsVolatile = false) {
320e5dd7070Spatrick     return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
321e5dd7070Spatrick                         Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
322e5dd7070Spatrick                         IsVolatile);
323e5dd7070Spatrick   }
324e5dd7070Spatrick 
325ec727ea7Spatrick   using CGBuilderBaseTy::CreateMemCpyInline;
CreateMemCpyInline(Address Dest,Address Src,uint64_t Size)326ec727ea7Spatrick   llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) {
327ec727ea7Spatrick     return CreateMemCpyInline(
328ec727ea7Spatrick         Dest.getPointer(), Dest.getAlignment().getAsAlign(), Src.getPointer(),
329ec727ea7Spatrick         Src.getAlignment().getAsAlign(), getInt64(Size));
330ec727ea7Spatrick   }
331ec727ea7Spatrick 
332e5dd7070Spatrick   using CGBuilderBaseTy::CreateMemMove;
333e5dd7070Spatrick   llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size,
334e5dd7070Spatrick                                 bool IsVolatile = false) {
335e5dd7070Spatrick     return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
336e5dd7070Spatrick                          Src.getPointer(), Src.getAlignment().getAsAlign(),
337e5dd7070Spatrick                          Size, IsVolatile);
338e5dd7070Spatrick   }
339e5dd7070Spatrick 
340e5dd7070Spatrick   using CGBuilderBaseTy::CreateMemSet;
341e5dd7070Spatrick   llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value,
342e5dd7070Spatrick                                llvm::Value *Size, bool IsVolatile = false) {
343e5dd7070Spatrick     return CreateMemSet(Dest.getPointer(), Value, Size,
344e5dd7070Spatrick                         Dest.getAlignment().getAsAlign(), IsVolatile);
345e5dd7070Spatrick   }
346e5dd7070Spatrick 
347*12c85518Srobert   using CGBuilderBaseTy::CreateMemSetInline;
CreateMemSetInline(Address Dest,llvm::Value * Value,uint64_t Size)348*12c85518Srobert   llvm::CallInst *CreateMemSetInline(Address Dest, llvm::Value *Value,
349*12c85518Srobert                                      uint64_t Size) {
350*12c85518Srobert     return CreateMemSetInline(Dest.getPointer(),
351*12c85518Srobert                               Dest.getAlignment().getAsAlign(), Value,
352*12c85518Srobert                               getInt64(Size));
353*12c85518Srobert   }
354*12c85518Srobert 
355e5dd7070Spatrick   using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
CreatePreserveStructAccessIndex(Address Addr,unsigned Index,unsigned FieldIndex,llvm::MDNode * DbgInfo)356*12c85518Srobert   Address CreatePreserveStructAccessIndex(Address Addr, unsigned Index,
357e5dd7070Spatrick                                           unsigned FieldIndex,
358e5dd7070Spatrick                                           llvm::MDNode *DbgInfo) {
359e5dd7070Spatrick     llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
360e5dd7070Spatrick     const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
361e5dd7070Spatrick     const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
362e5dd7070Spatrick     auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
363e5dd7070Spatrick 
364e5dd7070Spatrick     return Address(CreatePreserveStructAccessIndex(ElTy, Addr.getPointer(),
365e5dd7070Spatrick                                                    Index, FieldIndex, DbgInfo),
366*12c85518Srobert                    ElTy->getElementType(Index),
367e5dd7070Spatrick                    Addr.getAlignment().alignmentAtOffset(Offset));
368e5dd7070Spatrick   }
369*12c85518Srobert 
370*12c85518Srobert   using CGBuilderBaseTy::CreateLaunderInvariantGroup;
CreateLaunderInvariantGroup(Address Addr)371*12c85518Srobert   Address CreateLaunderInvariantGroup(Address Addr) {
372*12c85518Srobert     return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()));
373*12c85518Srobert   }
374e5dd7070Spatrick };
375e5dd7070Spatrick 
376e5dd7070Spatrick } // end namespace CodeGen
377e5dd7070Spatrick } // end namespace clang
378e5dd7070Spatrick 
379e5dd7070Spatrick #endif
380