Eliminate the PromoteInstance class, incorporating it into the PromotePass
[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->isNullValue())
229       return ConstantPointerNull::get(PTy);
230     return 0;  // Can't const prop other types of pointers
231   }
232 };
233
234
235 //===----------------------------------------------------------------------===//
236 //                             DirectRules Class
237 //===----------------------------------------------------------------------===//
238 //
239 // DirectRules provides a concrete base classes of ConstRules for a variety of
240 // different types.  This allows the C++ compiler to automatically generate our
241 // constant handling operations in a typesafe and accurate manner.
242 //
243 template<class ConstantClass, class BuiltinType, Type **Ty>
244 struct DirectRules 
245   : public TemplateRules<ConstantClass, 
246                          DirectRules<ConstantClass, BuiltinType, Ty> > {
247
248   inline static Constant *Not(const ConstantClass *V) { 
249     return ConstantClass::get(*Ty, !(BuiltinType)V->getValue());;
250   }
251
252   inline static Constant *Add(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 *Sub(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 Constant *Mul(const ConstantClass *V1, 
267                               const ConstantClass *V2) {
268     BuiltinType Result = (BuiltinType)V1->getValue() *
269                          (BuiltinType)V2->getValue();
270     return ConstantClass::get(*Ty, Result);
271   }
272
273   inline static Constant *Div(const ConstantClass *V1, 
274                               const ConstantClass *V2) {
275     BuiltinType Result = (BuiltinType)V1->getValue() /
276                          (BuiltinType)V2->getValue();
277     return ConstantClass::get(*Ty, Result);
278   }
279
280   inline static ConstantBool *LessThan(const ConstantClass *V1, 
281                                        const ConstantClass *V2) {
282     bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
283     return ConstantBool::get(Result);
284   } 
285
286   inline static ConstantPointer *CastToPointer(const ConstantClass *V,
287                                                const PointerType *PTy) {
288     if (V->isNullValue())    // Is it a FP or Integral null value?
289       return ConstantPointerNull::get(PTy);
290     return 0;  // Can't const prop other types of pointers
291   }
292
293   // Casting operators.  ick
294 #define DEF_CAST(TYPE, CLASS, CTYPE) \
295   inline static CLASS *CastTo##TYPE  (const ConstantClass *V) {    \
296     return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
297   }
298
299   DEF_CAST(Bool  , ConstantBool, bool)
300   DEF_CAST(SByte , ConstantSInt, signed char)
301   DEF_CAST(UByte , ConstantUInt, unsigned char)
302   DEF_CAST(Short , ConstantSInt, signed short)
303   DEF_CAST(UShort, ConstantUInt, unsigned short)
304   DEF_CAST(Int   , ConstantSInt, signed int)
305   DEF_CAST(UInt  , ConstantUInt, unsigned int)
306   DEF_CAST(Long  , ConstantSInt, int64_t)
307   DEF_CAST(ULong , ConstantUInt, uint64_t)
308   DEF_CAST(Float , ConstantFP  , float)
309   DEF_CAST(Double, ConstantFP  , double)
310 #undef DEF_CAST
311 };
312
313 //===----------------------------------------------------------------------===//
314 //                            DirectRules Subclasses
315 //===----------------------------------------------------------------------===//
316 //
317 // Given the DirectRules class we can now implement lots of types with little
318 // code.  Thank goodness C++ compilers are great at stomping out layers of 
319 // templates... can you imagine having to do this all by hand? (/me is lazy :)
320 //
321
322 // ConstRules::find - Return the constant rules that take care of the specified
323 // type.
324 //
325 Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
326   assert(AID == ConstRules::AID && "Bad annotation for factory!");
327   const Type *Ty = cast<Type>((const Value*)TyA);
328   
329   switch (Ty->getPrimitiveID()) {
330   case Type::BoolTyID:    return new BoolRules();
331   case Type::PointerTyID: return new PointerRules();
332   case Type::SByteTyID:
333     return new DirectRules<ConstantSInt,   signed char , &Type::SByteTy>();
334   case Type::UByteTyID:
335     return new DirectRules<ConstantUInt, unsigned char , &Type::UByteTy>();
336   case Type::ShortTyID:
337     return new DirectRules<ConstantSInt,   signed short, &Type::ShortTy>();
338   case Type::UShortTyID:
339     return new DirectRules<ConstantUInt, unsigned short, &Type::UShortTy>();
340   case Type::IntTyID:
341     return new DirectRules<ConstantSInt,   signed int  , &Type::IntTy>();
342   case Type::UIntTyID:
343     return new DirectRules<ConstantUInt, unsigned int  , &Type::UIntTy>();
344   case Type::LongTyID:
345     return new DirectRules<ConstantSInt,  int64_t      , &Type::LongTy>();
346   case Type::ULongTyID:
347     return new DirectRules<ConstantUInt, uint64_t      , &Type::ULongTy>();
348   case Type::FloatTyID:
349     return new DirectRules<ConstantFP  , float         , &Type::FloatTy>();
350   case Type::DoubleTyID:
351     return new DirectRules<ConstantFP  , double        , &Type::DoubleTy>();
352   default:
353     return new EmptyRules();
354   }
355 }