LLVM API Documentation

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(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