LLVM API Documentation
00001 //===- NoFolder.h - Constant folding helper ---------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the NoFolder class, a helper for IRBuilder. It provides 00011 // IRBuilder with a set of methods for creating unfolded constants. This is 00012 // useful for learners trying to understand how LLVM IR works, and who don't 00013 // want details to be hidden by the constant folder. For general constant 00014 // creation and folding, use ConstantExpr and the routines in 00015 // llvm/Analysis/ConstantFolding.h. 00016 // 00017 // Note: since it is not actually possible to create unfolded constants, this 00018 // class returns instructions rather than constants. 00019 // 00020 //===----------------------------------------------------------------------===// 00021 00022 #ifndef LLVM_IR_NOFOLDER_H 00023 #define LLVM_IR_NOFOLDER_H 00024 00025 #include "llvm/ADT/ArrayRef.h" 00026 #include "llvm/IR/Constants.h" 00027 #include "llvm/IR/Instructions.h" 00028 00029 namespace llvm { 00030 00031 /// NoFolder - Create "constants" (actually, instructions) with no folding. 00032 class NoFolder { 00033 public: 00034 explicit NoFolder() {} 00035 00036 //===--------------------------------------------------------------------===// 00037 // Binary Operators 00038 //===--------------------------------------------------------------------===// 00039 00040 Instruction *CreateAdd(Constant *LHS, Constant *RHS, 00041 bool HasNUW = false, bool HasNSW = false) const { 00042 BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS); 00043 if (HasNUW) BO->setHasNoUnsignedWrap(); 00044 if (HasNSW) BO->setHasNoSignedWrap(); 00045 return BO; 00046 } 00047 Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const { 00048 return BinaryOperator::CreateNSWAdd(LHS, RHS); 00049 } 00050 Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const { 00051 return BinaryOperator::CreateNUWAdd(LHS, RHS); 00052 } 00053 Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const { 00054 return BinaryOperator::CreateFAdd(LHS, RHS); 00055 } 00056 Instruction *CreateSub(Constant *LHS, Constant *RHS, 00057 bool HasNUW = false, bool HasNSW = false) const { 00058 BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS); 00059 if (HasNUW) BO->setHasNoUnsignedWrap(); 00060 if (HasNSW) BO->setHasNoSignedWrap(); 00061 return BO; 00062 } 00063 Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const { 00064 return BinaryOperator::CreateNSWSub(LHS, RHS); 00065 } 00066 Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const { 00067 return BinaryOperator::CreateNUWSub(LHS, RHS); 00068 } 00069 Instruction *CreateFSub(Constant *LHS, Constant *RHS) const { 00070 return BinaryOperator::CreateFSub(LHS, RHS); 00071 } 00072 Instruction *CreateMul(Constant *LHS, Constant *RHS, 00073 bool HasNUW = false, bool HasNSW = false) const { 00074 BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS); 00075 if (HasNUW) BO->setHasNoUnsignedWrap(); 00076 if (HasNSW) BO->setHasNoSignedWrap(); 00077 return BO; 00078 } 00079 Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const { 00080 return BinaryOperator::CreateNSWMul(LHS, RHS); 00081 } 00082 Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const { 00083 return BinaryOperator::CreateNUWMul(LHS, RHS); 00084 } 00085 Instruction *CreateFMul(Constant *LHS, Constant *RHS) const { 00086 return BinaryOperator::CreateFMul(LHS, RHS); 00087 } 00088 Instruction *CreateUDiv(Constant *LHS, Constant *RHS, 00089 bool isExact = false) const { 00090 if (!isExact) 00091 return BinaryOperator::CreateUDiv(LHS, RHS); 00092 return BinaryOperator::CreateExactUDiv(LHS, RHS); 00093 } 00094 Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const { 00095 return BinaryOperator::CreateExactUDiv(LHS, RHS); 00096 } 00097 Instruction *CreateSDiv(Constant *LHS, Constant *RHS, 00098 bool isExact = false) const { 00099 if (!isExact) 00100 return BinaryOperator::CreateSDiv(LHS, RHS); 00101 return BinaryOperator::CreateExactSDiv(LHS, RHS); 00102 } 00103 Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const { 00104 return BinaryOperator::CreateExactSDiv(LHS, RHS); 00105 } 00106 Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const { 00107 return BinaryOperator::CreateFDiv(LHS, RHS); 00108 } 00109 Instruction *CreateURem(Constant *LHS, Constant *RHS) const { 00110 return BinaryOperator::CreateURem(LHS, RHS); 00111 } 00112 Instruction *CreateSRem(Constant *LHS, Constant *RHS) const { 00113 return BinaryOperator::CreateSRem(LHS, RHS); 00114 } 00115 Instruction *CreateFRem(Constant *LHS, Constant *RHS) const { 00116 return BinaryOperator::CreateFRem(LHS, RHS); 00117 } 00118 Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false, 00119 bool HasNSW = false) const { 00120 BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS); 00121 if (HasNUW) BO->setHasNoUnsignedWrap(); 00122 if (HasNSW) BO->setHasNoSignedWrap(); 00123 return BO; 00124 } 00125 Instruction *CreateLShr(Constant *LHS, Constant *RHS, 00126 bool isExact = false) const { 00127 if (!isExact) 00128 return BinaryOperator::CreateLShr(LHS, RHS); 00129 return BinaryOperator::CreateExactLShr(LHS, RHS); 00130 } 00131 Instruction *CreateAShr(Constant *LHS, Constant *RHS, 00132 bool isExact = false) const { 00133 if (!isExact) 00134 return BinaryOperator::CreateAShr(LHS, RHS); 00135 return BinaryOperator::CreateExactAShr(LHS, RHS); 00136 } 00137 Instruction *CreateAnd(Constant *LHS, Constant *RHS) const { 00138 return BinaryOperator::CreateAnd(LHS, RHS); 00139 } 00140 Instruction *CreateOr(Constant *LHS, Constant *RHS) const { 00141 return BinaryOperator::CreateOr(LHS, RHS); 00142 } 00143 Instruction *CreateXor(Constant *LHS, Constant *RHS) const { 00144 return BinaryOperator::CreateXor(LHS, RHS); 00145 } 00146 00147 Instruction *CreateBinOp(Instruction::BinaryOps Opc, 00148 Constant *LHS, Constant *RHS) const { 00149 return BinaryOperator::Create(Opc, LHS, RHS); 00150 } 00151 00152 //===--------------------------------------------------------------------===// 00153 // Unary Operators 00154 //===--------------------------------------------------------------------===// 00155 00156 Instruction *CreateNeg(Constant *C, 00157 bool HasNUW = false, bool HasNSW = false) const { 00158 BinaryOperator *BO = BinaryOperator::CreateNeg(C); 00159 if (HasNUW) BO->setHasNoUnsignedWrap(); 00160 if (HasNSW) BO->setHasNoSignedWrap(); 00161 return BO; 00162 } 00163 Instruction *CreateNSWNeg(Constant *C) const { 00164 return BinaryOperator::CreateNSWNeg(C); 00165 } 00166 Instruction *CreateNUWNeg(Constant *C) const { 00167 return BinaryOperator::CreateNUWNeg(C); 00168 } 00169 Instruction *CreateFNeg(Constant *C) const { 00170 return BinaryOperator::CreateFNeg(C); 00171 } 00172 Instruction *CreateNot(Constant *C) const { 00173 return BinaryOperator::CreateNot(C); 00174 } 00175 00176 //===--------------------------------------------------------------------===// 00177 // Memory Instructions 00178 //===--------------------------------------------------------------------===// 00179 00180 Constant *CreateGetElementPtr(Constant *C, 00181 ArrayRef<Constant *> IdxList) const { 00182 return ConstantExpr::getGetElementPtr(C, IdxList); 00183 } 00184 Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { 00185 // This form of the function only exists to avoid ambiguous overload 00186 // warnings about whether to convert Idx to ArrayRef<Constant *> or 00187 // ArrayRef<Value *>. 00188 return ConstantExpr::getGetElementPtr(C, Idx); 00189 } 00190 Instruction *CreateGetElementPtr(Constant *C, 00191 ArrayRef<Value *> IdxList) const { 00192 return GetElementPtrInst::Create(C, IdxList); 00193 } 00194 00195 Constant *CreateInBoundsGetElementPtr(Constant *C, 00196 ArrayRef<Constant *> IdxList) const { 00197 return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); 00198 } 00199 Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { 00200 // This form of the function only exists to avoid ambiguous overload 00201 // warnings about whether to convert Idx to ArrayRef<Constant *> or 00202 // ArrayRef<Value *>. 00203 return ConstantExpr::getInBoundsGetElementPtr(C, Idx); 00204 } 00205 Instruction *CreateInBoundsGetElementPtr(Constant *C, 00206 ArrayRef<Value *> IdxList) const { 00207 return GetElementPtrInst::CreateInBounds(C, IdxList); 00208 } 00209 00210 //===--------------------------------------------------------------------===// 00211 // Cast/Conversion Operators 00212 //===--------------------------------------------------------------------===// 00213 00214 Instruction *CreateCast(Instruction::CastOps Op, Constant *C, 00215 Type *DestTy) const { 00216 return CastInst::Create(Op, C, DestTy); 00217 } 00218 Instruction *CreatePointerCast(Constant *C, Type *DestTy) const { 00219 return CastInst::CreatePointerCast(C, DestTy); 00220 } 00221 Instruction *CreateIntCast(Constant *C, Type *DestTy, 00222 bool isSigned) const { 00223 return CastInst::CreateIntegerCast(C, DestTy, isSigned); 00224 } 00225 Instruction *CreateFPCast(Constant *C, Type *DestTy) const { 00226 return CastInst::CreateFPCast(C, DestTy); 00227 } 00228 00229 Instruction *CreateBitCast(Constant *C, Type *DestTy) const { 00230 return CreateCast(Instruction::BitCast, C, DestTy); 00231 } 00232 Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const { 00233 return CreateCast(Instruction::IntToPtr, C, DestTy); 00234 } 00235 Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const { 00236 return CreateCast(Instruction::PtrToInt, C, DestTy); 00237 } 00238 Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { 00239 return CastInst::CreateZExtOrBitCast(C, DestTy); 00240 } 00241 Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { 00242 return CastInst::CreateSExtOrBitCast(C, DestTy); 00243 } 00244 00245 Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { 00246 return CastInst::CreateTruncOrBitCast(C, DestTy); 00247 } 00248 00249 //===--------------------------------------------------------------------===// 00250 // Compare Instructions 00251 //===--------------------------------------------------------------------===// 00252 00253 Instruction *CreateICmp(CmpInst::Predicate P, 00254 Constant *LHS, Constant *RHS) const { 00255 return new ICmpInst(P, LHS, RHS); 00256 } 00257 Instruction *CreateFCmp(CmpInst::Predicate P, 00258 Constant *LHS, Constant *RHS) const { 00259 return new FCmpInst(P, LHS, RHS); 00260 } 00261 00262 //===--------------------------------------------------------------------===// 00263 // Other Instructions 00264 //===--------------------------------------------------------------------===// 00265 00266 Instruction *CreateSelect(Constant *C, 00267 Constant *True, Constant *False) const { 00268 return SelectInst::Create(C, True, False); 00269 } 00270 00271 Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const { 00272 return ExtractElementInst::Create(Vec, Idx); 00273 } 00274 00275 Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt, 00276 Constant *Idx) const { 00277 return InsertElementInst::Create(Vec, NewElt, Idx); 00278 } 00279 00280 Instruction *CreateShuffleVector(Constant *V1, Constant *V2, 00281 Constant *Mask) const { 00282 return new ShuffleVectorInst(V1, V2, Mask); 00283 } 00284 00285 Instruction *CreateExtractValue(Constant *Agg, 00286 ArrayRef<unsigned> IdxList) const { 00287 return ExtractValueInst::Create(Agg, IdxList); 00288 } 00289 00290 Instruction *CreateInsertValue(Constant *Agg, Constant *Val, 00291 ArrayRef<unsigned> IdxList) const { 00292 return InsertValueInst::Create(Agg, Val, IdxList); 00293 } 00294 }; 00295 00296 } 00297 00298 #endif