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