CGBuilder.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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 "llvm/IR/DataLayout.h"
  11. #include "llvm/IR/IRBuilder.h"
  12. #include "Address.h"
  13. #include "CodeGenTypeCache.h"
  14. namespace clang {
  15. namespace CodeGen {
  16. class CodeGenFunction;
  17. /// This is an IRBuilder insertion helper that forwards to
  18. /// CodeGenFunction::InsertHelper, which adds necessary metadata to
  19. /// instructions.
  20. class CGBuilderInserter : protected llvm::IRBuilderDefaultInserter {
  21. public:
  22. CGBuilderInserter() = default;
  23. explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
  24. protected:
  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;
  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.getPointer(),
  60. Addr.getAlignment().getQuantity(),
  61. Name);
  62. }
  63. llvm::LoadInst *CreateLoad(Address Addr, const char *Name) {
  64. // This overload is required to prevent string literals from
  65. // ending up in the IsVolatile overload.
  66. return CreateAlignedLoad(Addr.getPointer(),
  67. Addr.getAlignment().getQuantity(),
  68. Name);
  69. }
  70. llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile,
  71. const llvm::Twine &Name = "") {
  72. return CreateAlignedLoad(Addr.getPointer(),
  73. Addr.getAlignment().getQuantity(),
  74. IsVolatile,
  75. Name);
  76. }
  77. using CGBuilderBaseTy::CreateAlignedLoad;
  78. llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align,
  79. const llvm::Twine &Name = "") {
  80. return CreateAlignedLoad(Addr, Align.getQuantity(), Name);
  81. }
  82. llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align,
  83. const char *Name) {
  84. return CreateAlignedLoad(Addr, Align.getQuantity(), Name);
  85. }
  86. llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr,
  87. CharUnits Align,
  88. const llvm::Twine &Name = "") {
  89. assert(Addr->getType()->getPointerElementType() == Ty);
  90. return CreateAlignedLoad(Addr, Align.getQuantity(), Name);
  91. }
  92. // Note that we intentionally hide the CreateStore APIs that don't
  93. // take an alignment.
  94. llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr,
  95. bool IsVolatile = false) {
  96. return CreateAlignedStore(Val, Addr.getPointer(),
  97. Addr.getAlignment().getQuantity(), IsVolatile);
  98. }
  99. using CGBuilderBaseTy::CreateAlignedStore;
  100. llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr,
  101. CharUnits Align, bool IsVolatile = false) {
  102. return CreateAlignedStore(Val, Addr, Align.getQuantity(), IsVolatile);
  103. }
  104. // FIXME: these "default-aligned" APIs should be removed,
  105. // but I don't feel like fixing all the builtin code right now.
  106. llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val,
  107. llvm::Value *Addr,
  108. bool IsVolatile = false) {
  109. return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile);
  110. }
  111. /// Emit a load from an i1 flag variable.
  112. llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr,
  113. const llvm::Twine &Name = "") {
  114. assert(Addr->getType()->getPointerElementType() == getInt1Ty());
  115. return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name);
  116. }
  117. /// Emit a store to an i1 flag variable.
  118. llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) {
  119. assert(Addr->getType()->getPointerElementType() == getInt1Ty());
  120. return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One());
  121. }
  122. using CGBuilderBaseTy::CreateBitCast;
  123. Address CreateBitCast(Address Addr, llvm::Type *Ty,
  124. const llvm::Twine &Name = "") {
  125. return Address(CreateBitCast(Addr.getPointer(), Ty, Name),
  126. Addr.getAlignment());
  127. }
  128. using CGBuilderBaseTy::CreateAddrSpaceCast;
  129. Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty,
  130. const llvm::Twine &Name = "") {
  131. return Address(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name),
  132. Addr.getAlignment());
  133. }
  134. /// Cast the element type of the given address to a different type,
  135. /// preserving information like the alignment and address space.
  136. Address CreateElementBitCast(Address Addr, llvm::Type *Ty,
  137. const llvm::Twine &Name = "") {
  138. auto PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
  139. return CreateBitCast(Addr, PtrTy, Name);
  140. }
  141. using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
  142. Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty,
  143. const llvm::Twine &Name = "") {
  144. llvm::Value *Ptr =
  145. CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
  146. return Address(Ptr, Addr.getAlignment());
  147. }
  148. /// Given
  149. /// %addr = {T1, T2...}* ...
  150. /// produce
  151. /// %name = getelementptr inbounds %addr, i32 0, i32 index
  152. ///
  153. /// This API assumes that drilling into a struct like this is always an
  154. /// inbounds operation.
  155. using CGBuilderBaseTy::CreateStructGEP;
  156. Address CreateStructGEP(Address Addr, unsigned Index,
  157. const llvm::Twine &Name = "") {
  158. llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
  159. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  160. const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
  161. auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
  162. return Address(CreateStructGEP(Addr.getElementType(),
  163. Addr.getPointer(), Index, Name),
  164. Addr.getAlignment().alignmentAtOffset(Offset));
  165. }
  166. /// Given
  167. /// %addr = [n x T]* ...
  168. /// produce
  169. /// %name = getelementptr inbounds %addr, i64 0, i64 index
  170. /// where i64 is actually the target word size.
  171. ///
  172. /// This API assumes that drilling into an array like this is always
  173. /// an inbounds operation.
  174. Address CreateConstArrayGEP(Address Addr, uint64_t Index,
  175. const llvm::Twine &Name = "") {
  176. llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType());
  177. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  178. CharUnits EltSize =
  179. CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
  180. return Address(
  181. CreateInBoundsGEP(Addr.getPointer(),
  182. {getSize(CharUnits::Zero()), getSize(Index)}, Name),
  183. Addr.getAlignment().alignmentAtOffset(Index * EltSize));
  184. }
  185. /// Given
  186. /// %addr = T* ...
  187. /// produce
  188. /// %name = getelementptr inbounds %addr, i64 index
  189. /// where i64 is actually the target word size.
  190. Address CreateConstInBoundsGEP(Address Addr, uint64_t Index,
  191. const llvm::Twine &Name = "") {
  192. llvm::Type *ElTy = Addr.getElementType();
  193. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  194. CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
  195. return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
  196. getSize(Index), Name),
  197. Addr.getAlignment().alignmentAtOffset(Index * EltSize));
  198. }
  199. /// Given
  200. /// %addr = T* ...
  201. /// produce
  202. /// %name = getelementptr inbounds %addr, i64 index
  203. /// where i64 is actually the target word size.
  204. Address CreateConstGEP(Address Addr, uint64_t Index,
  205. const llvm::Twine &Name = "") {
  206. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  207. CharUnits EltSize =
  208. CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
  209. return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
  210. getSize(Index), Name),
  211. Addr.getAlignment().alignmentAtOffset(Index * EltSize));
  212. }
  213. /// Given a pointer to i8, adjust it by a given constant offset.
  214. Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
  215. const llvm::Twine &Name = "") {
  216. assert(Addr.getElementType() == TypeCache.Int8Ty);
  217. return Address(CreateInBoundsGEP(Addr.getPointer(), getSize(Offset), Name),
  218. Addr.getAlignment().alignmentAtOffset(Offset));
  219. }
  220. Address CreateConstByteGEP(Address Addr, CharUnits Offset,
  221. const llvm::Twine &Name = "") {
  222. assert(Addr.getElementType() == TypeCache.Int8Ty);
  223. return Address(CreateGEP(Addr.getPointer(), getSize(Offset), Name),
  224. Addr.getAlignment().alignmentAtOffset(Offset));
  225. }
  226. using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
  227. Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1,
  228. const llvm::Twine &Name = "") {
  229. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  230. auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32(
  231. Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name));
  232. llvm::APInt Offset(
  233. DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0,
  234. /*isSigned=*/true);
  235. if (!GEP->accumulateConstantOffset(DL, Offset))
  236. llvm_unreachable("offset of GEP with constants is always computable");
  237. return Address(GEP, Addr.getAlignment().alignmentAtOffset(
  238. CharUnits::fromQuantity(Offset.getSExtValue())));
  239. }
  240. using CGBuilderBaseTy::CreateMemCpy;
  241. llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size,
  242. bool IsVolatile = false) {
  243. return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getQuantity(),
  244. Src.getPointer(), Src.getAlignment().getQuantity(),
  245. Size,IsVolatile);
  246. }
  247. llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size,
  248. bool IsVolatile = false) {
  249. return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getQuantity(),
  250. Src.getPointer(), Src.getAlignment().getQuantity(),
  251. Size, IsVolatile);
  252. }
  253. using CGBuilderBaseTy::CreateMemMove;
  254. llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size,
  255. bool IsVolatile = false) {
  256. return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getQuantity(),
  257. Src.getPointer(), Src.getAlignment().getQuantity(),
  258. Size, IsVolatile);
  259. }
  260. using CGBuilderBaseTy::CreateMemSet;
  261. llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value,
  262. llvm::Value *Size, bool IsVolatile = false) {
  263. return CreateMemSet(Dest.getPointer(), Value, Size,
  264. Dest.getAlignment().getQuantity(), IsVolatile);
  265. }
  266. using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
  267. Address CreatePreserveStructAccessIndex(Address Addr,
  268. unsigned Index,
  269. unsigned FieldIndex,
  270. llvm::MDNode *DbgInfo) {
  271. llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
  272. const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
  273. const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
  274. auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
  275. return Address(CreatePreserveStructAccessIndex(Addr.getPointer(),
  276. Index, FieldIndex, DbgInfo),
  277. Addr.getAlignment().alignmentAtOffset(Offset));
  278. }
  279. };
  280. } // end namespace CodeGen
  281. } // end namespace clang
  282. #endif