1 //===- NoFolder.h - Constant folding helper ---------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the NoFolder class, a helper for IRBuilder. It provides 11 // IRBuilder with a set of methods for creating unfolded constants. This is 12 // useful for learners trying to understand how LLVM IR works, and who don't 13 // want details to be hidden by the constant folder. For general constant 14 // creation and folding, use ConstantExpr and the routines in 15 // llvm/Analysis/ConstantFolding.h. 16 // 17 // Note: since it is not actually possible to create unfolded constants, this 18 // class returns instructions rather than constants. 19 // 20 //===----------------------------------------------------------------------===// 21 22 #ifndef LLVM_IR_NOFOLDER_H 23 #define LLVM_IR_NOFOLDER_H 24 25 #include "llvm/ADT/ArrayRef.h" 26 #include "llvm/IR/Constants.h" 27 #include "llvm/IR/InstrTypes.h" 28 #include "llvm/IR/Instruction.h" 29 #include "llvm/IR/Instructions.h" 30 31 namespace llvm { 32 33 /// NoFolder - Create "constants" (actually, instructions) with no folding. 34 class NoFolder { 35 public: 36 explicit NoFolder() = default; 37 38 //===--------------------------------------------------------------------===// 39 // Binary Operators 40 //===--------------------------------------------------------------------===// 41 42 Instruction *CreateAdd(Constant *LHS, Constant *RHS, 43 bool HasNUW = false, bool HasNSW = false) const { 44 BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS); 45 if (HasNUW) BO->setHasNoUnsignedWrap(); 46 if (HasNSW) BO->setHasNoSignedWrap(); 47 return BO; 48 } 49 CreateNSWAdd(Constant * LHS,Constant * RHS)50 Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const { 51 return BinaryOperator::CreateNSWAdd(LHS, RHS); 52 } 53 CreateNUWAdd(Constant * LHS,Constant * RHS)54 Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const { 55 return BinaryOperator::CreateNUWAdd(LHS, RHS); 56 } 57 CreateFAdd(Constant * LHS,Constant * RHS)58 Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const { 59 return BinaryOperator::CreateFAdd(LHS, RHS); 60 } 61 62 Instruction *CreateSub(Constant *LHS, Constant *RHS, 63 bool HasNUW = false, bool HasNSW = false) const { 64 BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS); 65 if (HasNUW) BO->setHasNoUnsignedWrap(); 66 if (HasNSW) BO->setHasNoSignedWrap(); 67 return BO; 68 } 69 CreateNSWSub(Constant * LHS,Constant * RHS)70 Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const { 71 return BinaryOperator::CreateNSWSub(LHS, RHS); 72 } 73 CreateNUWSub(Constant * LHS,Constant * RHS)74 Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const { 75 return BinaryOperator::CreateNUWSub(LHS, RHS); 76 } 77 CreateFSub(Constant * LHS,Constant * RHS)78 Instruction *CreateFSub(Constant *LHS, Constant *RHS) const { 79 return BinaryOperator::CreateFSub(LHS, RHS); 80 } 81 82 Instruction *CreateMul(Constant *LHS, Constant *RHS, 83 bool HasNUW = false, bool HasNSW = false) const { 84 BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS); 85 if (HasNUW) BO->setHasNoUnsignedWrap(); 86 if (HasNSW) BO->setHasNoSignedWrap(); 87 return BO; 88 } 89 CreateNSWMul(Constant * LHS,Constant * RHS)90 Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const { 91 return BinaryOperator::CreateNSWMul(LHS, RHS); 92 } 93 CreateNUWMul(Constant * LHS,Constant * RHS)94 Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const { 95 return BinaryOperator::CreateNUWMul(LHS, RHS); 96 } 97 CreateFMul(Constant * LHS,Constant * RHS)98 Instruction *CreateFMul(Constant *LHS, Constant *RHS) const { 99 return BinaryOperator::CreateFMul(LHS, RHS); 100 } 101 102 Instruction *CreateUDiv(Constant *LHS, Constant *RHS, 103 bool isExact = false) const { 104 if (!isExact) 105 return BinaryOperator::CreateUDiv(LHS, RHS); 106 return BinaryOperator::CreateExactUDiv(LHS, RHS); 107 } 108 CreateExactUDiv(Constant * LHS,Constant * RHS)109 Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const { 110 return BinaryOperator::CreateExactUDiv(LHS, RHS); 111 } 112 113 Instruction *CreateSDiv(Constant *LHS, Constant *RHS, 114 bool isExact = false) const { 115 if (!isExact) 116 return BinaryOperator::CreateSDiv(LHS, RHS); 117 return BinaryOperator::CreateExactSDiv(LHS, RHS); 118 } 119 CreateExactSDiv(Constant * LHS,Constant * RHS)120 Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const { 121 return BinaryOperator::CreateExactSDiv(LHS, RHS); 122 } 123 CreateFDiv(Constant * LHS,Constant * RHS)124 Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const { 125 return BinaryOperator::CreateFDiv(LHS, RHS); 126 } 127 CreateURem(Constant * LHS,Constant * RHS)128 Instruction *CreateURem(Constant *LHS, Constant *RHS) const { 129 return BinaryOperator::CreateURem(LHS, RHS); 130 } 131 CreateSRem(Constant * LHS,Constant * RHS)132 Instruction *CreateSRem(Constant *LHS, Constant *RHS) const { 133 return BinaryOperator::CreateSRem(LHS, RHS); 134 } 135 CreateFRem(Constant * LHS,Constant * RHS)136 Instruction *CreateFRem(Constant *LHS, Constant *RHS) const { 137 return BinaryOperator::CreateFRem(LHS, RHS); 138 } 139 140 Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false, 141 bool HasNSW = false) const { 142 BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS); 143 if (HasNUW) BO->setHasNoUnsignedWrap(); 144 if (HasNSW) BO->setHasNoSignedWrap(); 145 return BO; 146 } 147 148 Instruction *CreateLShr(Constant *LHS, Constant *RHS, 149 bool isExact = false) const { 150 if (!isExact) 151 return BinaryOperator::CreateLShr(LHS, RHS); 152 return BinaryOperator::CreateExactLShr(LHS, RHS); 153 } 154 155 Instruction *CreateAShr(Constant *LHS, Constant *RHS, 156 bool isExact = false) const { 157 if (!isExact) 158 return BinaryOperator::CreateAShr(LHS, RHS); 159 return BinaryOperator::CreateExactAShr(LHS, RHS); 160 } 161 CreateAnd(Constant * LHS,Constant * RHS)162 Instruction *CreateAnd(Constant *LHS, Constant *RHS) const { 163 return BinaryOperator::CreateAnd(LHS, RHS); 164 } 165 CreateOr(Constant * LHS,Constant * RHS)166 Instruction *CreateOr(Constant *LHS, Constant *RHS) const { 167 return BinaryOperator::CreateOr(LHS, RHS); 168 } 169 CreateXor(Constant * LHS,Constant * RHS)170 Instruction *CreateXor(Constant *LHS, Constant *RHS) const { 171 return BinaryOperator::CreateXor(LHS, RHS); 172 } 173 CreateBinOp(Instruction::BinaryOps Opc,Constant * LHS,Constant * RHS)174 Instruction *CreateBinOp(Instruction::BinaryOps Opc, 175 Constant *LHS, Constant *RHS) const { 176 return BinaryOperator::Create(Opc, LHS, RHS); 177 } 178 179 //===--------------------------------------------------------------------===// 180 // Unary Operators 181 //===--------------------------------------------------------------------===// 182 183 Instruction *CreateNeg(Constant *C, 184 bool HasNUW = false, bool HasNSW = false) const { 185 BinaryOperator *BO = BinaryOperator::CreateNeg(C); 186 if (HasNUW) BO->setHasNoUnsignedWrap(); 187 if (HasNSW) BO->setHasNoSignedWrap(); 188 return BO; 189 } 190 CreateNSWNeg(Constant * C)191 Instruction *CreateNSWNeg(Constant *C) const { 192 return BinaryOperator::CreateNSWNeg(C); 193 } 194 CreateNUWNeg(Constant * C)195 Instruction *CreateNUWNeg(Constant *C) const { 196 return BinaryOperator::CreateNUWNeg(C); 197 } 198 CreateFNeg(Constant * C)199 Instruction *CreateFNeg(Constant *C) const { 200 return BinaryOperator::CreateFNeg(C); 201 } 202 CreateNot(Constant * C)203 Instruction *CreateNot(Constant *C) const { 204 return BinaryOperator::CreateNot(C); 205 } 206 207 //===--------------------------------------------------------------------===// 208 // Memory Instructions 209 //===--------------------------------------------------------------------===// 210 CreateGetElementPtr(Type * Ty,Constant * C,ArrayRef<Constant * > IdxList)211 Constant *CreateGetElementPtr(Type *Ty, Constant *C, 212 ArrayRef<Constant *> IdxList) const { 213 return ConstantExpr::getGetElementPtr(Ty, C, IdxList); 214 } 215 CreateGetElementPtr(Type * Ty,Constant * C,Constant * Idx)216 Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const { 217 // This form of the function only exists to avoid ambiguous overload 218 // warnings about whether to convert Idx to ArrayRef<Constant *> or 219 // ArrayRef<Value *>. 220 return ConstantExpr::getGetElementPtr(Ty, C, Idx); 221 } 222 CreateGetElementPtr(Type * Ty,Constant * C,ArrayRef<Value * > IdxList)223 Instruction *CreateGetElementPtr(Type *Ty, Constant *C, 224 ArrayRef<Value *> IdxList) const { 225 return GetElementPtrInst::Create(Ty, C, IdxList); 226 } 227 CreateInBoundsGetElementPtr(Type * Ty,Constant * C,ArrayRef<Constant * > IdxList)228 Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, 229 ArrayRef<Constant *> IdxList) const { 230 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList); 231 } 232 CreateInBoundsGetElementPtr(Type * Ty,Constant * C,Constant * Idx)233 Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, 234 Constant *Idx) const { 235 // This form of the function only exists to avoid ambiguous overload 236 // warnings about whether to convert Idx to ArrayRef<Constant *> or 237 // ArrayRef<Value *>. 238 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx); 239 } 240 CreateInBoundsGetElementPtr(Type * Ty,Constant * C,ArrayRef<Value * > IdxList)241 Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, 242 ArrayRef<Value *> IdxList) const { 243 return GetElementPtrInst::CreateInBounds(Ty, C, IdxList); 244 } 245 246 //===--------------------------------------------------------------------===// 247 // Cast/Conversion Operators 248 //===--------------------------------------------------------------------===// 249 CreateCast(Instruction::CastOps Op,Constant * C,Type * DestTy)250 Instruction *CreateCast(Instruction::CastOps Op, Constant *C, 251 Type *DestTy) const { 252 return CastInst::Create(Op, C, DestTy); 253 } 254 CreatePointerCast(Constant * C,Type * DestTy)255 Instruction *CreatePointerCast(Constant *C, Type *DestTy) const { 256 return CastInst::CreatePointerCast(C, DestTy); 257 } 258 CreateIntCast(Constant * C,Type * DestTy,bool isSigned)259 Instruction *CreateIntCast(Constant *C, Type *DestTy, 260 bool isSigned) const { 261 return CastInst::CreateIntegerCast(C, DestTy, isSigned); 262 } 263 CreateFPCast(Constant * C,Type * DestTy)264 Instruction *CreateFPCast(Constant *C, Type *DestTy) const { 265 return CastInst::CreateFPCast(C, DestTy); 266 } 267 CreateBitCast(Constant * C,Type * DestTy)268 Instruction *CreateBitCast(Constant *C, Type *DestTy) const { 269 return CreateCast(Instruction::BitCast, C, DestTy); 270 } 271 CreateIntToPtr(Constant * C,Type * DestTy)272 Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const { 273 return CreateCast(Instruction::IntToPtr, C, DestTy); 274 } 275 CreatePtrToInt(Constant * C,Type * DestTy)276 Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const { 277 return CreateCast(Instruction::PtrToInt, C, DestTy); 278 } 279 CreateZExtOrBitCast(Constant * C,Type * DestTy)280 Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { 281 return CastInst::CreateZExtOrBitCast(C, DestTy); 282 } 283 CreateSExtOrBitCast(Constant * C,Type * DestTy)284 Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { 285 return CastInst::CreateSExtOrBitCast(C, DestTy); 286 } 287 CreateTruncOrBitCast(Constant * C,Type * DestTy)288 Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { 289 return CastInst::CreateTruncOrBitCast(C, DestTy); 290 } 291 292 //===--------------------------------------------------------------------===// 293 // Compare Instructions 294 //===--------------------------------------------------------------------===// 295 CreateICmp(CmpInst::Predicate P,Constant * LHS,Constant * RHS)296 Instruction *CreateICmp(CmpInst::Predicate P, 297 Constant *LHS, Constant *RHS) const { 298 return new ICmpInst(P, LHS, RHS); 299 } 300 CreateFCmp(CmpInst::Predicate P,Constant * LHS,Constant * RHS)301 Instruction *CreateFCmp(CmpInst::Predicate P, 302 Constant *LHS, Constant *RHS) const { 303 return new FCmpInst(P, LHS, RHS); 304 } 305 306 //===--------------------------------------------------------------------===// 307 // Other Instructions 308 //===--------------------------------------------------------------------===// 309 CreateSelect(Constant * C,Constant * True,Constant * False)310 Instruction *CreateSelect(Constant *C, 311 Constant *True, Constant *False) const { 312 return SelectInst::Create(C, True, False); 313 } 314 CreateExtractElement(Constant * Vec,Constant * Idx)315 Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const { 316 return ExtractElementInst::Create(Vec, Idx); 317 } 318 CreateInsertElement(Constant * Vec,Constant * NewElt,Constant * Idx)319 Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt, 320 Constant *Idx) const { 321 return InsertElementInst::Create(Vec, NewElt, Idx); 322 } 323 CreateShuffleVector(Constant * V1,Constant * V2,Constant * Mask)324 Instruction *CreateShuffleVector(Constant *V1, Constant *V2, 325 Constant *Mask) const { 326 return new ShuffleVectorInst(V1, V2, Mask); 327 } 328 CreateExtractValue(Constant * Agg,ArrayRef<unsigned> IdxList)329 Instruction *CreateExtractValue(Constant *Agg, 330 ArrayRef<unsigned> IdxList) const { 331 return ExtractValueInst::Create(Agg, IdxList); 332 } 333 CreateInsertValue(Constant * Agg,Constant * Val,ArrayRef<unsigned> IdxList)334 Instruction *CreateInsertValue(Constant *Agg, Constant *Val, 335 ArrayRef<unsigned> IdxList) const { 336 return InsertValueInst::Create(Agg, Val, IdxList); 337 } 338 }; 339 340 } // end namespace llvm 341 342 #endif // LLVM_IR_NOFOLDER_H 343