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