blob: a366970fae821d321383d6c8f7deee438e632ca3 [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 Lattner78a0d422002-05-07 20:44:59 +00008#include "llvm/iPHINode.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) {
Chris Lattner78a0d422002-05-07 20:44:59 +000018 if (PHINode *PN = dyn_cast<PHINode>(I)) {
19 if (PN->getNumIncomingValues() == 0)
20 return Constant::getNullValue(PN->getType());
21
22 Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
23 if (Result == 0) return 0;
24
25 // Handle PHI nodes specially here...
26 for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
27 if (PN->getIncomingValue(i) != Result)
28 return 0; // Not all the same incoming constants...
29
30 // If we reach here, all incoming values are the same constant.
31 return Result;
32 }
33
Chris Lattner9f307732002-05-06 17:54:27 +000034 Constant *Op0 = 0;
35 Constant *Op1 = 0;
36
37 if (I->getNumOperands() != 0) { // Get first operand if it's a constant...
38 Op0 = dyn_cast<Constant>(I->getOperand(0));
39 if (Op0 == 0) return 0; // Not a constant?, can't fold
40
41 if (I->getNumOperands() != 1) { // Get second operand if it's a constant...
42 Op1 = dyn_cast<Constant>(I->getOperand(1));
43 if (Op1 == 0) return 0; // Not a constant?, can't fold
44 }
45 }
46
47 switch (I->getOpcode()) {
48 case Instruction::Cast:
49 return ConstRules::get(*Op0)->castTo(Op0, I->getType());
50 case Instruction::Not: return ~*Op0;
51 case Instruction::Add: return *Op0 + *Op1;
52 case Instruction::Sub: return *Op0 - *Op1;
53 case Instruction::Mul: return *Op0 * *Op1;
54 case Instruction::Div: return *Op0 / *Op1;
55 case Instruction::Rem: return *Op0 % *Op1;
56
57 case Instruction::SetEQ: return *Op0 == *Op1;
58 case Instruction::SetNE: return *Op0 != *Op1;
59 case Instruction::SetLE: return *Op0 <= *Op1;
60 case Instruction::SetGE: return *Op0 >= *Op1;
61 case Instruction::SetLT: return *Op0 < *Op1;
62 case Instruction::SetGT: return *Op0 > *Op1;
63 case Instruction::Shl: return *Op0 << *Op1;
64 case Instruction::Shr: return *Op0 >> *Op1;
65 default:
66 return 0;
67 }
68}
69
70Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy) {
71 return ConstRules::get(*V)->castTo(V, DestTy);
72}
73
74Constant *ConstantFoldUnaryInstruction(unsigned Opcode, const Constant *V) {
75 switch (Opcode) {
76 case Instruction::Not: return ~*V;
77 }
78 return 0;
79}
80
81Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
82 const Constant *V2) {
83 switch (Opcode) {
84 case Instruction::Add: return *V1 + *V2;
85 case Instruction::Sub: return *V1 - *V2;
86 case Instruction::Mul: return *V1 * *V2;
87 case Instruction::Div: return *V1 / *V2;
88 case Instruction::Rem: return *V1 % *V2;
89
90 case Instruction::SetEQ: return *V1 == *V2;
91 case Instruction::SetNE: return *V1 != *V2;
92 case Instruction::SetLE: return *V1 <= *V2;
93 case Instruction::SetGE: return *V1 >= *V2;
94 case Instruction::SetLT: return *V1 < *V2;
95 case Instruction::SetGT: return *V1 > *V2;
96 }
97 return 0;
98}
99
100Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1,
101 const Constant *V2) {
102 switch (Opcode) {
103 case Instruction::Shl: return *V1 << *V2;
104 case Instruction::Shr: return *V1 >> *V2;
105 default: return 0;
106 }
107}
108
109
Chris Lattner2f7c9632001-06-06 20:29:01 +0000110//===----------------------------------------------------------------------===//
111// TemplateRules Class
112//===----------------------------------------------------------------------===//
113//
114// TemplateRules - Implement a subclass of ConstRules that provides all
115// operations as noops. All other rules classes inherit from this class so
116// that if functionality is needed in the future, it can simply be added here
117// and to ConstRules without changing anything else...
118//
119// This class also provides subclasses with typesafe implementations of methods
120// so that don't have to do type casting.
121//
122template<class ArgType, class SubClassName>
123class TemplateRules : public ConstRules {
124
125 //===--------------------------------------------------------------------===//
126 // Redirecting functions that cast to the appropriate types
127 //===--------------------------------------------------------------------===//
128
Chris Lattner3462ae32001-12-03 22:26:30 +0000129 virtual Constant *op_not(const Constant *V) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000130 return SubClassName::Not((const ArgType *)V);
131 }
132
133
Chris Lattner3462ae32001-12-03 22:26:30 +0000134 virtual Constant *add(const Constant *V1,
135 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000136 return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);
137 }
138
Chris Lattner3462ae32001-12-03 22:26:30 +0000139 virtual Constant *sub(const Constant *V1,
140 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000141 return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);
142 }
143
Chris Lattner3462ae32001-12-03 22:26:30 +0000144 virtual Constant *mul(const Constant *V1,
145 const Constant *V2) const {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000146 return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);
147 }
Chris Lattneraf259a72002-04-07 08:10:14 +0000148 virtual Constant *div(const Constant *V1,
149 const Constant *V2) const {
150 return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2);
151 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000152 virtual Constant *rem(const Constant *V1,
153 const Constant *V2) const {
154 return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2);
155 }
Chris Lattner6670d862002-05-06 03:00:54 +0000156 virtual Constant *shl(const Constant *V1,
157 const Constant *V2) const {
158 return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2);
159 }
160 virtual Constant *shr(const Constant *V1,
161 const Constant *V2) const {
162 return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2);
163 }
Chris Lattner4f6031f2001-07-20 19:15:36 +0000164
Chris Lattner3462ae32001-12-03 22:26:30 +0000165 virtual ConstantBool *lessthan(const Constant *V1,
166 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000167 return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
168 }
169
Chris Lattner55406842001-07-21 19:10:49 +0000170 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +0000171 virtual ConstantBool *castToBool(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000172 return SubClassName::CastToBool((const ArgType*)V);
173 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000174 virtual ConstantSInt *castToSByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000175 return SubClassName::CastToSByte((const ArgType*)V);
176 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000177 virtual ConstantUInt *castToUByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000178 return SubClassName::CastToUByte((const ArgType*)V);
179 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000180 virtual ConstantSInt *castToShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000181 return SubClassName::CastToShort((const ArgType*)V);
182 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000183 virtual ConstantUInt *castToUShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000184 return SubClassName::CastToUShort((const ArgType*)V);
185 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000186 virtual ConstantSInt *castToInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000187 return SubClassName::CastToInt((const ArgType*)V);
188 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000189 virtual ConstantUInt *castToUInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000190 return SubClassName::CastToUInt((const ArgType*)V);
191 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000192 virtual ConstantSInt *castToLong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000193 return SubClassName::CastToLong((const ArgType*)V);
194 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000195 virtual ConstantUInt *castToULong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000196 return SubClassName::CastToULong((const ArgType*)V);
197 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000198 virtual ConstantFP *castToFloat(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000199 return SubClassName::CastToFloat((const ArgType*)V);
200 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000201 virtual ConstantFP *castToDouble(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +0000202 return SubClassName::CastToDouble((const ArgType*)V);
203 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000204 virtual ConstantPointer *castToPointer(const Constant *V,
205 const PointerType *Ty) const {
Chris Lattner977f0042001-11-01 05:55:13 +0000206 return SubClassName::CastToPointer((const ArgType*)V, Ty);
207 }
Chris Lattner55406842001-07-21 19:10:49 +0000208
Chris Lattner2f7c9632001-06-06 20:29:01 +0000209 //===--------------------------------------------------------------------===//
210 // Default "noop" implementations
211 //===--------------------------------------------------------------------===//
212
Chris Lattner3462ae32001-12-03 22:26:30 +0000213 inline static Constant *Not(const ArgType *V) { return 0; }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000214
Chris Lattner3462ae32001-12-03 22:26:30 +0000215 inline static Constant *Add(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000216 return 0;
217 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000218 inline static Constant *Sub(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000219 return 0;
220 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000221 inline static Constant *Mul(const ArgType *V1, const ArgType *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000222 return 0;
223 }
Chris Lattneraf259a72002-04-07 08:10:14 +0000224 inline static Constant *Div(const ArgType *V1, const ArgType *V2) {
225 return 0;
226 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000227 inline static Constant *Rem(const ArgType *V1, const ArgType *V2) {
228 return 0;
229 }
Chris Lattner6670d862002-05-06 03:00:54 +0000230 inline static Constant *Shl(const ArgType *V1, const ArgType *V2) {
231 return 0;
232 }
233 inline static Constant *Shr(const ArgType *V1, const ArgType *V2) {
234 return 0;
235 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000236 inline static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000237 return 0;
238 }
Chris Lattner55406842001-07-21 19:10:49 +0000239
240 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +0000241 inline static ConstantBool *CastToBool (const Constant *V) { return 0; }
242 inline static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
243 inline static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
244 inline static ConstantSInt *CastToShort (const Constant *V) { return 0; }
245 inline static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
246 inline static ConstantSInt *CastToInt (const Constant *V) { return 0; }
247 inline static ConstantUInt *CastToUInt (const Constant *V) { return 0; }
248 inline static ConstantSInt *CastToLong (const Constant *V) { return 0; }
249 inline static ConstantUInt *CastToULong (const Constant *V) { return 0; }
250 inline static ConstantFP *CastToFloat (const Constant *V) { return 0; }
251 inline static ConstantFP *CastToDouble(const Constant *V) { return 0; }
252 inline static ConstantPointer *CastToPointer(const Constant *,
253 const PointerType *) {return 0;}
Chris Lattner2f7c9632001-06-06 20:29:01 +0000254};
255
256
257
258//===----------------------------------------------------------------------===//
259// EmptyRules Class
260//===----------------------------------------------------------------------===//
261//
262// EmptyRules provides a concrete base class of ConstRules that does nothing
263//
Chris Lattner3462ae32001-12-03 22:26:30 +0000264struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
Chris Lattner61607ee2001-09-09 21:01:20 +0000265};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000266
267
268
269//===----------------------------------------------------------------------===//
270// BoolRules Class
271//===----------------------------------------------------------------------===//
272//
273// BoolRules provides a concrete base class of ConstRules for the 'bool' type.
274//
Chris Lattner3462ae32001-12-03 22:26:30 +0000275struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000276
Chris Lattner3462ae32001-12-03 22:26:30 +0000277 inline static Constant *Not(const ConstantBool *V) {
278 return ConstantBool::get(!V->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000279 }
280
Chris Lattner3462ae32001-12-03 22:26:30 +0000281 inline static Constant *Or(const ConstantBool *V1,
282 const ConstantBool *V2) {
283 return ConstantBool::get(V1->getValue() | V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000284 }
285
Chris Lattner3462ae32001-12-03 22:26:30 +0000286 inline static Constant *And(const ConstantBool *V1,
287 const ConstantBool *V2) {
288 return ConstantBool::get(V1->getValue() & V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000289 }
Chris Lattner61607ee2001-09-09 21:01:20 +0000290};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000291
292
293//===----------------------------------------------------------------------===//
Chris Lattner977f0042001-11-01 05:55:13 +0000294// PointerRules Class
295//===----------------------------------------------------------------------===//
296//
297// PointerRules provides a concrete base class of ConstRules for pointer types
298//
Chris Lattner3462ae32001-12-03 22:26:30 +0000299struct PointerRules : public TemplateRules<ConstantPointer, PointerRules> {
300 inline static ConstantBool *CastToBool (const Constant *V) {
301 if (V->isNullValue()) return ConstantBool::False;
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 *CastToSByte (const Constant *V) {
305 if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 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 *CastToUByte (const Constant *V) {
309 if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 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 *CastToShort (const Constant *V) {
313 if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 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 *CastToUShort(const Constant *V) {
317 if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 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 ConstantSInt *CastToInt (const Constant *V) {
321 if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 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 ConstantUInt *CastToUInt (const Constant *V) {
325 if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000326 return 0; // Can't const prop other types of pointers
327 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000328 inline static ConstantSInt *CastToLong (const Constant *V) {
329 if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000330 return 0; // Can't const prop other types of pointers
331 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000332 inline static ConstantUInt *CastToULong (const Constant *V) {
333 if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000334 return 0; // Can't const prop other types of pointers
335 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000336 inline static ConstantFP *CastToFloat (const Constant *V) {
337 if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000338 return 0; // Can't const prop other types of pointers
339 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000340 inline static ConstantFP *CastToDouble(const Constant *V) {
341 if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000342 return 0; // Can't const prop other types of pointers
343 }
344
Chris Lattner3462ae32001-12-03 22:26:30 +0000345 inline static ConstantPointer *CastToPointer(const ConstantPointer *V,
346 const PointerType *PTy) {
Chris Lattner62af86e2002-05-03 20:09:52 +0000347 if (V->getType() == PTy)
348 return const_cast<ConstantPointer*>(V); // Allow cast %PTy %ptr to %PTy
Chris Lattner977f0042001-11-01 05:55:13 +0000349 if (V->isNullValue())
Chris Lattner3462ae32001-12-03 22:26:30 +0000350 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000351 return 0; // Can't const prop other types of pointers
352 }
353};
354
355
356//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000357// DirectRules Class
358//===----------------------------------------------------------------------===//
359//
360// DirectRules provides a concrete base classes of ConstRules for a variety of
361// different types. This allows the C++ compiler to automatically generate our
362// constant handling operations in a typesafe and accurate manner.
363//
Chris Lattner0a144ad2002-05-03 21:41:07 +0000364template<class ConstantClass, class BuiltinType, Type **Ty, class SuperClass>
365struct DirectRules : public TemplateRules<ConstantClass, SuperClass> {
Chris Lattner3462ae32001-12-03 22:26:30 +0000366 inline static Constant *Add(const ConstantClass *V1,
367 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000368 BuiltinType Result = (BuiltinType)V1->getValue() +
369 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000370 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000371 }
372
Chris Lattner3462ae32001-12-03 22:26:30 +0000373 inline static Constant *Sub(const ConstantClass *V1,
374 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000375 BuiltinType Result = (BuiltinType)V1->getValue() -
376 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000377 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000378 }
379
Chris Lattner3462ae32001-12-03 22:26:30 +0000380 inline static Constant *Mul(const ConstantClass *V1,
381 const ConstantClass *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000382 BuiltinType Result = (BuiltinType)V1->getValue() *
383 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000384 return ConstantClass::get(*Ty, Result);
Chris Lattner4f6031f2001-07-20 19:15:36 +0000385 }
386
Chris Lattner0a144ad2002-05-03 21:41:07 +0000387 inline static Constant *Div(const ConstantClass *V1,
Chris Lattneraf259a72002-04-07 08:10:14 +0000388 const ConstantClass *V2) {
Chris Lattner0a144ad2002-05-03 21:41:07 +0000389 if (V2->isNullValue()) return 0;
Chris Lattneraf259a72002-04-07 08:10:14 +0000390 BuiltinType Result = (BuiltinType)V1->getValue() /
391 (BuiltinType)V2->getValue();
392 return ConstantClass::get(*Ty, Result);
393 }
394
Chris Lattner3462ae32001-12-03 22:26:30 +0000395 inline static ConstantBool *LessThan(const ConstantClass *V1,
396 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000397 bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000398 return ConstantBool::get(Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000399 }
Chris Lattner55406842001-07-21 19:10:49 +0000400
Chris Lattner3462ae32001-12-03 22:26:30 +0000401 inline static ConstantPointer *CastToPointer(const ConstantClass *V,
402 const PointerType *PTy) {
Chris Lattner977f0042001-11-01 05:55:13 +0000403 if (V->isNullValue()) // Is it a FP or Integral null value?
Chris Lattner3462ae32001-12-03 22:26:30 +0000404 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000405 return 0; // Can't const prop other types of pointers
406 }
407
Chris Lattner55406842001-07-21 19:10:49 +0000408 // Casting operators. ick
409#define DEF_CAST(TYPE, CLASS, CTYPE) \
Chris Lattner3462ae32001-12-03 22:26:30 +0000410 inline static CLASS *CastTo##TYPE (const ConstantClass *V) { \
Chris Lattnerbbb22962001-09-07 16:40:34 +0000411 return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
Chris Lattner55406842001-07-21 19:10:49 +0000412 }
413
Chris Lattner3462ae32001-12-03 22:26:30 +0000414 DEF_CAST(Bool , ConstantBool, bool)
415 DEF_CAST(SByte , ConstantSInt, signed char)
416 DEF_CAST(UByte , ConstantUInt, unsigned char)
417 DEF_CAST(Short , ConstantSInt, signed short)
418 DEF_CAST(UShort, ConstantUInt, unsigned short)
419 DEF_CAST(Int , ConstantSInt, signed int)
420 DEF_CAST(UInt , ConstantUInt, unsigned int)
421 DEF_CAST(Long , ConstantSInt, int64_t)
422 DEF_CAST(ULong , ConstantUInt, uint64_t)
423 DEF_CAST(Float , ConstantFP , float)
424 DEF_CAST(Double, ConstantFP , double)
Chris Lattner55406842001-07-21 19:10:49 +0000425#undef DEF_CAST
Chris Lattner2f7c9632001-06-06 20:29:01 +0000426};
427
Chris Lattner62af86e2002-05-03 20:09:52 +0000428
429//===----------------------------------------------------------------------===//
430// DirectIntRules Class
431//===----------------------------------------------------------------------===//
432//
433// DirectIntRules provides implementations of functions that are valid on
434// integer types, but not all types in general.
435//
436template <class ConstantClass, class BuiltinType, Type **Ty>
Chris Lattner0a144ad2002-05-03 21:41:07 +0000437struct DirectIntRules
438 : public DirectRules<ConstantClass, BuiltinType, Ty,
439 DirectIntRules<ConstantClass, BuiltinType, Ty> > {
Chris Lattner62af86e2002-05-03 20:09:52 +0000440 inline static Constant *Not(const ConstantClass *V) {
441 return ConstantClass::get(*Ty, ~(BuiltinType)V->getValue());;
442 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000443
444 inline static Constant *Rem(const ConstantClass *V1,
445 const ConstantClass *V2) {
446 if (V2->isNullValue()) return 0;
447 BuiltinType Result = (BuiltinType)V1->getValue() %
448 (BuiltinType)V2->getValue();
449 return ConstantClass::get(*Ty, Result);
450 }
Chris Lattner6670d862002-05-06 03:00:54 +0000451
452 inline static Constant *Shl(const ConstantClass *V1,
453 const ConstantClass *V2) {
454 BuiltinType Result = (BuiltinType)V1->getValue() <<
455 (BuiltinType)V2->getValue();
456 return ConstantClass::get(*Ty, Result);
457 }
458
459 inline static Constant *Shr(const ConstantClass *V1,
460 const ConstantClass *V2) {
461 BuiltinType Result = (BuiltinType)V1->getValue() >>
462 (BuiltinType)V2->getValue();
463 return ConstantClass::get(*Ty, Result);
464 }
Chris Lattner0a144ad2002-05-03 21:41:07 +0000465};
466
467
468//===----------------------------------------------------------------------===//
469// DirectFPRules Class
470//===----------------------------------------------------------------------===//
471//
472// DirectFPRules provides implementations of functions that are valid on
473// floating point types, but not all types in general.
474//
475template <class ConstantClass, class BuiltinType, Type **Ty>
476struct DirectFPRules
477 : public DirectRules<ConstantClass, BuiltinType, Ty,
478 DirectFPRules<ConstantClass, BuiltinType, Ty> > {
479 inline static Constant *Rem(const ConstantClass *V1,
480 const ConstantClass *V2) {
481 if (V2->isNullValue()) return 0;
482 BuiltinType Result = std::fmod((BuiltinType)V1->getValue(),
483 (BuiltinType)V2->getValue());
484 return ConstantClass::get(*Ty, Result);
485 }
Chris Lattner62af86e2002-05-03 20:09:52 +0000486};
487
488
Chris Lattner2f7c9632001-06-06 20:29:01 +0000489//===----------------------------------------------------------------------===//
490// DirectRules Subclasses
491//===----------------------------------------------------------------------===//
492//
493// Given the DirectRules class we can now implement lots of types with little
494// code. Thank goodness C++ compilers are great at stomping out layers of
495// templates... can you imagine having to do this all by hand? (/me is lazy :)
496//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000497
498// ConstRules::find - Return the constant rules that take care of the specified
Chris Lattner61607ee2001-09-09 21:01:20 +0000499// type.
Chris Lattner2f7c9632001-06-06 20:29:01 +0000500//
Chris Lattner61607ee2001-09-09 21:01:20 +0000501Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
502 assert(AID == ConstRules::AID && "Bad annotation for factory!");
Chris Lattner8f191122001-10-01 18:26:53 +0000503 const Type *Ty = cast<Type>((const Value*)TyA);
Chris Lattner61607ee2001-09-09 21:01:20 +0000504
Chris Lattner2f7c9632001-06-06 20:29:01 +0000505 switch (Ty->getPrimitiveID()) {
Chris Lattner977f0042001-11-01 05:55:13 +0000506 case Type::BoolTyID: return new BoolRules();
507 case Type::PointerTyID: return new PointerRules();
Chris Lattner61607ee2001-09-09 21:01:20 +0000508 case Type::SByteTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000509 return new DirectIntRules<ConstantSInt, signed char , &Type::SByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000510 case Type::UByteTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000511 return new DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000512 case Type::ShortTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000513 return new DirectIntRules<ConstantSInt, signed short, &Type::ShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000514 case Type::UShortTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000515 return new DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000516 case Type::IntTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000517 return new DirectIntRules<ConstantSInt, signed int , &Type::IntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000518 case Type::UIntTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000519 return new DirectIntRules<ConstantUInt, unsigned int , &Type::UIntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000520 case Type::LongTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000521 return new DirectIntRules<ConstantSInt, int64_t , &Type::LongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000522 case Type::ULongTyID:
Chris Lattner62af86e2002-05-03 20:09:52 +0000523 return new DirectIntRules<ConstantUInt, uint64_t , &Type::ULongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000524 case Type::FloatTyID:
Chris Lattner0a144ad2002-05-03 21:41:07 +0000525 return new DirectFPRules<ConstantFP , float , &Type::FloatTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000526 case Type::DoubleTyID:
Chris Lattner0a144ad2002-05-03 21:41:07 +0000527 return new DirectFPRules<ConstantFP , double , &Type::DoubleTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000528 default:
529 return new EmptyRules();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000530 }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000531}