1a8def42e6da70207c1dfd8f3b3194a5c6cb9bf0
[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 ConstPoolBool::get(!V->getValue());
148   }
149
150   inline static ConstPoolVal *Or(const ConstPoolBool *V1,
151                                  const ConstPoolBool *V2) {
152     return ConstPoolBool::get(V1->getValue() | V2->getValue());
153   }
154
155   inline static ConstPoolVal *And(const ConstPoolBool *V1, 
156                                   const ConstPoolBool *V2) {
157     return ConstPoolBool::get(V1->getValue() & V2->getValue());
158   }
159 } BoolTyInst;
160
161
162 //===----------------------------------------------------------------------===//
163 //                             DirectRules Class
164 //===----------------------------------------------------------------------===//
165 //
166 // DirectRules provides a concrete base classes of ConstRules for a variety of
167 // different types.  This allows the C++ compiler to automatically generate our
168 // constant handling operations in a typesafe and accurate manner.
169 //
170 template<class ConstPoolClass, class BuiltinType, const Type **Ty>
171 struct DirectRules 
172   : public TemplateRules<ConstPoolClass, 
173                          DirectRules<ConstPoolClass, BuiltinType, Ty> > {
174
175   inline static ConstPoolVal *Not(const ConstPoolClass *V) { 
176     return ConstPoolClass::get(*Ty, !(BuiltinType)V->getValue());;
177   }
178
179   inline static ConstPoolVal *Add(const ConstPoolClass *V1, 
180                                   const ConstPoolClass *V2) {
181     BuiltinType Result = (BuiltinType)V1->getValue() + 
182                          (BuiltinType)V2->getValue();
183     return ConstPoolClass::get(*Ty, Result);
184   }
185
186   inline static ConstPoolVal *Sub(const ConstPoolClass *V1, 
187                                   const ConstPoolClass *V2) {
188     BuiltinType Result = (BuiltinType)V1->getValue() -
189                          (BuiltinType)V2->getValue();
190     return ConstPoolClass::get(*Ty, Result);
191   }
192
193   inline static ConstPoolVal *Mul(const ConstPoolClass *V1, 
194                                    const ConstPoolClass *V2) {
195     BuiltinType Result = (BuiltinType)V1->getValue() *
196                          (BuiltinType)V2->getValue();
197     return ConstPoolClass::get(*Ty, Result);
198   }
199
200   inline static ConstPoolBool *LessThan(const ConstPoolClass *V1, 
201                                         const ConstPoolClass *V2) {
202     bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
203     return ConstPoolBool::get(Result);
204   } 
205
206   // Casting operators.  ick
207 #define DEF_CAST(TYPE, CLASS, CTYPE) \
208   inline static CLASS *CastTo##TYPE  (const ConstPoolClass *V) {    \
209     return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
210   }
211
212   DEF_CAST(Bool  , ConstPoolBool, bool)
213   DEF_CAST(SByte , ConstPoolSInt, signed char)
214   DEF_CAST(UByte , ConstPoolUInt, unsigned char)
215   DEF_CAST(Short , ConstPoolSInt, signed short)
216   DEF_CAST(UShort, ConstPoolUInt, unsigned short)
217   DEF_CAST(Int   , ConstPoolSInt, signed int)
218   DEF_CAST(UInt  , ConstPoolUInt, unsigned int)
219   DEF_CAST(Long  , ConstPoolSInt, int64_t)
220   DEF_CAST(ULong , ConstPoolUInt, uint64_t)
221   DEF_CAST(Float , ConstPoolFP  , float)
222   DEF_CAST(Double, ConstPoolFP  , double)
223 #undef DEF_CAST
224 };
225
226 //===----------------------------------------------------------------------===//
227 //                            DirectRules Subclasses
228 //===----------------------------------------------------------------------===//
229 //
230 // Given the DirectRules class we can now implement lots of types with little
231 // code.  Thank goodness C++ compilers are great at stomping out layers of 
232 // templates... can you imagine having to do this all by hand? (/me is lazy :)
233 //
234 static DirectRules<ConstPoolSInt,   signed char , &Type::SByteTy>  SByteTyInst;
235 static DirectRules<ConstPoolUInt, unsigned char , &Type::UByteTy>  UByteTyInst;
236 static DirectRules<ConstPoolSInt,   signed short, &Type::ShortTy>  ShortTyInst;
237 static DirectRules<ConstPoolUInt, unsigned short, &Type::UShortTy> UShortTyInst;
238 static DirectRules<ConstPoolSInt,   signed int  , &Type::IntTy>    IntTyInst;
239 static DirectRules<ConstPoolUInt, unsigned int  , &Type::UIntTy>   UIntTyInst;
240 static DirectRules<ConstPoolSInt,  int64_t      , &Type::LongTy>   LongTyInst;
241 static DirectRules<ConstPoolUInt, uint64_t      , &Type::ULongTy>  ULongTyInst;
242 static DirectRules<ConstPoolFP  , float         , &Type::FloatTy>  FloatTyInst;
243 static DirectRules<ConstPoolFP  , double        , &Type::DoubleTy> DoubleTyInst;
244
245
246 // ConstRules::find - Return the constant rules that take care of the specified
247 // type.  Note that this is cached in the Type value itself, so switch statement
248 // is only hit at most once per type.
249 //
250 const ConstRules *ConstRules::find(const Type *Ty) {
251   const ConstRules *Result;
252   switch (Ty->getPrimitiveID()) {
253   case Type::BoolTyID:   Result = &BoolTyInst;   break;
254   case Type::SByteTyID:  Result = &SByteTyInst;  break;
255   case Type::UByteTyID:  Result = &UByteTyInst;  break;
256   case Type::ShortTyID:  Result = &ShortTyInst;  break;
257   case Type::UShortTyID: Result = &UShortTyInst; break;
258   case Type::IntTyID:    Result = &IntTyInst;    break;
259   case Type::UIntTyID:   Result = &UIntTyInst;   break;
260   case Type::LongTyID:   Result = &LongTyInst;   break;
261   case Type::ULongTyID:  Result = &ULongTyInst;  break;
262   case Type::FloatTyID:  Result = &FloatTyInst;  break;
263   case Type::DoubleTyID: Result = &DoubleTyInst; break;
264   default:               Result = &EmptyInst;    break;
265   }
266
267   Ty->setConstRules(Result);   // Cache the value for future short circuiting!
268   return Result;
269 }
270
271
272 } // End namespace opt