NoFolder.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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. // Value-based folders.
  41. //
  42. // Return an existing value or a constant if the operation can be simplified.
  43. // Otherwise return nullptr.
  44. //===--------------------------------------------------------------------===//
  45. Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false,
  46. bool HasNSW = false) const override {
  47. return nullptr;
  48. }
  49. Value *FoldAnd(Value *LHS, Value *RHS) const override { return nullptr; }
  50. Value *FoldOr(Value *LHS, Value *RHS) const override { return nullptr; }
  51. Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
  52. return nullptr;
  53. }
  54. Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
  55. bool IsInBounds = false) const override {
  56. return nullptr;
  57. }
  58. Value *FoldSelect(Value *C, Value *True, Value *False) const override {
  59. return nullptr;
  60. }
  61. //===--------------------------------------------------------------------===//
  62. // Binary Operators
  63. //===--------------------------------------------------------------------===//
  64. Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const override {
  65. return BinaryOperator::CreateFAdd(LHS, RHS);
  66. }
  67. Instruction *CreateSub(Constant *LHS, Constant *RHS,
  68. bool HasNUW = false,
  69. bool HasNSW = false) const override {
  70. BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
  71. if (HasNUW) BO->setHasNoUnsignedWrap();
  72. if (HasNSW) BO->setHasNoSignedWrap();
  73. return BO;
  74. }
  75. Instruction *CreateFSub(Constant *LHS, Constant *RHS) const override {
  76. return BinaryOperator::CreateFSub(LHS, RHS);
  77. }
  78. Instruction *CreateMul(Constant *LHS, Constant *RHS,
  79. bool HasNUW = false,
  80. bool HasNSW = false) const override {
  81. BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
  82. if (HasNUW) BO->setHasNoUnsignedWrap();
  83. if (HasNSW) BO->setHasNoSignedWrap();
  84. return BO;
  85. }
  86. Instruction *CreateFMul(Constant *LHS, Constant *RHS) const override {
  87. return BinaryOperator::CreateFMul(LHS, RHS);
  88. }
  89. Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
  90. bool isExact = false) const override {
  91. if (!isExact)
  92. return BinaryOperator::CreateUDiv(LHS, RHS);
  93. return BinaryOperator::CreateExactUDiv(LHS, RHS);
  94. }
  95. Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
  96. bool isExact = false) const override {
  97. if (!isExact)
  98. return BinaryOperator::CreateSDiv(LHS, RHS);
  99. return BinaryOperator::CreateExactSDiv(LHS, RHS);
  100. }
  101. Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const override {
  102. return BinaryOperator::CreateFDiv(LHS, RHS);
  103. }
  104. Instruction *CreateURem(Constant *LHS, Constant *RHS) const override {
  105. return BinaryOperator::CreateURem(LHS, RHS);
  106. }
  107. Instruction *CreateSRem(Constant *LHS, Constant *RHS) const override {
  108. return BinaryOperator::CreateSRem(LHS, RHS);
  109. }
  110. Instruction *CreateFRem(Constant *LHS, Constant *RHS) const override {
  111. return BinaryOperator::CreateFRem(LHS, RHS);
  112. }
  113. Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
  114. bool HasNSW = false) const override {
  115. BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
  116. if (HasNUW) BO->setHasNoUnsignedWrap();
  117. if (HasNSW) BO->setHasNoSignedWrap();
  118. return BO;
  119. }
  120. Instruction *CreateLShr(Constant *LHS, Constant *RHS,
  121. bool isExact = false) const override {
  122. if (!isExact)
  123. return BinaryOperator::CreateLShr(LHS, RHS);
  124. return BinaryOperator::CreateExactLShr(LHS, RHS);
  125. }
  126. Instruction *CreateAShr(Constant *LHS, Constant *RHS,
  127. bool isExact = false) const override {
  128. if (!isExact)
  129. return BinaryOperator::CreateAShr(LHS, RHS);
  130. return BinaryOperator::CreateExactAShr(LHS, RHS);
  131. }
  132. Instruction *CreateXor(Constant *LHS, Constant *RHS) const override {
  133. return BinaryOperator::CreateXor(LHS, RHS);
  134. }
  135. Instruction *CreateBinOp(Instruction::BinaryOps Opc,
  136. Constant *LHS, Constant *RHS) const override {
  137. return BinaryOperator::Create(Opc, LHS, RHS);
  138. }
  139. //===--------------------------------------------------------------------===//
  140. // Unary Operators
  141. //===--------------------------------------------------------------------===//
  142. Instruction *CreateNeg(Constant *C,
  143. bool HasNUW = false,
  144. bool HasNSW = false) const override {
  145. BinaryOperator *BO = BinaryOperator::CreateNeg(C);
  146. if (HasNUW) BO->setHasNoUnsignedWrap();
  147. if (HasNSW) BO->setHasNoSignedWrap();
  148. return BO;
  149. }
  150. Instruction *CreateFNeg(Constant *C) const override {
  151. return UnaryOperator::CreateFNeg(C);
  152. }
  153. Instruction *CreateNot(Constant *C) const override {
  154. return BinaryOperator::CreateNot(C);
  155. }
  156. Instruction *CreateUnOp(Instruction::UnaryOps Opc,
  157. Constant *C) const override {
  158. return UnaryOperator::Create(Opc, C);
  159. }
  160. //===--------------------------------------------------------------------===//
  161. // Cast/Conversion Operators
  162. //===--------------------------------------------------------------------===//
  163. Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
  164. Type *DestTy) const override {
  165. return CastInst::Create(Op, C, DestTy);
  166. }
  167. Instruction *CreatePointerCast(Constant *C, Type *DestTy) const override {
  168. return CastInst::CreatePointerCast(C, DestTy);
  169. }
  170. Instruction *CreatePointerBitCastOrAddrSpaceCast(
  171. Constant *C, Type *DestTy) const override {
  172. return CastInst::CreatePointerBitCastOrAddrSpaceCast(C, DestTy);
  173. }
  174. Instruction *CreateIntCast(Constant *C, Type *DestTy,
  175. bool isSigned) const override {
  176. return CastInst::CreateIntegerCast(C, DestTy, isSigned);
  177. }
  178. Instruction *CreateFPCast(Constant *C, Type *DestTy) const override {
  179. return CastInst::CreateFPCast(C, DestTy);
  180. }
  181. Instruction *CreateBitCast(Constant *C, Type *DestTy) const override {
  182. return CreateCast(Instruction::BitCast, C, DestTy);
  183. }
  184. Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const override {
  185. return CreateCast(Instruction::IntToPtr, C, DestTy);
  186. }
  187. Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const override {
  188. return CreateCast(Instruction::PtrToInt, C, DestTy);
  189. }
  190. Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
  191. return CastInst::CreateZExtOrBitCast(C, DestTy);
  192. }
  193. Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
  194. return CastInst::CreateSExtOrBitCast(C, DestTy);
  195. }
  196. Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
  197. return CastInst::CreateTruncOrBitCast(C, DestTy);
  198. }
  199. //===--------------------------------------------------------------------===//
  200. // Compare Instructions
  201. //===--------------------------------------------------------------------===//
  202. Instruction *CreateFCmp(CmpInst::Predicate P,
  203. Constant *LHS, Constant *RHS) const override {
  204. return new FCmpInst(P, LHS, RHS);
  205. }
  206. //===--------------------------------------------------------------------===//
  207. // Other Instructions
  208. //===--------------------------------------------------------------------===//
  209. Instruction *CreateExtractElement(Constant *Vec,
  210. Constant *Idx) const override {
  211. return ExtractElementInst::Create(Vec, Idx);
  212. }
  213. Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
  214. Constant *Idx) const override {
  215. return InsertElementInst::Create(Vec, NewElt, Idx);
  216. }
  217. Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
  218. ArrayRef<int> Mask) const override {
  219. return new ShuffleVectorInst(V1, V2, Mask);
  220. }
  221. Instruction *CreateExtractValue(Constant *Agg,
  222. ArrayRef<unsigned> IdxList) const override {
  223. return ExtractValueInst::Create(Agg, IdxList);
  224. }
  225. Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
  226. ArrayRef<unsigned> IdxList) const override {
  227. return InsertValueInst::Create(Agg, Val, IdxList);
  228. }
  229. };
  230. } // end namespace llvm
  231. #endif // LLVM_IR_NOFOLDER_H
  232. #ifdef __GNUC__
  233. #pragma GCC diagnostic pop
  234. #endif