CGBuilder.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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, llvm::LLVMContext &C,
  43. 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,
  92. bool IsVolatile = false) {
  93. return CreateAlignedStore(Val, Addr, Align.getAsAlign(), IsVolatile);
  94. }
  95. // FIXME: these "default-aligned" APIs should be removed,
  96. // but I don't feel like fixing all the builtin code right now.
  97. llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val,
  98. llvm::Value *Addr,
  99. bool IsVolatile = false) {
  100. return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile);
  101. }
  102. /// Emit a load from an i1 flag variable.
  103. llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr,
  104. const llvm::Twine &Name = "") {
  105. assert(llvm::cast<llvm::PointerType>(Addr->getType())
  106. ->isOpaqueOrPointeeTypeMatches(getInt1Ty()));
  107. return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name);
  108. }
  109. /// Emit a store to an i1 flag variable.
  110. llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) {
  111. assert(llvm::cast<llvm::PointerType>(Addr->getType())
  112. ->isOpaqueOrPointeeTypeMatches(getInt1Ty()));
  113. return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One());
  114. }
  115. // Temporarily use old signature; clang will be updated to an Address overload
  116. // in a subsequent patch.
  117. llvm::AtomicCmpXchgInst *
  118. CreateAtomicCmpXchg(llvm::Value *Ptr, llvm::Value *Cmp, llvm::Value *New,
  119. llvm::AtomicOrdering SuccessOrdering,
  120. llvm::AtomicOrdering FailureOrdering,
  121. llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
  122. return CGBuilderBaseTy::CreateAtomicCmpXchg(
  123. Ptr, Cmp, New, llvm::MaybeAlign(), SuccessOrdering, FailureOrdering,
  124. SSID);
  125. }
  126. // Temporarily use old signature; clang will be updated to an Address overload
  127. // in a subsequent patch.
  128. llvm::AtomicRMWInst *
  129. CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, llvm::Value *Ptr,
  130. llvm::Value *Val, llvm::AtomicOrdering Ordering,
  131. llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
  132. return CGBuilderBaseTy::CreateAtomicRMW(Op, Ptr, Val, llvm::MaybeAlign(),
  133. Ordering, SSID);
  134. }
  135. using CGBuilderBaseTy::CreateAddrSpaceCast;
  136. Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty,
  137. const llvm::Twine &Name = "") {
  138. assert(cast<llvm::PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(
  139. Addr.getElementType()) &&
  140. "Should not change the element type");
  141. return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name));
  142. }
  143. /// Cast the element type of the given address to a different type,
  144. /// preserving information like the alignment and address space.
  145. Address CreateElementBitCast(Address Addr, llvm::Type *Ty,
  146. const llvm::Twine &Name = "") {
  147. auto *PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
  148. return Address(CreateBitCast(Addr.getPointer(), PtrTy, Name), Ty,
  149. Addr.getAlignment());
  150. }
  151. using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
  152. Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty,
  153. llvm::Type *ElementTy,
  154. const llvm::Twine &Name = "") {
  155. llvm::Value *Ptr =
  156. CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
  157. return Address(Ptr, ElementTy, Addr.getAlignment());
  158. }
  159. /// Given
  160. /// %addr = {T1, T2...}* ...
  161. /// produce
  162. /// %name = getelementptr inbounds %addr, i32 0, i32 index
  163. ///
  164. /// This API assumes that drilling into a struct like this is always an
  165. /// inbounds operation.
  166. using CGBuilderBaseTy::CreateStructGEP;
  167. Address CreateStructGEP(Address Addr, unsigned Index,
  168. const llvm::Twine &Name = "") {
  169. llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
  170. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  171. const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
  172. auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
  173. return Address(
  174. CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
  175. ElTy->getElementType(Index),
  176. Addr.getAlignment().alignmentAtOffset(Offset));
  177. }
  178. /// Given
  179. /// %addr = [n x T]* ...
  180. /// produce
  181. /// %name = getelementptr inbounds %addr, i64 0, i64 index
  182. /// where i64 is actually the target word size.
  183. ///
  184. /// This API assumes that drilling into an array like this is always
  185. /// an inbounds operation.
  186. Address CreateConstArrayGEP(Address Addr, uint64_t Index,
  187. const llvm::Twine &Name = "") {
  188. llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType());
  189. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  190. CharUnits EltSize =
  191. CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
  192. return Address(
  193. CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
  194. {getSize(CharUnits::Zero()), getSize(Index)}, Name),
  195. ElTy->getElementType(),
  196. Addr.getAlignment().alignmentAtOffset(Index * EltSize));
  197. }
  198. /// Given
  199. /// %addr = T* ...
  200. /// produce
  201. /// %name = getelementptr inbounds %addr, i64 index
  202. /// where i64 is actually the target word size.
  203. Address CreateConstInBoundsGEP(Address Addr, uint64_t Index,
  204. const llvm::Twine &Name = "") {
  205. llvm::Type *ElTy = Addr.getElementType();
  206. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  207. CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
  208. return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
  209. getSize(Index), Name),
  210. ElTy,
  211. Addr.getAlignment().alignmentAtOffset(Index * EltSize));
  212. }
  213. /// Given
  214. /// %addr = T* ...
  215. /// produce
  216. /// %name = getelementptr inbounds %addr, i64 index
  217. /// where i64 is actually the target word size.
  218. Address CreateConstGEP(Address Addr, uint64_t Index,
  219. const llvm::Twine &Name = "") {
  220. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  221. CharUnits EltSize =
  222. CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
  223. return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
  224. getSize(Index), Name),
  225. Addr.getElementType(),
  226. Addr.getAlignment().alignmentAtOffset(Index * EltSize));
  227. }
  228. /// Create GEP with single dynamic index. The address alignment is reduced
  229. /// according to the element size.
  230. using CGBuilderBaseTy::CreateGEP;
  231. Address CreateGEP(Address Addr, llvm::Value *Index,
  232. const llvm::Twine &Name = "") {
  233. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  234. CharUnits EltSize =
  235. CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
  236. return Address(
  237. CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
  238. Addr.getElementType(),
  239. Addr.getAlignment().alignmentOfArrayElement(EltSize));
  240. }
  241. /// Given a pointer to i8, adjust it by a given constant offset.
  242. Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
  243. const llvm::Twine &Name = "") {
  244. assert(Addr.getElementType() == TypeCache.Int8Ty);
  245. return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
  246. getSize(Offset), Name),
  247. Addr.getElementType(),
  248. Addr.getAlignment().alignmentAtOffset(Offset));
  249. }
  250. Address CreateConstByteGEP(Address Addr, CharUnits Offset,
  251. const llvm::Twine &Name = "") {
  252. assert(Addr.getElementType() == TypeCache.Int8Ty);
  253. return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
  254. getSize(Offset), Name),
  255. Addr.getElementType(),
  256. Addr.getAlignment().alignmentAtOffset(Offset));
  257. }
  258. using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
  259. Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1,
  260. const llvm::Twine &Name = "") {
  261. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  262. auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32(
  263. Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name));
  264. llvm::APInt Offset(
  265. DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0,
  266. /*isSigned=*/true);
  267. if (!GEP->accumulateConstantOffset(DL, Offset))
  268. llvm_unreachable("offset of GEP with constants is always computable");
  269. return Address(GEP, GEP->getResultElementType(),
  270. Addr.getAlignment().alignmentAtOffset(
  271. CharUnits::fromQuantity(Offset.getSExtValue())));
  272. }
  273. using CGBuilderBaseTy::CreateMemCpy;
  274. llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size,
  275. bool IsVolatile = false) {
  276. return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
  277. Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
  278. IsVolatile);
  279. }
  280. llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size,
  281. bool IsVolatile = false) {
  282. return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
  283. Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
  284. IsVolatile);
  285. }
  286. using CGBuilderBaseTy::CreateMemCpyInline;
  287. llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) {
  288. return CreateMemCpyInline(
  289. Dest.getPointer(), Dest.getAlignment().getAsAlign(), Src.getPointer(),
  290. Src.getAlignment().getAsAlign(), getInt64(Size));
  291. }
  292. using CGBuilderBaseTy::CreateMemMove;
  293. llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size,
  294. bool IsVolatile = false) {
  295. return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
  296. Src.getPointer(), Src.getAlignment().getAsAlign(),
  297. Size, IsVolatile);
  298. }
  299. using CGBuilderBaseTy::CreateMemSet;
  300. llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value,
  301. llvm::Value *Size, bool IsVolatile = false) {
  302. return CreateMemSet(Dest.getPointer(), Value, Size,
  303. Dest.getAlignment().getAsAlign(), IsVolatile);
  304. }
  305. using CGBuilderBaseTy::CreateMemSetInline;
  306. llvm::CallInst *CreateMemSetInline(Address Dest, llvm::Value *Value,
  307. uint64_t Size) {
  308. return CreateMemSetInline(Dest.getPointer(),
  309. Dest.getAlignment().getAsAlign(), Value,
  310. getInt64(Size));
  311. }
  312. using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
  313. Address CreatePreserveStructAccessIndex(Address Addr, unsigned Index,
  314. unsigned FieldIndex,
  315. llvm::MDNode *DbgInfo) {
  316. llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
  317. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  318. const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
  319. auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
  320. return Address(CreatePreserveStructAccessIndex(ElTy, Addr.getPointer(),
  321. Index, FieldIndex, DbgInfo),
  322. ElTy->getElementType(Index),
  323. Addr.getAlignment().alignmentAtOffset(Offset));
  324. }
  325. using CGBuilderBaseTy::CreateLaunderInvariantGroup;
  326. Address CreateLaunderInvariantGroup(Address Addr) {
  327. return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()));
  328. }
  329. };
  330. } // end namespace CodeGen
  331. } // end namespace clang
  332. #endif