Remove some gross stuff
[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 //===----------------------------------------------------------------------===//
12 //                             TemplateRules Class
13 //===----------------------------------------------------------------------===//
14 //
15 // TemplateRules - Implement a subclass of ConstRules that provides all 
16 // operations as noops.  All other rules classes inherit from this class so 
17 // that if functionality is needed in the future, it can simply be added here 
18 // and to ConstRules without changing anything else...
19 // 
20 // This class also provides subclasses with typesafe implementations of methods
21 // so that don't have to do type casting.
22 //
23 template<class ArgType, class SubClassName>
24 class TemplateRules : public ConstRules {
25
26   //===--------------------------------------------------------------------===//
27   // Redirecting functions that cast to the appropriate types
28   //===--------------------------------------------------------------------===//
29
30   virtual ConstPoolVal *not(const ConstPoolVal *V) const {
31     return SubClassName::Not((const ArgType *)V);
32   }
33
34   
35   virtual ConstPoolVal *add(const ConstPoolVal *V1, 
36                             const ConstPoolVal *V2) const { 
37     return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);  
38   }
39
40   virtual ConstPoolVal *sub(const ConstPoolVal *V1, 
41                             const ConstPoolVal *V2) const { 
42     return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);  
43   }
44
45   virtual ConstPoolVal *mul(const ConstPoolVal *V1, 
46                             const ConstPoolVal *V2) const { 
47     return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);  
48   }
49
50   virtual ConstPoolBool *lessthan(const ConstPoolVal *V1, 
51                                   const ConstPoolVal *V2) const { 
52     return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
53   }
54
55   // Casting operators.  ick
56   virtual ConstPoolBool *castToBool(const ConstPoolVal *V) const {
57     return SubClassName::CastToBool((const ArgType*)V);
58   }
59   virtual ConstPoolSInt *castToSByte(const ConstPoolVal *V) const {
60     return SubClassName::CastToSByte((const ArgType*)V);
61   }
62   virtual ConstPoolUInt *castToUByte(const ConstPoolVal *V) const {
63     return SubClassName::CastToUByte((const ArgType*)V);
64   }
65   virtual ConstPoolSInt *castToShort(const ConstPoolVal *V) const {
66     return SubClassName::CastToShort((const ArgType*)V);
67   }
68   virtual ConstPoolUInt *castToUShort(const ConstPoolVal *V) const {
69     return SubClassName::CastToUShort((const ArgType*)V);
70   }
71   virtual ConstPoolSInt *castToInt(const ConstPoolVal *V) const {
72     return SubClassName::CastToInt((const ArgType*)V);
73   }
74   virtual ConstPoolUInt *castToUInt(const ConstPoolVal *V) const {
75     return SubClassName::CastToUInt((const ArgType*)V);
76   }
77   virtual ConstPoolSInt *castToLong(const ConstPoolVal *V) const {
78     return SubClassName::CastToLong((const ArgType*)V);
79   }
80   virtual ConstPoolUInt *castToULong(const ConstPoolVal *V) const {
81     return SubClassName::CastToULong((const ArgType*)V);
82   }
83   virtual ConstPoolFP   *castToFloat(const ConstPoolVal *V) const {
84     return SubClassName::CastToFloat((const ArgType*)V);
85   }
86   virtual ConstPoolFP   *castToDouble(const ConstPoolVal *V) const {
87     return SubClassName::CastToDouble((const ArgType*)V);
88   }
89
90   //===--------------------------------------------------------------------===//
91   // Default "noop" implementations
92   //===--------------------------------------------------------------------===//
93
94   inline static ConstPoolVal *Not(const ArgType *V) { return 0; }
95
96   inline static ConstPoolVal *Add(const ArgType *V1, const ArgType *V2) {
97     return 0;
98   }
99   inline static ConstPoolVal *Sub(const ArgType *V1, const ArgType *V2) {
100     return 0;
101   }
102   inline static ConstPoolVal *Mul(const ArgType *V1, const ArgType *V2) {
103     return 0;
104   }
105   inline static ConstPoolBool *LessThan(const ArgType *V1, const ArgType *V2) {
106     return 0;
107   }
108
109   // Casting operators.  ick
110   inline static ConstPoolBool *CastToBool  (const ConstPoolVal *V) { return 0; }
111   inline static ConstPoolSInt *CastToSByte (const ConstPoolVal *V) { return 0; }
112   inline static ConstPoolUInt *CastToUByte (const ConstPoolVal *V) { return 0; }
113   inline static ConstPoolSInt *CastToShort (const ConstPoolVal *V) { return 0; }
114   inline static ConstPoolUInt *CastToUShort(const ConstPoolVal *V) { return 0; }
115   inline static ConstPoolSInt *CastToInt   (const ConstPoolVal *V) { return 0; }
116   inline static ConstPoolUInt *CastToUInt  (const ConstPoolVal *V) { return 0; }
117   inline static ConstPoolSInt *CastToLong  (const ConstPoolVal *V) { return 0; }
118   inline static ConstPoolUInt *CastToULong (const ConstPoolVal *V) { return 0; }
119   inline static ConstPoolFP   *CastToFloat (const ConstPoolVal *V) { return 0; }
120   inline static ConstPoolFP   *CastToDouble(const ConstPoolVal *V) { return 0; }
121 };
122
123
124
125 //===----------------------------------------------------------------------===//
126 //                             EmptyRules Class
127 //===----------------------------------------------------------------------===//
128 //
129 // EmptyRules provides a concrete base class of ConstRules that does nothing
130 //
131 static    // EmptyInst is static
132 struct EmptyRules : public TemplateRules<ConstPoolVal, EmptyRules> {
133 } EmptyInst;
134
135
136
137 //===----------------------------------------------------------------------===//
138 //                              BoolRules Class
139 //===----------------------------------------------------------------------===//
140 //
141 // BoolRules provides a concrete base class of ConstRules for the 'bool' type.
142 //
143 static   // BoolTyInst is static...
144 struct BoolRules : public TemplateRules<ConstPoolBool, BoolRules> {
145
146   inline static ConstPoolVal *Not(const ConstPoolBool *V) { 
147     return new ConstPoolBool(!V->getValue());
148   }
149
150   inline static ConstPoolVal *Or(const ConstPoolBool *V1, 
151                                  const ConstPoolBool *V2) {
152     bool Result = V1->getValue() | V2->getValue();
153     return new ConstPoolBool(Result);
154   }
155
156   inline static ConstPoolVal *And(const ConstPoolBool *V1, 
157                                   const ConstPoolBool *V2) {
158     bool Result = V1->getValue() & V2->getValue();
159     return new ConstPoolBool(Result);
160   }
161 } BoolTyInst;
162
163
164 //===----------------------------------------------------------------------===//
165 //                             DirectRules Class
166 //===----------------------------------------------------------------------===//
167 //
168 // DirectRules provides a concrete base classes of ConstRules for a variety of
169 // different types.  This allows the C++ compiler to automatically generate our
170 // constant handling operations in a typesafe and accurate manner.
171 //
172 template<class ConstPoolClass, class BuiltinType, const Type **Ty>
173 struct DirectRules 
174   : public TemplateRules<ConstPoolClass, 
175                          DirectRules<ConstPoolClass, BuiltinType, Ty> > {
176
177   inline static ConstPoolVal *Not(const ConstPoolClass *V) { 
178     return new ConstPoolClass(*Ty, !(BuiltinType)V->getValue());;
179   }
180
181   inline static ConstPoolVal *Add(const ConstPoolClass *V1, 
182                                   const ConstPoolClass *V2) {
183     BuiltinType Result = (BuiltinType)V1->getValue() + 
184                          (BuiltinType)V2->getValue();
185     return new ConstPoolClass(*Ty, Result);
186   }
187
188   inline static ConstPoolVal *Sub(const ConstPoolClass *V1, 
189                                   const ConstPoolClass *V2) {
190     BuiltinType Result = (BuiltinType)V1->getValue() -
191                          (BuiltinType)V2->getValue();
192     return new ConstPoolClass(*Ty, Result);
193   }
194
195   inline static ConstPoolVal *Mul(const ConstPoolClass *V1, 
196                                    const ConstPoolClass *V2) {
197     BuiltinType Result = (BuiltinType)V1->getValue() *
198                          (BuiltinType)V2->getValue();
199     return new ConstPoolClass(*Ty, Result);
200   }
201
202   inline static ConstPoolBool *LessThan(const ConstPoolClass *V1, 
203                                         const ConstPoolClass *V2) {
204     bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
205     return new ConstPoolBool(Result);
206   } 
207
208   // Casting operators.  ick
209 #define DEF_CAST(TYPE, CLASS, CTYPE) \
210   inline static CLASS *CastTo##TYPE  (const ConstPoolClass *V) {    \
211     return new CLASS(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
212   }
213
214   DEF_CAST(Bool  , ConstPoolBool, bool)
215   DEF_CAST(SByte , ConstPoolSInt, signed char)
216   DEF_CAST(UByte , ConstPoolUInt, unsigned char)
217   DEF_CAST(Short , ConstPoolSInt, signed short)
218   DEF_CAST(UShort, ConstPoolUInt, unsigned short)
219   DEF_CAST(Int   , ConstPoolSInt, signed int)
220   DEF_CAST(UInt  , ConstPoolUInt, unsigned int)
221   DEF_CAST(Long  , ConstPoolSInt, int64_t)
222   DEF_CAST(ULong , ConstPoolUInt, uint64_t)
223   DEF_CAST(Float , ConstPoolFP  , float)
224   DEF_CAST(Double, ConstPoolFP  , double)
225 #undef DEF_CAST
226 };
227
228 //===----------------------------------------------------------------------===//
229 //                            DirectRules Subclasses
230 //===----------------------------------------------------------------------===//
231 //
232 // Given the DirectRules class we can now implement lots of types with little
233 // code.  Thank goodness C++ compilers are great at stomping out layers of 
234 // templates... can you imagine having to do this all by hand? (/me is lazy :)
235 //
236 static DirectRules<ConstPoolSInt,   signed char , &Type::SByteTy>  SByteTyInst;
237 static DirectRules<ConstPoolUInt, unsigned char , &Type::UByteTy>  UByteTyInst;
238 static DirectRules<ConstPoolSInt,   signed short, &Type::ShortTy>  ShortTyInst;
239 static DirectRules<ConstPoolUInt, unsigned short, &Type::UShortTy> UShortTyInst;
240 static DirectRules<ConstPoolSInt,   signed int  , &Type::IntTy>    IntTyInst;
241 static DirectRules<ConstPoolUInt, unsigned int  , &Type::UIntTy>   UIntTyInst;
242 static DirectRules<ConstPoolSInt,  int64_t      , &Type::LongTy>   LongTyInst;
243 static DirectRules<ConstPoolUInt, uint64_t      , &Type::ULongTy>  ULongTyInst;
244 static DirectRules<ConstPoolFP  , float         , &Type::FloatTy>  FloatTyInst;
245 static DirectRules<ConstPoolFP  , double        , &Type::DoubleTy> DoubleTyInst;
246
247
248 // ConstRules::find - Return the constant rules that take care of the specified
249 // type.  Note that this is cached in the Type value itself, so switch statement
250 // is only hit at most once per type.
251 //
252 const ConstRules *ConstRules::find(const Type *Ty) {
253   const ConstRules *Result;
254   switch (Ty->getPrimitiveID()) {
255   case Type::BoolTyID:   Result = &BoolTyInst;   break;
256   case Type::SByteTyID:  Result = &SByteTyInst;  break;
257   case Type::UByteTyID:  Result = &UByteTyInst;  break;
258   case Type::ShortTyID:  Result = &ShortTyInst;  break;
259   case Type::UShortTyID: Result = &UShortTyInst; break;
260   case Type::IntTyID:    Result = &IntTyInst;    break;
261   case Type::UIntTyID:   Result = &UIntTyInst;   break;
262   case Type::LongTyID:   Result = &LongTyInst;   break;
263   case Type::ULongTyID:  Result = &ULongTyInst;  break;
264   case Type::FloatTyID:  Result = &FloatTyInst;  break;
265   case Type::DoubleTyID: Result = &DoubleTyInst; break;
266   default:               Result = &EmptyInst;    break;
267   }
268
269   Ty->setConstRules(Result);   // Cache the value for future short circuiting!
270   return Result;
271 }
272
273
274 } // End namespace opt