CGBuilder.h 16 KB

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