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