Clean up ConstRules stuff to use annotations instead of a mutable member in Type
[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 *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
93   //===--------------------------------------------------------------------===//
94   // Default "noop" implementations
95   //===--------------------------------------------------------------------===//
96
97   inline static ConstPoolVal *Not(const ArgType *V) { return 0; }
98
99   inline static ConstPoolVal *Add(const ArgType *V1, const ArgType *V2) {
100     return 0;
101   }
102   inline static ConstPoolVal *Sub(const ArgType *V1, const ArgType *V2) {
103     return 0;
104   }
105   inline static ConstPoolVal *Mul(const ArgType *V1, const ArgType *V2) {
106     return 0;
107   }
108   inline static ConstPoolBool *LessThan(const ArgType *V1, const ArgType *V2) {
109     return 0;
110   }
111
112   // Casting operators.  ick
113   inline static ConstPoolBool *CastToBool  (const ConstPoolVal *V) { return 0; }
114   inline static ConstPoolSInt *CastToSByte (const ConstPoolVal *V) { return 0; }
115   inline static ConstPoolUInt *CastToUByte (const ConstPoolVal *V) { return 0; }
116   inline static ConstPoolSInt *CastToShort (const ConstPoolVal *V) { return 0; }
117   inline static ConstPoolUInt *CastToUShort(const ConstPoolVal *V) { return 0; }
118   inline static ConstPoolSInt *CastToInt   (const ConstPoolVal *V) { return 0; }
119   inline static ConstPoolUInt *CastToUInt  (const ConstPoolVal *V) { return 0; }
120   inline static ConstPoolSInt *CastToLong  (const ConstPoolVal *V) { return 0; }
121   inline static ConstPoolUInt *CastToULong (const ConstPoolVal *V) { return 0; }
122   inline static ConstPoolFP   *CastToFloat (const ConstPoolVal *V) { return 0; }
123   inline static ConstPoolFP   *CastToDouble(const ConstPoolVal *V) { return 0; }
124 };
125
126
127
128 //===----------------------------------------------------------------------===//
129 //                             EmptyRules Class
130 //===----------------------------------------------------------------------===//
131 //
132 // EmptyRules provides a concrete base class of ConstRules that does nothing
133 //
134 struct EmptyRules : public TemplateRules<ConstPoolVal, EmptyRules> {
135 };
136
137
138
139 //===----------------------------------------------------------------------===//
140 //                              BoolRules Class
141 //===----------------------------------------------------------------------===//
142 //
143 // BoolRules provides a concrete base class of ConstRules for the 'bool' type.
144 //
145 struct BoolRules : public TemplateRules<ConstPoolBool, BoolRules> {
146
147   inline static ConstPoolVal *Not(const ConstPoolBool *V) { 
148     return ConstPoolBool::get(!V->getValue());
149   }
150
151   inline static ConstPoolVal *Or(const ConstPoolBool *V1,
152                                  const ConstPoolBool *V2) {
153     return ConstPoolBool::get(V1->getValue() | V2->getValue());
154   }
155
156   inline static ConstPoolVal *And(const ConstPoolBool *V1, 
157                                   const ConstPoolBool *V2) {
158     return ConstPoolBool::get(V1->getValue() & V2->getValue());
159   }
160 };
161
162
163 //===----------------------------------------------------------------------===//
164 //                             DirectRules Class
165 //===----------------------------------------------------------------------===//
166 //
167 // DirectRules provides a concrete base classes of ConstRules for a variety of
168 // different types.  This allows the C++ compiler to automatically generate our
169 // constant handling operations in a typesafe and accurate manner.
170 //
171 template<class ConstPoolClass, class BuiltinType, const Type **Ty>
172 struct DirectRules 
173   : public TemplateRules<ConstPoolClass, 
174                          DirectRules<ConstPoolClass, BuiltinType, Ty> > {
175
176   inline static ConstPoolVal *Not(const ConstPoolClass *V) { 
177     return ConstPoolClass::get(*Ty, !(BuiltinType)V->getValue());;
178   }
179
180   inline static ConstPoolVal *Add(const ConstPoolClass *V1, 
181                                   const ConstPoolClass *V2) {
182     BuiltinType Result = (BuiltinType)V1->getValue() + 
183                          (BuiltinType)V2->getValue();
184     return ConstPoolClass::get(*Ty, Result);
185   }
186
187   inline static ConstPoolVal *Sub(const ConstPoolClass *V1, 
188                                   const ConstPoolClass *V2) {
189     BuiltinType Result = (BuiltinType)V1->getValue() -
190                          (BuiltinType)V2->getValue();
191     return ConstPoolClass::get(*Ty, Result);
192   }
193
194   inline static ConstPoolVal *Mul(const ConstPoolClass *V1, 
195                                    const ConstPoolClass *V2) {
196     BuiltinType Result = (BuiltinType)V1->getValue() *
197                          (BuiltinType)V2->getValue();
198     return ConstPoolClass::get(*Ty, Result);
199   }
200
201   inline static ConstPoolBool *LessThan(const ConstPoolClass *V1, 
202                                         const ConstPoolClass *V2) {
203     bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
204     return ConstPoolBool::get(Result);
205   } 
206
207   // Casting operators.  ick
208 #define DEF_CAST(TYPE, CLASS, CTYPE) \
209   inline static CLASS *CastTo##TYPE  (const ConstPoolClass *V) {    \
210     return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
211   }
212
213   DEF_CAST(Bool  , ConstPoolBool, bool)
214   DEF_CAST(SByte , ConstPoolSInt, signed char)
215   DEF_CAST(UByte , ConstPoolUInt, unsigned char)
216   DEF_CAST(Short , ConstPoolSInt, signed short)
217   DEF_CAST(UShort, ConstPoolUInt, unsigned short)
218   DEF_CAST(Int   , ConstPoolSInt, signed int)
219   DEF_CAST(UInt  , ConstPoolUInt, unsigned int)
220   DEF_CAST(Long  , ConstPoolSInt, int64_t)
221   DEF_CAST(ULong , ConstPoolUInt, uint64_t)
222   DEF_CAST(Float , ConstPoolFP  , float)
223   DEF_CAST(Double, ConstPoolFP  , double)
224 #undef DEF_CAST
225 };
226
227 //===----------------------------------------------------------------------===//
228 //                            DirectRules Subclasses
229 //===----------------------------------------------------------------------===//
230 //
231 // Given the DirectRules class we can now implement lots of types with little
232 // code.  Thank goodness C++ compilers are great at stomping out layers of 
233 // templates... can you imagine having to do this all by hand? (/me is lazy :)
234 //
235
236 // ConstRules::find - Return the constant rules that take care of the specified
237 // type.
238 //
239 Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
240   assert(AID == ConstRules::AID && "Bad annotation for factory!");
241   const Type *Ty = ((const Value*)TyA)->castTypeAsserting();
242   
243   switch (Ty->getPrimitiveID()) {
244   case Type::BoolTyID: return new BoolRules();
245   case Type::SByteTyID:
246     return new DirectRules<ConstPoolSInt,   signed char , &Type::SByteTy>();
247   case Type::UByteTyID:
248     return new DirectRules<ConstPoolUInt, unsigned char , &Type::UByteTy>();
249   case Type::ShortTyID:
250     return new DirectRules<ConstPoolSInt,   signed short, &Type::ShortTy>();
251   case Type::UShortTyID:
252     return new DirectRules<ConstPoolUInt, unsigned short, &Type::UShortTy>();
253   case Type::IntTyID:
254     return new DirectRules<ConstPoolSInt,   signed int  , &Type::IntTy>();
255   case Type::UIntTyID:
256     return new DirectRules<ConstPoolUInt, unsigned int  , &Type::UIntTy>();
257   case Type::LongTyID:
258     return new DirectRules<ConstPoolSInt,  int64_t      , &Type::LongTy>();
259   case Type::ULongTyID:
260     return new DirectRules<ConstPoolUInt, uint64_t      , &Type::ULongTy>();
261   case Type::FloatTyID:
262     return new DirectRules<ConstPoolFP  , float         , &Type::FloatTy>();
263   case Type::DoubleTyID:
264     return new DirectRules<ConstPoolFP  , double        , &Type::DoubleTy>();
265   default:
266     return new EmptyRules();
267   }
268 }
269
270
271 } // End namespace opt