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