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