LLVM API Documentation
00001 //====- TargetFolder.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 TargetFolder class, a helper for IRBuilder. 00011 // It provides IRBuilder with a set of methods for creating constants with 00012 // target dependent folding, in addition to the same target-independent 00013 // folding that the ConstantFolder class provides. For general constant 00014 // creation and folding, use ConstantExpr and the routines in 00015 // llvm/Analysis/ConstantFolding.h. 00016 // 00017 //===----------------------------------------------------------------------===// 00018 00019 #ifndef LLVM_ANALYSIS_TARGETFOLDER_H 00020 #define LLVM_ANALYSIS_TARGETFOLDER_H 00021 00022 #include "llvm/ADT/ArrayRef.h" 00023 #include "llvm/Analysis/ConstantFolding.h" 00024 #include "llvm/IR/Constants.h" 00025 #include "llvm/IR/InstrTypes.h" 00026 00027 namespace llvm { 00028 00029 class DataLayout; 00030 00031 /// TargetFolder - Create constants with target dependent folding. 00032 class TargetFolder { 00033 const DataLayout *DL; 00034 00035 /// Fold - Fold the constant using target specific information. 00036 Constant *Fold(Constant *C) const { 00037 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) 00038 if (Constant *CF = ConstantFoldConstantExpression(CE, DL)) 00039 return CF; 00040 return C; 00041 } 00042 00043 public: 00044 explicit TargetFolder(const DataLayout *DL) : DL(DL) {} 00045 00046 //===--------------------------------------------------------------------===// 00047 // Binary Operators 00048 //===--------------------------------------------------------------------===// 00049 00050 Constant *CreateAdd(Constant *LHS, Constant *RHS, 00051 bool HasNUW = false, bool HasNSW = false) const { 00052 return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW)); 00053 } 00054 Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { 00055 return Fold(ConstantExpr::getFAdd(LHS, RHS)); 00056 } 00057 Constant *CreateSub(Constant *LHS, Constant *RHS, 00058 bool HasNUW = false, bool HasNSW = false) const { 00059 return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW)); 00060 } 00061 Constant *CreateFSub(Constant *LHS, Constant *RHS) const { 00062 return Fold(ConstantExpr::getFSub(LHS, RHS)); 00063 } 00064 Constant *CreateMul(Constant *LHS, Constant *RHS, 00065 bool HasNUW = false, bool HasNSW = false) const { 00066 return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW)); 00067 } 00068 Constant *CreateFMul(Constant *LHS, Constant *RHS) const { 00069 return Fold(ConstantExpr::getFMul(LHS, RHS)); 00070 } 00071 Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ 00072 return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact)); 00073 } 00074 Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ 00075 return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact)); 00076 } 00077 Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { 00078 return Fold(ConstantExpr::getFDiv(LHS, RHS)); 00079 } 00080 Constant *CreateURem(Constant *LHS, Constant *RHS) const { 00081 return Fold(ConstantExpr::getURem(LHS, RHS)); 00082 } 00083 Constant *CreateSRem(Constant *LHS, Constant *RHS) const { 00084 return Fold(ConstantExpr::getSRem(LHS, RHS)); 00085 } 00086 Constant *CreateFRem(Constant *LHS, Constant *RHS) const { 00087 return Fold(ConstantExpr::getFRem(LHS, RHS)); 00088 } 00089 Constant *CreateShl(Constant *LHS, Constant *RHS, 00090 bool HasNUW = false, bool HasNSW = false) const { 00091 return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW)); 00092 } 00093 Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{ 00094 return Fold(ConstantExpr::getLShr(LHS, RHS, isExact)); 00095 } 00096 Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{ 00097 return Fold(ConstantExpr::getAShr(LHS, RHS, isExact)); 00098 } 00099 Constant *CreateAnd(Constant *LHS, Constant *RHS) const { 00100 return Fold(ConstantExpr::getAnd(LHS, RHS)); 00101 } 00102 Constant *CreateOr(Constant *LHS, Constant *RHS) const { 00103 return Fold(ConstantExpr::getOr(LHS, RHS)); 00104 } 00105 Constant *CreateXor(Constant *LHS, Constant *RHS) const { 00106 return Fold(ConstantExpr::getXor(LHS, RHS)); 00107 } 00108 00109 Constant *CreateBinOp(Instruction::BinaryOps Opc, 00110 Constant *LHS, Constant *RHS) const { 00111 return Fold(ConstantExpr::get(Opc, LHS, RHS)); 00112 } 00113 00114 //===--------------------------------------------------------------------===// 00115 // Unary Operators 00116 //===--------------------------------------------------------------------===// 00117 00118 Constant *CreateNeg(Constant *C, 00119 bool HasNUW = false, bool HasNSW = false) const { 00120 return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW)); 00121 } 00122 Constant *CreateFNeg(Constant *C) const { 00123 return Fold(ConstantExpr::getFNeg(C)); 00124 } 00125 Constant *CreateNot(Constant *C) const { 00126 return Fold(ConstantExpr::getNot(C)); 00127 } 00128 00129 //===--------------------------------------------------------------------===// 00130 // Memory Instructions 00131 //===--------------------------------------------------------------------===// 00132 00133 Constant *CreateGetElementPtr(Constant *C, 00134 ArrayRef<Constant *> IdxList) const { 00135 return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); 00136 } 00137 Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { 00138 // This form of the function only exists to avoid ambiguous overload 00139 // warnings about whether to convert Idx to ArrayRef<Constant *> or 00140 // ArrayRef<Value *>. 00141 return Fold(ConstantExpr::getGetElementPtr(C, Idx)); 00142 } 00143 Constant *CreateGetElementPtr(Constant *C, 00144 ArrayRef<Value *> IdxList) const { 00145 return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); 00146 } 00147 00148 Constant *CreateInBoundsGetElementPtr(Constant *C, 00149 ArrayRef<Constant *> IdxList) const { 00150 return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); 00151 } 00152 Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { 00153 // This form of the function only exists to avoid ambiguous overload 00154 // warnings about whether to convert Idx to ArrayRef<Constant *> or 00155 // ArrayRef<Value *>. 00156 return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx)); 00157 } 00158 Constant *CreateInBoundsGetElementPtr(Constant *C, 00159 ArrayRef<Value *> IdxList) const { 00160 return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); 00161 } 00162 00163 //===--------------------------------------------------------------------===// 00164 // Cast/Conversion Operators 00165 //===--------------------------------------------------------------------===// 00166 00167 Constant *CreateCast(Instruction::CastOps Op, Constant *C, 00168 Type *DestTy) const { 00169 if (C->getType() == DestTy) 00170 return C; // avoid calling Fold 00171 return Fold(ConstantExpr::getCast(Op, C, DestTy)); 00172 } 00173 Constant *CreateIntCast(Constant *C, Type *DestTy, 00174 bool isSigned) const { 00175 if (C->getType() == DestTy) 00176 return C; // avoid calling Fold 00177 return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned)); 00178 } 00179 Constant *CreatePointerCast(Constant *C, Type *DestTy) const { 00180 if (C->getType() == DestTy) 00181 return C; // avoid calling Fold 00182 return Fold(ConstantExpr::getPointerCast(C, DestTy)); 00183 } 00184 Constant *CreateFPCast(Constant *C, Type *DestTy) const { 00185 if (C->getType() == DestTy) 00186 return C; // avoid calling Fold 00187 return Fold(ConstantExpr::getFPCast(C, DestTy)); 00188 } 00189 Constant *CreateBitCast(Constant *C, Type *DestTy) const { 00190 return CreateCast(Instruction::BitCast, C, DestTy); 00191 } 00192 Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { 00193 return CreateCast(Instruction::IntToPtr, C, DestTy); 00194 } 00195 Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { 00196 return CreateCast(Instruction::PtrToInt, C, DestTy); 00197 } 00198 Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { 00199 if (C->getType() == DestTy) 00200 return C; // avoid calling Fold 00201 return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy)); 00202 } 00203 Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { 00204 if (C->getType() == DestTy) 00205 return C; // avoid calling Fold 00206 return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy)); 00207 } 00208 Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { 00209 if (C->getType() == DestTy) 00210 return C; // avoid calling Fold 00211 return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy)); 00212 } 00213 00214 Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C, 00215 Type *DestTy) const { 00216 if (C->getType() == DestTy) 00217 return C; // avoid calling Fold 00218 return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy)); 00219 } 00220 00221 //===--------------------------------------------------------------------===// 00222 // Compare Instructions 00223 //===--------------------------------------------------------------------===// 00224 00225 Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS, 00226 Constant *RHS) const { 00227 return Fold(ConstantExpr::getCompare(P, LHS, RHS)); 00228 } 00229 Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS, 00230 Constant *RHS) const { 00231 return Fold(ConstantExpr::getCompare(P, LHS, RHS)); 00232 } 00233 00234 //===--------------------------------------------------------------------===// 00235 // Other Instructions 00236 //===--------------------------------------------------------------------===// 00237 00238 Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const { 00239 return Fold(ConstantExpr::getSelect(C, True, False)); 00240 } 00241 00242 Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const { 00243 return Fold(ConstantExpr::getExtractElement(Vec, Idx)); 00244 } 00245 00246 Constant *CreateInsertElement(Constant *Vec, Constant *NewElt, 00247 Constant *Idx) const { 00248 return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx)); 00249 } 00250 00251 Constant *CreateShuffleVector(Constant *V1, Constant *V2, 00252 Constant *Mask) const { 00253 return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask)); 00254 } 00255 00256 Constant *CreateExtractValue(Constant *Agg, 00257 ArrayRef<unsigned> IdxList) const { 00258 return Fold(ConstantExpr::getExtractValue(Agg, IdxList)); 00259 } 00260 00261 Constant *CreateInsertValue(Constant *Agg, Constant *Val, 00262 ArrayRef<unsigned> IdxList) const { 00263 return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList)); 00264 } 00265 }; 00266 00267 } 00268 00269 #endif