ConstantFold.cpp revision 14712a6abf2587666e8171cbb6ebe6ffab3ea514
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
9namespace opt {
10
11AnnotationID 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//
26template<class ArgType, class SubClassName>
27class 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//
134struct 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//
145struct 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//
171template<class ConstPoolClass, class BuiltinType, const Type **Ty>
172struct 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//
239Annotation *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
272