ConstantFolder.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- ConstantFolder.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 ConstantFolder class, a helper for IRBuilder.
  15. // It provides IRBuilder with a set of methods for creating constants
  16. // with minimal folding. For general constant creation and folding,
  17. // use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_IR_CONSTANTFOLDER_H
  21. #define LLVM_IR_CONSTANTFOLDER_H
  22. #include "llvm/ADT/ArrayRef.h"
  23. #include "llvm/ADT/STLExtras.h"
  24. #include "llvm/IR/Constants.h"
  25. #include "llvm/IR/ConstantFold.h"
  26. #include "llvm/IR/IRBuilderFolder.h"
  27. #include "llvm/IR/Instruction.h"
  28. #include "llvm/IR/Operator.h"
  29. namespace llvm {
  30. /// ConstantFolder - Create constants with minimum, target independent, folding.
  31. class ConstantFolder final : public IRBuilderFolder {
  32. virtual void anchor();
  33. public:
  34. explicit ConstantFolder() = default;
  35. //===--------------------------------------------------------------------===//
  36. // Value-based folders.
  37. //
  38. // Return an existing value or a constant if the operation can be simplified.
  39. // Otherwise return nullptr.
  40. //===--------------------------------------------------------------------===//
  41. Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS,
  42. Value *RHS) const override {
  43. auto *LC = dyn_cast<Constant>(LHS);
  44. auto *RC = dyn_cast<Constant>(RHS);
  45. if (LC && RC) {
  46. if (ConstantExpr::isDesirableBinOp(Opc))
  47. return ConstantExpr::get(Opc, LC, RC);
  48. return ConstantFoldBinaryInstruction(Opc, LC, RC);
  49. }
  50. return nullptr;
  51. }
  52. Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
  53. bool IsExact) const override {
  54. auto *LC = dyn_cast<Constant>(LHS);
  55. auto *RC = dyn_cast<Constant>(RHS);
  56. if (LC && RC) {
  57. if (ConstantExpr::isDesirableBinOp(Opc))
  58. return ConstantExpr::get(Opc, LC, RC,
  59. IsExact ? PossiblyExactOperator::IsExact : 0);
  60. return ConstantFoldBinaryInstruction(Opc, LC, RC);
  61. }
  62. return nullptr;
  63. }
  64. Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
  65. bool HasNUW, bool HasNSW) const override {
  66. auto *LC = dyn_cast<Constant>(LHS);
  67. auto *RC = dyn_cast<Constant>(RHS);
  68. if (LC && RC) {
  69. if (ConstantExpr::isDesirableBinOp(Opc)) {
  70. unsigned Flags = 0;
  71. if (HasNUW)
  72. Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
  73. if (HasNSW)
  74. Flags |= OverflowingBinaryOperator::NoSignedWrap;
  75. return ConstantExpr::get(Opc, LC, RC, Flags);
  76. }
  77. return ConstantFoldBinaryInstruction(Opc, LC, RC);
  78. }
  79. return nullptr;
  80. }
  81. Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
  82. FastMathFlags FMF) const override {
  83. return FoldBinOp(Opc, LHS, RHS);
  84. }
  85. Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V,
  86. FastMathFlags FMF) const override {
  87. if (Constant *C = dyn_cast<Constant>(V))
  88. return ConstantFoldUnaryInstruction(Opc, C);
  89. return nullptr;
  90. }
  91. Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
  92. auto *LC = dyn_cast<Constant>(LHS);
  93. auto *RC = dyn_cast<Constant>(RHS);
  94. if (LC && RC)
  95. return ConstantExpr::getCompare(P, LC, RC);
  96. return nullptr;
  97. }
  98. Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
  99. bool IsInBounds = false) const override {
  100. if (auto *PC = dyn_cast<Constant>(Ptr)) {
  101. // Every index must be constant.
  102. if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
  103. return nullptr;
  104. if (IsInBounds)
  105. return ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList);
  106. else
  107. return ConstantExpr::getGetElementPtr(Ty, PC, IdxList);
  108. }
  109. return nullptr;
  110. }
  111. Value *FoldSelect(Value *C, Value *True, Value *False) const override {
  112. auto *CC = dyn_cast<Constant>(C);
  113. auto *TC = dyn_cast<Constant>(True);
  114. auto *FC = dyn_cast<Constant>(False);
  115. if (CC && TC && FC)
  116. return ConstantExpr::getSelect(CC, TC, FC);
  117. return nullptr;
  118. }
  119. Value *FoldExtractValue(Value *Agg,
  120. ArrayRef<unsigned> IdxList) const override {
  121. if (auto *CAgg = dyn_cast<Constant>(Agg))
  122. return ConstantFoldExtractValueInstruction(CAgg, IdxList);
  123. return nullptr;
  124. };
  125. Value *FoldInsertValue(Value *Agg, Value *Val,
  126. ArrayRef<unsigned> IdxList) const override {
  127. auto *CAgg = dyn_cast<Constant>(Agg);
  128. auto *CVal = dyn_cast<Constant>(Val);
  129. if (CAgg && CVal)
  130. return ConstantFoldInsertValueInstruction(CAgg, CVal, IdxList);
  131. return nullptr;
  132. }
  133. Value *FoldExtractElement(Value *Vec, Value *Idx) const override {
  134. auto *CVec = dyn_cast<Constant>(Vec);
  135. auto *CIdx = dyn_cast<Constant>(Idx);
  136. if (CVec && CIdx)
  137. return ConstantExpr::getExtractElement(CVec, CIdx);
  138. return nullptr;
  139. }
  140. Value *FoldInsertElement(Value *Vec, Value *NewElt,
  141. Value *Idx) const override {
  142. auto *CVec = dyn_cast<Constant>(Vec);
  143. auto *CNewElt = dyn_cast<Constant>(NewElt);
  144. auto *CIdx = dyn_cast<Constant>(Idx);
  145. if (CVec && CNewElt && CIdx)
  146. return ConstantExpr::getInsertElement(CVec, CNewElt, CIdx);
  147. return nullptr;
  148. }
  149. Value *FoldShuffleVector(Value *V1, Value *V2,
  150. ArrayRef<int> Mask) const override {
  151. auto *C1 = dyn_cast<Constant>(V1);
  152. auto *C2 = dyn_cast<Constant>(V2);
  153. if (C1 && C2)
  154. return ConstantExpr::getShuffleVector(C1, C2, Mask);
  155. return nullptr;
  156. }
  157. //===--------------------------------------------------------------------===//
  158. // Cast/Conversion Operators
  159. //===--------------------------------------------------------------------===//
  160. Constant *CreateCast(Instruction::CastOps Op, Constant *C,
  161. Type *DestTy) const override {
  162. return ConstantExpr::getCast(Op, C, DestTy);
  163. }
  164. Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
  165. return ConstantExpr::getPointerCast(C, DestTy);
  166. }
  167. Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
  168. Type *DestTy) const override {
  169. return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
  170. }
  171. Constant *CreateIntCast(Constant *C, Type *DestTy,
  172. bool isSigned) const override {
  173. return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
  174. }
  175. Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
  176. return ConstantExpr::getFPCast(C, DestTy);
  177. }
  178. Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
  179. return CreateCast(Instruction::BitCast, C, DestTy);
  180. }
  181. Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
  182. return CreateCast(Instruction::IntToPtr, C, DestTy);
  183. }
  184. Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
  185. return CreateCast(Instruction::PtrToInt, C, DestTy);
  186. }
  187. Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
  188. return ConstantExpr::getZExtOrBitCast(C, DestTy);
  189. }
  190. Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
  191. return ConstantExpr::getSExtOrBitCast(C, DestTy);
  192. }
  193. Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
  194. return ConstantExpr::getTruncOrBitCast(C, DestTy);
  195. }
  196. //===--------------------------------------------------------------------===//
  197. // Compare Instructions
  198. //===--------------------------------------------------------------------===//
  199. Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
  200. Constant *RHS) const override {
  201. return ConstantExpr::getCompare(P, LHS, RHS);
  202. }
  203. };
  204. } // end namespace llvm
  205. #endif // LLVM_IR_CONSTANTFOLDER_H
  206. #ifdef __GNUC__
  207. #pragma GCC diagnostic pop
  208. #endif