diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index e0f067a23c8..c573b5adffe 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -2438,10 +2438,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) { return OptoRegPair(0, 0); } -const int Matcher::float_pressure(int default_pressure_threshold) { - return default_pressure_threshold; -} - // Is this branch offset short enough that a short branch can be used? // // NOTE: If the platform does not provide any short branch variants, then @@ -2554,6 +2550,31 @@ bool Matcher::is_spillable_arg(int reg) return can_be_java_arg(reg); } +uint Matcher::int_pressure_limit() +{ + // JDK-8183543: When taking the number of available registers as int + // register pressure threshold, the jtreg test: + // test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java + // failed due to C2 compilation failure with + // "COMPILE SKIPPED: failed spill-split-recycle sanity check". + // + // A derived pointer is live at CallNode and then is flagged by RA + // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip + // derived pointers and lastly fail to spill after reaching maximum + // number of iterations. Lowering the default pressure threshold to + // (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become + // a high register pressure area of the code so that split_DEF can + // generate DefinitionSpillCopy for the derived pointer. + uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1; + return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE; +} + +uint Matcher::float_pressure_limit() +{ + // _FLOAT_REG_mask is generated by adlc from the float_reg register class. + return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE; +} + bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { return false; } diff --git a/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp b/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp index f15b6faa79d..34e6e688abb 100644 --- a/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp @@ -44,10 +44,8 @@ define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); -define_pd_global(intx, FLOATPRESSURE, 32); define_pd_global(intx, FreqInlineSize, 325); define_pd_global(intx, MinJumpTableSize, 10); -define_pd_global(intx, INTPRESSURE, 24); define_pd_global(intx, InteriorEntryAlignment, 16); define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K)); define_pd_global(intx, LoopUnrollLimit, 60); diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 06267046028..41512a33d93 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -1001,10 +1001,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) { return OptoRegPair(0, 0); } -const int Matcher::float_pressure(int default_pressure_threshold) { - return default_pressure_threshold; -} - // Vector width in bytes const int Matcher::vector_width_in_bytes(BasicType bt) { return MaxVectorSize; @@ -1100,6 +1096,16 @@ bool Matcher::is_spillable_arg( int reg ) { return can_be_java_arg(reg); } +uint Matcher::int_pressure_limit() +{ + return (INTPRESSURE == -1) ? 12 : INTPRESSURE; +} + +uint Matcher::float_pressure_limit() +{ + return (FLOATPRESSURE == -1) ? 30 : FLOATPRESSURE; +} + bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { return false; } diff --git a/src/hotspot/cpu/arm/c2_globals_arm.hpp b/src/hotspot/cpu/arm/c2_globals_arm.hpp index 7754001dd0a..1d666357b30 100644 --- a/src/hotspot/cpu/arm/c2_globals_arm.hpp +++ b/src/hotspot/cpu/arm/c2_globals_arm.hpp @@ -45,9 +45,7 @@ define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 4); // C2 gets to use all the float/double registers -define_pd_global(intx, FLOATPRESSURE, 30); define_pd_global(intx, FreqInlineSize, 175); -define_pd_global(intx, INTPRESSURE, 12); define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K)); // The default setting 16/16 seems to work best. diff --git a/src/hotspot/cpu/ppc/c2_globals_ppc.hpp b/src/hotspot/cpu/ppc/c2_globals_ppc.hpp index bb103cdf609..00a92ff6b62 100644 --- a/src/hotspot/cpu/ppc/c2_globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/c2_globals_ppc.hpp @@ -44,10 +44,8 @@ define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); -define_pd_global(intx, FLOATPRESSURE, 28); define_pd_global(intx, FreqInlineSize, 175); define_pd_global(intx, MinJumpTableSize, 10); -define_pd_global(intx, INTPRESSURE, 26); define_pd_global(intx, InteriorEntryAlignment, 16); define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K)); define_pd_global(intx, RegisterCostAreaRatio, 16000); diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 0b66ce7489a..f3550911f83 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -2193,10 +2193,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) { return OptoRegPair(0, 0); } -const int Matcher::float_pressure(int default_pressure_threshold) { - return default_pressure_threshold; -} - // Vector width in bytes. const int Matcher::vector_width_in_bytes(BasicType bt) { if (SuperwordUseVSX) { @@ -2363,6 +2359,16 @@ bool Matcher::is_spillable_arg(int reg) { return can_be_java_arg(reg); } +uint Matcher::int_pressure_limit() +{ + return (INTPRESSURE == -1) ? 26 : INTPRESSURE; +} + +uint Matcher::float_pressure_limit() +{ + return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE; +} + bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { return false; } diff --git a/src/hotspot/cpu/s390/c2_globals_s390.hpp b/src/hotspot/cpu/s390/c2_globals_s390.hpp index e747f6c8c51..0192cb716ba 100644 --- a/src/hotspot/cpu/s390/c2_globals_s390.hpp +++ b/src/hotspot/cpu/s390/c2_globals_s390.hpp @@ -44,10 +44,8 @@ define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 4); -define_pd_global(intx, FLOATPRESSURE, 15); define_pd_global(intx, FreqInlineSize, 175); // 10 prevents spill-split-recycle sanity check in JVM2008.xml.transform. -define_pd_global(intx, INTPRESSURE, 10); // Medium size register set, 6 special purpose regs, 3 SOE regs. define_pd_global(intx, InteriorEntryAlignment, 2); define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K)); define_pd_global(intx, RegisterCostAreaRatio, 12000); diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index acd601b4929..36a3a5b8d05 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -1554,10 +1554,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) { return OptoRegPair(0, 0); } -const int Matcher::float_pressure(int default_pressure_threshold) { - return default_pressure_threshold; -} - //----------SUPERWORD HELPERS---------------------------------------- // Vector width in bytes. @@ -1665,6 +1661,17 @@ bool Matcher::is_spillable_arg(int reg) { return can_be_java_arg(reg); } +uint Matcher::int_pressure_limit() +{ + // Medium size register set, 6 special purpose regs, 3 SOE regs. + return (INTPRESSURE == -1) ? 10 : INTPRESSURE; +} + +uint Matcher::float_pressure_limit() +{ + return (FLOATPRESSURE == -1) ? 15 : FLOATPRESSURE; +} + bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { return false; } diff --git a/src/hotspot/cpu/x86/c2_globals_x86.hpp b/src/hotspot/cpu/x86/c2_globals_x86.hpp index 776caa30cf9..7e5128d7f2d 100644 --- a/src/hotspot/cpu/x86/c2_globals_x86.hpp +++ b/src/hotspot/cpu/x86/c2_globals_x86.hpp @@ -46,8 +46,6 @@ define_pd_global(intx, FreqInlineSize, 325); define_pd_global(intx, MinJumpTableSize, 10); define_pd_global(intx, LoopPercentProfileLimit, 30); #ifdef AMD64 -define_pd_global(intx, INTPRESSURE, 13); -define_pd_global(intx, FLOATPRESSURE, 14); define_pd_global(intx, InteriorEntryAlignment, 16); define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K)); define_pd_global(intx, LoopUnrollLimit, 60); @@ -58,8 +56,6 @@ define_pd_global(uintx, CodeCacheExpansionSize, 64*K); // Ergonomics related flags define_pd_global(uint64_t, MaxRAM, 128ULL*G); #else -define_pd_global(intx, INTPRESSURE, 6); -define_pd_global(intx, FLOATPRESSURE, 6); define_pd_global(intx, InteriorEntryAlignment, 4); define_pd_global(size_t, NewSizeThreadIncrease, 4*K); define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1 diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 5c8fd485824..a9971e1c4a1 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1898,18 +1898,6 @@ const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { return new TypeVectMask(TypeInt::BOOL, length); } -const int Matcher::float_pressure(int default_pressure_threshold) { - int float_pressure_threshold = default_pressure_threshold; -#ifdef _LP64 - if (UseAVX > 2) { - // Increase pressure threshold on machines with AVX3 which have - // 2x more XMM registers. - float_pressure_threshold = default_pressure_threshold * 2; - } -#endif - return float_pressure_threshold; -} - // Max vector size in bytes. 0 if not supported. const int Matcher::vector_width_in_bytes(BasicType bt) { assert(is_java_primitive(bt), "only primitive type vectors"); diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index a2cf6192415..4edd0e52ada 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1440,6 +1440,16 @@ bool Matcher::is_spillable_arg( int reg ) { return can_be_java_arg(reg); } +uint Matcher::int_pressure_limit() +{ + return (INTPRESSURE == -1) ? 6 : INTPRESSURE; +} + +uint Matcher::float_pressure_limit() +{ + return (FLOATPRESSURE == -1) ? 6 : FLOATPRESSURE; +} + bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { // Use hardware integer DIV instruction when // it is faster than a code which use multiply. diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 606e76d6553..908b0bef5b8 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -322,6 +322,7 @@ extern RegMask _LONG_NO_RCX_REG_mask; extern RegMask _INT_REG_mask; extern RegMask _INT_NO_RAX_RDX_REG_mask; extern RegMask _INT_NO_RCX_REG_mask; +extern RegMask _FLOAT_REG_mask; extern RegMask _STACK_OR_PTR_REG_mask; extern RegMask _STACK_OR_LONG_REG_mask; @@ -350,6 +351,7 @@ RegMask _LONG_NO_RCX_REG_mask; RegMask _INT_REG_mask; RegMask _INT_NO_RAX_RDX_REG_mask; RegMask _INT_NO_RCX_REG_mask; +RegMask _FLOAT_REG_mask; RegMask _STACK_OR_PTR_REG_mask; RegMask _STACK_OR_LONG_REG_mask; RegMask _STACK_OR_INT_REG_mask; @@ -425,6 +427,10 @@ void reg_mask_init() { _INT_NO_RCX_REG_mask = _INT_REG_mask; _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); + // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc + // from the float_reg_legacy/float_reg_evex register class. + _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; + if (Matcher::has_predicated_vectors()) { // Post-loop multi-versioning expects mask to be present in K1 register, till the time // its fixed, RA should not be allocting K1 register, this shall prevent any accidental @@ -1758,6 +1764,20 @@ bool Matcher::is_spillable_arg(int reg) return can_be_java_arg(reg); } +uint Matcher::int_pressure_limit() +{ + return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; +} + +uint Matcher::float_pressure_limit() +{ + // After experiment around with different values, the following default threshold + // works best for LCM's register pressure scheduling on x64. + uint dec_count = VM_Version::supports_evex() ? 4 : 2; + uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; + return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; +} + bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { // In 64 bit mode a code which use multiply when // devisor is constant is faster than hardware diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index f6b0ba8da0e..ad3deee0210 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -287,13 +287,17 @@ notproduct(bool, VerifyRegisterAllocator , false, \ "Verify Register Allocator") \ \ - develop_pd(intx, FLOATPRESSURE, \ - "Number of float LRG's that constitute high register pressure") \ - range(0, max_jint) \ + develop(intx, FLOATPRESSURE, -1, \ + "Number of float LRG's that constitute high register pressure." \ + "-1: means the threshold is determined by number of available " \ + "float register for allocation") \ + range(-1, max_jint) \ \ - develop_pd(intx, INTPRESSURE, \ - "Number of integer LRG's that constitute high register pressure") \ - range(0, max_jint) \ + develop(intx, INTPRESSURE, -1, \ + "Number of integer LRG's that constitute high register pressure." \ + "-1: means the threshold is determined by number of available " \ + "integer register for allocation") \ + range(-1, max_jint) \ \ notproduct(bool, TraceOptoPipelining, false, \ "Trace pipelining information") \ diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp index 452ab356d3f..41917c2b7b1 100644 --- a/src/hotspot/share/opto/chaitin.cpp +++ b/src/hotspot/share/opto/chaitin.cpp @@ -210,10 +210,10 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher, bool sc #endif , _lrg_map(Thread::current()->resource_area(), unique) , _scheduling_info_generated(scheduling_info_generated) - , _sched_int_pressure(0, INTPRESSURE) - , _sched_float_pressure(0, FLOATPRESSURE) - , _scratch_int_pressure(0, INTPRESSURE) - , _scratch_float_pressure(0, FLOATPRESSURE) + , _sched_int_pressure(0, Matcher::int_pressure_limit()) + , _sched_float_pressure(0, Matcher::float_pressure_limit()) + , _scratch_int_pressure(0, Matcher::int_pressure_limit()) + , _scratch_float_pressure(0, Matcher::float_pressure_limit()) { Compile::TracePhase tp("ctorChaitin", &timers[_t_ctorChaitin]); diff --git a/src/hotspot/share/opto/ifg.cpp b/src/hotspot/share/opto/ifg.cpp index c2d043bfe9e..9c1d1c52771 100644 --- a/src/hotspot/share/opto/ifg.cpp +++ b/src/hotspot/share/opto/ifg.cpp @@ -856,8 +856,8 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { move_exception_node_up(block, first_inst, last_inst); - Pressure int_pressure(last_inst + 1, INTPRESSURE); - Pressure float_pressure(last_inst + 1, FLOATPRESSURE); + Pressure int_pressure(last_inst + 1, Matcher::int_pressure_limit()); + Pressure float_pressure(last_inst + 1, Matcher::float_pressure_limit()); block->_reg_pressure = 0; block->_freg_pressure = 0; diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp index 68127d7cc23..ceee780cb07 100644 --- a/src/hotspot/share/opto/lcm.cpp +++ b/src/hotspot/share/opto/lcm.cpp @@ -1076,11 +1076,10 @@ bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, Vecto if (OptoRegScheduling && block_size_threshold_ok) { // To stage register pressure calculations we need to examine the live set variables // breaking them up by register class to compartmentalize the calculations. - uint float_pressure = Matcher::float_pressure(FLOATPRESSURE); - _regalloc->_sched_int_pressure.init(INTPRESSURE); - _regalloc->_sched_float_pressure.init(float_pressure); - _regalloc->_scratch_int_pressure.init(INTPRESSURE); - _regalloc->_scratch_float_pressure.init(float_pressure); + _regalloc->_sched_int_pressure.init(Matcher::int_pressure_limit()); + _regalloc->_sched_float_pressure.init(Matcher::float_pressure_limit()); + _regalloc->_scratch_int_pressure.init(Matcher::int_pressure_limit()); + _regalloc->_scratch_float_pressure.init(Matcher::float_pressure_limit()); _regalloc->compute_entry_block_pressure(block); } diff --git a/src/hotspot/share/opto/matcher.hpp b/src/hotspot/share/opto/matcher.hpp index 3582f4657ad..afa3b1d6b4a 100644 --- a/src/hotspot/share/opto/matcher.hpp +++ b/src/hotspot/share/opto/matcher.hpp @@ -233,6 +233,10 @@ public: // Maps from machine register to boolean; true if machine register holds // a spillable argument. static bool is_spillable_arg( int reg ); + // Number of integer live ranges that constitute high register pressure + static uint int_pressure_limit(); + // Number of float live ranges that constitute high register pressure + static uint float_pressure_limit(); // List of IfFalse or IfTrue Nodes that indicate a taken null test. // List is valid in the post-matching space. @@ -328,9 +332,6 @@ public: static const RegMask* predicate_reg_mask(void); static const TypeVect* predicate_reg_type(const Type* elemTy, int length); - // Some uarchs have different sized float register resources - static const int float_pressure(int default_pressure_threshold); - // Vector width in bytes static const int vector_width_in_bytes(BasicType bt); diff --git a/src/hotspot/share/opto/reg_split.cpp b/src/hotspot/share/opto/reg_split.cpp index 1d2717e7556..d62837202bb 100644 --- a/src/hotspot/share/opto/reg_split.cpp +++ b/src/hotspot/share/opto/reg_split.cpp @@ -447,7 +447,7 @@ bool PhaseChaitin::is_high_pressure( Block *b, LRG *lrg, uint insidx ) { // Bound live ranges will split at the binding points first; // Intermediate splits should assume the live range's register set // got "freed up" and that num_regs will become INT_PRESSURE. - int bound_pres = is_float_or_vector ? FLOATPRESSURE : INTPRESSURE; + int bound_pres = is_float_or_vector ? Matcher::float_pressure_limit() : Matcher::int_pressure_limit(); // Effective register pressure limit. int lrg_pres = (lrg->get_invalid_mask_size() > lrg->num_regs()) ? (lrg->get_invalid_mask_size() >> (lrg->num_regs()-1)) : bound_pres; @@ -800,12 +800,12 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { continue; } assert( insidx > b->_ihrp_index || - (b->_reg_pressure < (uint)INTPRESSURE) || + (b->_reg_pressure < Matcher::int_pressure_limit()) || b->_ihrp_index > 4000000 || b->_ihrp_index >= b->end_idx() || !b->get_node(b->_ihrp_index)->is_Proj(), "" ); assert( insidx > b->_fhrp_index || - (b->_freg_pressure < (uint)FLOATPRESSURE) || + (b->_freg_pressure < Matcher::float_pressure_limit()) || b->_fhrp_index > 4000000 || b->_fhrp_index >= b->end_idx() || !b->get_node(b->_fhrp_index)->is_Proj(), "" ); diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 90ce0f99c51..9c3e86a4651 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -2694,7 +2694,7 @@ void SuperWord::output() { // if vector resources are limited, do not allow additional unrolling, also // do not unroll more on pure vector loops which were not reduced so that we can // program the post loop to single iteration execution. - if (FLOATPRESSURE > 8) { + if (Matcher::float_pressure_limit() > 8) { C->set_major_progress(); cl->mark_do_unroll_only(); } diff --git a/test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java b/test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java new file mode 100644 index 00000000000..1b4a31b3db5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Alibaba Group Holding Limited. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8183543 + * @summary C2 compilation often fails on aarch64 with "failed spill-split-recycle sanity check" + * + * @library /test/lib + * + * @build sun.hotspot.WhiteBox + * + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * + * @run main/othervm -Xbatch + * -XX:-Inline + * -XX:-TieredCompilation + * -XX:+PreserveFramePointer + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.regalloc.TestC2IntPressure + */ + +package compiler.regalloc; + +import sun.hotspot.WhiteBox; + +public class TestC2IntPressure { + + static volatile int vol_f; + + static void not_inlined() { + // Do nothing + } + + static int test(TestC2IntPressure arg) { + TestC2IntPressure a = arg; + int res = 0; + not_inlined(); + res = a.vol_f; + return res; + } + + public static void main(String args[]) { + TestC2IntPressure arg = new TestC2IntPressure(); + for (int i = 0; i < 10000; i++) { + test(arg); + } + try { + var method = TestC2IntPressure.class.getDeclaredMethod("test", TestC2IntPressure.class); + if (!WhiteBox.getWhiteBox().isMethodCompiled(method)) { + throw new Error("test method didn't get compiled"); + } + } catch (NoSuchMethodException e) { + throw new Error("TESTBUG : " + e, e); + } + } +} +