54a79804818262cc53f0264a315fe9d3a5de1229
[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 *neg(const ConstPoolVal *V) const {
31     return SubClassName::Neg((const ArgType *)V);
32   }
33
34   virtual ConstPoolVal *not(const ConstPoolVal *V) const {
35     return SubClassName::Not((const ArgType *)V);
36   }
37
38   
39   virtual ConstPoolVal *add(const ConstPoolVal *V1, 
40                             const ConstPoolVal *V2) const { 
41     return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);  
42   }
43
44   virtual ConstPoolVal *sub(const ConstPoolVal *V1, 
45                             const ConstPoolVal *V2) const { 
46     return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);  
47   }
48
49   virtual ConstPoolBool *lessthan(const ConstPoolVal *V1, 
50                                   const ConstPoolVal *V2) const { 
51     return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
52   }
53
54   //===--------------------------------------------------------------------===//
55   // Default "noop" implementations
56   //===--------------------------------------------------------------------===//
57
58   inline static ConstPoolVal *Neg(const ArgType *V) { return 0; }
59   inline static ConstPoolVal *Not(const ArgType *V) { return 0; }
60
61   inline static ConstPoolVal *Add(const ArgType *V1, const ArgType *V2) {
62     return 0;
63   }
64
65   inline static ConstPoolVal *Sub(const ArgType *V1, const ArgType *V2) {
66     return 0;
67   }
68
69   inline static ConstPoolBool *LessThan(const ArgType *V1, const ArgType *V2) {
70     return 0;
71   }
72 };
73
74
75
76 //===----------------------------------------------------------------------===//
77 //                             EmptyRules Class
78 //===----------------------------------------------------------------------===//
79 //
80 // EmptyRules provides a concrete base class of ConstRules that does nothing
81 //
82 static    // EmptyInst is static
83 struct EmptyRules : public TemplateRules<ConstPoolVal, EmptyRules> {
84 } EmptyInst;
85
86
87
88 //===----------------------------------------------------------------------===//
89 //                              BoolRules Class
90 //===----------------------------------------------------------------------===//
91 //
92 // BoolRules provides a concrete base class of ConstRules for the 'bool' type.
93 //
94 static   // BoolTyInst is static...
95 struct BoolRules : public TemplateRules<ConstPoolBool, BoolRules> {
96
97   inline static ConstPoolVal *Not(const ConstPoolBool *V) { 
98     return new ConstPoolBool(!V->getValue());
99   }
100
101   inline static ConstPoolVal *Or(const ConstPoolBool *V1, 
102                                  const ConstPoolBool *V2) {
103     bool Result = V1->getValue() | V2->getValue();
104     return new ConstPoolBool(Result);
105   }
106
107   inline static ConstPoolVal *And(const ConstPoolBool *V1, 
108                                   const ConstPoolBool *V2) {
109     bool Result = V1->getValue() & V2->getValue();
110     return new ConstPoolBool(Result);
111   }
112 } BoolTyInst;
113
114
115 //===----------------------------------------------------------------------===//
116 //                             DirectRules Class
117 //===----------------------------------------------------------------------===//
118 //
119 // DirectRules provides a concrete base classes of ConstRules for a variety of
120 // different types.  This allows the C++ compiler to automatically generate our
121 // constant handling operations in a typesafe and accurate manner.
122 //
123 template<class ConstPoolClass, class BuiltinType, const Type **Ty>
124 struct DirectRules 
125   : public TemplateRules<ConstPoolClass, 
126                          DirectRules<ConstPoolClass, BuiltinType, Ty> > {
127
128   inline static ConstPoolVal *Neg(const ConstPoolClass *V) { 
129     return new ConstPoolClass(*Ty, -(BuiltinType)V->getValue());;
130   }
131   inline static ConstPoolVal *Not(const ConstPoolClass *V) { 
132     return new ConstPoolClass(*Ty, !(BuiltinType)V->getValue());;
133   }
134
135   inline static ConstPoolVal *Add(const ConstPoolClass *V1, 
136                                   const ConstPoolClass *V2) {
137     BuiltinType Result = (BuiltinType)V1->getValue() + 
138                          (BuiltinType)V2->getValue();
139     return new ConstPoolClass(*Ty, Result);
140   }
141
142   inline static ConstPoolVal *Sub(const ConstPoolClass *V1, 
143                                   const ConstPoolClass *V2) {
144     BuiltinType Result = (BuiltinType)V1->getValue() -
145                          (BuiltinType)V2->getValue();
146     return new ConstPoolClass(*Ty, Result);
147   }
148
149   inline static ConstPoolBool *LessThan(const ConstPoolClass *V1, 
150                                         const ConstPoolClass *V2) {
151     bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
152     return new ConstPoolBool(Result);
153   } 
154 };
155
156 //===----------------------------------------------------------------------===//
157 //                            DirectRules Subclasses
158 //===----------------------------------------------------------------------===//
159 //
160 // Given the DirectRules class we can now implement lots of types with little
161 // code.  Thank goodness C++ compilers are great at stomping out layers of 
162 // templates... can you imagine having to do this all by hand? (/me is lazy :)
163 //
164 static DirectRules<ConstPoolSInt,   signed char , &Type::SByteTy>  SByteTyInst;
165 static DirectRules<ConstPoolUInt, unsigned char , &Type::UByteTy>  UByteTyInst;
166 static DirectRules<ConstPoolSInt,   signed short, &Type::ShortTy>  ShortTyInst;
167 static DirectRules<ConstPoolUInt, unsigned short, &Type::UShortTy> UShortTyInst;
168 static DirectRules<ConstPoolSInt,   signed int  , &Type::IntTy>    IntTyInst;
169 static DirectRules<ConstPoolUInt, unsigned int  , &Type::UIntTy>   UIntTyInst;
170 static DirectRules<ConstPoolSInt,  int64_t      , &Type::LongTy>   LongTyInst;
171 static DirectRules<ConstPoolUInt, uint64_t      , &Type::ULongTy>  ULongTyInst;
172 static DirectRules<ConstPoolFP  , float         , &Type::FloatTy>  FloatTyInst;
173 static DirectRules<ConstPoolFP  , double        , &Type::DoubleTy> DoubleTyInst;
174
175
176 // ConstRules::find - Return the constant rules that take care of the specified
177 // type.  Note that this is cached in the Type value itself, so switch statement
178 // is only hit at most once per type.
179 //
180 const ConstRules *ConstRules::find(const Type *Ty) {
181   const ConstRules *Result;
182   switch (Ty->getPrimitiveID()) {
183   case Type::BoolTyID:   Result = &BoolTyInst;   break;
184   case Type::SByteTyID:  Result = &SByteTyInst;  break;
185   case Type::UByteTyID:  Result = &UByteTyInst;  break;
186   case Type::ShortTyID:  Result = &ShortTyInst;  break;
187   case Type::UShortTyID: Result = &UShortTyInst; break;
188   case Type::IntTyID:    Result = &IntTyInst;    break;
189   case Type::UIntTyID:   Result = &UIntTyInst;   break;
190   case Type::LongTyID:   Result = &LongTyInst;   break;
191   case Type::ULongTyID:  Result = &ULongTyInst;  break;
192   case Type::FloatTyID:  Result = &FloatTyInst;  break;
193   case Type::DoubleTyID: Result = &DoubleTyInst; break;
194   default:               Result = &EmptyInst;    break;
195   }
196
197   Ty->setConstRules(Result);   // Cache the value for future short circuiting!
198   return Result;
199 }
200
201
202 } // End namespace opt