1 //===- ConstantFolder.h - Constant folding helper ---------------*- 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 // 9 // This file defines the ConstantFolder class, a helper for IRBuilder. 10 // It provides IRBuilder with a set of methods for creating constants 11 // with minimal folding. For general constant creation and folding, 12 // use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_IR_CONSTANTFOLDER_H 17 #define LLVM_IR_CONSTANTFOLDER_H 18 19 #include "llvm/ADT/ArrayRef.h" 20 #include "llvm/IR/Constants.h" 21 #include "llvm/IR/InstrTypes.h" 22 #include "llvm/IR/Instruction.h" 23 #include "llvm/IR/IRBuilderFolder.h" 24 25 namespace llvm { 26 27 /// ConstantFolder - Create constants with minimum, target independent, folding. 28 class ConstantFolder final : public IRBuilderFolder { 29 virtual void anchor(); 30 31 public: 32 explicit ConstantFolder() = default; 33 34 //===--------------------------------------------------------------------===// 35 // Binary Operators 36 //===--------------------------------------------------------------------===// 37 38 Constant *CreateAdd(Constant *LHS, Constant *RHS, 39 bool HasNUW = false, bool HasNSW = false) const override { 40 return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW); 41 } 42 CreateFAdd(Constant * LHS,Constant * RHS)43 Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override { 44 return ConstantExpr::getFAdd(LHS, RHS); 45 } 46 47 Constant *CreateSub(Constant *LHS, Constant *RHS, 48 bool HasNUW = false, bool HasNSW = false) const override { 49 return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW); 50 } 51 CreateFSub(Constant * LHS,Constant * RHS)52 Constant *CreateFSub(Constant *LHS, Constant *RHS) const override { 53 return ConstantExpr::getFSub(LHS, RHS); 54 } 55 56 Constant *CreateMul(Constant *LHS, Constant *RHS, 57 bool HasNUW = false, bool HasNSW = false) const override { 58 return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW); 59 } 60 CreateFMul(Constant * LHS,Constant * RHS)61 Constant *CreateFMul(Constant *LHS, Constant *RHS) const override { 62 return ConstantExpr::getFMul(LHS, RHS); 63 } 64 65 Constant *CreateUDiv(Constant *LHS, Constant *RHS, 66 bool isExact = false) const override { 67 return ConstantExpr::getUDiv(LHS, RHS, isExact); 68 } 69 70 Constant *CreateSDiv(Constant *LHS, Constant *RHS, 71 bool isExact = false) const override { 72 return ConstantExpr::getSDiv(LHS, RHS, isExact); 73 } 74 CreateFDiv(Constant * LHS,Constant * RHS)75 Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override { 76 return ConstantExpr::getFDiv(LHS, RHS); 77 } 78 CreateURem(Constant * LHS,Constant * RHS)79 Constant *CreateURem(Constant *LHS, Constant *RHS) const override { 80 return ConstantExpr::getURem(LHS, RHS); 81 } 82 CreateSRem(Constant * LHS,Constant * RHS)83 Constant *CreateSRem(Constant *LHS, Constant *RHS) const override { 84 return ConstantExpr::getSRem(LHS, RHS); 85 } 86 CreateFRem(Constant * LHS,Constant * RHS)87 Constant *CreateFRem(Constant *LHS, Constant *RHS) const override { 88 return ConstantExpr::getFRem(LHS, RHS); 89 } 90 91 Constant *CreateShl(Constant *LHS, Constant *RHS, 92 bool HasNUW = false, bool HasNSW = false) const override { 93 return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW); 94 } 95 96 Constant *CreateLShr(Constant *LHS, Constant *RHS, 97 bool isExact = false) const override { 98 return ConstantExpr::getLShr(LHS, RHS, isExact); 99 } 100 101 Constant *CreateAShr(Constant *LHS, Constant *RHS, 102 bool isExact = false) const override { 103 return ConstantExpr::getAShr(LHS, RHS, isExact); 104 } 105 CreateAnd(Constant * LHS,Constant * RHS)106 Constant *CreateAnd(Constant *LHS, Constant *RHS) const override { 107 return ConstantExpr::getAnd(LHS, RHS); 108 } 109 CreateOr(Constant * LHS,Constant * RHS)110 Constant *CreateOr(Constant *LHS, Constant *RHS) const override { 111 return ConstantExpr::getOr(LHS, RHS); 112 } 113 CreateXor(Constant * LHS,Constant * RHS)114 Constant *CreateXor(Constant *LHS, Constant *RHS) const override { 115 return ConstantExpr::getXor(LHS, RHS); 116 } 117 CreateBinOp(Instruction::BinaryOps Opc,Constant * LHS,Constant * RHS)118 Constant *CreateBinOp(Instruction::BinaryOps Opc, 119 Constant *LHS, Constant *RHS) const override { 120 return ConstantExpr::get(Opc, LHS, RHS); 121 } 122 123 //===--------------------------------------------------------------------===// 124 // Unary Operators 125 //===--------------------------------------------------------------------===// 126 127 Constant *CreateNeg(Constant *C, 128 bool HasNUW = false, bool HasNSW = false) const override { 129 return ConstantExpr::getNeg(C, HasNUW, HasNSW); 130 } 131 CreateFNeg(Constant * C)132 Constant *CreateFNeg(Constant *C) const override { 133 return ConstantExpr::getFNeg(C); 134 } 135 CreateNot(Constant * C)136 Constant *CreateNot(Constant *C) const override { 137 return ConstantExpr::getNot(C); 138 } 139 CreateUnOp(Instruction::UnaryOps Opc,Constant * C)140 Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override { 141 return ConstantExpr::get(Opc, C); 142 } 143 144 //===--------------------------------------------------------------------===// 145 // Memory Instructions 146 //===--------------------------------------------------------------------===// 147 CreateGetElementPtr(Type * Ty,Constant * C,ArrayRef<Constant * > IdxList)148 Constant *CreateGetElementPtr(Type *Ty, Constant *C, 149 ArrayRef<Constant *> IdxList) const override { 150 return ConstantExpr::getGetElementPtr(Ty, C, IdxList); 151 } 152 CreateGetElementPtr(Type * Ty,Constant * C,Constant * Idx)153 Constant *CreateGetElementPtr(Type *Ty, Constant *C, 154 Constant *Idx) const override { 155 // This form of the function only exists to avoid ambiguous overload 156 // warnings about whether to convert Idx to ArrayRef<Constant *> or 157 // ArrayRef<Value *>. 158 return ConstantExpr::getGetElementPtr(Ty, C, Idx); 159 } 160 CreateGetElementPtr(Type * Ty,Constant * C,ArrayRef<Value * > IdxList)161 Constant *CreateGetElementPtr(Type *Ty, Constant *C, 162 ArrayRef<Value *> IdxList) const override { 163 return ConstantExpr::getGetElementPtr(Ty, C, IdxList); 164 } 165 CreateInBoundsGetElementPtr(Type * Ty,Constant * C,ArrayRef<Constant * > IdxList)166 Constant *CreateInBoundsGetElementPtr( 167 Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override { 168 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList); 169 } 170 CreateInBoundsGetElementPtr(Type * Ty,Constant * C,Constant * Idx)171 Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, 172 Constant *Idx) const override { 173 // This form of the function only exists to avoid ambiguous overload 174 // warnings about whether to convert Idx to ArrayRef<Constant *> or 175 // ArrayRef<Value *>. 176 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx); 177 } 178 CreateInBoundsGetElementPtr(Type * Ty,Constant * C,ArrayRef<Value * > IdxList)179 Constant *CreateInBoundsGetElementPtr( 180 Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override { 181 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList); 182 } 183 184 //===--------------------------------------------------------------------===// 185 // Cast/Conversion Operators 186 //===--------------------------------------------------------------------===// 187 CreateCast(Instruction::CastOps Op,Constant * C,Type * DestTy)188 Constant *CreateCast(Instruction::CastOps Op, Constant *C, 189 Type *DestTy) const override { 190 return ConstantExpr::getCast(Op, C, DestTy); 191 } 192 CreatePointerCast(Constant * C,Type * DestTy)193 Constant *CreatePointerCast(Constant *C, Type *DestTy) const override { 194 return ConstantExpr::getPointerCast(C, DestTy); 195 } 196 CreatePointerBitCastOrAddrSpaceCast(Constant * C,Type * DestTy)197 Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C, 198 Type *DestTy) const override { 199 return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy); 200 } 201 CreateIntCast(Constant * C,Type * DestTy,bool isSigned)202 Constant *CreateIntCast(Constant *C, Type *DestTy, 203 bool isSigned) const override { 204 return ConstantExpr::getIntegerCast(C, DestTy, isSigned); 205 } 206 CreateFPCast(Constant * C,Type * DestTy)207 Constant *CreateFPCast(Constant *C, Type *DestTy) const override { 208 return ConstantExpr::getFPCast(C, DestTy); 209 } 210 CreateBitCast(Constant * C,Type * DestTy)211 Constant *CreateBitCast(Constant *C, Type *DestTy) const override { 212 return CreateCast(Instruction::BitCast, C, DestTy); 213 } 214 CreateIntToPtr(Constant * C,Type * DestTy)215 Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override { 216 return CreateCast(Instruction::IntToPtr, C, DestTy); 217 } 218 CreatePtrToInt(Constant * C,Type * DestTy)219 Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override { 220 return CreateCast(Instruction::PtrToInt, C, DestTy); 221 } 222 CreateZExtOrBitCast(Constant * C,Type * DestTy)223 Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override { 224 return ConstantExpr::getZExtOrBitCast(C, DestTy); 225 } 226 CreateSExtOrBitCast(Constant * C,Type * DestTy)227 Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override { 228 return ConstantExpr::getSExtOrBitCast(C, DestTy); 229 } 230 CreateTruncOrBitCast(Constant * C,Type * DestTy)231 Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override { 232 return ConstantExpr::getTruncOrBitCast(C, DestTy); 233 } 234 235 //===--------------------------------------------------------------------===// 236 // Compare Instructions 237 //===--------------------------------------------------------------------===// 238 CreateICmp(CmpInst::Predicate P,Constant * LHS,Constant * RHS)239 Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS, 240 Constant *RHS) const override { 241 return ConstantExpr::getCompare(P, LHS, RHS); 242 } 243 CreateFCmp(CmpInst::Predicate P,Constant * LHS,Constant * RHS)244 Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS, 245 Constant *RHS) const override { 246 return ConstantExpr::getCompare(P, LHS, RHS); 247 } 248 249 //===--------------------------------------------------------------------===// 250 // Other Instructions 251 //===--------------------------------------------------------------------===// 252 CreateSelect(Constant * C,Constant * True,Constant * False)253 Constant *CreateSelect(Constant *C, Constant *True, 254 Constant *False) const override { 255 return ConstantExpr::getSelect(C, True, False); 256 } 257 CreateExtractElement(Constant * Vec,Constant * Idx)258 Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override { 259 return ConstantExpr::getExtractElement(Vec, Idx); 260 } 261 CreateInsertElement(Constant * Vec,Constant * NewElt,Constant * Idx)262 Constant *CreateInsertElement(Constant *Vec, Constant *NewElt, 263 Constant *Idx) const override { 264 return ConstantExpr::getInsertElement(Vec, NewElt, Idx); 265 } 266 CreateShuffleVector(Constant * V1,Constant * V2,ArrayRef<int> Mask)267 Constant *CreateShuffleVector(Constant *V1, Constant *V2, 268 ArrayRef<int> Mask) const override { 269 return ConstantExpr::getShuffleVector(V1, V2, Mask); 270 } 271 CreateExtractValue(Constant * Agg,ArrayRef<unsigned> IdxList)272 Constant *CreateExtractValue(Constant *Agg, 273 ArrayRef<unsigned> IdxList) const override { 274 return ConstantExpr::getExtractValue(Agg, IdxList); 275 } 276 CreateInsertValue(Constant * Agg,Constant * Val,ArrayRef<unsigned> IdxList)277 Constant *CreateInsertValue(Constant *Agg, Constant *Val, 278 ArrayRef<unsigned> IdxList) const override { 279 return ConstantExpr::getInsertValue(Agg, Val, IdxList); 280 } 281 }; 282 283 } // end namespace llvm 284 285 #endif // LLVM_IR_CONSTANTFOLDER_H 286