1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "memory/allocation.inline.hpp" 27 #include "opto/addnode.hpp" 28 #include "opto/cfgnode.hpp" 29 #include "opto/machnode.hpp" 30 #include "opto/matcher.hpp" 31 #include "opto/mathexactnode.hpp" 32 #include "opto/subnode.hpp" 33 34 OverflowNode::OverflowNode(Node* in1) : CmpNode(in1, in1) { 35 } 36 37 OverflowNode::OverflowNode(Node* in1, Node* in2) : CmpNode(in1, in2) { 38 } 39 40 template <typename OverflowOp> 41 bool OverflowNode::AddHelper<OverflowOp>::will_overflow(ConstantType value1, ConstantType value2) { 42 ConstantType result = value1 + value2; 43 // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result 44 if ( (((value1 ^ result) & (value2 ^ result)) >= 0)) { 45 return false; 46 } 47 return true; 48 } 49 50 template <typename OverflowOp> 51 bool OverflowNode::AddHelper<OverflowOp>::can_overflow(const Type* type1, const Type* type2) { 52 if (type1 == TypeClass::ZERO || type2 == TypeClass::ZERO) { 53 return false; 54 } 55 return true; 56 } 57 58 template <typename OverflowOp> 59 bool OverflowNode::SubHelper<OverflowOp>::will_overflow(ConstantType value1, ConstantType value2) { 60 ConstantType result = value1 - value2; 61 // Hacker's Delight 2-12 Overflow iff the arguments have different signs and 62 // the sign of the result is different than the sign of arg1 63 if (((value1 ^ value2) & (value1 ^ result)) >= 0) { 64 return false; 65 } 66 return true; 67 } 68 69 template <typename OverflowOp> 70 bool OverflowNode::SubHelper<OverflowOp>::can_overflow(const Type* type1, const Type* type2) { 71 if (type2 == TypeClass::ZERO) { 72 return false; 73 } 74 return true; 75 } 76 77 template <typename OverflowOp> 78 bool OverflowNode::MulHelper<OverflowOp>::can_overflow(const Type* type1, const Type* type2) { 79 if (type1 == TypeClass::ZERO || type2 == TypeClass::ZERO) { 80 return false; 81 } else if (type1 == TypeClass::ONE || type2 == TypeClass::ONE) { 82 return false; 83 } 84 return true; 85 } 86 87 bool OverflowINode::will_overflow(jint v1, jint v2) const { 88 ShouldNotReachHere(); 89 return true; 90 } 91 92 bool OverflowLNode::will_overflow(jlong v1, jlong v2) const { 93 ShouldNotReachHere(); 94 return true; 95 } 96 97 bool OverflowINode::can_overflow(const Type* t1, const Type* t2) const { 98 ShouldNotReachHere(); 99 return true; 100 } 101 102 bool OverflowLNode::can_overflow(const Type* t1, const Type* t2) const { 103 ShouldNotReachHere(); 104 return true; 105 } 106 107 bool OverflowAddINode::will_overflow(jint v1, jint v2) const { 108 return OverflowHelper::will_overflow(v1, v2); 109 } 110 111 bool OverflowSubINode::will_overflow(jint v1, jint v2) const { 112 return OverflowHelper::will_overflow(v1, v2); 113 } 114 115 bool OverflowMulINode::will_overflow(jint v1, jint v2) const { 116 jlong result = (jlong) v1 * (jlong) v2; 117 if ((jint) result == result) { 118 return false; 119 } 120 return true; 121 } 122 123 bool OverflowAddLNode::will_overflow(jlong v1, jlong v2) const { 124 return OverflowHelper::will_overflow(v1, v2); 125 } 126 127 bool OverflowSubLNode::will_overflow(jlong v1, jlong v2) const { 128 return OverflowHelper::will_overflow(v1, v2); 129 } 130 131 bool OverflowMulLNode::will_overflow(jlong val1, jlong val2) const { 132 jlong result = val1 * val2; 133 jlong ax = (val1 < 0 ? -val1 : val1); 134 jlong ay = (val2 < 0 ? -val2 : val2); 135 136 bool overflow = false; 137 if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) { 138 // potential overflow if any bit in upper 32 bits are set 139 if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) { 140 // -1 * Long.MIN_VALUE will overflow 141 overflow = true; 142 } else if (val2 != 0 && (result / val2 != val1)) { 143 overflow = true; 144 } 145 } 146 147 return overflow; 148 } 149 150 151 template <typename TypeClass> 152 struct TypeHelper { 153 typedef typename TypeClass::native_type_t native_type_t; 154 155 static const TypeClass* get_type(const Type* type); 156 static native_type_t get_value(const Node* node); 157 }; 158 159 template<> 160 struct TypeHelper<TypeInt> { 161 typedef TypeInt::native_type_t native_type_t; 162 163 static const TypeInt* get_type(const Type* type) { 164 return type->isa_int(); 165 } 166 static native_type_t get_value(const Node* node) { 167 return node->get_int(); 168 } 169 }; 170 171 template<> 172 struct TypeHelper<TypeLong> { 173 typedef TypeLong::native_type_t native_type_t; 174 175 static const TypeLong* get_type(const Type* type) { 176 return type->isa_long(); 177 } 178 static native_type_t get_value(const Node* node) { 179 return node->get_long(); 180 } 181 }; 182 183 template <typename OverflowOp> 184 struct IdealHelper { 185 typedef typename OverflowOp::TypeClass TypeClass; // TypeInt, TypeLong 186 typedef typename TypeClass::native_type_t native_type_t; 187 188 static Node* Ideal(const OverflowOp* node, PhaseGVN* phase, bool can_reshape) { 189 Node* arg1 = node->in(1); 190 Node* arg2 = node->in(2); 191 const Type* type1 = phase->type(arg1); 192 const Type* type2 = phase->type(arg2); 193 194 if (type1 != Type::TOP && type1->singleton() && 195 type2 != Type::TOP && type2->singleton()) { 196 native_type_t val1 = TypeHelper<TypeClass>::get_value(arg1); 197 native_type_t val2 = TypeHelper<TypeClass>::get_value(arg2); 198 if (node->will_overflow(val1, val2) == false) { 199 Node* con_result = ConINode::make(phase->C, 0); 200 return con_result; 201 } 202 return NULL; 203 } 204 return NULL; 205 } 206 207 static const Type* Value(const OverflowOp* node, PhaseTransform* phase) { 208 const Type *t1 = phase->type( node->in(1) ); 209 const Type *t2 = phase->type( node->in(2) ); 210 if( t1 == Type::TOP ) return Type::TOP; 211 if( t2 == Type::TOP ) return Type::TOP; 212 213 const TypeClass* i1 = TypeHelper<TypeClass>::get_type(t1); 214 const TypeClass* i2 = TypeHelper<TypeClass>::get_type(t2); 215 216 if (t1->singleton() && t2->singleton()) { 217 if (i1 == NULL || i2 == NULL) { 218 return TypeInt::CC; 219 } 220 221 native_type_t val1 = i1->get_con(); 222 native_type_t val2 = i2->get_con(); 223 if (node->will_overflow(val1, val2)) { 224 return TypeInt::CC; 225 } 226 return TypeInt::ZERO; 227 } else if (i1 != TypeClass::top() && i2 != TypeClass::top()) { 228 if (node->will_overflow(i1->_lo, i2->_lo)) { 229 return TypeInt::CC; 230 } else if (node->will_overflow(i1->_lo, i2->_hi)) { 231 return TypeInt::CC; 232 } else if (node->will_overflow(i1->_hi, i2->_lo)) { 233 return TypeInt::CC; 234 } else if (node->will_overflow(i1->_hi, i2->_hi)) { 235 return TypeInt::CC; 236 } 237 return TypeInt::ZERO; 238 } 239 240 if (!node->can_overflow(t1, t2)) { 241 return TypeInt::ZERO; 242 } 243 return TypeInt::CC; 244 } 245 }; 246 247 Node* OverflowINode::Ideal(PhaseGVN* phase, bool can_reshape) { 248 return IdealHelper<OverflowINode>::Ideal(this, phase, can_reshape); 249 } 250 251 Node* OverflowLNode::Ideal(PhaseGVN* phase, bool can_reshape) { 252 return IdealHelper<OverflowLNode>::Ideal(this, phase, can_reshape); 253 } 254 255 const Type* OverflowINode::Value(PhaseTransform* phase) const { 256 return IdealHelper<OverflowINode>::Value(this, phase); 257 } 258 259 const Type* OverflowLNode::Value(PhaseTransform* phase) const { 260 return IdealHelper<OverflowLNode>::Value(this, phase); 261 } 262 263 bool OverflowAddINode::can_overflow(const Type* t1, const Type* t2) const { 264 return OverflowHelper::can_overflow(t1, t2); 265 } 266 267 bool OverflowSubINode::can_overflow(const Type* t1, const Type* t2) const { 268 if (in(1) == in(2)) { 269 return false; 270 } 271 return OverflowHelper::can_overflow(t1, t2); 272 } 273 274 bool OverflowMulINode::can_overflow(const Type* t1, const Type* t2) const { 275 return OverflowHelper::can_overflow(t1, t2); 276 } 277 278 bool OverflowAddLNode::can_overflow(const Type* t1, const Type* t2) const { 279 return OverflowHelper::can_overflow(t1, t2); 280 } 281 282 bool OverflowSubLNode::can_overflow(const Type* t1, const Type* t2) const { 283 return OverflowHelper::can_overflow(t1, t2); 284 } 285 286 bool OverflowMulLNode::can_overflow(const Type* t1, const Type* t2) const { 287 return OverflowHelper::can_overflow(t1, t2); 288 } 289 290 const Type* OverflowINode::sub(const Type* t1, const Type* t2) const { 291 ShouldNotReachHere(); 292 return TypeInt::CC; 293 } 294 295 const Type* OverflowLNode::sub(const Type* t1, const Type* t2) const { 296 ShouldNotReachHere(); 297 return TypeInt::CC; 298 }