src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/library_call.cpp Thu Jan 30 13:51:34 2014
--- new/src/share/vm/opto/library_call.cpp Thu Jan 30 13:51:34 2014
*** 201,211 ****
--- 201,215 ----
Node* round_double_node(Node* n);
bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
bool inline_math_native(vmIntrinsics::ID id);
bool inline_trig(vmIntrinsics::ID id);
bool inline_math(vmIntrinsics::ID id);
void inline_math_mathExact(Node* math);
+ template <typename OverflowOp>
+ bool inline_math_overflow(Node* arg1, Node* arg2);
+ template <typename OverflowOp>
+ bool inline_math_overflow(bool is_unary);
+ void inline_math_mathExact(Node* math, Node* test);
bool inline_math_addExactI(bool is_increment);
bool inline_math_addExactL(bool is_increment);
bool inline_math_multiplyExactI();
bool inline_math_multiplyExactL();
bool inline_math_negateExactI();
*** 515,549 ****
--- 519,553 ----
if (!UseCRC32Intrinsics) return NULL;
break;
case vmIntrinsics::_incrementExactI:
case vmIntrinsics::_addExactI:
! if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowAddI) || !UseMathExactIntrinsics) return NULL;
break;
case vmIntrinsics::_incrementExactL:
case vmIntrinsics::_addExactL:
! if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowAddL) || !UseMathExactIntrinsics) return NULL;
break;
case vmIntrinsics::_decrementExactI:
case vmIntrinsics::_subtractExactI:
! if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL;
break;
case vmIntrinsics::_decrementExactL:
case vmIntrinsics::_subtractExactL:
! if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL;
break;
case vmIntrinsics::_negateExactI:
! if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL;
break;
case vmIntrinsics::_negateExactL:
! if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL;
break;
case vmIntrinsics::_multiplyExactI:
! if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowMulI) || !UseMathExactIntrinsics) return NULL;
break;
case vmIntrinsics::_multiplyExactL:
! if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
! if (!Matcher::match_rule_supported(Op_OverflowMulL) || !UseMathExactIntrinsics) return NULL;
break;
default:
assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
*** 1968,1989 ****
--- 1972,1983 ----
bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
set_result(generate_min_max(id, argument(0), argument(1)));
return true;
}
! void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) {
// If we didn't get the expected opcode it means we have optimized
// the node to something else and don't need the exception edge.
if (!math->is_MathExact()) {
set_result(math);
return;
}
Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
+ Node* bol = _gvn.transform( new (C) BoolNode(test, BoolTest::overflow) );
IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
{
*** 1997,2108 ****
--- 1991,2057 ----
uncommon_trap(Deoptimization::Reason_intrinsic,
Deoptimization::Action_none);
}
set_control(fast_path);
! set_result(result);
! set_result(math);
}
bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
Node* arg1 = argument(0);
! Node* arg2 = NULL;
if (is_increment) {
arg2 = intcon(1);
} else {
arg2 = argument(1);
}
+ template <typename OverflowOp>
+ bool LibraryCallKit::inline_math_overflow(Node* arg1, Node* arg2) {
! typedef typename OverflowOp::MathOp MathOp;
! Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
! inline_math_mathExact(add);
! MathOp* mathOp = new(C) MathOp(arg1, arg2);
! Node* operation = _gvn.transform( mathOp );
+ Node* ofcheck = _gvn.transform( new(C) OverflowOp(arg1, arg2) );
+ inline_math_mathExact(operation, ofcheck);
return true;
}
bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
Node* arg1 = argument(0); // type long
// argument(1) == TOP
+ template <typename OverflowOp>
+ bool LibraryCallKit::inline_math_overflow(bool is_unary) {
+ Node* arg1 = argument(0);
Node* arg2 = NULL;
! if (is_increment) {
! arg2 = longcon(1);
! if (OverflowOp::IsLong) {
! arg2 = (is_unary ? longcon(1) : argument(2));
} else {
! arg2 = argument(2); // type long
// argument(3) == TOP
! arg2 = (is_unary ? intcon(1) : argument(1));
}
Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
inline_math_mathExact(add);
return true;
+ return inline_math_overflow<OverflowOp>(arg1, arg2);
}
! bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
! Node* arg1 = argument(0);
Node* arg2 = NULL;
! bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
! return inline_math_overflow<OverflowAddINode>(is_increment);
+ }
! if (is_decrement) {
! arg2 = intcon(1);
! } else {
arg2 = argument(1);
}
! bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
! return inline_math_overflow<OverflowAddLNode>(is_increment);
+ }
Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
! inline_math_mathExact(sub);
return true;
+ bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
! return inline_math_overflow<OverflowSubINode>(is_decrement);
}
bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
Node* arg1 = argument(0); // type long
// argument(1) == TOP
Node* arg2 = NULL;
if (is_decrement) {
arg2 = longcon(1);
} else {
arg2 = argument(2); // type long
// argument(3) == TOP
}
Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
inline_math_mathExact(sub);
return true;
+ return inline_math_overflow<OverflowSubLNode>(is_decrement);
}
bool LibraryCallKit::inline_math_negateExactI() {
! Node* arg1 = argument(0);
Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
inline_math_mathExact(neg);
return true;
! return inline_math_overflow<OverflowSubINode>(intcon(0), argument(0));
}
bool LibraryCallKit::inline_math_negateExactL() {
! Node* arg1 = argument(0);
// argument(1) == TOP
Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
inline_math_mathExact(neg);
return true;
! return inline_math_overflow<OverflowSubLNode>(longcon(0), argument(0));
}
bool LibraryCallKit::inline_math_multiplyExactI() {
! Node* arg1 = argument(0);
Node* arg2 = argument(1);
Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
inline_math_mathExact(mul);
return true;
! return inline_math_overflow<OverflowMulINode>(false);
}
bool LibraryCallKit::inline_math_multiplyExactL() {
! Node* arg1 = argument(0);
// argument(1) == TOP
Node* arg2 = argument(2);
// argument(3) == TOP
Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
inline_math_mathExact(mul);
return true;
! return inline_math_overflow<OverflowMulLNode>(false);
}
Node*
LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
// These are the candidate return value:
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File