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