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