1193323Sed//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- C++ -*-====// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines the TargetFolder class, a helper for IRBuilder. 11193323Sed// It provides IRBuilder with a set of methods for creating constants with 12193378Sed// target dependent folding, in addition to the same target-independent 13193378Sed// folding that the ConstantFolder class provides. For general constant 14193378Sed// creation and folding, use ConstantExpr and the routines in 15193378Sed// llvm/Analysis/ConstantFolding.h. 16193323Sed// 17193323Sed//===----------------------------------------------------------------------===// 18193323Sed 19193323Sed#ifndef LLVM_SUPPORT_TARGETFOLDER_H 20193323Sed#define LLVM_SUPPORT_TARGETFOLDER_H 21193323Sed 22224145Sdim#include "llvm/ADT/ArrayRef.h" 23193323Sed#include "llvm/Analysis/ConstantFolding.h" 24249423Sdim#include "llvm/IR/Constants.h" 25249423Sdim#include "llvm/IR/InstrTypes.h" 26193323Sed 27193323Sednamespace llvm { 28193323Sed 29243830Sdimclass DataLayout; 30193323Sed 31193323Sed/// TargetFolder - Create constants with target dependent folding. 32193323Sedclass TargetFolder { 33243830Sdim const DataLayout *TD; 34193323Sed 35193323Sed /// Fold - Fold the constant using target specific information. 36193323Sed Constant *Fold(Constant *C) const { 37193323Sed if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) 38199481Srdivacky if (Constant *CF = ConstantFoldConstantExpression(CE, TD)) 39193323Sed return CF; 40193323Sed return C; 41193323Sed } 42193323Sed 43193323Sedpublic: 44243830Sdim explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {} 45193323Sed 46193323Sed //===--------------------------------------------------------------------===// 47193323Sed // Binary Operators 48193323Sed //===--------------------------------------------------------------------===// 49193323Sed 50218893Sdim Constant *CreateAdd(Constant *LHS, Constant *RHS, 51218893Sdim bool HasNUW = false, bool HasNSW = false) const { 52218893Sdim return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW)); 53193323Sed } 54193574Sed Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { 55193574Sed return Fold(ConstantExpr::getFAdd(LHS, RHS)); 56193574Sed } 57218893Sdim Constant *CreateSub(Constant *LHS, Constant *RHS, 58218893Sdim bool HasNUW = false, bool HasNSW = false) const { 59218893Sdim return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW)); 60193323Sed } 61193574Sed Constant *CreateFSub(Constant *LHS, Constant *RHS) const { 62193574Sed return Fold(ConstantExpr::getFSub(LHS, RHS)); 63193574Sed } 64218893Sdim Constant *CreateMul(Constant *LHS, Constant *RHS, 65218893Sdim bool HasNUW = false, bool HasNSW = false) const { 66218893Sdim return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW)); 67193323Sed } 68193574Sed Constant *CreateFMul(Constant *LHS, Constant *RHS) const { 69193574Sed return Fold(ConstantExpr::getFMul(LHS, RHS)); 70193574Sed } 71218893Sdim Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ 72218893Sdim return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact)); 73193323Sed } 74218893Sdim Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ 75218893Sdim return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact)); 76193323Sed } 77193323Sed Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { 78193323Sed return Fold(ConstantExpr::getFDiv(LHS, RHS)); 79193323Sed } 80193323Sed Constant *CreateURem(Constant *LHS, Constant *RHS) const { 81193323Sed return Fold(ConstantExpr::getURem(LHS, RHS)); 82193323Sed } 83193323Sed Constant *CreateSRem(Constant *LHS, Constant *RHS) const { 84193323Sed return Fold(ConstantExpr::getSRem(LHS, RHS)); 85193323Sed } 86193323Sed Constant *CreateFRem(Constant *LHS, Constant *RHS) const { 87193323Sed return Fold(ConstantExpr::getFRem(LHS, RHS)); 88193323Sed } 89218893Sdim Constant *CreateShl(Constant *LHS, Constant *RHS, 90218893Sdim bool HasNUW = false, bool HasNSW = false) const { 91218893Sdim return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW)); 92193323Sed } 93218893Sdim Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{ 94218893Sdim return Fold(ConstantExpr::getLShr(LHS, RHS, isExact)); 95193323Sed } 96218893Sdim Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{ 97218893Sdim return Fold(ConstantExpr::getAShr(LHS, RHS, isExact)); 98193323Sed } 99193323Sed Constant *CreateAnd(Constant *LHS, Constant *RHS) const { 100193323Sed return Fold(ConstantExpr::getAnd(LHS, RHS)); 101193323Sed } 102193323Sed Constant *CreateOr(Constant *LHS, Constant *RHS) const { 103193323Sed return Fold(ConstantExpr::getOr(LHS, RHS)); 104193323Sed } 105193323Sed Constant *CreateXor(Constant *LHS, Constant *RHS) const { 106193323Sed return Fold(ConstantExpr::getXor(LHS, RHS)); 107193323Sed } 108193323Sed 109193323Sed Constant *CreateBinOp(Instruction::BinaryOps Opc, 110193323Sed Constant *LHS, Constant *RHS) const { 111193323Sed return Fold(ConstantExpr::get(Opc, LHS, RHS)); 112193323Sed } 113193323Sed 114193323Sed //===--------------------------------------------------------------------===// 115193323Sed // Unary Operators 116193323Sed //===--------------------------------------------------------------------===// 117193323Sed 118218893Sdim Constant *CreateNeg(Constant *C, 119218893Sdim bool HasNUW = false, bool HasNSW = false) const { 120218893Sdim return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW)); 121193323Sed } 122193574Sed Constant *CreateFNeg(Constant *C) const { 123193574Sed return Fold(ConstantExpr::getFNeg(C)); 124193574Sed } 125193323Sed Constant *CreateNot(Constant *C) const { 126193323Sed return Fold(ConstantExpr::getNot(C)); 127193323Sed } 128193323Sed 129193323Sed //===--------------------------------------------------------------------===// 130193323Sed // Memory Instructions 131193323Sed //===--------------------------------------------------------------------===// 132193323Sed 133226633Sdim Constant *CreateGetElementPtr(Constant *C, 134226633Sdim ArrayRef<Constant *> IdxList) const { 135226633Sdim return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); 136193323Sed } 137226633Sdim Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { 138226633Sdim // This form of the function only exists to avoid ambiguous overload 139226633Sdim // warnings about whether to convert Idx to ArrayRef<Constant *> or 140226633Sdim // ArrayRef<Value *>. 141226633Sdim return Fold(ConstantExpr::getGetElementPtr(C, Idx)); 142193323Sed } 143226633Sdim Constant *CreateGetElementPtr(Constant *C, 144226633Sdim ArrayRef<Value *> IdxList) const { 145226633Sdim return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); 146226633Sdim } 147193323Sed 148226633Sdim Constant *CreateInBoundsGetElementPtr(Constant *C, 149226633Sdim ArrayRef<Constant *> IdxList) const { 150226633Sdim return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); 151198090Srdivacky } 152226633Sdim Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { 153226633Sdim // This form of the function only exists to avoid ambiguous overload 154226633Sdim // warnings about whether to convert Idx to ArrayRef<Constant *> or 155226633Sdim // ArrayRef<Value *>. 156226633Sdim return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx)); 157198090Srdivacky } 158226633Sdim Constant *CreateInBoundsGetElementPtr(Constant *C, 159226633Sdim ArrayRef<Value *> IdxList) const { 160226633Sdim return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); 161226633Sdim } 162198090Srdivacky 163193323Sed //===--------------------------------------------------------------------===// 164193323Sed // Cast/Conversion Operators 165193323Sed //===--------------------------------------------------------------------===// 166193323Sed 167193323Sed Constant *CreateCast(Instruction::CastOps Op, Constant *C, 168226633Sdim Type *DestTy) const { 169193323Sed if (C->getType() == DestTy) 170193323Sed return C; // avoid calling Fold 171193323Sed return Fold(ConstantExpr::getCast(Op, C, DestTy)); 172193323Sed } 173226633Sdim Constant *CreateIntCast(Constant *C, Type *DestTy, 174193323Sed bool isSigned) const { 175193323Sed if (C->getType() == DestTy) 176193323Sed return C; // avoid calling Fold 177193323Sed return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned)); 178193323Sed } 179226633Sdim Constant *CreatePointerCast(Constant *C, Type *DestTy) const { 180243830Sdim if (C->getType() == DestTy) 181243830Sdim return C; // avoid calling Fold 182243830Sdim return Fold(ConstantExpr::getPointerCast(C, DestTy)); 183204642Srdivacky } 184243830Sdim Constant *CreateFPCast(Constant *C, Type *DestTy) const { 185243830Sdim if (C->getType() == DestTy) 186243830Sdim return C; // avoid calling Fold 187243830Sdim return Fold(ConstantExpr::getFPCast(C, DestTy)); 188243830Sdim } 189226633Sdim Constant *CreateBitCast(Constant *C, Type *DestTy) const { 190193323Sed return CreateCast(Instruction::BitCast, C, DestTy); 191193323Sed } 192226633Sdim Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { 193193323Sed return CreateCast(Instruction::IntToPtr, C, DestTy); 194193323Sed } 195226633Sdim Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { 196193323Sed return CreateCast(Instruction::PtrToInt, C, DestTy); 197193323Sed } 198226633Sdim Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { 199198892Srdivacky if (C->getType() == DestTy) 200198892Srdivacky return C; // avoid calling Fold 201198892Srdivacky return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy)); 202198892Srdivacky } 203226633Sdim Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { 204198892Srdivacky if (C->getType() == DestTy) 205198892Srdivacky return C; // avoid calling Fold 206198892Srdivacky return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy)); 207198892Srdivacky } 208226633Sdim Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { 209193323Sed if (C->getType() == DestTy) 210193323Sed return C; // avoid calling Fold 211193323Sed return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy)); 212193323Sed } 213193323Sed 214193323Sed //===--------------------------------------------------------------------===// 215193323Sed // Compare Instructions 216193323Sed //===--------------------------------------------------------------------===// 217193323Sed 218193323Sed Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS, 219193323Sed Constant *RHS) const { 220193323Sed return Fold(ConstantExpr::getCompare(P, LHS, RHS)); 221193323Sed } 222193323Sed Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS, 223193323Sed Constant *RHS) const { 224193323Sed return Fold(ConstantExpr::getCompare(P, LHS, RHS)); 225193323Sed } 226193323Sed 227193323Sed //===--------------------------------------------------------------------===// 228193323Sed // Other Instructions 229193323Sed //===--------------------------------------------------------------------===// 230193323Sed 231193323Sed Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const { 232193323Sed return Fold(ConstantExpr::getSelect(C, True, False)); 233193323Sed } 234193323Sed 235193323Sed Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const { 236193323Sed return Fold(ConstantExpr::getExtractElement(Vec, Idx)); 237193323Sed } 238193323Sed 239193323Sed Constant *CreateInsertElement(Constant *Vec, Constant *NewElt, 240193323Sed Constant *Idx) const { 241193323Sed return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx)); 242193323Sed } 243193323Sed 244193323Sed Constant *CreateShuffleVector(Constant *V1, Constant *V2, 245193323Sed Constant *Mask) const { 246193323Sed return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask)); 247193323Sed } 248193323Sed 249224145Sdim Constant *CreateExtractValue(Constant *Agg, 250224145Sdim ArrayRef<unsigned> IdxList) const { 251224145Sdim return Fold(ConstantExpr::getExtractValue(Agg, IdxList)); 252193323Sed } 253193323Sed 254193323Sed Constant *CreateInsertValue(Constant *Agg, Constant *Val, 255224145Sdim ArrayRef<unsigned> IdxList) const { 256224145Sdim return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList)); 257193323Sed } 258193323Sed}; 259193323Sed 260193323Sed} 261193323Sed 262193323Sed#endif 263