Implement remainder
[oota-llvm.git] / lib / VMCore / ConstantFold.cpp
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 <cmath>
9
10 AnnotationID ConstRules::AID(AnnotationManager::getID("opt::ConstRules",
11                                                       &ConstRules::find));
12
13 //===----------------------------------------------------------------------===//
14 //                             TemplateRules Class
15 //===----------------------------------------------------------------------===//
16 //
17 // TemplateRules - Implement a subclass of ConstRules that provides all 
18 // operations as noops.  All other rules classes inherit from this class so 
19 // that if functionality is needed in the future, it can simply be added here 
20 // and to ConstRules without changing anything else...
21 // 
22 // This class also provides subclasses with typesafe implementations of methods
23 // so that don't have to do type casting.
24 //
25 template<class ArgType, class SubClassName>
26 class TemplateRules : public ConstRules {
27
28   //===--------------------------------------------------------------------===//
29   // Redirecting functions that cast to the appropriate types
30   //===--------------------------------------------------------------------===//
31
32   virtual Constant *op_not(const Constant *V) const {
33     return SubClassName::Not((const ArgType *)V);
34   }
35
36   
37   virtual Constant *add(const Constant *V1, 
38                         const Constant *V2) const { 
39     return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);  
40   }
41
42   virtual Constant *sub(const Constant *V1, 
43                         const Constant *V2) const { 
44     return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);  
45   }
46
47   virtual Constant *mul(const Constant *V1, 
48                         const Constant *V2) const { 
49     return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);  
50   }
51   virtual Constant *div(const Constant *V1, 
52                         const Constant *V2) const { 
53     return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2);  
54   }
55   virtual Constant *rem(const Constant *V1, 
56                         const Constant *V2) const { 
57     return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2);  
58   }
59
60   virtual ConstantBool *lessthan(const Constant *V1, 
61                                  const Constant *V2) const { 
62     return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
63   }
64
65   // Casting operators.  ick
66   virtual ConstantBool *castToBool(const Constant *V) const {
67     return SubClassName::CastToBool((const ArgType*)V);
68   }
69   virtual ConstantSInt *castToSByte(const Constant *V) const {
70     return SubClassName::CastToSByte((const ArgType*)V);
71   }
72   virtual ConstantUInt *castToUByte(const Constant *V) const {
73     return SubClassName::CastToUByte((const ArgType*)V);
74   }
75   virtual ConstantSInt *castToShort(const Constant *V) const {
76     return SubClassName::CastToShort((const ArgType*)V);
77   }
78   virtual ConstantUInt *castToUShort(const Constant *V) const {
79     return SubClassName::CastToUShort((const ArgType*)V);
80   }
81   virtual ConstantSInt *castToInt(const Constant *V) const {
82     return SubClassName::CastToInt((const ArgType*)V);
83   }
84   virtual ConstantUInt *castToUInt(const Constant *V) const {
85     return SubClassName::CastToUInt((const ArgType*)V);
86   }
87   virtual ConstantSInt *castToLong(const Constant *V) const {
88     return SubClassName::CastToLong((const ArgType*)V);
89   }
90   virtual ConstantUInt *castToULong(const Constant *V) const {
91     return SubClassName::CastToULong((const ArgType*)V);
92   }
93   virtual ConstantFP   *castToFloat(const Constant *V) const {
94     return SubClassName::CastToFloat((const ArgType*)V);
95   }
96   virtual ConstantFP   *castToDouble(const Constant *V) const {
97     return SubClassName::CastToDouble((const ArgType*)V);
98   }
99   virtual ConstantPointer *castToPointer(const Constant *V, 
100                                          const PointerType *Ty) const {
101     return SubClassName::CastToPointer((const ArgType*)V, Ty);
102   }
103
104   //===--------------------------------------------------------------------===//
105   // Default "noop" implementations
106   //===--------------------------------------------------------------------===//
107
108   inline static Constant *Not(const ArgType *V) { return 0; }
109
110   inline static Constant *Add(const ArgType *V1, const ArgType *V2) {
111     return 0;
112   }
113   inline static Constant *Sub(const ArgType *V1, const ArgType *V2) {
114     return 0;
115   }
116   inline static Constant *Mul(const ArgType *V1, const ArgType *V2) {
117     return 0;
118   }
119   inline static Constant *Div(const ArgType *V1, const ArgType *V2) {
120     return 0;
121   }
122   inline static Constant *Rem(const ArgType *V1, const ArgType *V2) {
123     return 0;
124   }
125   inline static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
126     return 0;
127   }
128
129   // Casting operators.  ick
130   inline static ConstantBool *CastToBool  (const Constant *V) { return 0; }
131   inline static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
132   inline static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
133   inline static ConstantSInt *CastToShort (const Constant *V) { return 0; }
134   inline static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
135   inline static ConstantSInt *CastToInt   (const Constant *V) { return 0; }
136   inline static ConstantUInt *CastToUInt  (const Constant *V) { return 0; }
137   inline static ConstantSInt *CastToLong  (const Constant *V) { return 0; }
138   inline static ConstantUInt *CastToULong (const Constant *V) { return 0; }
139   inline static ConstantFP   *CastToFloat (const Constant *V) { return 0; }
140   inline static ConstantFP   *CastToDouble(const Constant *V) { return 0; }
141   inline static ConstantPointer *CastToPointer(const Constant *,
142                                                const PointerType *) {return 0;}
143 };
144
145
146
147 //===----------------------------------------------------------------------===//
148 //                             EmptyRules Class
149 //===----------------------------------------------------------------------===//
150 //
151 // EmptyRules provides a concrete base class of ConstRules that does nothing
152 //
153 struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
154 };
155
156
157
158 //===----------------------------------------------------------------------===//
159 //                              BoolRules Class
160 //===----------------------------------------------------------------------===//
161 //
162 // BoolRules provides a concrete base class of ConstRules for the 'bool' type.
163 //
164 struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
165
166   inline static Constant *Not(const ConstantBool *V) { 
167     return ConstantBool::get(!V->getValue());
168   }
169
170   inline static Constant *Or(const ConstantBool *V1,
171                              const ConstantBool *V2) {
172     return ConstantBool::get(V1->getValue() | V2->getValue());
173   }
174
175   inline static Constant *And(const ConstantBool *V1, 
176                               const ConstantBool *V2) {
177     return ConstantBool::get(V1->getValue() & V2->getValue());
178   }
179 };
180
181
182 //===----------------------------------------------------------------------===//
183 //                            PointerRules Class
184 //===----------------------------------------------------------------------===//
185 //
186 // PointerRules provides a concrete base class of ConstRules for pointer types
187 //
188 struct PointerRules : public TemplateRules<ConstantPointer, PointerRules> {
189   inline static ConstantBool *CastToBool  (const Constant *V) {
190     if (V->isNullValue()) return ConstantBool::False;
191     return 0;  // Can't const prop other types of pointers
192   }
193   inline static ConstantSInt *CastToSByte (const Constant *V) {
194     if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 0);
195     return 0;  // Can't const prop other types of pointers
196   }
197   inline static ConstantUInt *CastToUByte (const Constant *V) {
198     if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 0);
199     return 0;  // Can't const prop other types of pointers
200   }
201   inline static ConstantSInt *CastToShort (const Constant *V) {
202     if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 0);
203     return 0;  // Can't const prop other types of pointers
204   }
205   inline static ConstantUInt *CastToUShort(const Constant *V) {
206     if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 0);
207     return 0;  // Can't const prop other types of pointers
208   }
209   inline static ConstantSInt *CastToInt   (const Constant *V) {
210     if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 0);
211     return 0;  // Can't const prop other types of pointers
212   }
213   inline static ConstantUInt *CastToUInt  (const Constant *V) {
214     if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
215     return 0;  // Can't const prop other types of pointers
216   }
217   inline static ConstantSInt *CastToLong  (const Constant *V) {
218     if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
219     return 0;  // Can't const prop other types of pointers
220   }
221   inline static ConstantUInt *CastToULong (const Constant *V) {
222     if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
223     return 0;  // Can't const prop other types of pointers
224   }
225   inline static ConstantFP   *CastToFloat (const Constant *V) {
226     if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
227     return 0;  // Can't const prop other types of pointers
228   }
229   inline static ConstantFP   *CastToDouble(const Constant *V) {
230     if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
231     return 0;  // Can't const prop other types of pointers
232   }
233
234   inline static ConstantPointer *CastToPointer(const ConstantPointer *V,
235                                                const PointerType *PTy) {
236     if (V->getType() == PTy)
237       return const_cast<ConstantPointer*>(V);  // Allow cast %PTy %ptr to %PTy
238     if (V->isNullValue())
239       return ConstantPointerNull::get(PTy);
240     return 0;  // Can't const prop other types of pointers
241   }
242 };
243
244
245 //===----------------------------------------------------------------------===//
246 //                             DirectRules Class
247 //===----------------------------------------------------------------------===//
248 //
249 // DirectRules provides a concrete base classes of ConstRules for a variety of
250 // different types.  This allows the C++ compiler to automatically generate our
251 // constant handling operations in a typesafe and accurate manner.
252 //
253 template<class ConstantClass, class BuiltinType, Type **Ty, class SuperClass>
254 struct DirectRules : public TemplateRules<ConstantClass, SuperClass> {
255   inline static Constant *Add(const ConstantClass *V1, 
256                               const ConstantClass *V2) {
257     BuiltinType Result = (BuiltinType)V1->getValue() + 
258                          (BuiltinType)V2->getValue();
259     return ConstantClass::get(*Ty, Result);
260   }
261
262   inline static Constant *Sub(const ConstantClass *V1, 
263                               const ConstantClass *V2) {
264     BuiltinType Result = (BuiltinType)V1->getValue() -
265                          (BuiltinType)V2->getValue();
266     return ConstantClass::get(*Ty, Result);
267   }
268
269   inline static Constant *Mul(const ConstantClass *V1, 
270                               const ConstantClass *V2) {
271     BuiltinType Result = (BuiltinType)V1->getValue() *
272                          (BuiltinType)V2->getValue();
273     return ConstantClass::get(*Ty, Result);
274   }
275
276   inline static Constant *Div(const ConstantClass *V1,
277                               const ConstantClass *V2) {
278     if (V2->isNullValue()) return 0;
279     BuiltinType Result = (BuiltinType)V1->getValue() /
280                          (BuiltinType)V2->getValue();
281     return ConstantClass::get(*Ty, Result);
282   }
283
284   inline static ConstantBool *LessThan(const ConstantClass *V1, 
285                                        const ConstantClass *V2) {
286     bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
287     return ConstantBool::get(Result);
288   } 
289
290   inline static ConstantPointer *CastToPointer(const ConstantClass *V,
291                                                const PointerType *PTy) {
292     if (V->isNullValue())    // Is it a FP or Integral null value?
293       return ConstantPointerNull::get(PTy);
294     return 0;  // Can't const prop other types of pointers
295   }
296
297   // Casting operators.  ick
298 #define DEF_CAST(TYPE, CLASS, CTYPE) \
299   inline static CLASS *CastTo##TYPE  (const ConstantClass *V) {    \
300     return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
301   }
302
303   DEF_CAST(Bool  , ConstantBool, bool)
304   DEF_CAST(SByte , ConstantSInt, signed char)
305   DEF_CAST(UByte , ConstantUInt, unsigned char)
306   DEF_CAST(Short , ConstantSInt, signed short)
307   DEF_CAST(UShort, ConstantUInt, unsigned short)
308   DEF_CAST(Int   , ConstantSInt, signed int)
309   DEF_CAST(UInt  , ConstantUInt, unsigned int)
310   DEF_CAST(Long  , ConstantSInt, int64_t)
311   DEF_CAST(ULong , ConstantUInt, uint64_t)
312   DEF_CAST(Float , ConstantFP  , float)
313   DEF_CAST(Double, ConstantFP  , double)
314 #undef DEF_CAST
315 };
316
317
318 //===----------------------------------------------------------------------===//
319 //                           DirectIntRules Class
320 //===----------------------------------------------------------------------===//
321 //
322 // DirectIntRules provides implementations of functions that are valid on
323 // integer types, but not all types in general.
324 //
325 template <class ConstantClass, class BuiltinType, Type **Ty>
326 struct DirectIntRules
327   : public DirectRules<ConstantClass, BuiltinType, Ty,
328                        DirectIntRules<ConstantClass, BuiltinType, Ty> > {
329   inline static Constant *Not(const ConstantClass *V) { 
330     return ConstantClass::get(*Ty, ~(BuiltinType)V->getValue());;
331   }
332
333   inline static Constant *Rem(const ConstantClass *V1,
334                               const ConstantClass *V2) {
335     if (V2->isNullValue()) return 0;
336     BuiltinType Result = (BuiltinType)V1->getValue() %
337                          (BuiltinType)V2->getValue();
338     return ConstantClass::get(*Ty, Result);
339   }
340 };
341
342
343 //===----------------------------------------------------------------------===//
344 //                           DirectFPRules Class
345 //===----------------------------------------------------------------------===//
346 //
347 // DirectFPRules provides implementations of functions that are valid on
348 // floating point types, but not all types in general.
349 //
350 template <class ConstantClass, class BuiltinType, Type **Ty>
351 struct DirectFPRules
352   : public DirectRules<ConstantClass, BuiltinType, Ty,
353                        DirectFPRules<ConstantClass, BuiltinType, Ty> > {
354   inline static Constant *Rem(const ConstantClass *V1,
355                               const ConstantClass *V2) {
356     if (V2->isNullValue()) return 0;
357     BuiltinType Result = std::fmod((BuiltinType)V1->getValue(),
358                                    (BuiltinType)V2->getValue());
359     return ConstantClass::get(*Ty, Result);
360   }
361 };
362
363
364 //===----------------------------------------------------------------------===//
365 //                            DirectRules Subclasses
366 //===----------------------------------------------------------------------===//
367 //
368 // Given the DirectRules class we can now implement lots of types with little
369 // code.  Thank goodness C++ compilers are great at stomping out layers of 
370 // templates... can you imagine having to do this all by hand? (/me is lazy :)
371 //
372
373 // ConstRules::find - Return the constant rules that take care of the specified
374 // type.
375 //
376 Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
377   assert(AID == ConstRules::AID && "Bad annotation for factory!");
378   const Type *Ty = cast<Type>((const Value*)TyA);
379   
380   switch (Ty->getPrimitiveID()) {
381   case Type::BoolTyID:    return new BoolRules();
382   case Type::PointerTyID: return new PointerRules();
383   case Type::SByteTyID:
384     return new DirectIntRules<ConstantSInt,   signed char , &Type::SByteTy>();
385   case Type::UByteTyID:
386     return new DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>();
387   case Type::ShortTyID:
388     return new DirectIntRules<ConstantSInt,   signed short, &Type::ShortTy>();
389   case Type::UShortTyID:
390     return new DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy>();
391   case Type::IntTyID:
392     return new DirectIntRules<ConstantSInt,   signed int  , &Type::IntTy>();
393   case Type::UIntTyID:
394     return new DirectIntRules<ConstantUInt, unsigned int  , &Type::UIntTy>();
395   case Type::LongTyID:
396     return new DirectIntRules<ConstantSInt,  int64_t      , &Type::LongTy>();
397   case Type::ULongTyID:
398     return new DirectIntRules<ConstantUInt, uint64_t      , &Type::ULongTy>();
399   case Type::FloatTyID:
400     return new DirectFPRules<ConstantFP  , float         , &Type::FloatTy>();
401   case Type::DoubleTyID:
402     return new DirectFPRules<ConstantFP  , double        , &Type::DoubleTy>();
403   default:
404     return new EmptyRules();
405   }
406 }