InstSimplifyFolder.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- InstSimplifyFolder.h - InstSimplify 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 InstSimplifyFolder class, a helper for IRBuilder.
  15. // It provides IRBuilder with a set of methods for folding operations to
  16. // existing values using InstructionSimplify. At the moment, only a subset of
  17. // the implementation uses InstructionSimplify. The rest of the implementation
  18. // only folds constants.
  19. //
  20. // The folder also applies target-specific constant folding.
  21. //
  22. //===----------------------------------------------------------------------===//
  23. #ifndef LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H
  24. #define LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H
  25. #include "llvm/ADT/ArrayRef.h"
  26. #include "llvm/Analysis/InstructionSimplify.h"
  27. #include "llvm/Analysis/TargetFolder.h"
  28. #include "llvm/IR/Constants.h"
  29. #include "llvm/IR/IRBuilderFolder.h"
  30. #include "llvm/IR/InstrTypes.h"
  31. #include "llvm/IR/Instruction.h"
  32. namespace llvm {
  33. /// InstSimplifyFolder - Use InstructionSimplify to fold operations to existing
  34. /// values. Also applies target-specific constant folding when not using
  35. /// InstructionSimplify.
  36. class InstSimplifyFolder final : public IRBuilderFolder {
  37. TargetFolder ConstFolder;
  38. SimplifyQuery SQ;
  39. virtual void anchor();
  40. public:
  41. InstSimplifyFolder(const DataLayout &DL) : ConstFolder(DL), SQ(DL) {}
  42. //===--------------------------------------------------------------------===//
  43. // Value-based folders.
  44. //
  45. // Return an existing value or a constant if the operation can be simplified.
  46. // Otherwise return nullptr.
  47. //===--------------------------------------------------------------------===//
  48. Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false,
  49. bool HasNSW = false) const override {
  50. return SimplifyAddInst(LHS, RHS, HasNUW, HasNSW, SQ);
  51. }
  52. Value *FoldAnd(Value *LHS, Value *RHS) const override {
  53. return SimplifyAndInst(LHS, RHS, SQ);
  54. }
  55. Value *FoldOr(Value *LHS, Value *RHS) const override {
  56. return SimplifyOrInst(LHS, RHS, SQ);
  57. }
  58. Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
  59. return SimplifyICmpInst(P, LHS, RHS, SQ);
  60. }
  61. Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
  62. bool IsInBounds = false) const override {
  63. return SimplifyGEPInst(Ty, Ptr, IdxList, IsInBounds, SQ);
  64. }
  65. Value *FoldSelect(Value *C, Value *True, Value *False) const override {
  66. return SimplifySelectInst(C, True, False, SQ);
  67. }
  68. //===--------------------------------------------------------------------===//
  69. // Binary Operators
  70. //===--------------------------------------------------------------------===//
  71. Value *CreateFAdd(Constant *LHS, Constant *RHS) const override {
  72. return ConstFolder.CreateFAdd(LHS, RHS);
  73. }
  74. Value *CreateSub(Constant *LHS, Constant *RHS, bool HasNUW = false,
  75. bool HasNSW = false) const override {
  76. return ConstFolder.CreateSub(LHS, RHS, HasNUW, HasNSW);
  77. }
  78. Value *CreateFSub(Constant *LHS, Constant *RHS) const override {
  79. return ConstFolder.CreateFSub(LHS, RHS);
  80. }
  81. Value *CreateMul(Constant *LHS, Constant *RHS, bool HasNUW = false,
  82. bool HasNSW = false) const override {
  83. return ConstFolder.CreateMul(LHS, RHS, HasNUW, HasNSW);
  84. }
  85. Value *CreateFMul(Constant *LHS, Constant *RHS) const override {
  86. return ConstFolder.CreateFMul(LHS, RHS);
  87. }
  88. Value *CreateUDiv(Constant *LHS, Constant *RHS,
  89. bool isExact = false) const override {
  90. return ConstFolder.CreateUDiv(LHS, RHS, isExact);
  91. }
  92. Value *CreateSDiv(Constant *LHS, Constant *RHS,
  93. bool isExact = false) const override {
  94. return ConstFolder.CreateSDiv(LHS, RHS, isExact);
  95. }
  96. Value *CreateFDiv(Constant *LHS, Constant *RHS) const override {
  97. return ConstFolder.CreateFDiv(LHS, RHS);
  98. }
  99. Value *CreateURem(Constant *LHS, Constant *RHS) const override {
  100. return ConstFolder.CreateURem(LHS, RHS);
  101. }
  102. Value *CreateSRem(Constant *LHS, Constant *RHS) const override {
  103. return ConstFolder.CreateSRem(LHS, RHS);
  104. }
  105. Value *CreateFRem(Constant *LHS, Constant *RHS) const override {
  106. return ConstFolder.CreateFRem(LHS, RHS);
  107. }
  108. Value *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
  109. bool HasNSW = false) const override {
  110. return ConstFolder.CreateShl(LHS, RHS, HasNUW, HasNSW);
  111. }
  112. Value *CreateLShr(Constant *LHS, Constant *RHS,
  113. bool isExact = false) const override {
  114. return ConstFolder.CreateLShr(LHS, RHS, isExact);
  115. }
  116. Value *CreateAShr(Constant *LHS, Constant *RHS,
  117. bool isExact = false) const override {
  118. return ConstFolder.CreateAShr(LHS, RHS, isExact);
  119. }
  120. Value *CreateXor(Constant *LHS, Constant *RHS) const override {
  121. return ConstFolder.CreateXor(LHS, RHS);
  122. }
  123. Value *CreateBinOp(Instruction::BinaryOps Opc, Constant *LHS,
  124. Constant *RHS) const override {
  125. return ConstFolder.CreateBinOp(Opc, LHS, RHS);
  126. }
  127. //===--------------------------------------------------------------------===//
  128. // Unary Operators
  129. //===--------------------------------------------------------------------===//
  130. Value *CreateNeg(Constant *C, bool HasNUW = false,
  131. bool HasNSW = false) const override {
  132. return ConstFolder.CreateNeg(C, HasNUW, HasNSW);
  133. }
  134. Value *CreateFNeg(Constant *C) const override {
  135. return ConstFolder.CreateFNeg(C);
  136. }
  137. Value *CreateNot(Constant *C) const override {
  138. return ConstFolder.CreateNot(C);
  139. }
  140. Value *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
  141. return ConstFolder.CreateUnOp(Opc, C);
  142. }
  143. //===--------------------------------------------------------------------===//
  144. // Cast/Conversion Operators
  145. //===--------------------------------------------------------------------===//
  146. Value *CreateCast(Instruction::CastOps Op, Constant *C,
  147. Type *DestTy) const override {
  148. if (C->getType() == DestTy)
  149. return C; // avoid calling Fold
  150. return ConstFolder.CreateCast(Op, C, DestTy);
  151. }
  152. Value *CreateIntCast(Constant *C, Type *DestTy,
  153. bool isSigned) const override {
  154. if (C->getType() == DestTy)
  155. return C; // avoid calling Fold
  156. return ConstFolder.CreateIntCast(C, DestTy, isSigned);
  157. }
  158. Value *CreatePointerCast(Constant *C, Type *DestTy) const override {
  159. if (C->getType() == DestTy)
  160. return C; // avoid calling Fold
  161. return ConstFolder.CreatePointerCast(C, DestTy);
  162. }
  163. Value *CreateFPCast(Constant *C, Type *DestTy) const override {
  164. if (C->getType() == DestTy)
  165. return C; // avoid calling Fold
  166. return ConstFolder.CreateFPCast(C, DestTy);
  167. }
  168. Value *CreateBitCast(Constant *C, Type *DestTy) const override {
  169. return ConstFolder.CreateBitCast(C, DestTy);
  170. }
  171. Value *CreateIntToPtr(Constant *C, Type *DestTy) const override {
  172. return ConstFolder.CreateIntToPtr(C, DestTy);
  173. }
  174. Value *CreatePtrToInt(Constant *C, Type *DestTy) const override {
  175. return ConstFolder.CreatePtrToInt(C, DestTy);
  176. }
  177. Value *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
  178. if (C->getType() == DestTy)
  179. return C; // avoid calling Fold
  180. return ConstFolder.CreateZExtOrBitCast(C, DestTy);
  181. }
  182. Value *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
  183. if (C->getType() == DestTy)
  184. return C; // avoid calling Fold
  185. return ConstFolder.CreateSExtOrBitCast(C, DestTy);
  186. }
  187. Value *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
  188. if (C->getType() == DestTy)
  189. return C; // avoid calling Fold
  190. return ConstFolder.CreateTruncOrBitCast(C, DestTy);
  191. }
  192. Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
  193. Type *DestTy) const override {
  194. if (C->getType() == DestTy)
  195. return C; // avoid calling Fold
  196. return ConstFolder.CreatePointerBitCastOrAddrSpaceCast(C, DestTy);
  197. }
  198. //===--------------------------------------------------------------------===//
  199. // Compare Instructions
  200. //===--------------------------------------------------------------------===//
  201. Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
  202. Constant *RHS) const override {
  203. return ConstFolder.CreateFCmp(P, LHS, RHS);
  204. }
  205. //===--------------------------------------------------------------------===//
  206. // Other Instructions
  207. //===--------------------------------------------------------------------===//
  208. Value *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
  209. return ConstFolder.CreateExtractElement(Vec, Idx);
  210. }
  211. Value *CreateInsertElement(Constant *Vec, Constant *NewElt,
  212. Constant *Idx) const override {
  213. return ConstFolder.CreateInsertElement(Vec, NewElt, Idx);
  214. }
  215. Value *CreateShuffleVector(Constant *V1, Constant *V2,
  216. ArrayRef<int> Mask) const override {
  217. return ConstFolder.CreateShuffleVector(V1, V2, Mask);
  218. }
  219. Value *CreateExtractValue(Constant *Agg,
  220. ArrayRef<unsigned> IdxList) const override {
  221. return ConstFolder.CreateExtractValue(Agg, IdxList);
  222. }
  223. Value *CreateInsertValue(Constant *Agg, Constant *Val,
  224. ArrayRef<unsigned> IdxList) const override {
  225. return ConstFolder.CreateInsertValue(Agg, Val, IdxList);
  226. }
  227. };
  228. } // end namespace llvm
  229. #endif // LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H
  230. #ifdef __GNUC__
  231. #pragma GCC diagnostic pop
  232. #endif