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