ConstantFold.h revision 009505452b713ed2e3a8e99c5545a6e721c65495
1009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===-- ConstantHandling.h - Stuff for manipulating constants ----*- C++ -*--=// 2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This file contains the declarations of some cool operators that allow you 4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// to do natural things with constant pool values. 5009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 6009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// Unfortunately we can't overload operators on pointer types (like this:) 7009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 8009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// inline bool operator==(const ConstPoolVal *V1, const ConstPoolVal *V2) 9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 10009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// so we must make due with references, even though it leads to some butt ugly 11009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// looking code downstream. *sigh* (ex: ConstPoolVal *Result = *V1 + *v2; ) 12009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 13009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 14009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 15009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// WARNING: These operators return pointers to newly 'new'd objects. You MUST 16009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// make sure to free them if you don't want them hanging around. Also, 17009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// note that these may return a null object if I don't know how to 18009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// perform those operations on the specified constant types. 19009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 20009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 21009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 22009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// Implementation notes: 23009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This library is implemented this way for a reason: In most cases, we do 24009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// not want to have to link the constant mucking code into an executable. 25009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// We do, however want to tie some of this into the main type system, as an 26009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// optional component. By using a mutable cache member in the Type class, we 27009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// get exactly the kind of behavior we want. 28009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 29009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// In the end, we get performance almost exactly the same as having a virtual 30009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// function dispatch, but we don't have to put our virtual functions into the 31009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// "Type" class, and we can implement functionality with templates. Good deal. 32009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 33009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 34009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 35009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#ifndef LLVM_OPT_CONSTANTHANDLING_H 36009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#define LLVM_OPT_CONSTANTHANDLING_H 37009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 38009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/ConstPoolVals.h" 39009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Type.h" 40009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 41009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 42009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// Implement == directly... 43009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 44009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 45009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolBool *operator==(const ConstPoolVal &V1, 46009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal &V2) { 47009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner assert(V1.getType() == V2.getType() && "Constant types must be identical!"); 48009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return new ConstPoolBool(V1.equals(&V2)); 49009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 50009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 51009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 52009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// Implement all other operators indirectly through TypeRules system 53009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 54009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 55009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerclass ConstRules { 56009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprotected: 57009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline ConstRules() {} // Can only be subclassed... 58009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerpublic: 59009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Unary Operators... 60009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual ConstPoolVal *neg(const ConstPoolVal *V) const = 0; 61009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual ConstPoolVal *not(const ConstPoolVal *V) const = 0; 62009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 63009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Binary Operators... 64009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual ConstPoolVal *add(const ConstPoolVal *V1, 65009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal *V2) const = 0; 66009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual ConstPoolVal *sub(const ConstPoolVal *V1, 67009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal *V2) const = 0; 68009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 69009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual ConstPoolBool *lessthan(const ConstPoolVal *V1, 70009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal *V2) const = 0; 71009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 72009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // ConstRules::get - A type will cache its own type rules if one is needed... 73009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // we just want to make sure to hit the cache instead of doing it indirectly, 74009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // if possible... 75009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // 76009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner static inline const ConstRules *get(const ConstPoolVal &V) { 77009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstRules *Result = V.getType()->getConstRules(); 78009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return Result ? Result : find(V.getType()); 79009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 80009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprivate : 81009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner static const ConstRules *find(const Type *Ty); 82009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 83009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ConstRules(const ConstRules &); // Do not implement 84009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ConstRules &operator=(const ConstRules &); // Do not implement 85009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}; 86009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 87009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 88009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolVal *operator-(const ConstPoolVal &V) { 89009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return ConstRules::get(V)->neg(&V); 90009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 91009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 92009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolVal *operator!(const ConstPoolVal &V) { 93009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return ConstRules::get(V)->not(&V); 94009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 95009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 96009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 97009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 98009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolVal *operator+(const ConstPoolVal &V1, const ConstPoolVal &V2) { 99009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner assert(V1.getType() == V2.getType() && "Constant types must be identical!"); 100009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return ConstRules::get(V1)->add(&V1, &V2); 101009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 102009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 103009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolVal *operator-(const ConstPoolVal &V1, const ConstPoolVal &V2) { 104009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner assert(V1.getType() == V2.getType() && "Constant types must be identical!"); 105009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return ConstRules::get(V1)->sub(&V1, &V2); 106009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 107009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 108009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolBool *operator<(const ConstPoolVal &V1, 109009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal &V2) { 110009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner assert(V1.getType() == V2.getType() && "Constant types must be identical!"); 111009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return ConstRules::get(V1)->lessthan(&V1, &V2); 112009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 113009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 114009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 115009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 116009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// Implement 'derived' operators based on what we already have... 117009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 118009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 119009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolBool *operator>(const ConstPoolVal &V1, 120009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal &V2) { 121009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return V2 < V1; 122009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 123009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 124009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolBool *operator!=(const ConstPoolVal &V1, 125009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal &V2) { 126009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ConstPoolBool *Result = V1 == V2; 127009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Result->setValue(!Result->getValue()); // Invert value 128009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return Result; // !(V1 == V2) 129009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 130009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 131009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolBool *operator>=(const ConstPoolVal &V1, 132009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal &V2) { 133009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ConstPoolBool *Result = V1 < V2; 134009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Result->setValue(!Result->getValue()); // Invert value 135009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return Result; // !(V1 < V2) 136009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 137009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 138009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerinline ConstPoolBool *operator<=(const ConstPoolVal &V1, 139009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const ConstPoolVal &V2) { 140009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ConstPoolBool *Result = V1 > V2; 141009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Result->setValue(!Result->getValue()); // Invert value 142009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return Result; // !(V1 > V2) 143009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 144009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 145009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#endif 146