NoFolder.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- NoFolder.h - Constant folding helper ---------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the NoFolder class, a helper for IRBuilder. It provides
  15. // IRBuilder with a set of methods for creating unfolded constants. This is
  16. // useful for learners trying to understand how LLVM IR works, and who don't
  17. // want details to be hidden by the constant folder. For general constant
  18. // creation and folding, use ConstantExpr and the routines in
  19. // llvm/Analysis/ConstantFolding.h.
  20. //
  21. // Note: since it is not actually possible to create unfolded constants, this
  22. // class returns instructions rather than constants.
  23. //
  24. //===----------------------------------------------------------------------===//
  25. #ifndef LLVM_IR_NOFOLDER_H
  26. #define LLVM_IR_NOFOLDER_H
  27. #include "llvm/ADT/ArrayRef.h"
  28. #include "llvm/IR/Constants.h"
  29. #include "llvm/IR/InstrTypes.h"
  30. #include "llvm/IR/Instruction.h"
  31. #include "llvm/IR/Instructions.h"
  32. #include "llvm/IR/IRBuilderFolder.h"
  33. namespace llvm {
  34. /// NoFolder - Create "constants" (actually, instructions) with no folding.
  35. class NoFolder final : public IRBuilderFolder {
  36. virtual void anchor();
  37. public:
  38. explicit NoFolder() = default;
  39. //===--------------------------------------------------------------------===//
  40. // Binary Operators
  41. //===--------------------------------------------------------------------===//
  42. Instruction *CreateAdd(Constant *LHS, Constant *RHS,
  43. bool HasNUW = false,
  44. bool HasNSW = false) const override {
  45. BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
  46. if (HasNUW) BO->setHasNoUnsignedWrap();
  47. if (HasNSW) BO->setHasNoSignedWrap();
  48. return BO;
  49. }
  50. Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const override {
  51. return BinaryOperator::CreateFAdd(LHS, RHS);
  52. }
  53. Instruction *CreateSub(Constant *LHS, Constant *RHS,
  54. bool HasNUW = false,
  55. bool HasNSW = false) const override {
  56. BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
  57. if (HasNUW) BO->setHasNoUnsignedWrap();
  58. if (HasNSW) BO->setHasNoSignedWrap();
  59. return BO;
  60. }
  61. Instruction *CreateFSub(Constant *LHS, Constant *RHS) const override {
  62. return BinaryOperator::CreateFSub(LHS, RHS);
  63. }
  64. Instruction *CreateMul(Constant *LHS, Constant *RHS,
  65. bool HasNUW = false,
  66. bool HasNSW = false) const override {
  67. BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
  68. if (HasNUW) BO->setHasNoUnsignedWrap();
  69. if (HasNSW) BO->setHasNoSignedWrap();
  70. return BO;
  71. }
  72. Instruction *CreateFMul(Constant *LHS, Constant *RHS) const override {
  73. return BinaryOperator::CreateFMul(LHS, RHS);
  74. }
  75. Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
  76. bool isExact = false) const override {
  77. if (!isExact)
  78. return BinaryOperator::CreateUDiv(LHS, RHS);
  79. return BinaryOperator::CreateExactUDiv(LHS, RHS);
  80. }
  81. Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
  82. bool isExact = false) const override {
  83. if (!isExact)
  84. return BinaryOperator::CreateSDiv(LHS, RHS);
  85. return BinaryOperator::CreateExactSDiv(LHS, RHS);
  86. }
  87. Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const override {
  88. return BinaryOperator::CreateFDiv(LHS, RHS);
  89. }
  90. Instruction *CreateURem(Constant *LHS, Constant *RHS) const override {
  91. return BinaryOperator::CreateURem(LHS, RHS);
  92. }
  93. Instruction *CreateSRem(Constant *LHS, Constant *RHS) const override {
  94. return BinaryOperator::CreateSRem(LHS, RHS);
  95. }
  96. Instruction *CreateFRem(Constant *LHS, Constant *RHS) const override {
  97. return BinaryOperator::CreateFRem(LHS, RHS);
  98. }
  99. Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
  100. bool HasNSW = false) const override {
  101. BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
  102. if (HasNUW) BO->setHasNoUnsignedWrap();
  103. if (HasNSW) BO->setHasNoSignedWrap();
  104. return BO;
  105. }
  106. Instruction *CreateLShr(Constant *LHS, Constant *RHS,
  107. bool isExact = false) const override {
  108. if (!isExact)
  109. return BinaryOperator::CreateLShr(LHS, RHS);
  110. return BinaryOperator::CreateExactLShr(LHS, RHS);
  111. }
  112. Instruction *CreateAShr(Constant *LHS, Constant *RHS,
  113. bool isExact = false) const override {
  114. if (!isExact)
  115. return BinaryOperator::CreateAShr(LHS, RHS);
  116. return BinaryOperator::CreateExactAShr(LHS, RHS);
  117. }
  118. Instruction *CreateAnd(Constant *LHS, Constant *RHS) const override {
  119. return BinaryOperator::CreateAnd(LHS, RHS);
  120. }
  121. Instruction *CreateOr(Constant *LHS, Constant *RHS) const override {
  122. return BinaryOperator::CreateOr(LHS, RHS);
  123. }
  124. Instruction *CreateXor(Constant *LHS, Constant *RHS) const override {
  125. return BinaryOperator::CreateXor(LHS, RHS);
  126. }
  127. Instruction *CreateBinOp(Instruction::BinaryOps Opc,
  128. Constant *LHS, Constant *RHS) const override {
  129. return BinaryOperator::Create(Opc, LHS, RHS);
  130. }
  131. //===--------------------------------------------------------------------===//
  132. // Unary Operators
  133. //===--------------------------------------------------------------------===//
  134. Instruction *CreateNeg(Constant *C,
  135. bool HasNUW = false,
  136. bool HasNSW = false) const override {
  137. BinaryOperator *BO = BinaryOperator::CreateNeg(C);
  138. if (HasNUW) BO->setHasNoUnsignedWrap();
  139. if (HasNSW) BO->setHasNoSignedWrap();
  140. return BO;
  141. }
  142. Instruction *CreateFNeg(Constant *C) const override {
  143. return UnaryOperator::CreateFNeg(C);
  144. }
  145. Instruction *CreateNot(Constant *C) const override {
  146. return BinaryOperator::CreateNot(C);
  147. }
  148. Instruction *CreateUnOp(Instruction::UnaryOps Opc,
  149. Constant *C) const override {
  150. return UnaryOperator::Create(Opc, C);
  151. }
  152. //===--------------------------------------------------------------------===//
  153. // Memory Instructions
  154. //===--------------------------------------------------------------------===//
  155. Constant *CreateGetElementPtr(Type *Ty, Constant *C,
  156. ArrayRef<Constant *> IdxList) const override {
  157. return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
  158. }
  159. Constant *CreateGetElementPtr(Type *Ty, Constant *C,
  160. Constant *Idx) const override {
  161. // This form of the function only exists to avoid ambiguous overload
  162. // warnings about whether to convert Idx to ArrayRef<Constant *> or
  163. // ArrayRef<Value *>.
  164. return ConstantExpr::getGetElementPtr(Ty, C, Idx);
  165. }
  166. Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
  167. ArrayRef<Value *> IdxList) const override {
  168. return GetElementPtrInst::Create(Ty, C, IdxList);
  169. }
  170. Constant *CreateInBoundsGetElementPtr(
  171. Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
  172. return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
  173. }
  174. Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
  175. Constant *Idx) const override {
  176. // This form of the function only exists to avoid ambiguous overload
  177. // warnings about whether to convert Idx to ArrayRef<Constant *> or
  178. // ArrayRef<Value *>.
  179. return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
  180. }
  181. Instruction *CreateInBoundsGetElementPtr(
  182. Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
  183. return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
  184. }
  185. //===--------------------------------------------------------------------===//
  186. // Cast/Conversion Operators
  187. //===--------------------------------------------------------------------===//
  188. Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
  189. Type *DestTy) const override {
  190. return CastInst::Create(Op, C, DestTy);
  191. }
  192. Instruction *CreatePointerCast(Constant *C, Type *DestTy) const override {
  193. return CastInst::CreatePointerCast(C, DestTy);
  194. }
  195. Instruction *CreatePointerBitCastOrAddrSpaceCast(
  196. Constant *C, Type *DestTy) const override {
  197. return CastInst::CreatePointerBitCastOrAddrSpaceCast(C, DestTy);
  198. }
  199. Instruction *CreateIntCast(Constant *C, Type *DestTy,
  200. bool isSigned) const override {
  201. return CastInst::CreateIntegerCast(C, DestTy, isSigned);
  202. }
  203. Instruction *CreateFPCast(Constant *C, Type *DestTy) const override {
  204. return CastInst::CreateFPCast(C, DestTy);
  205. }
  206. Instruction *CreateBitCast(Constant *C, Type *DestTy) const override {
  207. return CreateCast(Instruction::BitCast, C, DestTy);
  208. }
  209. Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const override {
  210. return CreateCast(Instruction::IntToPtr, C, DestTy);
  211. }
  212. Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const override {
  213. return CreateCast(Instruction::PtrToInt, C, DestTy);
  214. }
  215. Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
  216. return CastInst::CreateZExtOrBitCast(C, DestTy);
  217. }
  218. Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
  219. return CastInst::CreateSExtOrBitCast(C, DestTy);
  220. }
  221. Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
  222. return CastInst::CreateTruncOrBitCast(C, DestTy);
  223. }
  224. //===--------------------------------------------------------------------===//
  225. // Compare Instructions
  226. //===--------------------------------------------------------------------===//
  227. Instruction *CreateICmp(CmpInst::Predicate P,
  228. Constant *LHS, Constant *RHS) const override {
  229. return new ICmpInst(P, LHS, RHS);
  230. }
  231. Instruction *CreateFCmp(CmpInst::Predicate P,
  232. Constant *LHS, Constant *RHS) const override {
  233. return new FCmpInst(P, LHS, RHS);
  234. }
  235. //===--------------------------------------------------------------------===//
  236. // Other Instructions
  237. //===--------------------------------------------------------------------===//
  238. Instruction *CreateSelect(Constant *C,
  239. Constant *True, Constant *False) const override {
  240. return SelectInst::Create(C, True, False);
  241. }
  242. Instruction *CreateExtractElement(Constant *Vec,
  243. Constant *Idx) const override {
  244. return ExtractElementInst::Create(Vec, Idx);
  245. }
  246. Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
  247. Constant *Idx) const override {
  248. return InsertElementInst::Create(Vec, NewElt, Idx);
  249. }
  250. Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
  251. ArrayRef<int> Mask) const override {
  252. return new ShuffleVectorInst(V1, V2, Mask);
  253. }
  254. Instruction *CreateExtractValue(Constant *Agg,
  255. ArrayRef<unsigned> IdxList) const override {
  256. return ExtractValueInst::Create(Agg, IdxList);
  257. }
  258. Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
  259. ArrayRef<unsigned> IdxList) const override {
  260. return InsertValueInst::Create(Agg, Val, IdxList);
  261. }
  262. };
  263. } // end namespace llvm
  264. #endif // LLVM_IR_NOFOLDER_H
  265. #ifdef __GNUC__
  266. #pragma GCC diagnostic pop
  267. #endif