ConstantFold.cpp revision 0908309e3c4b4f423e88d8d8fe8060cb10eaa1c9
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 11//===----------------------------------------------------------------------===// 12// TemplateRules Class 13//===----------------------------------------------------------------------===// 14// 15// TemplateRules - Implement a subclass of ConstRules that provides all 16// operations as noops. All other rules classes inherit from this class so 17// that if functionality is needed in the future, it can simply be added here 18// and to ConstRules without changing anything else... 19// 20// This class also provides subclasses with typesafe implementations of methods 21// so that don't have to do type casting. 22// 23template<class ArgType, class SubClassName> 24class TemplateRules : public ConstRules { 25 26 //===--------------------------------------------------------------------===// 27 // Redirecting functions that cast to the appropriate types 28 //===--------------------------------------------------------------------===// 29 30 virtual ConstPoolVal *not(const ConstPoolVal *V) const { 31 return SubClassName::Not((const ArgType *)V); 32 } 33 34 35 virtual ConstPoolVal *add(const ConstPoolVal *V1, 36 const ConstPoolVal *V2) const { 37 return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2); 38 } 39 40 virtual ConstPoolVal *sub(const ConstPoolVal *V1, 41 const ConstPoolVal *V2) const { 42 return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2); 43 } 44 45 virtual ConstPoolBool *lessthan(const ConstPoolVal *V1, 46 const ConstPoolVal *V2) const { 47 return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2); 48 } 49 50 //===--------------------------------------------------------------------===// 51 // Default "noop" implementations 52 //===--------------------------------------------------------------------===// 53 54 inline static ConstPoolVal *Not(const ArgType *V) { return 0; } 55 56 inline static ConstPoolVal *Add(const ArgType *V1, const ArgType *V2) { 57 return 0; 58 } 59 60 inline static ConstPoolVal *Sub(const ArgType *V1, const ArgType *V2) { 61 return 0; 62 } 63 64 inline static ConstPoolBool *LessThan(const ArgType *V1, const ArgType *V2) { 65 return 0; 66 } 67}; 68 69 70 71//===----------------------------------------------------------------------===// 72// EmptyRules Class 73//===----------------------------------------------------------------------===// 74// 75// EmptyRules provides a concrete base class of ConstRules that does nothing 76// 77static // EmptyInst is static 78struct EmptyRules : public TemplateRules<ConstPoolVal, EmptyRules> { 79} EmptyInst; 80 81 82 83//===----------------------------------------------------------------------===// 84// BoolRules Class 85//===----------------------------------------------------------------------===// 86// 87// BoolRules provides a concrete base class of ConstRules for the 'bool' type. 88// 89static // BoolTyInst is static... 90struct BoolRules : public TemplateRules<ConstPoolBool, BoolRules> { 91 92 inline static ConstPoolVal *Not(const ConstPoolBool *V) { 93 return new ConstPoolBool(!V->getValue()); 94 } 95 96 inline static ConstPoolVal *Or(const ConstPoolBool *V1, 97 const ConstPoolBool *V2) { 98 bool Result = V1->getValue() | V2->getValue(); 99 return new ConstPoolBool(Result); 100 } 101 102 inline static ConstPoolVal *And(const ConstPoolBool *V1, 103 const ConstPoolBool *V2) { 104 bool Result = V1->getValue() & V2->getValue(); 105 return new ConstPoolBool(Result); 106 } 107} BoolTyInst; 108 109 110//===----------------------------------------------------------------------===// 111// DirectRules Class 112//===----------------------------------------------------------------------===// 113// 114// DirectRules provides a concrete base classes of ConstRules for a variety of 115// different types. This allows the C++ compiler to automatically generate our 116// constant handling operations in a typesafe and accurate manner. 117// 118template<class ConstPoolClass, class BuiltinType, const Type **Ty> 119struct DirectRules 120 : public TemplateRules<ConstPoolClass, 121 DirectRules<ConstPoolClass, BuiltinType, Ty> > { 122 123 inline static ConstPoolVal *Not(const ConstPoolClass *V) { 124 return new ConstPoolClass(*Ty, !(BuiltinType)V->getValue());; 125 } 126 127 inline static ConstPoolVal *Add(const ConstPoolClass *V1, 128 const ConstPoolClass *V2) { 129 BuiltinType Result = (BuiltinType)V1->getValue() + 130 (BuiltinType)V2->getValue(); 131 return new ConstPoolClass(*Ty, Result); 132 } 133 134 inline static ConstPoolVal *Sub(const ConstPoolClass *V1, 135 const ConstPoolClass *V2) { 136 BuiltinType Result = (BuiltinType)V1->getValue() - 137 (BuiltinType)V2->getValue(); 138 return new ConstPoolClass(*Ty, Result); 139 } 140 141 inline static ConstPoolBool *LessThan(const ConstPoolClass *V1, 142 const ConstPoolClass *V2) { 143 bool Result = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue(); 144 return new ConstPoolBool(Result); 145 } 146}; 147 148//===----------------------------------------------------------------------===// 149// DirectRules Subclasses 150//===----------------------------------------------------------------------===// 151// 152// Given the DirectRules class we can now implement lots of types with little 153// code. Thank goodness C++ compilers are great at stomping out layers of 154// templates... can you imagine having to do this all by hand? (/me is lazy :) 155// 156static DirectRules<ConstPoolSInt, signed char , &Type::SByteTy> SByteTyInst; 157static DirectRules<ConstPoolUInt, unsigned char , &Type::UByteTy> UByteTyInst; 158static DirectRules<ConstPoolSInt, signed short, &Type::ShortTy> ShortTyInst; 159static DirectRules<ConstPoolUInt, unsigned short, &Type::UShortTy> UShortTyInst; 160static DirectRules<ConstPoolSInt, signed int , &Type::IntTy> IntTyInst; 161static DirectRules<ConstPoolUInt, unsigned int , &Type::UIntTy> UIntTyInst; 162static DirectRules<ConstPoolSInt, int64_t , &Type::LongTy> LongTyInst; 163static DirectRules<ConstPoolUInt, uint64_t , &Type::ULongTy> ULongTyInst; 164static DirectRules<ConstPoolFP , float , &Type::FloatTy> FloatTyInst; 165static DirectRules<ConstPoolFP , double , &Type::DoubleTy> DoubleTyInst; 166 167 168// ConstRules::find - Return the constant rules that take care of the specified 169// type. Note that this is cached in the Type value itself, so switch statement 170// is only hit at most once per type. 171// 172const ConstRules *ConstRules::find(const Type *Ty) { 173 const ConstRules *Result; 174 switch (Ty->getPrimitiveID()) { 175 case Type::BoolTyID: Result = &BoolTyInst; break; 176 case Type::SByteTyID: Result = &SByteTyInst; break; 177 case Type::UByteTyID: Result = &UByteTyInst; break; 178 case Type::ShortTyID: Result = &ShortTyInst; break; 179 case Type::UShortTyID: Result = &UShortTyInst; break; 180 case Type::IntTyID: Result = &IntTyInst; break; 181 case Type::UIntTyID: Result = &UIntTyInst; break; 182 case Type::LongTyID: Result = &LongTyInst; break; 183 case Type::ULongTyID: Result = &ULongTyInst; break; 184 case Type::FloatTyID: Result = &FloatTyInst; break; 185 case Type::DoubleTyID: Result = &DoubleTyInst; break; 186 default: Result = &EmptyInst; break; 187 } 188 189 Ty->setConstRules(Result); // Cache the value for future short circuiting! 190 return Result; 191} 192 193 194} // End namespace opt 195