Skip to content
Permalink
Browse files
8276217: Harmonize StrictMath intrinsics handling
Reviewed-by: aph, kvn
  • Loading branch information
shipilev committed Nov 4, 2021
1 parent fb0be81 commit 9eadcbb47e902f42d933ba68e24f2bfb0ee20915
Show file tree
Hide file tree
Showing 15 changed files with 98 additions and 45 deletions.
@@ -769,14 +769,16 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
}
switch (x->id()) {
case vmIntrinsics::_dabs:
case vmIntrinsics::_dsqrt: {
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict: {
assert(x->number_of_arguments() == 1, "wrong type");
LIRItem value(x->argument_at(0), this);
value.load_item();
LIR_Opr dst = rlock_result(x);

switch (x->id()) {
case vmIntrinsics::_dsqrt: {
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict: {
__ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
break;
}
@@ -788,7 +788,8 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
return;
#endif // __SOFTFP__
}
case vmIntrinsics::_dsqrt: {
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict: {
#ifdef __SOFTFP__
runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt);
break;
@@ -722,7 +722,8 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
__ abs(value.result(), dst, LIR_OprFact::illegalOpr);
break;
}
case vmIntrinsics::_dsqrt: {
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict: {
if (VM_Version::has_fsqrt()) {
assert(x->number_of_arguments() == 1, "wrong type");
LIRItem value(x->argument_at(0), this);
@@ -743,6 +744,7 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
address runtime_entry = NULL;
switch (x->id()) {
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt);
break;
case vmIntrinsics::_dsin:
@@ -629,14 +629,16 @@ LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) {
void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
switch (x->id()) {
case vmIntrinsics::_dabs:
case vmIntrinsics::_dsqrt: {
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict: {
assert(x->number_of_arguments() == 1, "wrong type");
LIRItem value(x->argument_at(0), this);
value.load_item();
LIR_Opr dst = rlock_result(x);

switch (x->id()) {
case vmIntrinsics::_dsqrt: {
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict: {
__ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
break;
}
@@ -813,9 +813,15 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
#endif

switch(x->id()) {
case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, tmp); break;
case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
default: ShouldNotReachHere();
case vmIntrinsics::_dabs:
__ abs(calc_input, calc_result, tmp);
break;
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
__ sqrt(calc_input, calc_result, LIR_OprFact::illegalOpr);
break;
default:
ShouldNotReachHere();
}

if (use_fpu) {
@@ -155,6 +155,7 @@ bool Compiler::is_intrinsic_supported(const methodHandle& method) {
case vmIntrinsics::_currentThread:
case vmIntrinsics::_dabs:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
@@ -3220,6 +3220,7 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
switch (scope->method()->intrinsic_id()) {
case vmIntrinsics::_dabs : // fall through
case vmIntrinsics::_dsqrt : // fall through
case vmIntrinsics::_dsqrt_strict : // fall through
case vmIntrinsics::_dsin : // fall through
case vmIntrinsics::_dcos : // fall through
case vmIntrinsics::_dtan : // fall through
@@ -2951,6 +2951,7 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) {
case vmIntrinsics::_dlog10: // fall through
case vmIntrinsics::_dabs: // fall through
case vmIntrinsics::_dsqrt: // fall through
case vmIntrinsics::_dsqrt_strict: // fall through
case vmIntrinsics::_dtan: // fall through
case vmIntrinsics::_dsin : // fall through
case vmIntrinsics::_dcos : // fall through
@@ -81,6 +81,7 @@ bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
case vmIntrinsics::_iabs:
case vmIntrinsics::_labs:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
@@ -127,6 +128,7 @@ bool vmIntrinsics::can_trap(vmIntrinsics::ID id) {
case vmIntrinsics::_iabs:
case vmIntrinsics::_labs:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
@@ -265,6 +267,7 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
case vmIntrinsics::_iabs:
case vmIntrinsics::_labs:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
@@ -273,14 +276,20 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
case vmIntrinsics::_dpow:
case vmIntrinsics::_dlog10:
case vmIntrinsics::_datan2:
case vmIntrinsics::_min:
case vmIntrinsics::_max:
case vmIntrinsics::_floatToIntBits:
case vmIntrinsics::_doubleToLongBits:
case vmIntrinsics::_min:
case vmIntrinsics::_max:
case vmIntrinsics::_maxF:
case vmIntrinsics::_minF:
case vmIntrinsics::_maxD:
case vmIntrinsics::_minD:
case vmIntrinsics::_min_strict:
case vmIntrinsics::_max_strict:
case vmIntrinsics::_maxF_strict:
case vmIntrinsics::_minF_strict:
case vmIntrinsics::_maxD_strict:
case vmIntrinsics::_minD_strict:
if (!InlineMathNatives) return true;
break;
case vmIntrinsics::_fmaD:
@@ -190,6 +190,16 @@ class methodHandle;
do_intrinsic(_dsignum, java_lang_Math, signum_name, double_double_signature, F_S) \
do_intrinsic(_fsignum, java_lang_Math, signum_name, float_float_signature, F_S) \
\
/* StrictMath intrinsics, similar to what we have in Math. */ \
do_intrinsic(_min_strict, java_lang_StrictMath, min_name, int2_int_signature, F_S) \
do_intrinsic(_max_strict, java_lang_StrictMath, max_name, int2_int_signature, F_S) \
do_intrinsic(_minF_strict, java_lang_StrictMath, min_name, float2_float_signature, F_S) \
do_intrinsic(_maxF_strict, java_lang_StrictMath, max_name, float2_float_signature, F_S) \
do_intrinsic(_minD_strict, java_lang_StrictMath, min_name, double2_double_signature, F_S) \
do_intrinsic(_maxD_strict, java_lang_StrictMath, max_name, double2_double_signature, F_S) \
/* Special flavor of dsqrt intrinsic to handle the "native" method in StrictMath. Otherwise the same as in Math. */ \
do_intrinsic(_dsqrt_strict, java_lang_StrictMath, sqrt_name, double_double_signature, F_SN) \
\
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \
do_name( floatToRawIntBits_name, "floatToRawIntBits") \
do_intrinsic(_floatToIntBits, java_lang_Float, floatToIntBits_name, float_int_signature, F_S) \
@@ -145,14 +145,9 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHan
case vmIntrinsics::_dexp: return java_lang_math_exp;
case vmIntrinsics::_fmaD: return java_lang_math_fmaD;
case vmIntrinsics::_fmaF: return java_lang_math_fmaF;
case vmIntrinsics::_dsqrt: return java_lang_math_sqrt;
case vmIntrinsics::_dsqrt_strict: return native;
case vmIntrinsics::_Reference_get: return java_lang_ref_reference_get;
case vmIntrinsics::_dsqrt:
// _dsqrt will be selected for both Math::sqrt and StrictMath::sqrt, but the latter
// is native. Keep treating it like a native method in the interpreter
assert(m->name() == vmSymbols::sqrt_name() &&
(m->klass_name() == vmSymbols::java_lang_Math() ||
m->klass_name() == vmSymbols::java_lang_StrictMath()), "must be");
return m->is_native() ? native : java_lang_math_sqrt;
case vmIntrinsics::_Object_init:
if (RegisterFinalizersAtInit && m->code_size() == 1) {
// We need to execute the special return bytecode to check for
@@ -149,6 +149,7 @@ class AbstractInterpreter: AllStatic {
case vmIntrinsics::_dtan : // fall thru
case vmIntrinsics::_dabs : // fall thru
case vmIntrinsics::_dsqrt : // fall thru
case vmIntrinsics::_dsqrt_strict : // fall thru
case vmIntrinsics::_dlog : // fall thru
case vmIntrinsics::_dlog10: // fall thru
case vmIntrinsics::_dpow : // fall thru
@@ -1645,21 +1645,6 @@ void Method::init_intrinsic_id(vmSymbolID klass_id) {

// A few slightly irregular cases:
switch (klass_id) {
case VM_SYMBOL_ENUM_NAME(java_lang_StrictMath):
// Second chance: check in regular Math.
switch (name_id) {
case VM_SYMBOL_ENUM_NAME(min_name):
case VM_SYMBOL_ENUM_NAME(max_name):
case VM_SYMBOL_ENUM_NAME(sqrt_name):
// pretend it is the corresponding method in the non-strict class:
klass_id = VM_SYMBOL_ENUM_NAME(java_lang_Math);
id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
break;
default:
break;
}
break;

// Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*., VarHandle
case VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle):
case VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle):
@@ -454,15 +454,19 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
if (!Matcher::match_rule_supported(Op_Whitespace)) return false;
break;
case vmIntrinsics::_maxF:
case vmIntrinsics::_maxF_strict:
if (!Matcher::match_rule_supported(Op_MaxF)) return false;
break;
case vmIntrinsics::_minF:
case vmIntrinsics::_minF_strict:
if (!Matcher::match_rule_supported(Op_MinF)) return false;
break;
case vmIntrinsics::_maxD:
case vmIntrinsics::_maxD_strict:
if (!Matcher::match_rule_supported(Op_MaxD)) return false;
break;
case vmIntrinsics::_minD:
case vmIntrinsics::_minD_strict:
if (!Matcher::match_rule_supported(Op_MinD)) return false;
break;
case vmIntrinsics::_writeback0:
@@ -503,12 +507,15 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
case vmIntrinsics::_labs:
case vmIntrinsics::_datan2:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
case vmIntrinsics::_dexp:
case vmIntrinsics::_dlog:
case vmIntrinsics::_dlog10:
case vmIntrinsics::_dpow:
case vmIntrinsics::_min:
case vmIntrinsics::_max:
case vmIntrinsics::_min_strict:
case vmIntrinsics::_max_strict:
case vmIntrinsics::_arraycopy:
case vmIntrinsics::_indexOfL:
case vmIntrinsics::_indexOfU:
@@ -261,6 +261,7 @@ bool LibraryCallKit::try_to_inline(int predicate) {
case vmIntrinsics::_labs:
case vmIntrinsics::_datan2:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
case vmIntrinsics::_dexp:
case vmIntrinsics::_dlog:
case vmIntrinsics::_dlog10:
@@ -270,9 +271,6 @@ bool LibraryCallKit::try_to_inline(int predicate) {
case vmIntrinsics::_dsignum:
case vmIntrinsics::_fsignum: return inline_math_native(intrinsic_id());

case vmIntrinsics::_min:
case vmIntrinsics::_max: return inline_min_max(intrinsic_id());

case vmIntrinsics::_notify:
case vmIntrinsics::_notifyAll:
return inline_notify(intrinsic_id());
@@ -632,11 +630,21 @@ bool LibraryCallKit::try_to_inline(int predicate) {
case vmIntrinsics::_isWhitespace:
return inline_character_compare(intrinsic_id());

case vmIntrinsics::_min:
case vmIntrinsics::_max:
case vmIntrinsics::_min_strict:
case vmIntrinsics::_max_strict:
return inline_min_max(intrinsic_id());

case vmIntrinsics::_maxF:
case vmIntrinsics::_minF:
case vmIntrinsics::_maxD:
case vmIntrinsics::_minD:
return inline_fp_min_max(intrinsic_id());
case vmIntrinsics::_maxF_strict:
case vmIntrinsics::_minF_strict:
case vmIntrinsics::_maxD_strict:
case vmIntrinsics::_minD_strict:
return inline_fp_min_max(intrinsic_id());

case vmIntrinsics::_VectorUnaryOp:
return inline_vector_nary_operation(1);
@@ -1599,7 +1607,9 @@ bool LibraryCallKit::inline_double_math(vmIntrinsics::ID id) {
Node* n = NULL;
switch (id) {
case vmIntrinsics::_dabs: n = new AbsDNode( arg); break;
case vmIntrinsics::_dsqrt: n = new SqrtDNode(C, control(), arg); break;
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
n = new SqrtDNode(C, control(), arg); break;
case vmIntrinsics::_ceil: n = RoundDoubleModeNode::make(_gvn, arg, RoundDoubleModeNode::rmode_ceil); break;
case vmIntrinsics::_floor: n = RoundDoubleModeNode::make(_gvn, arg, RoundDoubleModeNode::rmode_floor); break;
case vmIntrinsics::_rint: n = RoundDoubleModeNode::make(_gvn, arg, RoundDoubleModeNode::rmode_rint); break;
@@ -1742,7 +1752,9 @@ bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
case vmIntrinsics::_ceil:
case vmIntrinsics::_floor:
case vmIntrinsics::_rint: return Matcher::match_rule_supported(Op_RoundDoubleMode) ? inline_double_math(id) : false;
case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_double_math(id) : false;
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsqrt_strict:
return Matcher::match_rule_supported(Op_SqrtD) ? inline_double_math(id) : false;
case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_double_math(id) : false;
case vmIntrinsics::_fabs: return Matcher::match_rule_supported(Op_AbsF) ? inline_math(id) : false;
case vmIntrinsics::_iabs: return Matcher::match_rule_supported(Op_AbsI) ? inline_math(id) : false;
@@ -1884,7 +1896,7 @@ LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
return xvalue;
}

bool want_max = (id == vmIntrinsics::_max);
bool want_max = (id == vmIntrinsics::_max || id == vmIntrinsics::_max_strict);

const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
@@ -7061,12 +7073,16 @@ bool LibraryCallKit::inline_fp_min_max(vmIntrinsics::ID id) {
switch (id) {
case vmIntrinsics::_maxF:
case vmIntrinsics::_minF:
case vmIntrinsics::_maxF_strict:
case vmIntrinsics::_minF_strict:
assert(callee()->signature()->size() == 2, "minF/maxF has 2 parameters of size 1 each.");
a = argument(0);
b = argument(1);
break;
case vmIntrinsics::_maxD:
case vmIntrinsics::_minD:
case vmIntrinsics::_maxD_strict:
case vmIntrinsics::_minD_strict:
assert(callee()->signature()->size() == 4, "minD/maxD has 2 parameters of size 2 each.");
a = round_double_node(argument(0));
b = round_double_node(argument(2));
@@ -7076,11 +7092,25 @@ bool LibraryCallKit::inline_fp_min_max(vmIntrinsics::ID id) {
break;
}
switch (id) {
case vmIntrinsics::_maxF: n = new MaxFNode(a, b); break;
case vmIntrinsics::_minF: n = new MinFNode(a, b); break;
case vmIntrinsics::_maxD: n = new MaxDNode(a, b); break;
case vmIntrinsics::_minD: n = new MinDNode(a, b); break;
default: fatal_unexpected_iid(id); break;
case vmIntrinsics::_maxF:
case vmIntrinsics::_maxF_strict:
n = new MaxFNode(a, b);
break;
case vmIntrinsics::_minF:
case vmIntrinsics::_minF_strict:
n = new MinFNode(a, b);
break;
case vmIntrinsics::_maxD:
case vmIntrinsics::_maxD_strict:
n = new MaxDNode(a, b);
break;
case vmIntrinsics::_minD:
case vmIntrinsics::_minD_strict:
n = new MinDNode(a, b);
break;
default:
fatal_unexpected_iid(id);
break;
}
set_result(_gvn.transform(n));
return true;

1 comment on commit 9eadcbb

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 9eadcbb Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.