blob: 0dae62865c9ddb0fed23d2517b686b62d5b8cf66 [file] [log] [blame]
Chris Lattner2f7c9632001-06-06 20:29:01 +00001//===- ConstantHandling.cpp - Implement ConstantHandling.h ----------------===//
2//
3// This file implements the various intrinsic operations, on constant values.
4//
5//===----------------------------------------------------------------------===//
6
Chris Lattner65b529f2002-04-08 20:18:09 +00007#include "llvm/ConstantHandling.h"
Chris Lattner9f307732002-05-06 17:54:27 +00008#include "llvm/Instruction.h"
Chris Lattner0a144ad2002-05-03 21:41:07 +00009#include <cmath>
Chris Lattnerd42d4922001-06-30 04:36:40 +000010
Chris Lattner61607ee2001-09-09 21:01:20 +000011AnnotationID ConstRules::AID(AnnotationManager::getID("opt::ConstRules",
12 &ConstRules::find));
13
Chris Lattner9f307732002-05-06 17:54:27 +000014// ConstantFoldInstruction - Attempt to constant fold the specified instruction.
15// If successful, the constant result is returned, if not, null is returned.
16//
17Constant *ConstantFoldInstruction(Instruction *I) {
18 Constant *Op0 = 0;
19 Constant *Op1 = 0;
20
21 if (I->getNumOperands() != 0) { // Get first operand if it's a constant...
22 Op0 = dyn_cast<Constant>(I->getOperand(0));
23 if (Op0 == 0) return 0; // Not a constant?, can't fold
24
25 if (I->getNumOperands() != 1) { // Get second operand if it's a constant...
26 Op1 = dyn_cast<Constant>(I->getOperand(1));
27 if (Op1 == 0) return 0; // Not a constant?, can't fold
28 }
29 }
30
31 switch (I->getOpcode()) {
32 case Instruction::Cast:
33 return ConstRules::get(*Op0)->castTo(Op0, I->getType());
34 case Instruction::Not: return ~*Op0;
35 case Instruction::Add: return *Op0 + *Op1;
36 case Instruction::Sub: return *Op0 - *Op1;
37 case Instruction::Mul: return *Op0 * *Op1;
38 case Instruction::Div: return *Op0 / *Op1;
39 case Instruction::Rem: return *Op0 % *Op1;
40
41 case Instruction::SetEQ: return *Op0 == *Op1;
42 case Instruction::SetNE: return *Op0 != *Op1;
43 case Instruction::SetLE: return *Op0 <= *Op1;
44 case Instruction::SetGE: return *Op0 >= *Op1;
45 case Instruction::SetLT: return *Op0 < *Op1;
46 case Instruction::SetGT: return *Op0 > *Op1;
47 case Instruction::Shl: return *Op0 << *Op1;
48 case Instruction::Shr: return *Op0 >> *Op1;
49 default:
50 return 0;
51 }
52}
53
54Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy) {
55 return ConstRules::get(*V)->castTo(V, DestTy);
56}
57
58Constant *ConstantFoldUnaryInstruction(unsigned Opcode, const Constant *V) {
59 switch (Opcode) {
60 case Instruction::Not: return ~*V;
61 }
62 return 0;
63}
64
65Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
66 const Constant *V2) {
67 switch (Opcode) {
68 case Instruction::Add: return *V1 + *V2;
69 case Instruction::Sub: return *V1 - *V2;
70 case Instruction::Mul: return *V1 * *V2;
71 case Instruction::Div: return *V1 / *V2;
72 case Instruction::Rem: return *V1 % *V2;
73
74 case Instruction::SetEQ: return *V1 == *V2;
75 case Instruction::SetNE: return *V1 != *V2;
76 case Instruction::SetLE: return *V1 <= *V2;
77 case Instruction::SetGE: return *V1 >= *V2;
78 case Instruction::SetLT: return *V1 < *V2;
79 case Instruction::SetGT: return *V1 > *V2;
80 }
81 return 0;
82}
83
84Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1,
85 const Constant *V2) {
86 switch (Opcode) {
87 case Instruction::Shl: return *V1 << *V2;
88 case Instruction::Shr: return *V1 >> *V2;
89 default: return 0;
90 }
91}
92
93
Chris Lattner2f7c9632001-06-06 20:29:01 +000094//===----------------------------------------------------------------------===//
95// TemplateRules Class
96//===----------------------------------------------------------------------===//
97//
98// TemplateRules - Implement a subclass of ConstRules that provides all
99// operations as noops. All other rules classes inherit from this class so
100// that if functionality is needed in the future, it can simply be added here
101// and to ConstRules without changing anything else...
102//
103// This class also provides subclasses with typesafe implementations of methods
104// so that don't have to do type casting.
105//
106template<class ArgType, class SubClassName>
107class TemplateRules : public ConstRules {
108
109 //===--------------------------------------------------------------------===//
110 // Redirecting functions that cast to the appropriate types
111 //===--------------------------------------------------------------------===//
112
Chris Lattner3462ae32001-12-03 22:26:30 +0000113 virtual Constant *op_not(const Constant *V) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000114 return SubClassName::Not((const ArgType *)V);
115 }
116
117
Chris Lattner3462ae32001-12-03 22:26:30 +0000118 virtual Constant *add(const Constant *V1,
119 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000120 return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);
121 }
122
Chris Lattner3462ae32001-12-03 22:26:30 +0000123 virtual Constant *sub(const Constant *V1,
124 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000125 return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);
126 }
127
Chris Lattner3462ae32001-12-03 22:26:30 +0000128 virtual Constant *mul(const Constant *V1,
129 const Constant *V2) const {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000130 return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);
131 }
Chris Lattneraf259a72002-04-07 08:10:14 +0000132 virtual Constant *div(const Constant *V1,
133 const Constant *V2) const {
134 return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2);
135 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000136 virtual Constant *rem(const Constant *V1,
137 const Constant *V2) const {
138 return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2);
139 }
Chris Lattner6670d862002-05-06 03:00:54 +0000140 virtual Constant *shl(const Constant *V1,
141 const Constant *V2) const {
142 return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2);
143 }
144 virtual Constant *shr(const Constant *V1,
145 const Constant *V2) const {
146 return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2);
147 }
Chris Lattner4f6031f2001-07-20 19:15:36 +0000148
Chris Lattner3462ae32001-12-03 22:26:30 +0000149 virtual ConstantBool *lessthan(const Constant *V1,
150 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000151 return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
152 }
153
Chris Lattner55406842001-07-21 19:10:49 +0000154 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +0000155 virtual ConstantBool *castToBool(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000156 return SubClassName::CastToBool((const ArgType*)V);
157 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000158 virtual ConstantSInt *castToSByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000159 return SubClassName::CastToSByte((const ArgType*)V);
160 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000161 virtual ConstantUInt *castToUByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000162 return SubClassName::CastToUByte((const ArgType*)V);
163 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000164 virtual ConstantSInt *castToShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000165 return SubClassName::CastToShort((const ArgType*)V);
166 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000167 virtual ConstantUInt *castToUShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000168 return SubClassName::CastToUShort((const ArgType*)V);
169 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000170 virtual ConstantSInt *castToInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000171 return SubClassName::CastToInt((const ArgType*)V);
172 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000173 virtual ConstantUInt *castToUInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000174 return SubClassName::CastToUInt((const ArgType*)V);
175 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000176 virtual ConstantSInt *castToLong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000177 return SubClassName::CastToLong((const ArgType*)V);
178 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000179 virtual ConstantUInt *castToULong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000180 return SubClassName::CastToULong((const ArgType*)V);
181 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000182 virtual ConstantFP *castToFloat(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000183 return SubClassName::CastToFloat((const ArgType*)V);
184 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000185 virtual ConstantFP *castToDouble(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000186 return SubClassName::CastToDouble((const ArgType*)V);
187 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000188 virtual ConstantPointer *castToPointer(const Constant *V,
189 const PointerType *Ty) const {
Chris Lattner977f0042001-11-01 05:55:13 +0000190 return SubClassName::CastToPointer((const ArgType*)V, Ty);
191 }
Chris Lattner55406842001-07-21 19:10:49 +0000192
Chris Lattner2f7c9632001-06-06 20:29:01 +0000193 //===--------------------------------------------------------------------===//
194 // Default "noop" implementations
195 //===--------------------------------------------------------------------===//
196
Chris Lattner3462ae32001-12-03 22:26:30 +0000197 inline static Constant *Not(const ArgType *V) { return 0; }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000198
Chris Lattner3462ae32001-12-03 22:26:30 +0000199 inline static Constant *Add(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000200 return 0;
201 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000202 inline static Constant *Sub(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000203 return 0;
204 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000205 inline static Constant *Mul(const ArgType *V1, const ArgType *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000206 return 0;
207 }
Chris Lattneraf259a72002-04-07 08:10:14 +0000208 inline static Constant *Div(const ArgType *V1, const ArgType *V2) {
209 return 0;
210 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000211 inline static Constant *Rem(const ArgType *V1, const ArgType *V2) {
212 return 0;
213 }
Chris Lattner6670d862002-05-06 03:00:54 +0000214 inline static Constant *Shl(const ArgType *V1, const ArgType *V2) {
215 return 0;
216 }
217 inline static Constant *Shr(const ArgType *V1, const ArgType *V2) {
218 return 0;
219 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000220 inline static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000221 return 0;
222 }
Chris Lattner55406842001-07-21 19:10:49 +0000223
224 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +0000225 inline static ConstantBool *CastToBool (const Constant *V) { return 0; }
226 inline static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
227 inline static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
228 inline static ConstantSInt *CastToShort (const Constant *V) { return 0; }
229 inline static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
230 inline static ConstantSInt *CastToInt (const Constant *V) { return 0; }
231 inline static ConstantUInt *CastToUInt (const Constant *V) { return 0; }
232 inline static ConstantSInt *CastToLong (const Constant *V) { return 0; }
233 inline static ConstantUInt *CastToULong (const Constant *V) { return 0; }
234 inline static ConstantFP *CastToFloat (const Constant *V) { return 0; }
235 inline static ConstantFP *CastToDouble(const Constant *V) { return 0; }
236 inline static ConstantPointer *CastToPointer(const Constant *,
237 const PointerType *) {return 0;}
Chris Lattner2f7c9632001-06-06 20:29:01 +0000238};
239
240
241
242//===----------------------------------------------------------------------===//
243// EmptyRules Class
244//===----------------------------------------------------------------------===//
245//
246// EmptyRules provides a concrete base class of ConstRules that does nothing
247//
Chris Lattner3462ae32001-12-03 22:26:30 +0000248struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
Chris Lattner61607ee2001-09-09 21:01:20 +0000249};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000250
251
252
253//===----------------------------------------------------------------------===//
254// BoolRules Class
255//===----------------------------------------------------------------------===//
256//
257// BoolRules provides a concrete base class of ConstRules for the 'bool' type.
258//
Chris Lattner3462ae32001-12-03 22:26:30 +0000259struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000260
Chris Lattner3462ae32001-12-03 22:26:30 +0000261 inline static Constant *Not(const ConstantBool *V) {
262 return ConstantBool::get(!V->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000263 }
264
Chris Lattner3462ae32001-12-03 22:26:30 +0000265 inline static Constant *Or(const ConstantBool *V1,
266 const ConstantBool *V2) {
267 return ConstantBool::get(V1->getValue() | V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000268 }
269
Chris Lattner3462ae32001-12-03 22:26:30 +0000270 inline static Constant *And(const ConstantBool *V1,
271 const ConstantBool *V2) {
272 return ConstantBool::get(V1->getValue() & V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000273 }
Chris Lattner61607ee2001-09-09 21:01:20 +0000274};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000275
276
277//===----------------------------------------------------------------------===//
Chris Lattner977f0042001-11-01 05:55:13 +0000278// PointerRules Class
279//===----------------------------------------------------------------------===//
280//
281// PointerRules provides a concrete base class of ConstRules for pointer types
282//
Chris Lattner3462ae32001-12-03 22:26:30 +0000283struct PointerRules : public TemplateRules<ConstantPointer, PointerRules> {
284 inline static ConstantBool *CastToBool (const Constant *V) {
285 if (V->isNullValue()) return ConstantBool::False;
Chris Lattner977f0042001-11-01 05:55:13 +0000286 return 0; // Can't const prop other types of pointers
287 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000288 inline static ConstantSInt *CastToSByte (const Constant *V) {
289 if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000290 return 0; // Can't const prop other types of pointers
291 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000292 inline static ConstantUInt *CastToUByte (const Constant *V) {
293 if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000294 return 0; // Can't const prop other types of pointers
295 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000296 inline static ConstantSInt *CastToShort (const Constant *V) {
297 if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000298 return 0; // Can't const prop other types of pointers
299 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000300 inline static ConstantUInt *CastToUShort(const Constant *V) {
301 if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000302 return 0; // Can't const prop other types of pointers
303 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000304 inline static ConstantSInt *CastToInt (const Constant *V) {
305 if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000306 return 0; // Can't const prop other types of pointers
307 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000308 inline static ConstantUInt *CastToUInt (const Constant *V) {
309 if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000310 return 0; // Can't const prop other types of pointers
311 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000312 inline static ConstantSInt *CastToLong (const Constant *V) {
313 if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000314 return 0; // Can't const prop other types of pointers
315 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000316 inline static ConstantUInt *CastToULong (const Constant *V) {
317 if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000318 return 0; // Can't const prop other types of pointers
319 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000320 inline static ConstantFP *CastToFloat (const Constant *V) {
321 if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000322 return 0; // Can't const prop other types of pointers
323 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000324 inline static ConstantFP *CastToDouble(const Constant *V) {
325 if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000326 return 0; // Can't const prop other types of pointers
327 }
328
Chris Lattner3462ae32001-12-03 22:26:30 +0000329 inline static ConstantPointer *CastToPointer(const ConstantPointer *V,
330 const PointerType *PTy) {
Chris Lattner62af86e2002-05-03 20:09:52 +0000331 if (V->getType() == PTy)
332 return const_cast<ConstantPointer*>(V); // Allow cast %PTy %ptr to %PTy
Chris Lattner977f0042001-11-01 05:55:13 +0000333 if (V->isNullValue())
Chris Lattner3462ae32001-12-03 22:26:30 +0000334 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000335 return 0; // Can't const prop other types of pointers
336 }
337};
338
339
340//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000341// DirectRules Class
342//===----------------------------------------------------------------------===//
343//
344// DirectRules provides a concrete base classes of ConstRules for a variety of
345// different types. This allows the C++ compiler to automatically generate our
346// constant handling operations in a typesafe and accurate manner.
347//
Chris Lattner0a144ad2002-05-03 21:41:07 +0000348template<class ConstantClass, class BuiltinType, Type **Ty, class SuperClass>
349struct DirectRules : public TemplateRules<ConstantClass, SuperClass> {
Chris Lattner3462ae32001-12-03 22:26:30 +0000350 inline static Constant *Add(const ConstantClass *V1,
351 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000352 BuiltinType Result = (BuiltinType)V1->getValue() +
353 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000354 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000355 }
356
Chris Lattner3462ae32001-12-03 22:26:30 +0000357 inline static Constant *Sub(const ConstantClass *V1,
358 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000359 BuiltinType Result = (BuiltinType)V1->getValue() -
360 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000361 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000362 }
363
Chris Lattner3462ae32001-12-03 22:26:30 +0000364 inline static Constant *Mul(const ConstantClass *V1,
365 const ConstantClass *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000366 BuiltinType Result = (BuiltinType)V1->getValue() *
367 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000368 return ConstantClass::get(*Ty, Result);
Chris Lattner4f6031f2001-07-20 19:15:36 +0000369 }
370
Chris Lattner0a144ad2002-05-03 21:41:07 +0000371 inline static Constant *Div(const ConstantClass *V1,
Chris Lattneraf259a72002-04-07 08:10:14 +0000372 const ConstantClass *V2) {
Chris Lattner0a144ad2002-05-03 21:41:07 +0000373 if (V2->isNullValue()) return 0;
Chris Lattneraf259a72002-04-07 08:10:14 +0000374 BuiltinType Result = (BuiltinType)V1->getValue() /
375 (BuiltinType)V2->getValue();
376 return ConstantClass::get(*Ty, Result);
377 }
378
Chris Lattner3462ae32001-12-03 22:26:30 +0000379 inline static ConstantBool *LessThan(const ConstantClass *V1,
380 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000381 bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000382 return ConstantBool::get(Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000383 }
Chris Lattner55406842001-07-21 19:10:49 +0000384
Chris Lattner3462ae32001-12-03 22:26:30 +0000385 inline static ConstantPointer *CastToPointer(const ConstantClass *V,
386 const PointerType *PTy) {
Chris Lattner977f0042001-11-01 05:55:13 +0000387 if (V->isNullValue()) // Is it a FP or Integral null value?
Chris Lattner3462ae32001-12-03 22:26:30 +0000388 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000389 return 0; // Can't const prop other types of pointers
390 }
391
Chris Lattner55406842001-07-21 19:10:49 +0000392 // Casting operators. ick
393#define DEF_CAST(TYPE, CLASS, CTYPE) \
Chris Lattner3462ae32001-12-03 22:26:30 +0000394 inline static CLASS *CastTo##TYPE (const ConstantClass *V) { \
Chris Lattnerbbb22962001-09-07 16:40:34 +0000395 return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
Chris Lattner55406842001-07-21 19:10:49 +0000396 }
397
Chris Lattner3462ae32001-12-03 22:26:30 +0000398 DEF_CAST(Bool , ConstantBool, bool)
399 DEF_CAST(SByte , ConstantSInt, signed char)
400 DEF_CAST(UByte , ConstantUInt, unsigned char)
401 DEF_CAST(Short , ConstantSInt, signed short)
402 DEF_CAST(UShort, ConstantUInt, unsigned short)
403 DEF_CAST(Int , ConstantSInt, signed int)
404 DEF_CAST(UInt , ConstantUInt, unsigned int)
405 DEF_CAST(Long , ConstantSInt, int64_t)
406 DEF_CAST(ULong , ConstantUInt, uint64_t)
407 DEF_CAST(Float , ConstantFP , float)
408 DEF_CAST(Double, ConstantFP , double)
Chris Lattner55406842001-07-21 19:10:49 +0000409#undef DEF_CAST
Chris Lattner2f7c9632001-06-06 20:29:01 +0000410};
411
Chris Lattner62af86e2002-05-03 20:09:52 +0000412
413//===----------------------------------------------------------------------===//
414// DirectIntRules Class
415//===----------------------------------------------------------------------===//
416//
417// DirectIntRules provides implementations of functions that are valid on
418// integer types, but not all types in general.
419//
420template <class ConstantClass, class BuiltinType, Type **Ty>
Chris Lattner0a144ad2002-05-03 21:41:07 +0000421struct DirectIntRules
422 : public DirectRules<ConstantClass, BuiltinType, Ty,
423 DirectIntRules<ConstantClass, BuiltinType, Ty> > {
Chris Lattner62af86e2002-05-03 20:09:52 +0000424 inline static Constant *Not(const ConstantClass *V) {
425 return ConstantClass::get(*Ty, ~(BuiltinType)V->getValue());;
426 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000427
428 inline static Constant *Rem(const ConstantClass *V1,
429 const ConstantClass *V2) {
430 if (V2->isNullValue()) return 0;
431 BuiltinType Result = (BuiltinType)V1->getValue() %
432 (BuiltinType)V2->getValue();
433 return ConstantClass::get(*Ty, Result);
434 }
Chris Lattner6670d862002-05-06 03:00:54 +0000435
436 inline static Constant *Shl(const ConstantClass *V1,
437 const ConstantClass *V2) {
438 BuiltinType Result = (BuiltinType)V1->getValue() <<
439 (BuiltinType)V2->getValue();
440 return ConstantClass::get(*Ty, Result);
441 }
442
443 inline static Constant *Shr(const ConstantClass *V1,
444 const ConstantClass *V2) {
445 BuiltinType Result = (BuiltinType)V1->getValue() >>
446 (BuiltinType)V2->getValue();
447 return ConstantClass::get(*Ty, Result);
448 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000449};
450
451
452//===----------------------------------------------------------------------===//
453// DirectFPRules Class
454//===----------------------------------------------------------------------===//
455//
456// DirectFPRules provides implementations of functions that are valid on
457// floating point types, but not all types in general.
458//
459template <class ConstantClass, class BuiltinType, Type **Ty>
460struct DirectFPRules
461 : public DirectRules<ConstantClass, BuiltinType, Ty,
462 DirectFPRules<ConstantClass, BuiltinType, Ty> > {
463 inline static Constant *Rem(const ConstantClass *V1,
464 const ConstantClass *V2) {
465 if (V2->isNullValue()) return 0;
466 BuiltinType Result = std::fmod((BuiltinType)V1->getValue(),
467 (BuiltinType)V2->getValue());
468 return ConstantClass::get(*Ty, Result);
469 }
Chris Lattner62af86e2002-05-03 20:09:52 +0000470};
471
472
Chris Lattner2f7c9632001-06-06 20:29:01 +0000473//===----------------------------------------------------------------------===//
474// DirectRules Subclasses
475//===----------------------------------------------------------------------===//
476//
477// Given the DirectRules class we can now implement lots of types with little
478// code. Thank goodness C++ compilers are great at stomping out layers of
479// templates... can you imagine having to do this all by hand? (/me is lazy :)
480//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000481
482// ConstRules::find - Return the constant rules that take care of the specified
Chris Lattner61607ee2001-09-09 21:01:20 +0000483// type.
Chris Lattner2f7c9632001-06-06 20:29:01 +0000484//
Chris Lattner61607ee2001-09-09 21:01:20 +0000485Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
486 assert(AID == ConstRules::AID && "Bad annotation for factory!");
Chris Lattner8f191122001-10-01 18:26:53 +0000487 const Type *Ty = cast<Type>((const Value*)TyA);
Chris Lattner61607ee2001-09-09 21:01:20 +0000488
Chris Lattner2f7c9632001-06-06 20:29:01 +0000489 switch (Ty->getPrimitiveID()) {
Chris Lattner977f0042001-11-01 05:55:13 +0000490 case Type::BoolTyID: return new BoolRules();
491 case Type::PointerTyID: return new PointerRules();
Chris Lattner61607ee2001-09-09 21:01:20 +0000492 case Type::SByteTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000493 return new DirectIntRules<ConstantSInt, signed char , &Type::SByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000494 case Type::UByteTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000495 return new DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000496 case Type::ShortTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000497 return new DirectIntRules<ConstantSInt, signed short, &Type::ShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000498 case Type::UShortTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000499 return new DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000500 case Type::IntTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000501 return new DirectIntRules<ConstantSInt, signed int , &Type::IntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000502 case Type::UIntTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000503 return new DirectIntRules<ConstantUInt, unsigned int , &Type::UIntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000504 case Type::LongTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000505 return new DirectIntRules<ConstantSInt, int64_t , &Type::LongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000506 case Type::ULongTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000507 return new DirectIntRules<ConstantUInt, uint64_t , &Type::ULongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000508 case Type::FloatTyID:
Chris Lattner0a144ad2002-05-03 21:41:07 +0000509 return new DirectFPRules<ConstantFP , float , &Type::FloatTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000510 case Type::DoubleTyID:
Chris Lattner0a144ad2002-05-03 21:41:07 +0000511 return new DirectFPRules<ConstantFP , double , &Type::DoubleTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000512 default:
513 return new EmptyRules();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000514 }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000515}