diff --git a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp index 5f65ef5f04328..51887619ec159 100644 --- a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp @@ -32,11 +32,6 @@ enum { pd_hi_word_offset_in_bytes = BytesPerWord }; -// explicit rounding operations are required to implement the strictFP mode -enum { - pd_strict_fp_requires_explicit_rounding = false -}; - // FIXME: There are no callee-saved // registers diff --git a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp index e85daed732429..5fee15c840071 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp @@ -407,7 +407,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { arithmetic_op_fpu(x->op(), reg, left.result(), right.result()); - set_result(x, round_item(reg)); + set_result(x, reg); } // for _ladd, _lmul, _lsub, _ldiv, _lrem diff --git a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp index 447c5f57a8aa5..a6cd055775870 100644 --- a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp @@ -115,9 +115,6 @@ // C code as the Java calling convention forces doubles to be aligned. static const bool misaligned_doubles_ok = true; - // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. - static const bool strict_fp_requires_explicit_rounding = false; - // Are floats converted to double when stored to stack during // deoptimization? static constexpr bool float_in_double() { return false; } diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 6a935c26d544a..486d51ac46353 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -4510,18 +4510,6 @@ instruct unnecessary_membar_volatile() %{ %} //----------Register Move Instructions----------------------------------------- -// instruct roundDouble_nop(regD dst) %{ -// match(Set dst (RoundDouble dst)); -// ins_pipe(empty); -// %} - - -// instruct roundFloat_nop(regF dst) %{ -// match(Set dst (RoundFloat dst)); -// ins_pipe(empty); -// %} - - // Cast Index to Pointer for unsafe natives instruct castX2P(iRegX src, iRegP dst) %{ diff --git a/src/hotspot/cpu/arm/c1_Defs_arm.hpp b/src/hotspot/cpu/arm/c1_Defs_arm.hpp index 32e0b02964879..5145efd011a8d 100644 --- a/src/hotspot/cpu/arm/c1_Defs_arm.hpp +++ b/src/hotspot/cpu/arm/c1_Defs_arm.hpp @@ -31,11 +31,6 @@ enum { pd_hi_word_offset_in_bytes = BytesPerWord }; -// explicit rounding operations are required to implement the strictFP mode -enum { - pd_strict_fp_requires_explicit_rounding = false -}; - #ifdef __SOFTFP__ #define SOFT(n) n #define VFP(n) diff --git a/src/hotspot/cpu/arm/matcher_arm.hpp b/src/hotspot/cpu/arm/matcher_arm.hpp index a4436b7eab410..66fe8ac330eb5 100644 --- a/src/hotspot/cpu/arm/matcher_arm.hpp +++ b/src/hotspot/cpu/arm/matcher_arm.hpp @@ -101,9 +101,6 @@ // Java calling convention forces doubles to be aligned. static const bool misaligned_doubles_ok = false; - // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. - static const bool strict_fp_requires_explicit_rounding = false; - // Are floats converted to double when stored to stack during deoptimization? // ARM does not handle callee-save floats. static constexpr bool float_in_double() { diff --git a/src/hotspot/cpu/ppc/c1_Defs_ppc.hpp b/src/hotspot/cpu/ppc/c1_Defs_ppc.hpp index 9044b9edd2653..f322e548e2161 100644 --- a/src/hotspot/cpu/ppc/c1_Defs_ppc.hpp +++ b/src/hotspot/cpu/ppc/c1_Defs_ppc.hpp @@ -38,12 +38,6 @@ enum { }; -// Explicit rounding operations are not required to implement the strictFP mode. -enum { - pd_strict_fp_requires_explicit_rounding = false -}; - - // registers enum { pd_nof_cpu_regs_frame_map = 32, // Number of registers used during code emission. diff --git a/src/hotspot/cpu/ppc/matcher_ppc.hpp b/src/hotspot/cpu/ppc/matcher_ppc.hpp index 441339b94c61b..666bec9e0c802 100644 --- a/src/hotspot/cpu/ppc/matcher_ppc.hpp +++ b/src/hotspot/cpu/ppc/matcher_ppc.hpp @@ -115,9 +115,6 @@ // Java calling convention forces doubles to be aligned. static const bool misaligned_doubles_ok = true; - // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. - static const bool strict_fp_requires_explicit_rounding = false; - // Do floats take an entire double register or just half? // // A float occupies a ppc64 double register. For the allocator, a diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index acb98f8ea5ced..022a70d52a2b0 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -9537,28 +9537,6 @@ instruct sqrtF_reg(regF dst, regF src) %{ ins_pipe(pipe_class_default); %} -instruct roundDouble_nop(regD dst) %{ - match(Set dst (RoundDouble dst)); - ins_cost(0); - - format %{ " -- \t// RoundDouble not needed - empty" %} - size(0); - // PPC results are already "rounded" (i.e., normal-format IEEE). - ins_encode( /*empty*/ ); - ins_pipe(pipe_class_default); -%} - -instruct roundFloat_nop(regF dst) %{ - match(Set dst (RoundFloat dst)); - ins_cost(0); - - format %{ " -- \t// RoundFloat not needed - empty" %} - size(0); - // PPC results are already "rounded" (i.e., normal-format IEEE). - ins_encode( /*empty*/ ); - ins_pipe(pipe_class_default); -%} - // Multiply-Accumulate // src1 * src2 + src3 diff --git a/src/hotspot/cpu/riscv/c1_Defs_riscv.hpp b/src/hotspot/cpu/riscv/c1_Defs_riscv.hpp index bce243802980b..651136566013a 100644 --- a/src/hotspot/cpu/riscv/c1_Defs_riscv.hpp +++ b/src/hotspot/cpu/riscv/c1_Defs_riscv.hpp @@ -32,11 +32,6 @@ enum { pd_hi_word_offset_in_bytes = BytesPerWord }; -// explicit rounding operations are required to implement the strictFP mode -enum { - pd_strict_fp_requires_explicit_rounding = false -}; - // registers enum { pd_nof_cpu_regs_frame_map = Register::number_of_registers, // number of registers used during code emission diff --git a/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp index 3868c5ea8293c..b9ebd49779e98 100644 --- a/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp @@ -355,7 +355,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { LIR_Opr reg = rlock(x); arithmetic_op_fpu(x->op(), reg, left.result(), right.result()); - set_result(x, round_item(reg)); + set_result(x, reg); } // for _ladd, _lmul, _lsub, _ldiv, _lrem diff --git a/src/hotspot/cpu/riscv/matcher_riscv.hpp b/src/hotspot/cpu/riscv/matcher_riscv.hpp index ed1519ec1503a..1b490a07f92a6 100644 --- a/src/hotspot/cpu/riscv/matcher_riscv.hpp +++ b/src/hotspot/cpu/riscv/matcher_riscv.hpp @@ -114,9 +114,6 @@ // C code as the Java calling convention forces doubles to be aligned. static const bool misaligned_doubles_ok = true; - // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. - static const bool strict_fp_requires_explicit_rounding = false; - // Are floats converted to double when stored to stack during // deoptimization? static constexpr bool float_in_double() { return false; } diff --git a/src/hotspot/cpu/s390/c1_Defs_s390.hpp b/src/hotspot/cpu/s390/c1_Defs_s390.hpp index 6343a40bb06c7..31e0f85efcc2a 100644 --- a/src/hotspot/cpu/s390/c1_Defs_s390.hpp +++ b/src/hotspot/cpu/s390/c1_Defs_s390.hpp @@ -32,11 +32,6 @@ enum { pd_hi_word_offset_in_bytes = 0 }; -// Explicit rounding operations are not required to implement the strictFP mode. -enum { - pd_strict_fp_requires_explicit_rounding = false -}; - // registers enum { pd_nof_cpu_regs_frame_map = 16, // Number of registers used during code emission. diff --git a/src/hotspot/cpu/s390/matcher_s390.hpp b/src/hotspot/cpu/s390/matcher_s390.hpp index d8b1ae68f6f50..e4c277c63a8b9 100644 --- a/src/hotspot/cpu/s390/matcher_s390.hpp +++ b/src/hotspot/cpu/s390/matcher_s390.hpp @@ -108,9 +108,6 @@ // Java calling convention forces doubles to be aligned. static const bool misaligned_doubles_ok = true; - // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. - static const bool strict_fp_requires_explicit_rounding = false; - // Do floats take an entire double register or just half? // // A float in resides in a zarch double register. When storing it by diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index d6ab89a61d2c9..fc7de7e70e909 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -5317,23 +5317,6 @@ instruct membar_storestore() %{ //----------Register Move Instructions----------------------------------------- -instruct roundDouble_nop(regD dst) %{ - match(Set dst (RoundDouble dst)); - ins_cost(0); - // TODO: s390 port size(FIXED_SIZE); - // z/Architecture results are already "rounded" (i.e., normal-format IEEE). - ins_encode(); - ins_pipe(pipe_class_dummy); -%} - -instruct roundFloat_nop(regF dst) %{ - match(Set dst (RoundFloat dst)); - ins_cost(0); - // TODO: s390 port size(FIXED_SIZE); - // z/Architecture results are already "rounded" (i.e., normal-format IEEE). - ins_encode(); - ins_pipe(pipe_class_dummy); -%} // Cast Long to Pointer for unsafe natives. instruct castX2P(iRegP dst, iRegL src) %{ diff --git a/src/hotspot/cpu/x86/c1_Defs_x86.hpp b/src/hotspot/cpu/x86/c1_Defs_x86.hpp index 1125097ee0567..1637789e79884 100644 --- a/src/hotspot/cpu/x86/c1_Defs_x86.hpp +++ b/src/hotspot/cpu/x86/c1_Defs_x86.hpp @@ -31,12 +31,6 @@ enum { pd_hi_word_offset_in_bytes = BytesPerWord }; -// explicit rounding operations are required to implement the strictFP mode -enum { - pd_strict_fp_requires_explicit_rounding = LP64_ONLY( false ) NOT_LP64 ( true ) -}; - - // registers enum { pd_nof_cpu_regs_frame_map = NOT_LP64(8) LP64_ONLY(16), // number of registers used during code emission diff --git a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp index d0064b62dd856..107107a75b95e 100644 --- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp @@ -345,7 +345,7 @@ void LIRGenerator::do_NegateOp(NegateOp* x) { __ negate(value.result(), reg); - set_result(x, round_item(reg)); + set_result(x, reg); } // for _fadd, _fmul, _fsub, _fdiv, _frem @@ -433,7 +433,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { __ move(result_reg, result); } else { arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), tmp); - set_result(x, round_item(reg)); + set_result(x, reg); } #else if ((UseSSE >= 1 && x->op() == Bytecodes::_frem) || (UseSSE >= 2 && x->op() == Bytecodes::_drem)) { @@ -454,7 +454,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { } else { arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), tmp); } - set_result(x, round_item(reg)); + set_result(x, reg); #endif // _LP64 } diff --git a/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp b/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp index 7c4da998db895..5881609843586 100644 --- a/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp @@ -624,16 +624,6 @@ void FpuStackAllocator::handle_op1(LIR_Op1* op1) { break; } - case lir_roundfp: { - assert(in->is_fpu_register() && !in->is_xmm_register(), "input must be in register"); - assert(res->is_stack(), "result must be on stack"); - - insert_exchange(in); - new_in = to_fpu_stack_top(in); - pop_if_last_use(op1, in); - break; - } - case lir_abs: case lir_sqrt: case lir_neg: { diff --git a/src/hotspot/cpu/x86/matcher_x86.hpp b/src/hotspot/cpu/x86/matcher_x86.hpp index b311f4144b2bf..51756903792d6 100644 --- a/src/hotspot/cpu/x86/matcher_x86.hpp +++ b/src/hotspot/cpu/x86/matcher_x86.hpp @@ -121,13 +121,6 @@ // Java calling convention forces doubles to be aligned. static const bool misaligned_doubles_ok = true; - // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. -#ifdef _LP64 - static const bool strict_fp_requires_explicit_rounding = false; -#else - static const bool strict_fp_requires_explicit_rounding = true; -#endif - // Are floats converted to double when stored to stack during deoptimization? // On x64 it is stored without conversion so we can use normal access. // On x32 it is stored with conversion only when FPU is used for floats. diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index 2edec13c0ff29..7239031c8986b 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -4225,9 +4225,7 @@ int MatchRule::is_expensive() const { strcmp(opType,"FmaD") == 0 || strcmp(opType,"FmaF") == 0 || strcmp(opType,"FmaHF") == 0 || - strcmp(opType,"RoundDouble")==0 || strcmp(opType,"RoundDoubleMode")==0 || - strcmp(opType,"RoundFloat")==0 || strcmp(opType,"ReverseBytesI")==0 || strcmp(opType,"ReverseBytesL")==0 || strcmp(opType,"ReverseBytesUS")==0 || diff --git a/src/hotspot/share/c1/c1_Canonicalizer.cpp b/src/hotspot/share/c1/c1_Canonicalizer.cpp index f5a1d14e69431..573e1ac24d73c 100644 --- a/src/hotspot/share/c1/c1_Canonicalizer.cpp +++ b/src/hotspot/share/c1/c1_Canonicalizer.cpp @@ -840,7 +840,6 @@ void Canonicalizer::do_Throw (Throw* x) {} void Canonicalizer::do_Base (Base* x) {} void Canonicalizer::do_OsrEntry (OsrEntry* x) {} void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {} -void Canonicalizer::do_RoundFP (RoundFP* x) {} void Canonicalizer::do_UnsafeGet (UnsafeGet* x) {} void Canonicalizer::do_UnsafePut (UnsafePut* x) {} void Canonicalizer::do_UnsafeGetAndSet(UnsafeGetAndSet* x) {} diff --git a/src/hotspot/share/c1/c1_Canonicalizer.hpp b/src/hotspot/share/c1/c1_Canonicalizer.hpp index 8c7651256e95d..f1c99d4996c0e 100644 --- a/src/hotspot/share/c1/c1_Canonicalizer.hpp +++ b/src/hotspot/share/c1/c1_Canonicalizer.hpp @@ -88,7 +88,6 @@ class Canonicalizer: InstructionVisitor { virtual void do_Base (Base* x); virtual void do_OsrEntry (OsrEntry* x); virtual void do_ExceptionObject(ExceptionObject* x); - virtual void do_RoundFP (RoundFP* x); virtual void do_UnsafeGet (UnsafeGet* x); virtual void do_UnsafePut (UnsafePut* x); virtual void do_UnsafeGetAndSet(UnsafeGetAndSet* x); diff --git a/src/hotspot/share/c1/c1_Defs.hpp b/src/hotspot/share/c1/c1_Defs.hpp index 0e7b120ef8d6a..5803e1ce6863f 100644 --- a/src/hotspot/share/c1/c1_Defs.hpp +++ b/src/hotspot/share/c1/c1_Defs.hpp @@ -44,13 +44,6 @@ enum { hi_word_offset_in_bytes = pd_hi_word_offset_in_bytes }; - -// the processor may require explicit rounding operations to implement the strictFP mode -enum { - strict_fp_requires_explicit_rounding = pd_strict_fp_requires_explicit_rounding -}; - - // for debug info: a float value in a register may be saved in double precision by runtime stubs enum { float_saved_as_double = pd_float_saved_as_double diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index e918aa7d19ae7..b2750345a08ec 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -673,17 +673,6 @@ class MemoryBuffer: public CompilationResourceObj { return load; } - if (strict_fp_requires_explicit_rounding && load->type()->is_float_kind()) { -#ifdef IA32 - if (UseSSE < 2) { - // can't skip load since value might get rounded as a side effect - return load; - } -#else - Unimplemented(); -#endif // IA32 - } - ciField* field = load->field(); Value object = load->obj(); if (field->holder()->is_loaded() && !field->is_volatile()) { @@ -1052,7 +1041,7 @@ void GraphBuilder::store_local(ValueStack* state, Value x, int index) { } } - state->store_local(index, round_fp(x)); + state->store_local(index, x); } @@ -1204,10 +1193,7 @@ void GraphBuilder::arithmetic_op(ValueType* type, Bytecodes::Code code, ValueSta Value y = pop(type); Value x = pop(type); Value res = new ArithmeticOp(code, x, y, state_before); - // Note: currently single-precision floating-point rounding on Intel is handled at the LIRGenerator level - res = append(res); - res = round_fp(res); - push(type, res); + push(type, append(res)); } @@ -2228,7 +2214,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) { append_split(result); if (result_type != voidType) { - push(result_type, round_fp(result)); + push(result_type, result); } if (profile_return() && result_type->is_object_kind()) { profile_return_type(result, target); @@ -2356,29 +2342,6 @@ void GraphBuilder::throw_op(int bci) { } -Value GraphBuilder::round_fp(Value fp_value) { - if (strict_fp_requires_explicit_rounding) { -#ifdef IA32 - // no rounding needed if SSE2 is used - if (UseSSE < 2) { - // Must currently insert rounding node for doubleword values that - // are results of expressions (i.e., not loads from memory or - // constants) - if (fp_value->type()->tag() == doubleTag && - fp_value->as_Constant() == nullptr && - fp_value->as_Local() == nullptr && // method parameters need no rounding - fp_value->as_RoundFP() == nullptr) { - return append(new RoundFP(fp_value)); - } - } -#else - Unimplemented(); -#endif // IA32 - } - return fp_value; -} - - Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) { Canonicalizer canon(compilation(), instr, bci); Instruction* i1 = canon.canonical(); diff --git a/src/hotspot/share/c1/c1_GraphBuilder.hpp b/src/hotspot/share/c1/c1_GraphBuilder.hpp index 270c344833ef8..9b9ee0072ad63 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.hpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.hpp @@ -266,7 +266,6 @@ class GraphBuilder { void monitorexit(Value x, int bci); void new_multi_array(int dimensions); void throw_op(int bci); - Value round_fp(Value fp_value); // stack/code manipulation helpers Instruction* append_with_bci(Instruction* instr, int bci); diff --git a/src/hotspot/share/c1/c1_Instruction.hpp b/src/hotspot/share/c1/c1_Instruction.hpp index e950afc981d19..af22d5b8fc9aa 100644 --- a/src/hotspot/share/c1/c1_Instruction.hpp +++ b/src/hotspot/share/c1/c1_Instruction.hpp @@ -91,7 +91,6 @@ class LookupSwitch; class Return; class Throw; class Base; -class RoundFP; class UnsafeOp; class UnsafeGet; class UnsafePut; @@ -187,7 +186,6 @@ class InstructionVisitor: public StackObj { virtual void do_Base (Base* x) = 0; virtual void do_OsrEntry (OsrEntry* x) = 0; virtual void do_ExceptionObject(ExceptionObject* x) = 0; - virtual void do_RoundFP (RoundFP* x) = 0; virtual void do_UnsafeGet (UnsafeGet* x) = 0; virtual void do_UnsafePut (UnsafePut* x) = 0; virtual void do_UnsafeGetAndSet(UnsafeGetAndSet* x) = 0; @@ -556,7 +554,6 @@ class Instruction: public CompilationResourceObj { virtual Return* as_Return() { return nullptr; } virtual Throw* as_Throw() { return nullptr; } virtual Base* as_Base() { return nullptr; } - virtual RoundFP* as_RoundFP() { return nullptr; } virtual ExceptionObject* as_ExceptionObject() { return nullptr; } virtual UnsafeOp* as_UnsafeOp() { return nullptr; } virtual ProfileInvoke* as_ProfileInvoke() { return nullptr; } @@ -2142,30 +2139,6 @@ LEAF(ExceptionObject, Instruction) }; -// Models needed rounding for floating-point values on Intel. -// Currently only used to represent rounding of double-precision -// values stored into local variables, but could be used to model -// intermediate rounding of single-precision values as well. -LEAF(RoundFP, Instruction) - private: - Value _input; // floating-point value to be rounded - - public: - RoundFP(Value input) - : Instruction(input->type()) // Note: should not be used for constants - , _input(input) - { - ASSERT_VALUES - } - - // accessors - Value input() const { return _input; } - - // generic - virtual void input_values_do(ValueVisitor* f) { f->visit(&_input); } -}; - - BASE(UnsafeOp, Instruction) private: Value _object; // Object to be fetched from or mutated diff --git a/src/hotspot/share/c1/c1_InstructionPrinter.cpp b/src/hotspot/share/c1/c1_InstructionPrinter.cpp index 35818188496f8..633c5e575c2ab 100644 --- a/src/hotspot/share/c1/c1_InstructionPrinter.cpp +++ b/src/hotspot/share/c1/c1_InstructionPrinter.cpp @@ -779,12 +779,6 @@ void InstructionPrinter::do_ExceptionObject(ExceptionObject* x) { output()->print("incoming exception"); } - -void InstructionPrinter::do_RoundFP(RoundFP* x) { - output()->print("round_fp "); - print_value(x->input()); -} - void InstructionPrinter::do_UnsafeGet(UnsafeGet* x) { print_unsafe_op(x, x->is_raw() ? "UnsafeGet (raw)" : "UnsafeGet"); output()->put(')'); diff --git a/src/hotspot/share/c1/c1_InstructionPrinter.hpp b/src/hotspot/share/c1/c1_InstructionPrinter.hpp index 0e5ba78bdc762..6bc31d3fe55d8 100644 --- a/src/hotspot/share/c1/c1_InstructionPrinter.hpp +++ b/src/hotspot/share/c1/c1_InstructionPrinter.hpp @@ -120,7 +120,6 @@ class InstructionPrinter: public InstructionVisitor { virtual void do_Base (Base* x); virtual void do_OsrEntry (OsrEntry* x); virtual void do_ExceptionObject(ExceptionObject* x); - virtual void do_RoundFP (RoundFP* x); virtual void do_UnsafeGet (UnsafeGet* x); virtual void do_UnsafePut (UnsafePut* x); virtual void do_UnsafeGetAndSet(UnsafeGetAndSet* x); diff --git a/src/hotspot/share/c1/c1_LIR.cpp b/src/hotspot/share/c1/c1_LIR.cpp index fc90530ec95d8..e11b59cd0a546 100644 --- a/src/hotspot/share/c1/c1_LIR.cpp +++ b/src/hotspot/share/c1/c1_LIR.cpp @@ -550,20 +550,6 @@ void LIR_OpVisitState::visit(LIR_Op* op) { } -// LIR_OpRoundFP; - case lir_roundfp: { - assert(op->as_OpRoundFP() != nullptr, "must be"); - LIR_OpRoundFP* opRoundFP = (LIR_OpRoundFP*)op; - - assert(op->_info == nullptr, "info not used by this instruction"); - assert(opRoundFP->_tmp->is_illegal(), "not used"); - do_input(opRoundFP->_opr); - do_output(opRoundFP->_result); - - break; - } - - // LIR_Op2 case lir_cmp: case lir_cmp_l2i: @@ -1731,7 +1717,6 @@ const char * LIR_Op::name() const { case lir_branch: s = "branch"; break; case lir_cond_float_branch: s = "flt_cond_br"; break; case lir_move: s = "move"; break; - case lir_roundfp: s = "roundfp"; break; case lir_abs: s = "abs"; break; case lir_neg: s = "neg"; break; case lir_sqrt: s = "sqrt"; break; @@ -1976,12 +1961,6 @@ void LIR_OpAllocObj::print_instr(outputStream* out) const { out->print("[lbl:" INTPTR_FORMAT "]", p2i(stub()->entry())); } -void LIR_OpRoundFP::print_instr(outputStream* out) const { - _opr->print(out); out->print(" "); - tmp()->print(out); out->print(" "); - result_opr()->print(out); out->print(" "); -} - // LIR_Op2 void LIR_Op2::print_instr(outputStream* out) const { if (code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch) { diff --git a/src/hotspot/share/c1/c1_LIR.hpp b/src/hotspot/share/c1/c1_LIR.hpp index d9005c49c89d4..a4e0cc18daa95 100644 --- a/src/hotspot/share/c1/c1_LIR.hpp +++ b/src/hotspot/share/c1/c1_LIR.hpp @@ -884,7 +884,6 @@ class LIR_OpBranch; class LIR_OpConvert; class LIR_OpAllocObj; class LIR_OpReturn; -class LIR_OpRoundFP; class LIR_Op2; class LIR_OpDelay; class LIR_Op3; @@ -938,7 +937,6 @@ enum LIR_Code { , lir_convert , lir_alloc_object , lir_monaddr - , lir_roundfp , lir_sqrt , lir_abs , lir_neg @@ -1147,7 +1145,6 @@ class LIR_Op: public CompilationResourceObj { virtual LIR_OpLock* as_OpLock() { return nullptr; } virtual LIR_OpAllocArray* as_OpAllocArray() { return nullptr; } virtual LIR_OpAllocObj* as_OpAllocObj() { return nullptr; } - virtual LIR_OpRoundFP* as_OpRoundFP() { return nullptr; } virtual LIR_OpBranch* as_OpBranch() { return nullptr; } virtual LIR_OpReturn* as_OpReturn() { return nullptr; } virtual LIR_OpRTCall* as_OpRTCall() { return nullptr; } @@ -1527,23 +1524,6 @@ class LIR_OpAllocObj : public LIR_Op1 { }; -// LIR_OpRoundFP -class LIR_OpRoundFP : public LIR_Op1 { - friend class LIR_OpVisitState; - - private: - LIR_Opr _tmp; - - public: - LIR_OpRoundFP(LIR_Opr reg, LIR_Opr stack_loc_temp, LIR_Opr result) - : LIR_Op1(lir_roundfp, reg, result) - , _tmp(stack_loc_temp) {} - - LIR_Opr tmp() const { return _tmp; } - virtual LIR_OpRoundFP* as_OpRoundFP() { return this; } - void print_instr(outputStream* out) const PRODUCT_RETURN; -}; - // LIR_OpTypeCheck class LIR_OpTypeCheck: public LIR_Op { friend class LIR_OpVisitState; @@ -2205,7 +2185,6 @@ class LIR_List: public CompilationResourceObj { // result is a stack location for old backend and vreg for UseLinearScan // stack_loc_temp is an illegal register for old backend - void roundfp(LIR_Opr reg, LIR_Opr stack_loc_temp, LIR_Opr result) { append(new LIR_OpRoundFP(reg, stack_loc_temp, result)); } void move(LIR_Opr src, LIR_Opr dst, CodeEmitInfo* info = nullptr) { append(new LIR_Op1(lir_move, src, dst, dst->type(), lir_patch_none, info)); } void move(LIR_Address* src, LIR_Opr dst, CodeEmitInfo* info = nullptr) { append(new LIR_Op1(lir_move, LIR_OprFact::address(src), dst, src->type(), lir_patch_none, info)); } void move(LIR_Opr src, LIR_Address* dst, CodeEmitInfo* info = nullptr) { append(new LIR_Op1(lir_move, src, LIR_OprFact::address(dst), dst->type(), lir_patch_none, info)); } diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index a5930ba54d880..4d50a863801de 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -519,12 +519,6 @@ void LIR_Assembler::emit_op1(LIR_Op1* op) { } break; - case lir_roundfp: { - LIR_OpRoundFP* round_op = op->as_OpRoundFP(); - roundfp_op(round_op->in_opr(), round_op->tmp(), round_op->result_opr(), round_op->pop_fpu_stack()); - break; - } - case lir_abs: case lir_sqrt: case lir_f2hf: @@ -775,16 +769,6 @@ void LIR_Assembler::build_frame() { } -void LIR_Assembler::roundfp_op(LIR_Opr src, LIR_Opr tmp, LIR_Opr dest, bool pop_fpu_stack) { - assert(strict_fp_requires_explicit_rounding, "not required"); - assert((src->is_single_fpu() && dest->is_single_stack()) || - (src->is_double_fpu() && dest->is_double_stack()), - "round_fp: rounds register -> stack location"); - - reg2stack (src, dest, src->type(), pop_fpu_stack); -} - - void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide) { if (src->is_register()) { if (dest->is_register()) { diff --git a/src/hotspot/share/c1/c1_LIRAssembler.hpp b/src/hotspot/share/c1/c1_LIRAssembler.hpp index 34aa679daedd0..5b653b74ef5e9 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.hpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp @@ -215,7 +215,6 @@ class LIR_Assembler: public CompilationResourceObj { void logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest); - void roundfp_op(LIR_Opr src, LIR_Opr tmp, LIR_Opr dest, bool pop_fpu_stack); void move_op(LIR_Opr src, LIR_Opr result, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide); void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info); diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 959e49749c5e5..214da53799367 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -881,27 +881,6 @@ void LIRGenerator::arraycopy_helper(Intrinsic* x, int* flagsp, ciArrayKlass** ex } -LIR_Opr LIRGenerator::round_item(LIR_Opr opr) { - assert(opr->is_register(), "why spill if item is not register?"); - - if (strict_fp_requires_explicit_rounding) { -#ifdef IA32 - if (UseSSE < 1 && opr->is_single_fpu()) { - LIR_Opr result = new_register(T_FLOAT); - set_vreg_flag(result, must_start_in_memory); - assert(opr->is_register(), "only a register can be spilled"); - assert(opr->value_type()->is_float(), "rounding only for floats available"); - __ roundfp(opr, LIR_OprFact::illegalOpr, result); - return result; - } -#else - Unimplemented(); -#endif // IA32 - } - return opr; -} - - LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) { assert(type2size[t] == type2size[value->type()], "size mismatch: t=%s, value->type()=%s", type2name(t), type2name(value->type())); @@ -2053,25 +2032,6 @@ void LIRGenerator::do_Throw(Throw* x) { } -void LIRGenerator::do_RoundFP(RoundFP* x) { - assert(strict_fp_requires_explicit_rounding, "not required"); - - LIRItem input(x->input(), this); - input.load_item(); - LIR_Opr input_opr = input.result(); - assert(input_opr->is_register(), "why round if value is not in a register?"); - assert(input_opr->is_single_fpu() || input_opr->is_double_fpu(), "input should be floating-point value"); - if (input_opr->is_single_fpu()) { - set_result(x, round_item(input_opr)); // This code path not currently taken - } else { - LIR_Opr result = new_register(T_DOUBLE); - set_vreg_flag(result, must_start_in_memory); - __ roundfp(input_opr, LIR_OprFact::illegalOpr, result); - set_result(x, result); - } -} - - void LIRGenerator::do_UnsafeGet(UnsafeGet* x) { BasicType type = x->basic_type(); LIRItem src(x->object(), this); diff --git a/src/hotspot/share/c1/c1_LIRGenerator.hpp b/src/hotspot/share/c1/c1_LIRGenerator.hpp index 73bd883a7468e..e70bbd9618935 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.hpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.hpp @@ -233,7 +233,6 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { friend class LIRItem; - LIR_Opr round_item(LIR_Opr opr); LIR_Opr force_to_spill(LIR_Opr value, BasicType t); PhiResolverState& resolver_state() { return _resolver_state; } @@ -579,7 +578,6 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { virtual void do_Base (Base* x); virtual void do_OsrEntry (OsrEntry* x); virtual void do_ExceptionObject(ExceptionObject* x); - virtual void do_RoundFP (RoundFP* x); virtual void do_UnsafeGet (UnsafeGet* x); virtual void do_UnsafePut (UnsafePut* x); virtual void do_UnsafeGetAndSet(UnsafeGetAndSet* x); diff --git a/src/hotspot/share/c1/c1_LinearScan.cpp b/src/hotspot/share/c1/c1_LinearScan.cpp index c099bb47d9726..b0e2ff28c587b 100644 --- a/src/hotspot/share/c1/c1_LinearScan.cpp +++ b/src/hotspot/share/c1/c1_LinearScan.cpp @@ -5888,7 +5888,6 @@ bool LinearScanWalker::activate_current() { } else if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::must_start_in_memory)) { // activating an interval that must start in a stack slot, but may get a register later - // used for lir_roundfp: rounding is done by store to stack and reload later TRACE_LINEAR_SCAN(4, tty->print_cr(" interval must start in stack slot -> split it before first use")); assert(cur->assigned_reg() == any_reg && cur->assigned_regHi() == any_reg, "register already assigned"); @@ -6770,7 +6769,6 @@ void LinearScanStatistic::collect(LinearScan* allocator) { case lir_push: case lir_pop: case lir_convert: - case lir_roundfp: case lir_cmove: inc_counter(counter_misc_inst); break; default: inc_counter(counter_other_inst); break; diff --git a/src/hotspot/share/c1/c1_Optimizer.cpp b/src/hotspot/share/c1/c1_Optimizer.cpp index f8339b0004993..721ad1d9ff59d 100644 --- a/src/hotspot/share/c1/c1_Optimizer.cpp +++ b/src/hotspot/share/c1/c1_Optimizer.cpp @@ -577,7 +577,6 @@ class NullCheckVisitor: public InstructionVisitor { void do_Base (Base* x); void do_OsrEntry (OsrEntry* x); void do_ExceptionObject(ExceptionObject* x); - void do_RoundFP (RoundFP* x); void do_UnsafeGet (UnsafeGet* x); void do_UnsafePut (UnsafePut* x); void do_UnsafeGetAndSet(UnsafeGetAndSet* x); @@ -762,7 +761,6 @@ void NullCheckVisitor::do_Throw (Throw* x) { nce()->clear_las void NullCheckVisitor::do_Base (Base* x) {} void NullCheckVisitor::do_OsrEntry (OsrEntry* x) {} void NullCheckVisitor::do_ExceptionObject(ExceptionObject* x) { nce()->handle_ExceptionObject(x); } -void NullCheckVisitor::do_RoundFP (RoundFP* x) {} void NullCheckVisitor::do_UnsafeGet (UnsafeGet* x) {} void NullCheckVisitor::do_UnsafePut (UnsafePut* x) {} void NullCheckVisitor::do_UnsafeGetAndSet(UnsafeGetAndSet* x) {} diff --git a/src/hotspot/share/c1/c1_RangeCheckElimination.hpp b/src/hotspot/share/c1/c1_RangeCheckElimination.hpp index 371dc59714bc2..833f5dd1e99cb 100644 --- a/src/hotspot/share/c1/c1_RangeCheckElimination.hpp +++ b/src/hotspot/share/c1/c1_RangeCheckElimination.hpp @@ -154,7 +154,6 @@ class RangeCheckEliminator { void do_Base (Base* x) { /* nothing to do */ }; void do_OsrEntry (OsrEntry* x) { /* nothing to do */ }; void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }; - void do_RoundFP (RoundFP* x) { /* nothing to do */ }; void do_UnsafePut (UnsafePut* x) { /* nothing to do */ }; void do_UnsafeGet (UnsafeGet* x) { /* nothing to do */ }; void do_UnsafeGetAndSet(UnsafeGetAndSet* x) { /* nothing to do */ }; diff --git a/src/hotspot/share/c1/c1_ValueMap.hpp b/src/hotspot/share/c1/c1_ValueMap.hpp index c36bb5559ba66..12c372f27c84e 100644 --- a/src/hotspot/share/c1/c1_ValueMap.hpp +++ b/src/hotspot/share/c1/c1_ValueMap.hpp @@ -203,7 +203,6 @@ class ValueNumberingVisitor: public InstructionVisitor { void do_Base (Base* x) { /* nothing to do */ } void do_OsrEntry (OsrEntry* x) { /* nothing to do */ } void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ } - void do_RoundFP (RoundFP* x) { /* nothing to do */ } void do_ProfileCall (ProfileCall* x) { /* nothing to do */ } void do_ProfileReturnType (ProfileReturnType* x) { /* nothing to do */ } void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; diff --git a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp index b0082b6444df2..92154e7a46e96 100644 --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp @@ -149,11 +149,6 @@ Node* BarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) cons C2ParseAccess& parse_access = static_cast(access); GraphKit* kit = parse_access.kit(); - if (bt == T_DOUBLE) { - Node* new_val = kit->dprecision_rounding(val.node()); - val.set_node(new_val); - } - store = kit->store_to_memory(kit->control(), access.addr().node(), val.node(), bt, mo, requires_atomic_access, unaligned, mismatched, unsafe, access.barrier_data()); diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp index 41b621dfce972..a8d1a29250aca 100644 --- a/src/hotspot/share/opto/classes.hpp +++ b/src/hotspot/share/opto/classes.hpp @@ -313,10 +313,8 @@ macro(ReverseI) macro(ReverseL) macro(ReverseV) macro(Root) -macro(RoundDouble) macro(RoundDoubleMode) macro(RoundDoubleModeV) -macro(RoundFloat) macro(RotateLeft) macro(RotateLeftV) macro(RotateRight) diff --git a/src/hotspot/share/opto/convertnode.cpp b/src/hotspot/share/opto/convertnode.cpp index bdfb211da834e..3e99277d90330 100644 --- a/src/hotspot/share/opto/convertnode.cpp +++ b/src/hotspot/share/opto/convertnode.cpp @@ -181,16 +181,6 @@ const Type* ConvD2INode::Value(PhaseGVN* phase) const { return TypeInt::make( SharedRuntime::d2i( td->getd() ) ); } -//------------------------------Ideal------------------------------------------ -// If converting to an int type, skip any rounding nodes -Node *ConvD2INode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (in(1)->Opcode() == Op_RoundDouble) { - set_req(1, in(1)->in(1)); - return this; - } - return nullptr; -} - //------------------------------Identity--------------------------------------- // Int's can be converted to doubles with no loss of bits. Hence // converting an integer to a double and back to an integer is a NOP. @@ -217,16 +207,6 @@ Node* ConvD2LNode::Identity(PhaseGVN* phase) { return this; } -//------------------------------Ideal------------------------------------------ -// If converting to an int type, skip any rounding nodes -Node *ConvD2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (in(1)->Opcode() == Op_RoundDouble) { - set_req(1, in(1)->in(1)); - return this; - } - return nullptr; -} - //============================================================================= //------------------------------Value------------------------------------------ const Type* ConvF2DNode::Value(PhaseGVN* phase) const { @@ -300,16 +280,6 @@ Node* ConvF2INode::Identity(PhaseGVN* phase) { return this; } -//------------------------------Ideal------------------------------------------ -// If converting to an int type, skip any rounding nodes -Node *ConvF2INode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (in(1)->Opcode() == Op_RoundFloat) { - set_req(1, in(1)->in(1)); - return this; - } - return nullptr; -} - //============================================================================= //------------------------------Value------------------------------------------ const Type* ConvF2LNode::Value(PhaseGVN* phase) const { @@ -329,16 +299,6 @@ Node* ConvF2LNode::Identity(PhaseGVN* phase) { return this; } -//------------------------------Ideal------------------------------------------ -// If converting to an int type, skip any rounding nodes -Node *ConvF2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (in(1)->Opcode() == Op_RoundFloat) { - set_req(1, in(1)->in(1)); - return this; - } - return nullptr; -} - //============================================================================= //------------------------------Value------------------------------------------ const Type* ConvHF2FNode::Value(PhaseGVN* phase) const { @@ -865,52 +825,6 @@ Node *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) { return nullptr; } - - -//============================================================================= -//------------------------------Identity--------------------------------------- -// Remove redundant roundings -Node* RoundFloatNode::Identity(PhaseGVN* phase) { - assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); - // Do not round constants - if (phase->type(in(1))->base() == Type::FloatCon) return in(1); - int op = in(1)->Opcode(); - // Redundant rounding - if( op == Op_RoundFloat ) return in(1); - // Already rounded - if( op == Op_Parm ) return in(1); - if( op == Op_LoadF ) return in(1); - return this; -} - -//------------------------------Value------------------------------------------ -const Type* RoundFloatNode::Value(PhaseGVN* phase) const { - return phase->type( in(1) ); -} - -//============================================================================= -//------------------------------Identity--------------------------------------- -// Remove redundant roundings. Incoming arguments are already rounded. -Node* RoundDoubleNode::Identity(PhaseGVN* phase) { - assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); - // Do not round constants - if (phase->type(in(1))->base() == Type::DoubleCon) return in(1); - int op = in(1)->Opcode(); - // Redundant rounding - if( op == Op_RoundDouble ) return in(1); - // Already rounded - if( op == Op_Parm ) return in(1); - if( op == Op_LoadD ) return in(1); - if( op == Op_ConvF2D ) return in(1); - if( op == Op_ConvI2D ) return in(1); - return this; -} - -//------------------------------Value------------------------------------------ -const Type* RoundDoubleNode::Value(PhaseGVN* phase) const { - return phase->type( in(1) ); -} - //============================================================================= RoundDoubleModeNode* RoundDoubleModeNode::make(PhaseGVN& gvn, Node* arg, RoundDoubleModeNode::RoundingMode rmode) { ConINode* rm = gvn.intcon(rmode); diff --git a/src/hotspot/share/opto/convertnode.hpp b/src/hotspot/share/opto/convertnode.hpp index 64b2d2571b2a1..7035573589db9 100644 --- a/src/hotspot/share/opto/convertnode.hpp +++ b/src/hotspot/share/opto/convertnode.hpp @@ -79,7 +79,6 @@ class ConvD2INode : public ConvertNode { virtual const Type* in_type() const { return Type::DOUBLE; } virtual const Type* Value(PhaseGVN* phase) const; virtual Node* Identity(PhaseGVN* phase); - virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------ConvD2LNode------------------------------------ @@ -91,7 +90,6 @@ class ConvD2LNode : public ConvertNode { virtual const Type* in_type() const { return Type::DOUBLE; } virtual const Type* Value(PhaseGVN* phase) const; virtual Node* Identity(PhaseGVN* phase); - virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------ConvF2DNode------------------------------------ @@ -124,7 +122,6 @@ class ConvF2INode : public ConvertNode { virtual const Type* in_type() const { return TypeInt::FLOAT; } virtual const Type* Value(PhaseGVN* phase) const; virtual Node* Identity(PhaseGVN* phase); - virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------ConvF2LNode------------------------------------ @@ -136,7 +133,6 @@ class ConvF2LNode : public ConvertNode { virtual const Type* in_type() const { return TypeInt::FLOAT; } virtual const Type* Value(PhaseGVN* phase) const; virtual Node* Identity(PhaseGVN* phase); - virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------ConvHF2FNode------------------------------------ @@ -254,28 +250,6 @@ class RoundFNode : public Node { virtual uint ideal_reg() const { return Op_RegI; } }; -//-----------------------------RoundFloatNode---------------------------------- -class RoundFloatNode: public Node { - public: - RoundFloatNode(Node* c, Node *in1): Node(c, in1) {} - virtual int Opcode() const; - virtual const Type *bottom_type() const { return Type::FLOAT; } - virtual uint ideal_reg() const { return Op_RegF; } - virtual Node* Identity(PhaseGVN* phase); - virtual const Type* Value(PhaseGVN* phase) const; -}; - - -//-----------------------------RoundDoubleNode--------------------------------- -class RoundDoubleNode: public Node { - public: - RoundDoubleNode(Node* c, Node *in1): Node(c, in1) {} - virtual int Opcode() const; - virtual const Type *bottom_type() const { return Type::DOUBLE; } - virtual uint ideal_reg() const { return Op_RegD; } - virtual Node* Identity(PhaseGVN* phase); - virtual const Type* Value(PhaseGVN* phase) const; -}; //-----------------------------RoundDoubleModeNode----------------------------- class RoundDoubleModeNode: public Node { diff --git a/src/hotspot/share/opto/doCall.cpp b/src/hotspot/share/opto/doCall.cpp index f4b36674968f5..ad7b64f93f5a0 100644 --- a/src/hotspot/share/opto/doCall.cpp +++ b/src/hotspot/share/opto/doCall.cpp @@ -648,8 +648,6 @@ void Parse::do_call() { orig_callee = callee = nullptr; // --------------------- - // Round double arguments before call - round_double_arguments(cg->method()); // Feed profiling data for arguments to the type system so it can // propagate it as speculative types diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index bb225eeabf554..5836ea579a297 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -2364,51 +2364,6 @@ void GraphKit::record_profiled_return_for_speculation() { } } -void GraphKit::round_double_arguments(ciMethod* dest_method) { - if (Matcher::strict_fp_requires_explicit_rounding) { - // (Note: TypeFunc::make has a cache that makes this fast.) - const TypeFunc* tf = TypeFunc::make(dest_method); - int nargs = tf->domain()->cnt() - TypeFunc::Parms; - for (int j = 0; j < nargs; j++) { - const Type *targ = tf->domain()->field_at(j + TypeFunc::Parms); - if (targ->basic_type() == T_DOUBLE) { - // If any parameters are doubles, they must be rounded before - // the call, dprecision_rounding does gvn.transform - Node *arg = argument(j); - arg = dprecision_rounding(arg); - set_argument(j, arg); - } - } - } -} - -// rounding for strict float precision conformance -Node* GraphKit::precision_rounding(Node* n) { - if (Matcher::strict_fp_requires_explicit_rounding) { -#ifdef IA32 - if (UseSSE == 0) { - return _gvn.transform(new RoundFloatNode(nullptr, n)); - } -#else - Unimplemented(); -#endif // IA32 - } - return n; -} - -// rounding for strict double precision conformance -Node* GraphKit::dprecision_rounding(Node *n) { - if (Matcher::strict_fp_requires_explicit_rounding) { -#ifdef IA32 - if (UseSSE < 2) { - return _gvn.transform(new RoundDoubleNode(nullptr, n)); - } -#else - Unimplemented(); -#endif // IA32 - } - return n; -} //============================================================================= // Generate a fast path/slow path idiom. Graph looks like: diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp index b0150df04ed2b..d9a725fc10c0c 100644 --- a/src/hotspot/share/opto/graphKit.hpp +++ b/src/hotspot/share/opto/graphKit.hpp @@ -752,15 +752,6 @@ class GraphKit : public Phase { void final_sync(IdealKit& ideal); public: - // Helper function to round double arguments before a call - void round_double_arguments(ciMethod* dest_method); - - // rounding for strict float precision conformance - Node* precision_rounding(Node* n); - - // rounding for strict double precision conformance - Node* dprecision_rounding(Node* n); - // Helper functions for fast/slow path codes Node* opt_iff(Node* region, Node* iff); Node* make_runtime_call(int flags, diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 9e98c9883f76a..3bb432ac6077b 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -1721,20 +1721,6 @@ bool LibraryCallKit::inline_string_char_access(bool is_store) { return true; } -//--------------------------round_double_node-------------------------------- -// Round a double node if necessary. -Node* LibraryCallKit::round_double_node(Node* n) { - if (Matcher::strict_fp_requires_explicit_rounding) { -#ifdef IA32 - if (UseSSE < 2) { - n = _gvn.transform(new RoundDoubleNode(nullptr, n)); - } -#else - Unimplemented(); -#endif // IA32 - } - return n; -} //------------------------------inline_math----------------------------------- // public static double Math.abs(double) @@ -1743,7 +1729,7 @@ Node* LibraryCallKit::round_double_node(Node* n) { // public static double Math.log10(double) // public static double Math.round(double) bool LibraryCallKit::inline_double_math(vmIntrinsics::ID id) { - Node* arg = round_double_node(argument(0)); + Node* arg = argument(0); Node* n = nullptr; switch (id) { case vmIntrinsics::_dabs: n = new AbsDNode( arg); break; @@ -1754,7 +1740,7 @@ bool LibraryCallKit::inline_double_math(vmIntrinsics::ID id) { case vmIntrinsics::_floor: n = RoundDoubleModeNode::make(_gvn, arg, RoundDoubleModeNode::rmode_floor); break; case vmIntrinsics::_rint: n = RoundDoubleModeNode::make(_gvn, arg, RoundDoubleModeNode::rmode_rint); break; case vmIntrinsics::_roundD: n = new RoundDNode(arg); break; - case vmIntrinsics::_dcopySign: n = CopySignDNode::make(_gvn, arg, round_double_node(argument(2))); break; + case vmIntrinsics::_dcopySign: n = CopySignDNode::make(_gvn, arg, argument(2)); break; case vmIntrinsics::_dsignum: n = SignumDNode::make(_gvn, arg); break; default: fatal_unexpected_iid(id); break; } @@ -1788,8 +1774,8 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c "must be (DD)D or (D)D type"); // Inputs - Node* a = round_double_node(argument(0)); - Node* b = (call_type == OptoRuntime::Math_DD_D_Type()) ? round_double_node(argument(2)) : nullptr; + Node* a = argument(0); + Node* b = (call_type == OptoRuntime::Math_DD_D_Type()) ? argument(2) : nullptr; const TypePtr* no_memory_effects = nullptr; Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, @@ -1807,17 +1793,17 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c //------------------------------inline_math_pow----------------------------- bool LibraryCallKit::inline_math_pow() { - Node* exp = round_double_node(argument(2)); + Node* exp = argument(2); const TypeD* d = _gvn.type(exp)->isa_double_constant(); if (d != nullptr) { if (d->getd() == 2.0) { // Special case: pow(x, 2.0) => x * x - Node* base = round_double_node(argument(0)); + Node* base = argument(0); set_result(_gvn.transform(new MulDNode(base, base))); return true; } else if (d->getd() == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) { // Special case: pow(x, 0.5) => sqrt(x) - Node* base = round_double_node(argument(0)); + Node* base = argument(0); Node* zero = _gvn.zerocon(T_DOUBLE); RegionNode* region = new RegionNode(3); @@ -1963,8 +1949,8 @@ bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) { case vmIntrinsics::_minD_strict: case vmIntrinsics::_maxD_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)); + a = argument(0); + b = argument(2); break; case vmIntrinsics::_minL: case vmIntrinsics::_maxL: @@ -8483,9 +8469,9 @@ bool LibraryCallKit::inline_fma(vmIntrinsics::ID id) { case vmIntrinsics::_fmaD: assert(callee()->signature()->size() == 6, "fma has 3 parameters of size 2 each."); // no receiver since it is static method - a = round_double_node(argument(0)); - b = round_double_node(argument(2)); - c = round_double_node(argument(4)); + a = argument(0); + b = argument(2); + c = argument(4); result = _gvn.transform(new FmaDNode(a, b, c)); break; case vmIntrinsics::_fmaF: diff --git a/src/hotspot/share/opto/library_call.hpp b/src/hotspot/share/opto/library_call.hpp index 790c03be7ca51..1f83e28932b70 100644 --- a/src/hotspot/share/opto/library_call.hpp +++ b/src/hotspot/share/opto/library_call.hpp @@ -202,7 +202,6 @@ class LibraryCallKit : public GraphKit { bool inline_string_getCharsU(); bool inline_string_copy(bool compress); bool inline_string_char_access(bool is_store); - 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_math(vmIntrinsics::ID id); diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index 6257a6b872d42..1a4c3c91c4f08 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -2062,19 +2062,19 @@ void Parse::do_one_bytecode() { // double stores case Bytecodes::_dstore_0: - set_pair_local( 0, dprecision_rounding(pop_pair()) ); + set_pair_local( 0, pop_pair() ); break; case Bytecodes::_dstore_1: - set_pair_local( 1, dprecision_rounding(pop_pair()) ); + set_pair_local( 1, pop_pair() ); break; case Bytecodes::_dstore_2: - set_pair_local( 2, dprecision_rounding(pop_pair()) ); + set_pair_local( 2, pop_pair() ); break; case Bytecodes::_dstore_3: - set_pair_local( 3, dprecision_rounding(pop_pair()) ); + set_pair_local( 3, pop_pair() ); break; case Bytecodes::_dstore: - set_pair_local( iter().get_index(), dprecision_rounding(pop_pair()) ); + set_pair_local( iter().get_index(), pop_pair() ); break; case Bytecodes::_pop: dec_sp(1); break; @@ -2256,32 +2256,28 @@ void Parse::do_one_bytecode() { b = pop(); a = pop(); c = _gvn.transform( new SubFNode(a,b) ); - d = precision_rounding(c); - push( d ); + push(c); break; case Bytecodes::_fadd: b = pop(); a = pop(); c = _gvn.transform( new AddFNode(a,b) ); - d = precision_rounding(c); - push( d ); + push(c); break; case Bytecodes::_fmul: b = pop(); a = pop(); c = _gvn.transform( new MulFNode(a,b) ); - d = precision_rounding(c); - push( d ); + push(c); break; case Bytecodes::_fdiv: b = pop(); a = pop(); c = _gvn.transform( new DivFNode(nullptr,a,b) ); - d = precision_rounding(c); - push( d ); + push(c); break; case Bytecodes::_frem: @@ -2331,8 +2327,6 @@ void Parse::do_one_bytecode() { case Bytecodes::_d2f: a = pop_pair(); b = _gvn.transform( new ConvD2FNode(a)); - // This breaks _227_mtrt (speed & correctness) and _222_mpegaudio (speed) - //b = _gvn.transform(new RoundFloatNode(nullptr, b) ); push( b ); break; @@ -2340,11 +2334,6 @@ void Parse::do_one_bytecode() { if (Matcher::convL2FSupported()) { a = pop_pair(); b = _gvn.transform( new ConvL2FNode(a)); - // For x86_32.ad, FILD doesn't restrict precision to 24 or 53 bits. - // Rather than storing the result into an FP register then pushing - // out to memory to round, the machine instruction that implements - // ConvL2D is responsible for rounding. - // c = precision_rounding(b); push(b); } else { l2f(); @@ -2354,8 +2343,6 @@ void Parse::do_one_bytecode() { case Bytecodes::_l2d: a = pop_pair(); b = _gvn.transform( new ConvL2DNode(a)); - // For x86_32.ad, rounding is always necessary (see _l2f above). - // c = dprecision_rounding(b); push_pair(b); break; @@ -2375,32 +2362,28 @@ void Parse::do_one_bytecode() { b = pop_pair(); a = pop_pair(); c = _gvn.transform( new SubDNode(a,b) ); - d = dprecision_rounding(c); - push_pair( d ); + push_pair(c); break; case Bytecodes::_dadd: b = pop_pair(); a = pop_pair(); c = _gvn.transform( new AddDNode(a,b) ); - d = dprecision_rounding(c); - push_pair( d ); + push_pair(c); break; case Bytecodes::_dmul: b = pop_pair(); a = pop_pair(); c = _gvn.transform( new MulDNode(a,b) ); - d = dprecision_rounding(c); - push_pair( d ); + push_pair(c); break; case Bytecodes::_ddiv: b = pop_pair(); a = pop_pair(); c = _gvn.transform( new DivDNode(nullptr,a,b) ); - d = dprecision_rounding(c); - push_pair( d ); + push_pair(c); break; case Bytecodes::_dneg: @@ -2585,8 +2568,7 @@ void Parse::do_one_bytecode() { case Bytecodes::_i2f: a = pop(); b = _gvn.transform( new ConvI2FNode(a) ) ; - c = precision_rounding(b); - push (b); + push(b); break; case Bytecodes::_i2d: