1 //===- ConstantHandling.cpp - Implement ConstantHandling.h ----------------===//
3 // This file implements the various intrinsic operations, on constant values.
5 //===----------------------------------------------------------------------===//
7 #include "llvm/ConstantHandling.h"
8 #include "llvm/Instruction.h"
11 AnnotationID ConstRules::AID(AnnotationManager::getID("opt::ConstRules",
14 // ConstantFoldInstruction - Attempt to constant fold the specified instruction.
15 // If successful, the constant result is returned, if not, null is returned.
17 Constant *ConstantFoldInstruction(Instruction *I) {
21 if (I->getNumOperands() != 0) { // Get first operand if it's a constant...
22 Op0 = dyn_cast<Constant>(I->getOperand(0));
23 if (Op0 == 0) return 0; // Not a constant?, can't fold
25 if (I->getNumOperands() != 1) { // Get second operand if it's a constant...
26 Op1 = dyn_cast<Constant>(I->getOperand(1));
27 if (Op1 == 0) return 0; // Not a constant?, can't fold
31 switch (I->getOpcode()) {
32 case Instruction::Cast:
33 return ConstRules::get(*Op0)->castTo(Op0, I->getType());
34 case Instruction::Not: return ~*Op0;
35 case Instruction::Add: return *Op0 + *Op1;
36 case Instruction::Sub: return *Op0 - *Op1;
37 case Instruction::Mul: return *Op0 * *Op1;
38 case Instruction::Div: return *Op0 / *Op1;
39 case Instruction::Rem: return *Op0 % *Op1;
41 case Instruction::SetEQ: return *Op0 == *Op1;
42 case Instruction::SetNE: return *Op0 != *Op1;
43 case Instruction::SetLE: return *Op0 <= *Op1;
44 case Instruction::SetGE: return *Op0 >= *Op1;
45 case Instruction::SetLT: return *Op0 < *Op1;
46 case Instruction::SetGT: return *Op0 > *Op1;
47 case Instruction::Shl: return *Op0 << *Op1;
48 case Instruction::Shr: return *Op0 >> *Op1;
54 Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy) {
55 return ConstRules::get(*V)->castTo(V, DestTy);
58 Constant *ConstantFoldUnaryInstruction(unsigned Opcode, const Constant *V) {
60 case Instruction::Not: return ~*V;
65 Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
68 case Instruction::Add: return *V1 + *V2;
69 case Instruction::Sub: return *V1 - *V2;
70 case Instruction::Mul: return *V1 * *V2;
71 case Instruction::Div: return *V1 / *V2;
72 case Instruction::Rem: return *V1 % *V2;
74 case Instruction::SetEQ: return *V1 == *V2;
75 case Instruction::SetNE: return *V1 != *V2;
76 case Instruction::SetLE: return *V1 <= *V2;
77 case Instruction::SetGE: return *V1 >= *V2;
78 case Instruction::SetLT: return *V1 < *V2;
79 case Instruction::SetGT: return *V1 > *V2;
84 Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1,
87 case Instruction::Shl: return *V1 << *V2;
88 case Instruction::Shr: return *V1 >> *V2;
94 //===----------------------------------------------------------------------===//
95 // TemplateRules Class
96 //===----------------------------------------------------------------------===//
98 // TemplateRules - Implement a subclass of ConstRules that provides all
99 // operations as noops. All other rules classes inherit from this class so
100 // that if functionality is needed in the future, it can simply be added here
101 // and to ConstRules without changing anything else...
103 // This class also provides subclasses with typesafe implementations of methods
104 // so that don't have to do type casting.
106 template<class ArgType, class SubClassName>
107 class TemplateRules : public ConstRules {
109 //===--------------------------------------------------------------------===//
110 // Redirecting functions that cast to the appropriate types
111 //===--------------------------------------------------------------------===//
113 virtual Constant *op_not(const Constant *V) const {
114 return SubClassName::Not((const ArgType *)V);
118 virtual Constant *add(const Constant *V1,
119 const Constant *V2) const {
120 return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);
123 virtual Constant *sub(const Constant *V1,
124 const Constant *V2) const {
125 return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);
128 virtual Constant *mul(const Constant *V1,
129 const Constant *V2) const {
130 return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);
132 virtual Constant *div(const Constant *V1,
133 const Constant *V2) const {
134 return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2);
136 virtual Constant *rem(const Constant *V1,
137 const Constant *V2) const {
138 return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2);
140 virtual Constant *shl(const Constant *V1,
141 const Constant *V2) const {
142 return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2);
144 virtual Constant *shr(const Constant *V1,
145 const Constant *V2) const {
146 return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2);
149 virtual ConstantBool *lessthan(const Constant *V1,
150 const Constant *V2) const {
151 return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
154 // Casting operators. ick
155 virtual ConstantBool *castToBool(const Constant *V) const {
156 return SubClassName::CastToBool((const ArgType*)V);
158 virtual ConstantSInt *castToSByte(const Constant *V) const {
159 return SubClassName::CastToSByte((const ArgType*)V);
161 virtual ConstantUInt *castToUByte(const Constant *V) const {
162 return SubClassName::CastToUByte((const ArgType*)V);
164 virtual ConstantSInt *castToShort(const Constant *V) const {
165 return SubClassName::CastToShort((const ArgType*)V);
167 virtual ConstantUInt *castToUShort(const Constant *V) const {
168 return SubClassName::CastToUShort((const ArgType*)V);
170 virtual ConstantSInt *castToInt(const Constant *V) const {
171 return SubClassName::CastToInt((const ArgType*)V);
173 virtual ConstantUInt *castToUInt(const Constant *V) const {
174 return SubClassName::CastToUInt((const ArgType*)V);
176 virtual ConstantSInt *castToLong(const Constant *V) const {
177 return SubClassName::CastToLong((const ArgType*)V);
179 virtual ConstantUInt *castToULong(const Constant *V) const {
180 return SubClassName::CastToULong((const ArgType*)V);
182 virtual ConstantFP *castToFloat(const Constant *V) const {
183 return SubClassName::CastToFloat((const ArgType*)V);
185 virtual ConstantFP *castToDouble(const Constant *V) const {
186 return SubClassName::CastToDouble((const ArgType*)V);
188 virtual ConstantPointer *castToPointer(const Constant *V,
189 const PointerType *Ty) const {
190 return SubClassName::CastToPointer((const ArgType*)V, Ty);
193 //===--------------------------------------------------------------------===//
194 // Default "noop" implementations
195 //===--------------------------------------------------------------------===//
197 inline static Constant *Not(const ArgType *V) { return 0; }
199 inline static Constant *Add(const ArgType *V1, const ArgType *V2) {
202 inline static Constant *Sub(const ArgType *V1, const ArgType *V2) {
205 inline static Constant *Mul(const ArgType *V1, const ArgType *V2) {
208 inline static Constant *Div(const ArgType *V1, const ArgType *V2) {
211 inline static Constant *Rem(const ArgType *V1, const ArgType *V2) {
214 inline static Constant *Shl(const ArgType *V1, const ArgType *V2) {
217 inline static Constant *Shr(const ArgType *V1, const ArgType *V2) {
220 inline static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
224 // Casting operators. ick
225 inline static ConstantBool *CastToBool (const Constant *V) { return 0; }
226 inline static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
227 inline static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
228 inline static ConstantSInt *CastToShort (const Constant *V) { return 0; }
229 inline static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
230 inline static ConstantSInt *CastToInt (const Constant *V) { return 0; }
231 inline static ConstantUInt *CastToUInt (const Constant *V) { return 0; }
232 inline static ConstantSInt *CastToLong (const Constant *V) { return 0; }
233 inline static ConstantUInt *CastToULong (const Constant *V) { return 0; }
234 inline static ConstantFP *CastToFloat (const Constant *V) { return 0; }
235 inline static ConstantFP *CastToDouble(const Constant *V) { return 0; }
236 inline static ConstantPointer *CastToPointer(const Constant *,
237 const PointerType *) {return 0;}
242 //===----------------------------------------------------------------------===//
244 //===----------------------------------------------------------------------===//
246 // EmptyRules provides a concrete base class of ConstRules that does nothing
248 struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
253 //===----------------------------------------------------------------------===//
255 //===----------------------------------------------------------------------===//
257 // BoolRules provides a concrete base class of ConstRules for the 'bool' type.
259 struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
261 inline static Constant *Not(const ConstantBool *V) {
262 return ConstantBool::get(!V->getValue());
265 inline static Constant *Or(const ConstantBool *V1,
266 const ConstantBool *V2) {
267 return ConstantBool::get(V1->getValue() | V2->getValue());
270 inline static Constant *And(const ConstantBool *V1,
271 const ConstantBool *V2) {
272 return ConstantBool::get(V1->getValue() & V2->getValue());
277 //===----------------------------------------------------------------------===//
278 // PointerRules Class
279 //===----------------------------------------------------------------------===//
281 // PointerRules provides a concrete base class of ConstRules for pointer types
283 struct PointerRules : public TemplateRules<ConstantPointer, PointerRules> {
284 inline static ConstantBool *CastToBool (const Constant *V) {
285 if (V->isNullValue()) return ConstantBool::False;
286 return 0; // Can't const prop other types of pointers
288 inline static ConstantSInt *CastToSByte (const Constant *V) {
289 if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 0);
290 return 0; // Can't const prop other types of pointers
292 inline static ConstantUInt *CastToUByte (const Constant *V) {
293 if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 0);
294 return 0; // Can't const prop other types of pointers
296 inline static ConstantSInt *CastToShort (const Constant *V) {
297 if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 0);
298 return 0; // Can't const prop other types of pointers
300 inline static ConstantUInt *CastToUShort(const Constant *V) {
301 if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 0);
302 return 0; // Can't const prop other types of pointers
304 inline static ConstantSInt *CastToInt (const Constant *V) {
305 if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 0);
306 return 0; // Can't const prop other types of pointers
308 inline static ConstantUInt *CastToUInt (const Constant *V) {
309 if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
310 return 0; // Can't const prop other types of pointers
312 inline static ConstantSInt *CastToLong (const Constant *V) {
313 if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
314 return 0; // Can't const prop other types of pointers
316 inline static ConstantUInt *CastToULong (const Constant *V) {
317 if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
318 return 0; // Can't const prop other types of pointers
320 inline static ConstantFP *CastToFloat (const Constant *V) {
321 if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
322 return 0; // Can't const prop other types of pointers
324 inline static ConstantFP *CastToDouble(const Constant *V) {
325 if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
326 return 0; // Can't const prop other types of pointers
329 inline static ConstantPointer *CastToPointer(const ConstantPointer *V,
330 const PointerType *PTy) {
331 if (V->getType() == PTy)
332 return const_cast<ConstantPointer*>(V); // Allow cast %PTy %ptr to %PTy
333 if (V->isNullValue())
334 return ConstantPointerNull::get(PTy);
335 return 0; // Can't const prop other types of pointers
340 //===----------------------------------------------------------------------===//
342 //===----------------------------------------------------------------------===//
344 // DirectRules provides a concrete base classes of ConstRules for a variety of
345 // different types. This allows the C++ compiler to automatically generate our
346 // constant handling operations in a typesafe and accurate manner.
348 template<class ConstantClass, class BuiltinType, Type **Ty, class SuperClass>
349 struct DirectRules : public TemplateRules<ConstantClass, SuperClass> {
350 inline static Constant *Add(const ConstantClass *V1,
351 const ConstantClass *V2) {
352 BuiltinType Result = (BuiltinType)V1->getValue() +
353 (BuiltinType)V2->getValue();
354 return ConstantClass::get(*Ty, Result);
357 inline static Constant *Sub(const ConstantClass *V1,
358 const ConstantClass *V2) {
359 BuiltinType Result = (BuiltinType)V1->getValue() -
360 (BuiltinType)V2->getValue();
361 return ConstantClass::get(*Ty, Result);
364 inline static Constant *Mul(const ConstantClass *V1,
365 const ConstantClass *V2) {
366 BuiltinType Result = (BuiltinType)V1->getValue() *
367 (BuiltinType)V2->getValue();
368 return ConstantClass::get(*Ty, Result);
371 inline static Constant *Div(const ConstantClass *V1,
372 const ConstantClass *V2) {
373 if (V2->isNullValue()) return 0;
374 BuiltinType Result = (BuiltinType)V1->getValue() /
375 (BuiltinType)V2->getValue();
376 return ConstantClass::get(*Ty, Result);
379 inline static ConstantBool *LessThan(const ConstantClass *V1,
380 const ConstantClass *V2) {
381 bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
382 return ConstantBool::get(Result);
385 inline static ConstantPointer *CastToPointer(const ConstantClass *V,
386 const PointerType *PTy) {
387 if (V->isNullValue()) // Is it a FP or Integral null value?
388 return ConstantPointerNull::get(PTy);
389 return 0; // Can't const prop other types of pointers
392 // Casting operators. ick
393 #define DEF_CAST(TYPE, CLASS, CTYPE) \
394 inline static CLASS *CastTo##TYPE (const ConstantClass *V) { \
395 return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
398 DEF_CAST(Bool , ConstantBool, bool)
399 DEF_CAST(SByte , ConstantSInt, signed char)
400 DEF_CAST(UByte , ConstantUInt, unsigned char)
401 DEF_CAST(Short , ConstantSInt, signed short)
402 DEF_CAST(UShort, ConstantUInt, unsigned short)
403 DEF_CAST(Int , ConstantSInt, signed int)
404 DEF_CAST(UInt , ConstantUInt, unsigned int)
405 DEF_CAST(Long , ConstantSInt, int64_t)
406 DEF_CAST(ULong , ConstantUInt, uint64_t)
407 DEF_CAST(Float , ConstantFP , float)
408 DEF_CAST(Double, ConstantFP , double)
413 //===----------------------------------------------------------------------===//
414 // DirectIntRules Class
415 //===----------------------------------------------------------------------===//
417 // DirectIntRules provides implementations of functions that are valid on
418 // integer types, but not all types in general.
420 template <class ConstantClass, class BuiltinType, Type **Ty>
421 struct DirectIntRules
422 : public DirectRules<ConstantClass, BuiltinType, Ty,
423 DirectIntRules<ConstantClass, BuiltinType, Ty> > {
424 inline static Constant *Not(const ConstantClass *V) {
425 return ConstantClass::get(*Ty, ~(BuiltinType)V->getValue());;
428 inline static Constant *Rem(const ConstantClass *V1,
429 const ConstantClass *V2) {
430 if (V2->isNullValue()) return 0;
431 BuiltinType Result = (BuiltinType)V1->getValue() %
432 (BuiltinType)V2->getValue();
433 return ConstantClass::get(*Ty, Result);
436 inline static Constant *Shl(const ConstantClass *V1,
437 const ConstantClass *V2) {
438 BuiltinType Result = (BuiltinType)V1->getValue() <<
439 (BuiltinType)V2->getValue();
440 return ConstantClass::get(*Ty, Result);
443 inline static Constant *Shr(const ConstantClass *V1,
444 const ConstantClass *V2) {
445 BuiltinType Result = (BuiltinType)V1->getValue() >>
446 (BuiltinType)V2->getValue();
447 return ConstantClass::get(*Ty, Result);
452 //===----------------------------------------------------------------------===//
453 // DirectFPRules Class
454 //===----------------------------------------------------------------------===//
456 // DirectFPRules provides implementations of functions that are valid on
457 // floating point types, but not all types in general.
459 template <class ConstantClass, class BuiltinType, Type **Ty>
461 : public DirectRules<ConstantClass, BuiltinType, Ty,
462 DirectFPRules<ConstantClass, BuiltinType, Ty> > {
463 inline static Constant *Rem(const ConstantClass *V1,
464 const ConstantClass *V2) {
465 if (V2->isNullValue()) return 0;
466 BuiltinType Result = std::fmod((BuiltinType)V1->getValue(),
467 (BuiltinType)V2->getValue());
468 return ConstantClass::get(*Ty, Result);
473 //===----------------------------------------------------------------------===//
474 // DirectRules Subclasses
475 //===----------------------------------------------------------------------===//
477 // Given the DirectRules class we can now implement lots of types with little
478 // code. Thank goodness C++ compilers are great at stomping out layers of
479 // templates... can you imagine having to do this all by hand? (/me is lazy :)
482 // ConstRules::find - Return the constant rules that take care of the specified
485 Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
486 assert(AID == ConstRules::AID && "Bad annotation for factory!");
487 const Type *Ty = cast<Type>((const Value*)TyA);
489 switch (Ty->getPrimitiveID()) {
490 case Type::BoolTyID: return new BoolRules();
491 case Type::PointerTyID: return new PointerRules();
492 case Type::SByteTyID:
493 return new DirectIntRules<ConstantSInt, signed char , &Type::SByteTy>();
494 case Type::UByteTyID:
495 return new DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>();
496 case Type::ShortTyID:
497 return new DirectIntRules<ConstantSInt, signed short, &Type::ShortTy>();
498 case Type::UShortTyID:
499 return new DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy>();
501 return new DirectIntRules<ConstantSInt, signed int , &Type::IntTy>();
503 return new DirectIntRules<ConstantUInt, unsigned int , &Type::UIntTy>();
505 return new DirectIntRules<ConstantSInt, int64_t , &Type::LongTy>();
506 case Type::ULongTyID:
507 return new DirectIntRules<ConstantUInt, uint64_t , &Type::ULongTy>();
508 case Type::FloatTyID:
509 return new DirectFPRules<ConstantFP , float , &Type::FloatTy>();
510 case Type::DoubleTyID:
511 return new DirectFPRules<ConstantFP , double , &Type::DoubleTy>();
513 return new EmptyRules();