ConstantFold.cpp revision 8b0f0cb9088a7746fea2ba23821e50d87cef4a56
1//===- ConstantHandling.cpp - Implement ConstantHandling.h ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the various intrinsic operations, on constant values. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ConstantHandling.h" 15#include "llvm/Constants.h" 16#include "llvm/iPHINode.h" 17#include "llvm/InstrTypes.h" 18#include "llvm/DerivedTypes.h" 19#include "llvm/Support/GetElementPtrTypeIterator.h" 20#include <cmath> 21using namespace llvm; 22 23static unsigned getSize(const Type *Ty) { 24 unsigned S = Ty->getPrimitiveSize(); 25 return S ? S : 8; // Treat pointers at 8 bytes 26} 27 28Constant *llvm::ConstantFoldCastInstruction(const Constant *V, 29 const Type *DestTy) { 30 if (V->getType() == DestTy) return (Constant*)V; 31 32 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) 33 if (CE->getOpcode() == Instruction::Cast) { 34 Constant *Op = const_cast<Constant*>(CE->getOperand(0)); 35 // Try to not produce a cast of a cast, which is almost always redundant. 36 if (!Op->getType()->isFloatingPoint() && 37 !CE->getType()->isFloatingPoint() && 38 !DestTy->getType()->isFloatingPoint()) { 39 unsigned S1 = getSize(Op->getType()), S2 = getSize(CE->getType()); 40 unsigned S3 = getSize(DestTy); 41 if (Op->getType() == DestTy && S3 >= S2) 42 return Op; 43 if (S1 >= S2 && S2 >= S3) 44 return ConstantExpr::getCast(Op, DestTy); 45 if (S1 <= S2 && S2 >= S3 && S1 <= S3) 46 return ConstantExpr::getCast(Op, DestTy); 47 } 48 } else if (CE->getOpcode() == Instruction::GetElementPtr) { 49 // If all of the indexes in the GEP are null values, there is no pointer 50 // adjustment going on. We might as well cast the source pointer. 51 bool isAllNull = true; 52 for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) 53 if (!CE->getOperand(i)->isNullValue()) { 54 isAllNull = false; 55 break; 56 } 57 if (isAllNull) 58 return ConstantExpr::getCast(CE->getOperand(0), DestTy); 59 } 60 61 ConstRules &Rules = ConstRules::get(V, V); 62 63 switch (DestTy->getPrimitiveID()) { 64 case Type::BoolTyID: return Rules.castToBool(V); 65 case Type::UByteTyID: return Rules.castToUByte(V); 66 case Type::SByteTyID: return Rules.castToSByte(V); 67 case Type::UShortTyID: return Rules.castToUShort(V); 68 case Type::ShortTyID: return Rules.castToShort(V); 69 case Type::UIntTyID: return Rules.castToUInt(V); 70 case Type::IntTyID: return Rules.castToInt(V); 71 case Type::ULongTyID: return Rules.castToULong(V); 72 case Type::LongTyID: return Rules.castToLong(V); 73 case Type::FloatTyID: return Rules.castToFloat(V); 74 case Type::DoubleTyID: return Rules.castToDouble(V); 75 case Type::PointerTyID: 76 return Rules.castToPointer(V, cast<PointerType>(DestTy)); 77 default: return 0; 78 } 79} 80 81Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, 82 const Constant *V1, 83 const Constant *V2) { 84 Constant *C; 85 switch (Opcode) { 86 default: return 0; 87 case Instruction::Add: return ConstRules::get(V1, V2).add(V1, V2); 88 case Instruction::Sub: return ConstRules::get(V1, V2).sub(V1, V2); 89 case Instruction::Mul: return ConstRules::get(V1, V2).mul(V1, V2); 90 case Instruction::Div: return ConstRules::get(V1, V2).div(V1, V2); 91 case Instruction::Rem: return ConstRules::get(V1, V2).rem(V1, V2); 92 case Instruction::And: return ConstRules::get(V1, V2).op_and(V1, V2); 93 case Instruction::Or: return ConstRules::get(V1, V2).op_or (V1, V2); 94 case Instruction::Xor: return ConstRules::get(V1, V2).op_xor(V1, V2); 95 96 case Instruction::Shl: return ConstRules::get(V1, V2).shl(V1, V2); 97 case Instruction::Shr: return ConstRules::get(V1, V2).shr(V1, V2); 98 99 case Instruction::SetEQ: return ConstRules::get(V1, V2).equalto(V1, V2); 100 case Instruction::SetLT: return ConstRules::get(V1, V2).lessthan(V1, V2); 101 case Instruction::SetGT: return ConstRules::get(V1, V2).lessthan(V2, V1); 102 case Instruction::SetNE: // V1 != V2 === !(V1 == V2) 103 C = ConstRules::get(V1, V2).equalto(V1, V2); 104 break; 105 case Instruction::SetLE: // V1 <= V2 === !(V2 < V1) 106 C = ConstRules::get(V1, V2).lessthan(V2, V1); 107 break; 108 case Instruction::SetGE: // V1 >= V2 === !(V1 < V2) 109 C = ConstRules::get(V1, V2).lessthan(V1, V2); 110 break; 111 } 112 113 // If the folder broke out of the switch statement, invert the boolean 114 // constant value, if it exists, and return it. 115 if (!C) return 0; 116 return ConstantExpr::get(Instruction::Xor, ConstantBool::True, C); 117} 118 119Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, 120 const std::vector<Constant*> &IdxList) { 121 if (IdxList.size() == 0 || 122 (IdxList.size() == 1 && IdxList[0]->isNullValue())) 123 return const_cast<Constant*>(C); 124 125 // TODO If C is null and all idx's are null, return null of the right type. 126 127 128 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(const_cast<Constant*>(C))) { 129 // Combine Indices - If the source pointer to this getelementptr instruction 130 // is a getelementptr instruction, combine the indices of the two 131 // getelementptr instructions into a single instruction. 132 // 133 if (CE->getOpcode() == Instruction::GetElementPtr) { 134 const Type *LastTy = 0; 135 for (gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE); 136 I != E; ++I) 137 LastTy = *I; 138 139 if ((LastTy && isa<ArrayType>(LastTy)) || IdxList[0]->isNullValue()) { 140 std::vector<Constant*> NewIndices; 141 NewIndices.reserve(IdxList.size() + CE->getNumOperands()); 142 for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) 143 NewIndices.push_back(cast<Constant>(CE->getOperand(i))); 144 145 // Add the last index of the source with the first index of the new GEP. 146 // Make sure to handle the case when they are actually different types. 147 Constant *Combined = CE->getOperand(CE->getNumOperands()-1); 148 if (!IdxList[0]->isNullValue()) // Otherwise it must be an array 149 Combined = 150 ConstantExpr::get(Instruction::Add, 151 ConstantExpr::getCast(IdxList[0], Type::LongTy), 152 ConstantExpr::getCast(Combined, Type::LongTy)); 153 154 NewIndices.push_back(Combined); 155 NewIndices.insert(NewIndices.end(), IdxList.begin()+1, IdxList.end()); 156 return ConstantExpr::getGetElementPtr(CE->getOperand(0), NewIndices); 157 } 158 } 159 160 // Implement folding of: 161 // int* getelementptr ([2 x int]* cast ([3 x int]* %X to [2 x int]*), 162 // long 0, long 0) 163 // To: int* getelementptr ([3 x int]* %X, long 0, long 0) 164 // 165 if (CE->getOpcode() == Instruction::Cast && IdxList.size() > 1 && 166 IdxList[0]->isNullValue()) 167 if (const PointerType *SPT = 168 dyn_cast<PointerType>(CE->getOperand(0)->getType())) 169 if (const ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType())) 170 if (const ArrayType *CAT = 171 dyn_cast<ArrayType>(cast<PointerType>(C->getType())->getElementType())) 172 if (CAT->getElementType() == SAT->getElementType()) 173 return ConstantExpr::getGetElementPtr( 174 (Constant*)CE->getOperand(0), IdxList); 175 } 176 return 0; 177} 178 179 180//===----------------------------------------------------------------------===// 181// TemplateRules Class 182//===----------------------------------------------------------------------===// 183// 184// TemplateRules - Implement a subclass of ConstRules that provides all 185// operations as noops. All other rules classes inherit from this class so 186// that if functionality is needed in the future, it can simply be added here 187// and to ConstRules without changing anything else... 188// 189// This class also provides subclasses with typesafe implementations of methods 190// so that don't have to do type casting. 191// 192template<class ArgType, class SubClassName> 193class TemplateRules : public ConstRules { 194 195 //===--------------------------------------------------------------------===// 196 // Redirecting functions that cast to the appropriate types 197 //===--------------------------------------------------------------------===// 198 199 virtual Constant *add(const Constant *V1, const Constant *V2) const { 200 return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2); 201 } 202 virtual Constant *sub(const Constant *V1, const Constant *V2) const { 203 return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2); 204 } 205 virtual Constant *mul(const Constant *V1, const Constant *V2) const { 206 return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2); 207 } 208 virtual Constant *div(const Constant *V1, const Constant *V2) const { 209 return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2); 210 } 211 virtual Constant *rem(const Constant *V1, const Constant *V2) const { 212 return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2); 213 } 214 virtual Constant *op_and(const Constant *V1, const Constant *V2) const { 215 return SubClassName::And((const ArgType *)V1, (const ArgType *)V2); 216 } 217 virtual Constant *op_or(const Constant *V1, const Constant *V2) const { 218 return SubClassName::Or((const ArgType *)V1, (const ArgType *)V2); 219 } 220 virtual Constant *op_xor(const Constant *V1, const Constant *V2) const { 221 return SubClassName::Xor((const ArgType *)V1, (const ArgType *)V2); 222 } 223 virtual Constant *shl(const Constant *V1, const Constant *V2) const { 224 return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2); 225 } 226 virtual Constant *shr(const Constant *V1, const Constant *V2) const { 227 return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2); 228 } 229 230 virtual Constant *lessthan(const Constant *V1, const Constant *V2) const { 231 return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2); 232 } 233 virtual Constant *equalto(const Constant *V1, const Constant *V2) const { 234 return SubClassName::EqualTo((const ArgType *)V1, (const ArgType *)V2); 235 } 236 237 // Casting operators. ick 238 virtual Constant *castToBool(const Constant *V) const { 239 return SubClassName::CastToBool((const ArgType*)V); 240 } 241 virtual Constant *castToSByte(const Constant *V) const { 242 return SubClassName::CastToSByte((const ArgType*)V); 243 } 244 virtual Constant *castToUByte(const Constant *V) const { 245 return SubClassName::CastToUByte((const ArgType*)V); 246 } 247 virtual Constant *castToShort(const Constant *V) const { 248 return SubClassName::CastToShort((const ArgType*)V); 249 } 250 virtual Constant *castToUShort(const Constant *V) const { 251 return SubClassName::CastToUShort((const ArgType*)V); 252 } 253 virtual Constant *castToInt(const Constant *V) const { 254 return SubClassName::CastToInt((const ArgType*)V); 255 } 256 virtual Constant *castToUInt(const Constant *V) const { 257 return SubClassName::CastToUInt((const ArgType*)V); 258 } 259 virtual Constant *castToLong(const Constant *V) const { 260 return SubClassName::CastToLong((const ArgType*)V); 261 } 262 virtual Constant *castToULong(const Constant *V) const { 263 return SubClassName::CastToULong((const ArgType*)V); 264 } 265 virtual Constant *castToFloat(const Constant *V) const { 266 return SubClassName::CastToFloat((const ArgType*)V); 267 } 268 virtual Constant *castToDouble(const Constant *V) const { 269 return SubClassName::CastToDouble((const ArgType*)V); 270 } 271 virtual Constant *castToPointer(const Constant *V, 272 const PointerType *Ty) const { 273 return SubClassName::CastToPointer((const ArgType*)V, Ty); 274 } 275 276 //===--------------------------------------------------------------------===// 277 // Default "noop" implementations 278 //===--------------------------------------------------------------------===// 279 280 static Constant *Add(const ArgType *V1, const ArgType *V2) { return 0; } 281 static Constant *Sub(const ArgType *V1, const ArgType *V2) { return 0; } 282 static Constant *Mul(const ArgType *V1, const ArgType *V2) { return 0; } 283 static Constant *Div(const ArgType *V1, const ArgType *V2) { return 0; } 284 static Constant *Rem(const ArgType *V1, const ArgType *V2) { return 0; } 285 static Constant *And(const ArgType *V1, const ArgType *V2) { return 0; } 286 static Constant *Or (const ArgType *V1, const ArgType *V2) { return 0; } 287 static Constant *Xor(const ArgType *V1, const ArgType *V2) { return 0; } 288 static Constant *Shl(const ArgType *V1, const ArgType *V2) { return 0; } 289 static Constant *Shr(const ArgType *V1, const ArgType *V2) { return 0; } 290 static Constant *LessThan(const ArgType *V1, const ArgType *V2) { 291 return 0; 292 } 293 static Constant *EqualTo(const ArgType *V1, const ArgType *V2) { 294 return 0; 295 } 296 297 // Casting operators. ick 298 static Constant *CastToBool (const Constant *V) { return 0; } 299 static Constant *CastToSByte (const Constant *V) { return 0; } 300 static Constant *CastToUByte (const Constant *V) { return 0; } 301 static Constant *CastToShort (const Constant *V) { return 0; } 302 static Constant *CastToUShort(const Constant *V) { return 0; } 303 static Constant *CastToInt (const Constant *V) { return 0; } 304 static Constant *CastToUInt (const Constant *V) { return 0; } 305 static Constant *CastToLong (const Constant *V) { return 0; } 306 static Constant *CastToULong (const Constant *V) { return 0; } 307 static Constant *CastToFloat (const Constant *V) { return 0; } 308 static Constant *CastToDouble(const Constant *V) { return 0; } 309 static Constant *CastToPointer(const Constant *, 310 const PointerType *) {return 0;} 311}; 312 313 314 315//===----------------------------------------------------------------------===// 316// EmptyRules Class 317//===----------------------------------------------------------------------===// 318// 319// EmptyRules provides a concrete base class of ConstRules that does nothing 320// 321struct EmptyRules : public TemplateRules<Constant, EmptyRules> { 322 static Constant *EqualTo(const Constant *V1, const Constant *V2) { 323 if (V1 == V2) return ConstantBool::True; 324 return 0; 325 } 326}; 327 328 329 330//===----------------------------------------------------------------------===// 331// BoolRules Class 332//===----------------------------------------------------------------------===// 333// 334// BoolRules provides a concrete base class of ConstRules for the 'bool' type. 335// 336struct BoolRules : public TemplateRules<ConstantBool, BoolRules> { 337 338 static Constant *LessThan(const ConstantBool *V1, const ConstantBool *V2){ 339 return ConstantBool::get(V1->getValue() < V2->getValue()); 340 } 341 342 static Constant *EqualTo(const Constant *V1, const Constant *V2) { 343 return ConstantBool::get(V1 == V2); 344 } 345 346 static Constant *And(const ConstantBool *V1, const ConstantBool *V2) { 347 return ConstantBool::get(V1->getValue() & V2->getValue()); 348 } 349 350 static Constant *Or(const ConstantBool *V1, const ConstantBool *V2) { 351 return ConstantBool::get(V1->getValue() | V2->getValue()); 352 } 353 354 static Constant *Xor(const ConstantBool *V1, const ConstantBool *V2) { 355 return ConstantBool::get(V1->getValue() ^ V2->getValue()); 356 } 357 358 // Casting operators. ick 359#define DEF_CAST(TYPE, CLASS, CTYPE) \ 360 static Constant *CastTo##TYPE (const ConstantBool *V) { \ 361 return CLASS::get(Type::TYPE##Ty, (CTYPE)(bool)V->getValue()); \ 362 } 363 364 DEF_CAST(Bool , ConstantBool, bool) 365 DEF_CAST(SByte , ConstantSInt, signed char) 366 DEF_CAST(UByte , ConstantUInt, unsigned char) 367 DEF_CAST(Short , ConstantSInt, signed short) 368 DEF_CAST(UShort, ConstantUInt, unsigned short) 369 DEF_CAST(Int , ConstantSInt, signed int) 370 DEF_CAST(UInt , ConstantUInt, unsigned int) 371 DEF_CAST(Long , ConstantSInt, int64_t) 372 DEF_CAST(ULong , ConstantUInt, uint64_t) 373 DEF_CAST(Float , ConstantFP , float) 374 DEF_CAST(Double, ConstantFP , double) 375#undef DEF_CAST 376}; 377 378 379//===----------------------------------------------------------------------===// 380// NullPointerRules Class 381//===----------------------------------------------------------------------===// 382// 383// NullPointerRules provides a concrete base class of ConstRules for null 384// pointers. 385// 386struct NullPointerRules : public TemplateRules<ConstantPointerNull, 387 NullPointerRules> { 388 static Constant *EqualTo(const Constant *V1, const Constant *V2) { 389 return ConstantBool::True; // Null pointers are always equal 390 } 391 static Constant *CastToBool(const Constant *V) { 392 return ConstantBool::False; 393 } 394 static Constant *CastToSByte (const Constant *V) { 395 return ConstantSInt::get(Type::SByteTy, 0); 396 } 397 static Constant *CastToUByte (const Constant *V) { 398 return ConstantUInt::get(Type::UByteTy, 0); 399 } 400 static Constant *CastToShort (const Constant *V) { 401 return ConstantSInt::get(Type::ShortTy, 0); 402 } 403 static Constant *CastToUShort(const Constant *V) { 404 return ConstantUInt::get(Type::UShortTy, 0); 405 } 406 static Constant *CastToInt (const Constant *V) { 407 return ConstantSInt::get(Type::IntTy, 0); 408 } 409 static Constant *CastToUInt (const Constant *V) { 410 return ConstantUInt::get(Type::UIntTy, 0); 411 } 412 static Constant *CastToLong (const Constant *V) { 413 return ConstantSInt::get(Type::LongTy, 0); 414 } 415 static Constant *CastToULong (const Constant *V) { 416 return ConstantUInt::get(Type::ULongTy, 0); 417 } 418 static Constant *CastToFloat (const Constant *V) { 419 return ConstantFP::get(Type::FloatTy, 0); 420 } 421 static Constant *CastToDouble(const Constant *V) { 422 return ConstantFP::get(Type::DoubleTy, 0); 423 } 424 425 static Constant *CastToPointer(const ConstantPointerNull *V, 426 const PointerType *PTy) { 427 return ConstantPointerNull::get(PTy); 428 } 429}; 430 431 432//===----------------------------------------------------------------------===// 433// DirectRules Class 434//===----------------------------------------------------------------------===// 435// 436// DirectRules provides a concrete base classes of ConstRules for a variety of 437// different types. This allows the C++ compiler to automatically generate our 438// constant handling operations in a typesafe and accurate manner. 439// 440template<class ConstantClass, class BuiltinType, Type **Ty, class SuperClass> 441struct DirectRules : public TemplateRules<ConstantClass, SuperClass> { 442 static Constant *Add(const ConstantClass *V1, const ConstantClass *V2) { 443 BuiltinType R = (BuiltinType)V1->getValue() + (BuiltinType)V2->getValue(); 444 return ConstantClass::get(*Ty, R); 445 } 446 447 static Constant *Sub(const ConstantClass *V1, const ConstantClass *V2) { 448 BuiltinType R = (BuiltinType)V1->getValue() - (BuiltinType)V2->getValue(); 449 return ConstantClass::get(*Ty, R); 450 } 451 452 static Constant *Mul(const ConstantClass *V1, const ConstantClass *V2) { 453 BuiltinType R = (BuiltinType)V1->getValue() * (BuiltinType)V2->getValue(); 454 return ConstantClass::get(*Ty, R); 455 } 456 457 static Constant *Div(const ConstantClass *V1, const ConstantClass *V2) { 458 if (V2->isNullValue()) return 0; 459 BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue(); 460 return ConstantClass::get(*Ty, R); 461 } 462 463 static Constant *LessThan(const ConstantClass *V1, const ConstantClass *V2) { 464 bool R = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue(); 465 return ConstantBool::get(R); 466 } 467 468 static Constant *EqualTo(const ConstantClass *V1, const ConstantClass *V2) { 469 bool R = (BuiltinType)V1->getValue() == (BuiltinType)V2->getValue(); 470 return ConstantBool::get(R); 471 } 472 473 static Constant *CastToPointer(const ConstantClass *V, 474 const PointerType *PTy) { 475 if (V->isNullValue()) // Is it a FP or Integral null value? 476 return ConstantPointerNull::get(PTy); 477 return 0; // Can't const prop other types of pointers 478 } 479 480 // Casting operators. ick 481#define DEF_CAST(TYPE, CLASS, CTYPE) \ 482 static Constant *CastTo##TYPE (const ConstantClass *V) { \ 483 return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \ 484 } 485 486 DEF_CAST(Bool , ConstantBool, bool) 487 DEF_CAST(SByte , ConstantSInt, signed char) 488 DEF_CAST(UByte , ConstantUInt, unsigned char) 489 DEF_CAST(Short , ConstantSInt, signed short) 490 DEF_CAST(UShort, ConstantUInt, unsigned short) 491 DEF_CAST(Int , ConstantSInt, signed int) 492 DEF_CAST(UInt , ConstantUInt, unsigned int) 493 DEF_CAST(Long , ConstantSInt, int64_t) 494 DEF_CAST(ULong , ConstantUInt, uint64_t) 495 DEF_CAST(Float , ConstantFP , float) 496 DEF_CAST(Double, ConstantFP , double) 497#undef DEF_CAST 498}; 499 500 501//===----------------------------------------------------------------------===// 502// DirectIntRules Class 503//===----------------------------------------------------------------------===// 504// 505// DirectIntRules provides implementations of functions that are valid on 506// integer types, but not all types in general. 507// 508template <class ConstantClass, class BuiltinType, Type **Ty> 509struct DirectIntRules 510 : public DirectRules<ConstantClass, BuiltinType, Ty, 511 DirectIntRules<ConstantClass, BuiltinType, Ty> > { 512 513 static Constant *Div(const ConstantClass *V1, const ConstantClass *V2) { 514 if (V2->isNullValue()) return 0; 515 if (V2->isAllOnesValue() && // MIN_INT / -1 516 (BuiltinType)V1->getValue() == -(BuiltinType)V1->getValue()) 517 return 0; 518 BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue(); 519 return ConstantClass::get(*Ty, R); 520 } 521 522 static Constant *Rem(const ConstantClass *V1, 523 const ConstantClass *V2) { 524 if (V2->isNullValue()) return 0; // X / 0 525 if (V2->isAllOnesValue() && // MIN_INT / -1 526 (BuiltinType)V1->getValue() == -(BuiltinType)V1->getValue()) 527 return 0; 528 BuiltinType R = (BuiltinType)V1->getValue() % (BuiltinType)V2->getValue(); 529 return ConstantClass::get(*Ty, R); 530 } 531 532 static Constant *And(const ConstantClass *V1, const ConstantClass *V2) { 533 BuiltinType R = (BuiltinType)V1->getValue() & (BuiltinType)V2->getValue(); 534 return ConstantClass::get(*Ty, R); 535 } 536 static Constant *Or(const ConstantClass *V1, const ConstantClass *V2) { 537 BuiltinType R = (BuiltinType)V1->getValue() | (BuiltinType)V2->getValue(); 538 return ConstantClass::get(*Ty, R); 539 } 540 static Constant *Xor(const ConstantClass *V1, const ConstantClass *V2) { 541 BuiltinType R = (BuiltinType)V1->getValue() ^ (BuiltinType)V2->getValue(); 542 return ConstantClass::get(*Ty, R); 543 } 544 545 static Constant *Shl(const ConstantClass *V1, const ConstantClass *V2) { 546 BuiltinType R = (BuiltinType)V1->getValue() << (BuiltinType)V2->getValue(); 547 return ConstantClass::get(*Ty, R); 548 } 549 550 static Constant *Shr(const ConstantClass *V1, const ConstantClass *V2) { 551 BuiltinType R = (BuiltinType)V1->getValue() >> (BuiltinType)V2->getValue(); 552 return ConstantClass::get(*Ty, R); 553 } 554}; 555 556 557//===----------------------------------------------------------------------===// 558// DirectFPRules Class 559//===----------------------------------------------------------------------===// 560// 561// DirectFPRules provides implementations of functions that are valid on 562// floating point types, but not all types in general. 563// 564template <class ConstantClass, class BuiltinType, Type **Ty> 565struct DirectFPRules 566 : public DirectRules<ConstantClass, BuiltinType, Ty, 567 DirectFPRules<ConstantClass, BuiltinType, Ty> > { 568 static Constant *Rem(const ConstantClass *V1, const ConstantClass *V2) { 569 if (V2->isNullValue()) return 0; 570 BuiltinType Result = std::fmod((BuiltinType)V1->getValue(), 571 (BuiltinType)V2->getValue()); 572 return ConstantClass::get(*Ty, Result); 573 } 574}; 575 576ConstRules &ConstRules::get(const Constant *V1, const Constant *V2) { 577 static EmptyRules EmptyR; 578 static BoolRules BoolR; 579 static NullPointerRules NullPointerR; 580 static DirectIntRules<ConstantSInt, signed char , &Type::SByteTy> SByteR; 581 static DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy> UByteR; 582 static DirectIntRules<ConstantSInt, signed short, &Type::ShortTy> ShortR; 583 static DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy> UShortR; 584 static DirectIntRules<ConstantSInt, signed int , &Type::IntTy> IntR; 585 static DirectIntRules<ConstantUInt, unsigned int , &Type::UIntTy> UIntR; 586 static DirectIntRules<ConstantSInt, int64_t , &Type::LongTy> LongR; 587 static DirectIntRules<ConstantUInt, uint64_t , &Type::ULongTy> ULongR; 588 static DirectFPRules <ConstantFP , float , &Type::FloatTy> FloatR; 589 static DirectFPRules <ConstantFP , double , &Type::DoubleTy> DoubleR; 590 591 if (isa<ConstantExpr>(V1) || isa<ConstantExpr>(V2) || 592 isa<ConstantPointerRef>(V1) || isa<ConstantPointerRef>(V2)) 593 return EmptyR; 594 595 switch (V1->getType()->getPrimitiveID()) { 596 default: assert(0 && "Unknown value type for constant folding!"); 597 case Type::BoolTyID: return BoolR; 598 case Type::PointerTyID: return NullPointerR; 599 case Type::SByteTyID: return SByteR; 600 case Type::UByteTyID: return UByteR; 601 case Type::ShortTyID: return ShortR; 602 case Type::UShortTyID: return UShortR; 603 case Type::IntTyID: return IntR; 604 case Type::UIntTyID: return UIntR; 605 case Type::LongTyID: return LongR; 606 case Type::ULongTyID: return ULongR; 607 case Type::FloatTyID: return FloatR; 608 case Type::DoubleTyID: return DoubleR; 609 } 610} 611