Rename ConstPoolVal -> Constant
[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 Constant *op_not(const Constant *V) const {
34     return SubClassName::Not((const ArgType *)V);
35   }
36
37   
38   virtual Constant *add(const Constant *V1, 
39                         const Constant *V2) const { 
40     return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);  
41   }
42
43   virtual Constant *sub(const Constant *V1, 
44                         const Constant *V2) const { 
45     return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);  
46   }
47
48   virtual Constant *mul(const Constant *V1, 
49                         const Constant *V2) const { 
50     return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);  
51   }
52
53   virtual ConstantBool *lessthan(const Constant *V1, 
54                                  const Constant *V2) const { 
55     return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
56   }
57
58   // Casting operators.  ick
59   virtual ConstantBool *castToBool(const Constant *V) const {
60     return SubClassName::CastToBool((const ArgType*)V);
61   }
62   virtual ConstantSInt *castToSByte(const Constant *V) const {
63     return SubClassName::CastToSByte((const ArgType*)V);
64   }
65   virtual ConstantUInt *castToUByte(const Constant *V) const {
66     return SubClassName::CastToUByte((const ArgType*)V);
67   }
68   virtual ConstantSInt *castToShort(const Constant *V) const {
69     return SubClassName::CastToShort((const ArgType*)V);
70   }
71   virtual ConstantUInt *castToUShort(const Constant *V) const {
72     return SubClassName::CastToUShort((const ArgType*)V);
73   }
74   virtual ConstantSInt *castToInt(const Constant *V) const {
75     return SubClassName::CastToInt((const ArgType*)V);
76   }
77   virtual ConstantUInt *castToUInt(const Constant *V) const {
78     return SubClassName::CastToUInt((const ArgType*)V);
79   }
80   virtual ConstantSInt *castToLong(const Constant *V) const {
81     return SubClassName::CastToLong((const ArgType*)V);
82   }
83   virtual ConstantUInt *castToULong(const Constant *V) const {
84     return SubClassName::CastToULong((const ArgType*)V);
85   }
86   virtual ConstantFP   *castToFloat(const Constant *V) const {
87     return SubClassName::CastToFloat((const ArgType*)V);
88   }
89   virtual ConstantFP   *castToDouble(const Constant *V) const {
90     return SubClassName::CastToDouble((const ArgType*)V);
91   }
92   virtual ConstantPointer *castToPointer(const Constant *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 Constant *Not(const ArgType *V) { return 0; }
102
103   inline static Constant *Add(const ArgType *V1, const ArgType *V2) {
104     return 0;
105   }
106   inline static Constant *Sub(const ArgType *V1, const ArgType *V2) {
107     return 0;
108   }
109   inline static Constant *Mul(const ArgType *V1, const ArgType *V2) {
110     return 0;
111   }
112   inline static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
113     return 0;
114   }
115
116   // Casting operators.  ick
117   inline static ConstantBool *CastToBool  (const Constant *V) { return 0; }
118   inline static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
119   inline static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
120   inline static ConstantSInt *CastToShort (const Constant *V) { return 0; }
121   inline static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
122   inline static ConstantSInt *CastToInt   (const Constant *V) { return 0; }
123   inline static ConstantUInt *CastToUInt  (const Constant *V) { return 0; }
124   inline static ConstantSInt *CastToLong  (const Constant *V) { return 0; }
125   inline static ConstantUInt *CastToULong (const Constant *V) { return 0; }
126   inline static ConstantFP   *CastToFloat (const Constant *V) { return 0; }
127   inline static ConstantFP   *CastToDouble(const Constant *V) { return 0; }
128   inline static ConstantPointer *CastToPointer(const Constant *,
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<Constant, 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<ConstantBool, BoolRules> {
152
153   inline static Constant *Not(const ConstantBool *V) { 
154     return ConstantBool::get(!V->getValue());
155   }
156
157   inline static Constant *Or(const ConstantBool *V1,
158                              const ConstantBool *V2) {
159     return ConstantBool::get(V1->getValue() | V2->getValue());
160   }
161
162   inline static Constant *And(const ConstantBool *V1, 
163                               const ConstantBool *V2) {
164     return ConstantBool::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<ConstantPointer, PointerRules> {
176   inline static ConstantBool *CastToBool  (const Constant *V) {
177     if (V->isNullValue()) return ConstantBool::False;
178     return 0;  // Can't const prop other types of pointers
179   }
180   inline static ConstantSInt *CastToSByte (const Constant *V) {
181     if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 0);
182     return 0;  // Can't const prop other types of pointers
183   }
184   inline static ConstantUInt *CastToUByte (const Constant *V) {
185     if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 0);
186     return 0;  // Can't const prop other types of pointers
187   }
188   inline static ConstantSInt *CastToShort (const Constant *V) {
189     if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 0);
190     return 0;  // Can't const prop other types of pointers
191   }
192   inline static ConstantUInt *CastToUShort(const Constant *V) {
193     if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 0);
194     return 0;  // Can't const prop other types of pointers
195   }
196   inline static ConstantSInt *CastToInt   (const Constant *V) {
197     if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 0);
198     return 0;  // Can't const prop other types of pointers
199   }
200   inline static ConstantUInt *CastToUInt  (const Constant *V) {
201     if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
202     return 0;  // Can't const prop other types of pointers
203   }
204   inline static ConstantSInt *CastToLong  (const Constant *V) {
205     if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
206     return 0;  // Can't const prop other types of pointers
207   }
208   inline static ConstantUInt *CastToULong (const Constant *V) {
209     if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
210     return 0;  // Can't const prop other types of pointers
211   }
212   inline static ConstantFP   *CastToFloat (const Constant *V) {
213     if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
214     return 0;  // Can't const prop other types of pointers
215   }
216   inline static ConstantFP   *CastToDouble(const Constant *V) {
217     if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
218     return 0;  // Can't const prop other types of pointers
219   }
220
221   inline static ConstantPointer *CastToPointer(const ConstantPointer *V,
222                                                const PointerType *PTy) {
223     if (V->isNullValue())
224       return ConstantPointerNull::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 ConstantClass, class BuiltinType, Type **Ty>
239 struct DirectRules 
240   : public TemplateRules<ConstantClass, 
241                          DirectRules<ConstantClass, BuiltinType, Ty> > {
242
243   inline static Constant *Not(const ConstantClass *V) { 
244     return ConstantClass::get(*Ty, !(BuiltinType)V->getValue());;
245   }
246
247   inline static Constant *Add(const ConstantClass *V1, 
248                               const ConstantClass *V2) {
249     BuiltinType Result = (BuiltinType)V1->getValue() + 
250                          (BuiltinType)V2->getValue();
251     return ConstantClass::get(*Ty, Result);
252   }
253
254   inline static Constant *Sub(const ConstantClass *V1, 
255                               const ConstantClass *V2) {
256     BuiltinType Result = (BuiltinType)V1->getValue() -
257                          (BuiltinType)V2->getValue();
258     return ConstantClass::get(*Ty, Result);
259   }
260
261   inline static Constant *Mul(const ConstantClass *V1, 
262                               const ConstantClass *V2) {
263     BuiltinType Result = (BuiltinType)V1->getValue() *
264                          (BuiltinType)V2->getValue();
265     return ConstantClass::get(*Ty, Result);
266   }
267
268   inline static ConstantBool *LessThan(const ConstantClass *V1, 
269                                        const ConstantClass *V2) {
270     bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
271     return ConstantBool::get(Result);
272   } 
273
274   inline static ConstantPointer *CastToPointer(const ConstantClass *V,
275                                                const PointerType *PTy) {
276     if (V->isNullValue())    // Is it a FP or Integral null value?
277       return ConstantPointerNull::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 ConstantClass *V) {    \
284     return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
285   }
286
287   DEF_CAST(Bool  , ConstantBool, bool)
288   DEF_CAST(SByte , ConstantSInt, signed char)
289   DEF_CAST(UByte , ConstantUInt, unsigned char)
290   DEF_CAST(Short , ConstantSInt, signed short)
291   DEF_CAST(UShort, ConstantUInt, unsigned short)
292   DEF_CAST(Int   , ConstantSInt, signed int)
293   DEF_CAST(UInt  , ConstantUInt, unsigned int)
294   DEF_CAST(Long  , ConstantSInt, int64_t)
295   DEF_CAST(ULong , ConstantUInt, uint64_t)
296   DEF_CAST(Float , ConstantFP  , float)
297   DEF_CAST(Double, ConstantFP  , 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<ConstantSInt,   signed char , &Type::SByteTy>();
322   case Type::UByteTyID:
323     return new DirectRules<ConstantUInt, unsigned char , &Type::UByteTy>();
324   case Type::ShortTyID:
325     return new DirectRules<ConstantSInt,   signed short, &Type::ShortTy>();
326   case Type::UShortTyID:
327     return new DirectRules<ConstantUInt, unsigned short, &Type::UShortTy>();
328   case Type::IntTyID:
329     return new DirectRules<ConstantSInt,   signed int  , &Type::IntTy>();
330   case Type::UIntTyID:
331     return new DirectRules<ConstantUInt, unsigned int  , &Type::UIntTy>();
332   case Type::LongTyID:
333     return new DirectRules<ConstantSInt,  int64_t      , &Type::LongTy>();
334   case Type::ULongTyID:
335     return new DirectRules<ConstantUInt, uint64_t      , &Type::ULongTy>();
336   case Type::FloatTyID:
337     return new DirectRules<ConstantFP  , float         , &Type::FloatTy>();
338   case Type::DoubleTyID:
339     return new DirectRules<ConstantFP  , double        , &Type::DoubleTy>();
340   default:
341     return new EmptyRules();
342   }
343 }
344
345
346 } // End namespace opt