blob: 80374f339c5a930fcc0bd30d81d5483fb56deb5c [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 Lattneree965ab2002-01-21 23:17:48 +00007#include "llvm/Transforms/Scalar/ConstantHandling.h"
Chris Lattnerd42d4922001-06-30 04:36:40 +00008
Chris Lattner61607ee2001-09-09 21:01:20 +00009AnnotationID ConstRules::AID(AnnotationManager::getID("opt::ConstRules",
10 &ConstRules::find));
11
Chris Lattner2f7c9632001-06-06 20:29:01 +000012//===----------------------------------------------------------------------===//
13// TemplateRules Class
14//===----------------------------------------------------------------------===//
15//
16// TemplateRules - Implement a subclass of ConstRules that provides all
17// operations as noops. All other rules classes inherit from this class so
18// that if functionality is needed in the future, it can simply be added here
19// and to ConstRules without changing anything else...
20//
21// This class also provides subclasses with typesafe implementations of methods
22// so that don't have to do type casting.
23//
24template<class ArgType, class SubClassName>
25class TemplateRules : public ConstRules {
26
27 //===--------------------------------------------------------------------===//
28 // Redirecting functions that cast to the appropriate types
29 //===--------------------------------------------------------------------===//
30
Chris Lattner3462ae32001-12-03 22:26:30 +000031 virtual Constant *op_not(const Constant *V) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000032 return SubClassName::Not((const ArgType *)V);
33 }
34
35
Chris Lattner3462ae32001-12-03 22:26:30 +000036 virtual Constant *add(const Constant *V1,
37 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000038 return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);
39 }
40
Chris Lattner3462ae32001-12-03 22:26:30 +000041 virtual Constant *sub(const Constant *V1,
42 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000043 return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);
44 }
45
Chris Lattner3462ae32001-12-03 22:26:30 +000046 virtual Constant *mul(const Constant *V1,
47 const Constant *V2) const {
Chris Lattner4f6031f2001-07-20 19:15:36 +000048 return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);
49 }
50
Chris Lattner3462ae32001-12-03 22:26:30 +000051 virtual ConstantBool *lessthan(const Constant *V1,
52 const Constant *V2) const {
Chris Lattner2f7c9632001-06-06 20:29:01 +000053 return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
54 }
55
Chris Lattner55406842001-07-21 19:10:49 +000056 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +000057 virtual ConstantBool *castToBool(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000058 return SubClassName::CastToBool((const ArgType*)V);
59 }
Chris Lattner3462ae32001-12-03 22:26:30 +000060 virtual ConstantSInt *castToSByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000061 return SubClassName::CastToSByte((const ArgType*)V);
62 }
Chris Lattner3462ae32001-12-03 22:26:30 +000063 virtual ConstantUInt *castToUByte(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000064 return SubClassName::CastToUByte((const ArgType*)V);
65 }
Chris Lattner3462ae32001-12-03 22:26:30 +000066 virtual ConstantSInt *castToShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000067 return SubClassName::CastToShort((const ArgType*)V);
68 }
Chris Lattner3462ae32001-12-03 22:26:30 +000069 virtual ConstantUInt *castToUShort(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000070 return SubClassName::CastToUShort((const ArgType*)V);
71 }
Chris Lattner3462ae32001-12-03 22:26:30 +000072 virtual ConstantSInt *castToInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000073 return SubClassName::CastToInt((const ArgType*)V);
74 }
Chris Lattner3462ae32001-12-03 22:26:30 +000075 virtual ConstantUInt *castToUInt(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000076 return SubClassName::CastToUInt((const ArgType*)V);
77 }
Chris Lattner3462ae32001-12-03 22:26:30 +000078 virtual ConstantSInt *castToLong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000079 return SubClassName::CastToLong((const ArgType*)V);
80 }
Chris Lattner3462ae32001-12-03 22:26:30 +000081 virtual ConstantUInt *castToULong(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000082 return SubClassName::CastToULong((const ArgType*)V);
83 }
Chris Lattner3462ae32001-12-03 22:26:30 +000084 virtual ConstantFP *castToFloat(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000085 return SubClassName::CastToFloat((const ArgType*)V);
86 }
Chris Lattner3462ae32001-12-03 22:26:30 +000087 virtual ConstantFP *castToDouble(const Constant *V) const {
Chris Lattner55406842001-07-21 19:10:49 +000088 return SubClassName::CastToDouble((const ArgType*)V);
89 }
Chris Lattner3462ae32001-12-03 22:26:30 +000090 virtual ConstantPointer *castToPointer(const Constant *V,
91 const PointerType *Ty) const {
Chris Lattner977f0042001-11-01 05:55:13 +000092 return SubClassName::CastToPointer((const ArgType*)V, Ty);
93 }
Chris Lattner55406842001-07-21 19:10:49 +000094
Chris Lattner2f7c9632001-06-06 20:29:01 +000095 //===--------------------------------------------------------------------===//
96 // Default "noop" implementations
97 //===--------------------------------------------------------------------===//
98
Chris Lattner3462ae32001-12-03 22:26:30 +000099 inline static Constant *Not(const ArgType *V) { return 0; }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000100
Chris Lattner3462ae32001-12-03 22:26:30 +0000101 inline static Constant *Add(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000102 return 0;
103 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000104 inline static Constant *Sub(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000105 return 0;
106 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000107 inline static Constant *Mul(const ArgType *V1, const ArgType *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000108 return 0;
109 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000110 inline static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000111 return 0;
112 }
Chris Lattner55406842001-07-21 19:10:49 +0000113
114 // Casting operators. ick
Chris Lattner3462ae32001-12-03 22:26:30 +0000115 inline static ConstantBool *CastToBool (const Constant *V) { return 0; }
116 inline static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
117 inline static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
118 inline static ConstantSInt *CastToShort (const Constant *V) { return 0; }
119 inline static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
120 inline static ConstantSInt *CastToInt (const Constant *V) { return 0; }
121 inline static ConstantUInt *CastToUInt (const Constant *V) { return 0; }
122 inline static ConstantSInt *CastToLong (const Constant *V) { return 0; }
123 inline static ConstantUInt *CastToULong (const Constant *V) { return 0; }
124 inline static ConstantFP *CastToFloat (const Constant *V) { return 0; }
125 inline static ConstantFP *CastToDouble(const Constant *V) { return 0; }
126 inline static ConstantPointer *CastToPointer(const Constant *,
127 const PointerType *) {return 0;}
Chris Lattner2f7c9632001-06-06 20:29:01 +0000128};
129
130
131
132//===----------------------------------------------------------------------===//
133// EmptyRules Class
134//===----------------------------------------------------------------------===//
135//
136// EmptyRules provides a concrete base class of ConstRules that does nothing
137//
Chris Lattner3462ae32001-12-03 22:26:30 +0000138struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
Chris Lattner61607ee2001-09-09 21:01:20 +0000139};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000140
141
142
143//===----------------------------------------------------------------------===//
144// BoolRules Class
145//===----------------------------------------------------------------------===//
146//
147// BoolRules provides a concrete base class of ConstRules for the 'bool' type.
148//
Chris Lattner3462ae32001-12-03 22:26:30 +0000149struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000150
Chris Lattner3462ae32001-12-03 22:26:30 +0000151 inline static Constant *Not(const ConstantBool *V) {
152 return ConstantBool::get(!V->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000153 }
154
Chris Lattner3462ae32001-12-03 22:26:30 +0000155 inline static Constant *Or(const ConstantBool *V1,
156 const ConstantBool *V2) {
157 return ConstantBool::get(V1->getValue() | V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000158 }
159
Chris Lattner3462ae32001-12-03 22:26:30 +0000160 inline static Constant *And(const ConstantBool *V1,
161 const ConstantBool *V2) {
162 return ConstantBool::get(V1->getValue() & V2->getValue());
Chris Lattner2f7c9632001-06-06 20:29:01 +0000163 }
Chris Lattner61607ee2001-09-09 21:01:20 +0000164};
Chris Lattner2f7c9632001-06-06 20:29:01 +0000165
166
167//===----------------------------------------------------------------------===//
Chris Lattner977f0042001-11-01 05:55:13 +0000168// PointerRules Class
169//===----------------------------------------------------------------------===//
170//
171// PointerRules provides a concrete base class of ConstRules for pointer types
172//
Chris Lattner3462ae32001-12-03 22:26:30 +0000173struct PointerRules : public TemplateRules<ConstantPointer, PointerRules> {
174 inline static ConstantBool *CastToBool (const Constant *V) {
175 if (V->isNullValue()) return ConstantBool::False;
Chris Lattner977f0042001-11-01 05:55:13 +0000176 return 0; // Can't const prop other types of pointers
177 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000178 inline static ConstantSInt *CastToSByte (const Constant *V) {
179 if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000180 return 0; // Can't const prop other types of pointers
181 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000182 inline static ConstantUInt *CastToUByte (const Constant *V) {
183 if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000184 return 0; // Can't const prop other types of pointers
185 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000186 inline static ConstantSInt *CastToShort (const Constant *V) {
187 if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000188 return 0; // Can't const prop other types of pointers
189 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000190 inline static ConstantUInt *CastToUShort(const Constant *V) {
191 if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000192 return 0; // Can't const prop other types of pointers
193 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000194 inline static ConstantSInt *CastToInt (const Constant *V) {
195 if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000196 return 0; // Can't const prop other types of pointers
197 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000198 inline static ConstantUInt *CastToUInt (const Constant *V) {
199 if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000200 return 0; // Can't const prop other types of pointers
201 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000202 inline static ConstantSInt *CastToLong (const Constant *V) {
203 if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000204 return 0; // Can't const prop other types of pointers
205 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000206 inline static ConstantUInt *CastToULong (const Constant *V) {
207 if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000208 return 0; // Can't const prop other types of pointers
209 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000210 inline static ConstantFP *CastToFloat (const Constant *V) {
211 if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000212 return 0; // Can't const prop other types of pointers
213 }
Chris Lattner3462ae32001-12-03 22:26:30 +0000214 inline static ConstantFP *CastToDouble(const Constant *V) {
215 if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
Chris Lattner977f0042001-11-01 05:55:13 +0000216 return 0; // Can't const prop other types of pointers
217 }
218
Chris Lattner3462ae32001-12-03 22:26:30 +0000219 inline static ConstantPointer *CastToPointer(const ConstantPointer *V,
220 const PointerType *PTy) {
Chris Lattner977f0042001-11-01 05:55:13 +0000221 if (V->isNullValue())
Chris Lattner3462ae32001-12-03 22:26:30 +0000222 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000223 return 0; // Can't const prop other types of pointers
224 }
225};
226
227
228//===----------------------------------------------------------------------===//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000229// DirectRules Class
230//===----------------------------------------------------------------------===//
231//
232// DirectRules provides a concrete base classes of ConstRules for a variety of
233// different types. This allows the C++ compiler to automatically generate our
234// constant handling operations in a typesafe and accurate manner.
235//
Chris Lattner3462ae32001-12-03 22:26:30 +0000236template<class ConstantClass, class BuiltinType, Type **Ty>
Chris Lattner2f7c9632001-06-06 20:29:01 +0000237struct DirectRules
Chris Lattner3462ae32001-12-03 22:26:30 +0000238 : public TemplateRules<ConstantClass,
239 DirectRules<ConstantClass, BuiltinType, Ty> > {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000240
Chris Lattner3462ae32001-12-03 22:26:30 +0000241 inline static Constant *Not(const ConstantClass *V) {
242 return ConstantClass::get(*Ty, !(BuiltinType)V->getValue());;
Chris Lattner2f7c9632001-06-06 20:29:01 +0000243 }
244
Chris Lattner3462ae32001-12-03 22:26:30 +0000245 inline static Constant *Add(const ConstantClass *V1,
246 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000247 BuiltinType Result = (BuiltinType)V1->getValue() +
248 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000249 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000250 }
251
Chris Lattner3462ae32001-12-03 22:26:30 +0000252 inline static Constant *Sub(const ConstantClass *V1,
253 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000254 BuiltinType Result = (BuiltinType)V1->getValue() -
255 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000256 return ConstantClass::get(*Ty, Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000257 }
258
Chris Lattner3462ae32001-12-03 22:26:30 +0000259 inline static Constant *Mul(const ConstantClass *V1,
260 const ConstantClass *V2) {
Chris Lattner4f6031f2001-07-20 19:15:36 +0000261 BuiltinType Result = (BuiltinType)V1->getValue() *
262 (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000263 return ConstantClass::get(*Ty, Result);
Chris Lattner4f6031f2001-07-20 19:15:36 +0000264 }
265
Chris Lattner3462ae32001-12-03 22:26:30 +0000266 inline static ConstantBool *LessThan(const ConstantClass *V1,
267 const ConstantClass *V2) {
Chris Lattner2f7c9632001-06-06 20:29:01 +0000268 bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
Chris Lattner3462ae32001-12-03 22:26:30 +0000269 return ConstantBool::get(Result);
Chris Lattner2f7c9632001-06-06 20:29:01 +0000270 }
Chris Lattner55406842001-07-21 19:10:49 +0000271
Chris Lattner3462ae32001-12-03 22:26:30 +0000272 inline static ConstantPointer *CastToPointer(const ConstantClass *V,
273 const PointerType *PTy) {
Chris Lattner977f0042001-11-01 05:55:13 +0000274 if (V->isNullValue()) // Is it a FP or Integral null value?
Chris Lattner3462ae32001-12-03 22:26:30 +0000275 return ConstantPointerNull::get(PTy);
Chris Lattner977f0042001-11-01 05:55:13 +0000276 return 0; // Can't const prop other types of pointers
277 }
278
Chris Lattner55406842001-07-21 19:10:49 +0000279 // Casting operators. ick
280#define DEF_CAST(TYPE, CLASS, CTYPE) \
Chris Lattner3462ae32001-12-03 22:26:30 +0000281 inline static CLASS *CastTo##TYPE (const ConstantClass *V) { \
Chris Lattnerbbb22962001-09-07 16:40:34 +0000282 return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
Chris Lattner55406842001-07-21 19:10:49 +0000283 }
284
Chris Lattner3462ae32001-12-03 22:26:30 +0000285 DEF_CAST(Bool , ConstantBool, bool)
286 DEF_CAST(SByte , ConstantSInt, signed char)
287 DEF_CAST(UByte , ConstantUInt, unsigned char)
288 DEF_CAST(Short , ConstantSInt, signed short)
289 DEF_CAST(UShort, ConstantUInt, unsigned short)
290 DEF_CAST(Int , ConstantSInt, signed int)
291 DEF_CAST(UInt , ConstantUInt, unsigned int)
292 DEF_CAST(Long , ConstantSInt, int64_t)
293 DEF_CAST(ULong , ConstantUInt, uint64_t)
294 DEF_CAST(Float , ConstantFP , float)
295 DEF_CAST(Double, ConstantFP , double)
Chris Lattner55406842001-07-21 19:10:49 +0000296#undef DEF_CAST
Chris Lattner2f7c9632001-06-06 20:29:01 +0000297};
298
299//===----------------------------------------------------------------------===//
300// DirectRules Subclasses
301//===----------------------------------------------------------------------===//
302//
303// Given the DirectRules class we can now implement lots of types with little
304// code. Thank goodness C++ compilers are great at stomping out layers of
305// templates... can you imagine having to do this all by hand? (/me is lazy :)
306//
Chris Lattner2f7c9632001-06-06 20:29:01 +0000307
308// ConstRules::find - Return the constant rules that take care of the specified
Chris Lattner61607ee2001-09-09 21:01:20 +0000309// type.
Chris Lattner2f7c9632001-06-06 20:29:01 +0000310//
Chris Lattner61607ee2001-09-09 21:01:20 +0000311Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
312 assert(AID == ConstRules::AID && "Bad annotation for factory!");
Chris Lattner8f191122001-10-01 18:26:53 +0000313 const Type *Ty = cast<Type>((const Value*)TyA);
Chris Lattner61607ee2001-09-09 21:01:20 +0000314
Chris Lattner2f7c9632001-06-06 20:29:01 +0000315 switch (Ty->getPrimitiveID()) {
Chris Lattner977f0042001-11-01 05:55:13 +0000316 case Type::BoolTyID: return new BoolRules();
317 case Type::PointerTyID: return new PointerRules();
Chris Lattner61607ee2001-09-09 21:01:20 +0000318 case Type::SByteTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000319 return new DirectRules<ConstantSInt, signed char , &Type::SByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000320 case Type::UByteTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000321 return new DirectRules<ConstantUInt, unsigned char , &Type::UByteTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000322 case Type::ShortTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000323 return new DirectRules<ConstantSInt, signed short, &Type::ShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000324 case Type::UShortTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000325 return new DirectRules<ConstantUInt, unsigned short, &Type::UShortTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000326 case Type::IntTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000327 return new DirectRules<ConstantSInt, signed int , &Type::IntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000328 case Type::UIntTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000329 return new DirectRules<ConstantUInt, unsigned int , &Type::UIntTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000330 case Type::LongTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000331 return new DirectRules<ConstantSInt, int64_t , &Type::LongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000332 case Type::ULongTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000333 return new DirectRules<ConstantUInt, uint64_t , &Type::ULongTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000334 case Type::FloatTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000335 return new DirectRules<ConstantFP , float , &Type::FloatTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000336 case Type::DoubleTyID:
Chris Lattner3462ae32001-12-03 22:26:30 +0000337 return new DirectRules<ConstantFP , double , &Type::DoubleTy>();
Chris Lattner61607ee2001-09-09 21:01:20 +0000338 default:
339 return new EmptyRules();
Chris Lattner2f7c9632001-06-06 20:29:01 +0000340 }
Chris Lattner2f7c9632001-06-06 20:29:01 +0000341}