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