8268858: Determine register pressure automatically by the number of available registers for allocation
Reviewed-by: kvn, dlong
This commit is contained in:
parent
ae3eedce9d
commit
36d82b6ef1
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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") \
|
||||
|
@ -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]);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(), "" );
|
||||
|
@ -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();
|
||||
}
|
||||
|
79
test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java
Normal file
79
test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user