LLVM  mainline
TargetFolder.h
Go to the documentation of this file.
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(Type *Ty, Constant *C,
00134                                 ArrayRef<Constant *> IdxList) const {
00135     return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
00136   }
00137   Constant *CreateGetElementPtr(Type *Ty, 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(Ty, C, Idx));
00142   }
00143   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
00144                                 ArrayRef<Value *> IdxList) const {
00145     return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
00146   }
00147 
00148   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
00149                                         ArrayRef<Constant *> IdxList) const {
00150     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
00151   }
00152   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
00153                                         Constant *Idx) const {
00154     // This form of the function only exists to avoid ambiguous overload
00155     // warnings about whether to convert Idx to ArrayRef<Constant *> or
00156     // ArrayRef<Value *>.
00157     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
00158   }
00159   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
00160                                         ArrayRef<Value *> IdxList) const {
00161     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
00162   }
00163 
00164   //===--------------------------------------------------------------------===//
00165   // Cast/Conversion Operators
00166   //===--------------------------------------------------------------------===//
00167 
00168   Constant *CreateCast(Instruction::CastOps Op, Constant *C,
00169                        Type *DestTy) const {
00170     if (C->getType() == DestTy)
00171       return C; // avoid calling Fold
00172     return Fold(ConstantExpr::getCast(Op, C, DestTy));
00173   }
00174   Constant *CreateIntCast(Constant *C, Type *DestTy,
00175                           bool isSigned) const {
00176     if (C->getType() == DestTy)
00177       return C; // avoid calling Fold
00178     return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
00179   }
00180   Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
00181     if (C->getType() == DestTy)
00182       return C; // avoid calling Fold
00183     return Fold(ConstantExpr::getPointerCast(C, DestTy));
00184   }
00185   Constant *CreateFPCast(Constant *C, Type *DestTy) const {
00186     if (C->getType() == DestTy)
00187       return C; // avoid calling Fold
00188     return Fold(ConstantExpr::getFPCast(C, DestTy));
00189   }
00190   Constant *CreateBitCast(Constant *C, Type *DestTy) const {
00191     return CreateCast(Instruction::BitCast, C, DestTy);
00192   }
00193   Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
00194     return CreateCast(Instruction::IntToPtr, C, DestTy);
00195   }
00196   Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
00197     return CreateCast(Instruction::PtrToInt, C, DestTy);
00198   }
00199   Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
00200     if (C->getType() == DestTy)
00201       return C; // avoid calling Fold
00202     return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
00203   }
00204   Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
00205     if (C->getType() == DestTy)
00206       return C; // avoid calling Fold
00207     return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
00208   }
00209   Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
00210     if (C->getType() == DestTy)
00211       return C; // avoid calling Fold
00212     return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
00213   }
00214 
00215   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
00216                                                 Type *DestTy) const {
00217     if (C->getType() == DestTy)
00218       return C; // avoid calling Fold
00219     return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
00220   }
00221 
00222   //===--------------------------------------------------------------------===//
00223   // Compare Instructions
00224   //===--------------------------------------------------------------------===//
00225 
00226   Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
00227                        Constant *RHS) const {
00228     return Fold(ConstantExpr::getCompare(P, LHS, RHS));
00229   }
00230   Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
00231                        Constant *RHS) const {
00232     return Fold(ConstantExpr::getCompare(P, LHS, RHS));
00233   }
00234 
00235   //===--------------------------------------------------------------------===//
00236   // Other Instructions
00237   //===--------------------------------------------------------------------===//
00238 
00239   Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
00240     return Fold(ConstantExpr::getSelect(C, True, False));
00241   }
00242 
00243   Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
00244     return Fold(ConstantExpr::getExtractElement(Vec, Idx));
00245   }
00246 
00247   Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
00248                                 Constant *Idx) const {
00249     return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
00250   }
00251 
00252   Constant *CreateShuffleVector(Constant *V1, Constant *V2,
00253                                 Constant *Mask) const {
00254     return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
00255   }
00256 
00257   Constant *CreateExtractValue(Constant *Agg,
00258                                ArrayRef<unsigned> IdxList) const {
00259     return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
00260   }
00261 
00262   Constant *CreateInsertValue(Constant *Agg, Constant *Val,
00263                               ArrayRef<unsigned> IdxList) const {
00264     return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
00265   }
00266 };
00267 
00268 }
00269 
00270 #endif