NoFolder.h revision c9cc9e7d29b8970d8ddb734c88fb62d01e0b7279
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 31namespace llvm { 32 33/// NoFolder - Create "constants" (actually, instructions) with no folding. 34class NoFolder { 35public: 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 50 Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const { 51 return BinaryOperator::CreateNSWAdd(LHS, RHS); 52 } 53 54 Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const { 55 return BinaryOperator::CreateNUWAdd(LHS, RHS); 56 } 57 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 70 Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const { 71 return BinaryOperator::CreateNSWSub(LHS, RHS); 72 } 73 74 Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const { 75 return BinaryOperator::CreateNUWSub(LHS, RHS); 76 } 77 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 90 Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const { 91 return BinaryOperator::CreateNSWMul(LHS, RHS); 92 } 93 94 Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const { 95 return BinaryOperator::CreateNUWMul(LHS, RHS); 96 } 97 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 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 120 Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const { 121 return BinaryOperator::CreateExactSDiv(LHS, RHS); 122 } 123 124 Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const { 125 return BinaryOperator::CreateFDiv(LHS, RHS); 126 } 127 128 Instruction *CreateURem(Constant *LHS, Constant *RHS) const { 129 return BinaryOperator::CreateURem(LHS, RHS); 130 } 131 132 Instruction *CreateSRem(Constant *LHS, Constant *RHS) const { 133 return BinaryOperator::CreateSRem(LHS, RHS); 134 } 135 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 162 Instruction *CreateAnd(Constant *LHS, Constant *RHS) const { 163 return BinaryOperator::CreateAnd(LHS, RHS); 164 } 165 166 Instruction *CreateOr(Constant *LHS, Constant *RHS) const { 167 return BinaryOperator::CreateOr(LHS, RHS); 168 } 169 170 Instruction *CreateXor(Constant *LHS, Constant *RHS) const { 171 return BinaryOperator::CreateXor(LHS, RHS); 172 } 173 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 191 Instruction *CreateNSWNeg(Constant *C) const { 192 return BinaryOperator::CreateNSWNeg(C); 193 } 194 195 Instruction *CreateNUWNeg(Constant *C) const { 196 return BinaryOperator::CreateNUWNeg(C); 197 } 198 199 Instruction *CreateFNeg(Constant *C) const { 200 return BinaryOperator::CreateFNeg(C); 201 } 202 203 Instruction *CreateNot(Constant *C) const { 204 return BinaryOperator::CreateNot(C); 205 } 206 207 //===--------------------------------------------------------------------===// 208 // Memory Instructions 209 //===--------------------------------------------------------------------===// 210 211 Constant *CreateGetElementPtr(Type *Ty, Constant *C, 212 ArrayRef<Constant *> IdxList) const { 213 return ConstantExpr::getGetElementPtr(Ty, C, IdxList); 214 } 215 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 223 Instruction *CreateGetElementPtr(Type *Ty, Constant *C, 224 ArrayRef<Value *> IdxList) const { 225 return GetElementPtrInst::Create(Ty, C, IdxList); 226 } 227 228 Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, 229 ArrayRef<Constant *> IdxList) const { 230 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList); 231 } 232 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 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 250 Instruction *CreateCast(Instruction::CastOps Op, Constant *C, 251 Type *DestTy) const { 252 return CastInst::Create(Op, C, DestTy); 253 } 254 255 Instruction *CreatePointerCast(Constant *C, Type *DestTy) const { 256 return CastInst::CreatePointerCast(C, DestTy); 257 } 258 259 Instruction *CreateIntCast(Constant *C, Type *DestTy, 260 bool isSigned) const { 261 return CastInst::CreateIntegerCast(C, DestTy, isSigned); 262 } 263 264 Instruction *CreateFPCast(Constant *C, Type *DestTy) const { 265 return CastInst::CreateFPCast(C, DestTy); 266 } 267 268 Instruction *CreateBitCast(Constant *C, Type *DestTy) const { 269 return CreateCast(Instruction::BitCast, C, DestTy); 270 } 271 272 Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const { 273 return CreateCast(Instruction::IntToPtr, C, DestTy); 274 } 275 276 Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const { 277 return CreateCast(Instruction::PtrToInt, C, DestTy); 278 } 279 280 Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { 281 return CastInst::CreateZExtOrBitCast(C, DestTy); 282 } 283 284 Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { 285 return CastInst::CreateSExtOrBitCast(C, DestTy); 286 } 287 288 Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { 289 return CastInst::CreateTruncOrBitCast(C, DestTy); 290 } 291 292 //===--------------------------------------------------------------------===// 293 // Compare Instructions 294 //===--------------------------------------------------------------------===// 295 296 Instruction *CreateICmp(CmpInst::Predicate P, 297 Constant *LHS, Constant *RHS) const { 298 return new ICmpInst(P, LHS, RHS); 299 } 300 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 310 Instruction *CreateSelect(Constant *C, 311 Constant *True, Constant *False) const { 312 return SelectInst::Create(C, True, False); 313 } 314 315 Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const { 316 return ExtractElementInst::Create(Vec, Idx); 317 } 318 319 Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt, 320 Constant *Idx) const { 321 return InsertElementInst::Create(Vec, NewElt, Idx); 322 } 323 324 Instruction *CreateShuffleVector(Constant *V1, Constant *V2, 325 Constant *Mask) const { 326 return new ShuffleVectorInst(V1, V2, Mask); 327 } 328 329 Instruction *CreateExtractValue(Constant *Agg, 330 ArrayRef<unsigned> IdxList) const { 331 return ExtractValueInst::Create(Agg, IdxList); 332 } 333 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