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
src/hotspot
cpu
aarch64
arm
ppc
s390
x86
share/opto
test/hotspot/jtreg/compiler/regalloc
@ -2438,10 +2438,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
|
|||||||
return OptoRegPair(0, 0);
|
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?
|
// 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
|
// 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);
|
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) {
|
bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,8 @@ define_pd_global(intx, CompileThreshold, 10000);
|
|||||||
|
|
||||||
define_pd_global(intx, OnStackReplacePercentage, 140);
|
define_pd_global(intx, OnStackReplacePercentage, 140);
|
||||||
define_pd_global(intx, ConditionalMoveLimit, 3);
|
define_pd_global(intx, ConditionalMoveLimit, 3);
|
||||||
define_pd_global(intx, FLOATPRESSURE, 32);
|
|
||||||
define_pd_global(intx, FreqInlineSize, 325);
|
define_pd_global(intx, FreqInlineSize, 325);
|
||||||
define_pd_global(intx, MinJumpTableSize, 10);
|
define_pd_global(intx, MinJumpTableSize, 10);
|
||||||
define_pd_global(intx, INTPRESSURE, 24);
|
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||||
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||||
|
@ -1001,10 +1001,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
|
|||||||
return OptoRegPair(0, 0);
|
return OptoRegPair(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int Matcher::float_pressure(int default_pressure_threshold) {
|
|
||||||
return default_pressure_threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector width in bytes
|
// Vector width in bytes
|
||||||
const int Matcher::vector_width_in_bytes(BasicType bt) {
|
const int Matcher::vector_width_in_bytes(BasicType bt) {
|
||||||
return MaxVectorSize;
|
return MaxVectorSize;
|
||||||
@ -1100,6 +1096,16 @@ bool Matcher::is_spillable_arg( int reg ) {
|
|||||||
return can_be_java_arg(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 ) {
|
bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,7 @@ define_pd_global(intx, CompileThreshold, 10000);
|
|||||||
define_pd_global(intx, OnStackReplacePercentage, 140);
|
define_pd_global(intx, OnStackReplacePercentage, 140);
|
||||||
define_pd_global(intx, ConditionalMoveLimit, 4);
|
define_pd_global(intx, ConditionalMoveLimit, 4);
|
||||||
// C2 gets to use all the float/double registers
|
// 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, FreqInlineSize, 175);
|
||||||
define_pd_global(intx, INTPRESSURE, 12);
|
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
|
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
|
||||||
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
// The default setting 16/16 seems to work best.
|
// 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, OnStackReplacePercentage, 140);
|
||||||
define_pd_global(intx, ConditionalMoveLimit, 3);
|
define_pd_global(intx, ConditionalMoveLimit, 3);
|
||||||
define_pd_global(intx, FLOATPRESSURE, 28);
|
|
||||||
define_pd_global(intx, FreqInlineSize, 175);
|
define_pd_global(intx, FreqInlineSize, 175);
|
||||||
define_pd_global(intx, MinJumpTableSize, 10);
|
define_pd_global(intx, MinJumpTableSize, 10);
|
||||||
define_pd_global(intx, INTPRESSURE, 26);
|
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||||
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
define_pd_global(intx, RegisterCostAreaRatio, 16000);
|
define_pd_global(intx, RegisterCostAreaRatio, 16000);
|
||||||
|
@ -2193,10 +2193,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
|
|||||||
return OptoRegPair(0, 0);
|
return OptoRegPair(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int Matcher::float_pressure(int default_pressure_threshold) {
|
|
||||||
return default_pressure_threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector width in bytes.
|
// Vector width in bytes.
|
||||||
const int Matcher::vector_width_in_bytes(BasicType bt) {
|
const int Matcher::vector_width_in_bytes(BasicType bt) {
|
||||||
if (SuperwordUseVSX) {
|
if (SuperwordUseVSX) {
|
||||||
@ -2363,6 +2359,16 @@ bool Matcher::is_spillable_arg(int reg) {
|
|||||||
return can_be_java_arg(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) {
|
bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,8 @@ define_pd_global(intx, CompileThreshold, 10000);
|
|||||||
|
|
||||||
define_pd_global(intx, OnStackReplacePercentage, 140);
|
define_pd_global(intx, OnStackReplacePercentage, 140);
|
||||||
define_pd_global(intx, ConditionalMoveLimit, 4);
|
define_pd_global(intx, ConditionalMoveLimit, 4);
|
||||||
define_pd_global(intx, FLOATPRESSURE, 15);
|
|
||||||
define_pd_global(intx, FreqInlineSize, 175);
|
define_pd_global(intx, FreqInlineSize, 175);
|
||||||
// 10 prevents spill-split-recycle sanity check in JVM2008.xml.transform.
|
// 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(intx, InteriorEntryAlignment, 2);
|
||||||
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
define_pd_global(intx, RegisterCostAreaRatio, 12000);
|
define_pd_global(intx, RegisterCostAreaRatio, 12000);
|
||||||
|
@ -1554,10 +1554,6 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
|
|||||||
return OptoRegPair(0, 0);
|
return OptoRegPair(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int Matcher::float_pressure(int default_pressure_threshold) {
|
|
||||||
return default_pressure_threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------SUPERWORD HELPERS----------------------------------------
|
//----------SUPERWORD HELPERS----------------------------------------
|
||||||
|
|
||||||
// Vector width in bytes.
|
// Vector width in bytes.
|
||||||
@ -1665,6 +1661,17 @@ bool Matcher::is_spillable_arg(int reg) {
|
|||||||
return can_be_java_arg(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) {
|
bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,6 @@ define_pd_global(intx, FreqInlineSize, 325);
|
|||||||
define_pd_global(intx, MinJumpTableSize, 10);
|
define_pd_global(intx, MinJumpTableSize, 10);
|
||||||
define_pd_global(intx, LoopPercentProfileLimit, 30);
|
define_pd_global(intx, LoopPercentProfileLimit, 30);
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
define_pd_global(intx, INTPRESSURE, 13);
|
|
||||||
define_pd_global(intx, FLOATPRESSURE, 14);
|
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 16);
|
define_pd_global(intx, InteriorEntryAlignment, 16);
|
||||||
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
|
||||||
define_pd_global(intx, LoopUnrollLimit, 60);
|
define_pd_global(intx, LoopUnrollLimit, 60);
|
||||||
@ -58,8 +56,6 @@ define_pd_global(uintx, CodeCacheExpansionSize, 64*K);
|
|||||||
// Ergonomics related flags
|
// Ergonomics related flags
|
||||||
define_pd_global(uint64_t, MaxRAM, 128ULL*G);
|
define_pd_global(uint64_t, MaxRAM, 128ULL*G);
|
||||||
#else
|
#else
|
||||||
define_pd_global(intx, INTPRESSURE, 6);
|
|
||||||
define_pd_global(intx, FLOATPRESSURE, 6);
|
|
||||||
define_pd_global(intx, InteriorEntryAlignment, 4);
|
define_pd_global(intx, InteriorEntryAlignment, 4);
|
||||||
define_pd_global(size_t, NewSizeThreadIncrease, 4*K);
|
define_pd_global(size_t, NewSizeThreadIncrease, 4*K);
|
||||||
define_pd_global(intx, LoopUnrollLimit, 50); // Design center runs on 1.3.1
|
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);
|
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.
|
// Max vector size in bytes. 0 if not supported.
|
||||||
const int Matcher::vector_width_in_bytes(BasicType bt) {
|
const int Matcher::vector_width_in_bytes(BasicType bt) {
|
||||||
assert(is_java_primitive(bt), "only primitive type vectors");
|
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);
|
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 ) {
|
bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
|
||||||
// Use hardware integer DIV instruction when
|
// Use hardware integer DIV instruction when
|
||||||
// it is faster than a code which use multiply.
|
// 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_REG_mask;
|
||||||
extern RegMask _INT_NO_RAX_RDX_REG_mask;
|
extern RegMask _INT_NO_RAX_RDX_REG_mask;
|
||||||
extern RegMask _INT_NO_RCX_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_PTR_REG_mask;
|
||||||
extern RegMask _STACK_OR_LONG_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_REG_mask;
|
||||||
RegMask _INT_NO_RAX_RDX_REG_mask;
|
RegMask _INT_NO_RAX_RDX_REG_mask;
|
||||||
RegMask _INT_NO_RCX_REG_mask;
|
RegMask _INT_NO_RCX_REG_mask;
|
||||||
|
RegMask _FLOAT_REG_mask;
|
||||||
RegMask _STACK_OR_PTR_REG_mask;
|
RegMask _STACK_OR_PTR_REG_mask;
|
||||||
RegMask _STACK_OR_LONG_REG_mask;
|
RegMask _STACK_OR_LONG_REG_mask;
|
||||||
RegMask _STACK_OR_INT_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 = _INT_REG_mask;
|
||||||
_INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()));
|
_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()) {
|
if (Matcher::has_predicated_vectors()) {
|
||||||
// Post-loop multi-versioning expects mask to be present in K1 register, till the time
|
// 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
|
// 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);
|
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 ) {
|
bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
|
||||||
// In 64 bit mode a code which use multiply when
|
// In 64 bit mode a code which use multiply when
|
||||||
// devisor is constant is faster than hardware
|
// devisor is constant is faster than hardware
|
||||||
|
@ -287,13 +287,17 @@
|
|||||||
notproduct(bool, VerifyRegisterAllocator , false, \
|
notproduct(bool, VerifyRegisterAllocator , false, \
|
||||||
"Verify Register Allocator") \
|
"Verify Register Allocator") \
|
||||||
\
|
\
|
||||||
develop_pd(intx, FLOATPRESSURE, \
|
develop(intx, FLOATPRESSURE, -1, \
|
||||||
"Number of float LRG's that constitute high register pressure") \
|
"Number of float LRG's that constitute high register pressure." \
|
||||||
range(0, max_jint) \
|
"-1: means the threshold is determined by number of available " \
|
||||||
|
"float register for allocation") \
|
||||||
|
range(-1, max_jint) \
|
||||||
\
|
\
|
||||||
develop_pd(intx, INTPRESSURE, \
|
develop(intx, INTPRESSURE, -1, \
|
||||||
"Number of integer LRG's that constitute high register pressure") \
|
"Number of integer LRG's that constitute high register pressure." \
|
||||||
range(0, max_jint) \
|
"-1: means the threshold is determined by number of available " \
|
||||||
|
"integer register for allocation") \
|
||||||
|
range(-1, max_jint) \
|
||||||
\
|
\
|
||||||
notproduct(bool, TraceOptoPipelining, false, \
|
notproduct(bool, TraceOptoPipelining, false, \
|
||||||
"Trace pipelining information") \
|
"Trace pipelining information") \
|
||||||
|
@ -210,10 +210,10 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher, bool sc
|
|||||||
#endif
|
#endif
|
||||||
, _lrg_map(Thread::current()->resource_area(), unique)
|
, _lrg_map(Thread::current()->resource_area(), unique)
|
||||||
, _scheduling_info_generated(scheduling_info_generated)
|
, _scheduling_info_generated(scheduling_info_generated)
|
||||||
, _sched_int_pressure(0, INTPRESSURE)
|
, _sched_int_pressure(0, Matcher::int_pressure_limit())
|
||||||
, _sched_float_pressure(0, FLOATPRESSURE)
|
, _sched_float_pressure(0, Matcher::float_pressure_limit())
|
||||||
, _scratch_int_pressure(0, INTPRESSURE)
|
, _scratch_int_pressure(0, Matcher::int_pressure_limit())
|
||||||
, _scratch_float_pressure(0, FLOATPRESSURE)
|
, _scratch_float_pressure(0, Matcher::float_pressure_limit())
|
||||||
{
|
{
|
||||||
Compile::TracePhase tp("ctorChaitin", &timers[_t_ctorChaitin]);
|
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);
|
move_exception_node_up(block, first_inst, last_inst);
|
||||||
|
|
||||||
Pressure int_pressure(last_inst + 1, INTPRESSURE);
|
Pressure int_pressure(last_inst + 1, Matcher::int_pressure_limit());
|
||||||
Pressure float_pressure(last_inst + 1, FLOATPRESSURE);
|
Pressure float_pressure(last_inst + 1, Matcher::float_pressure_limit());
|
||||||
block->_reg_pressure = 0;
|
block->_reg_pressure = 0;
|
||||||
block->_freg_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) {
|
if (OptoRegScheduling && block_size_threshold_ok) {
|
||||||
// To stage register pressure calculations we need to examine the live set variables
|
// To stage register pressure calculations we need to examine the live set variables
|
||||||
// breaking them up by register class to compartmentalize the calculations.
|
// breaking them up by register class to compartmentalize the calculations.
|
||||||
uint float_pressure = Matcher::float_pressure(FLOATPRESSURE);
|
_regalloc->_sched_int_pressure.init(Matcher::int_pressure_limit());
|
||||||
_regalloc->_sched_int_pressure.init(INTPRESSURE);
|
_regalloc->_sched_float_pressure.init(Matcher::float_pressure_limit());
|
||||||
_regalloc->_sched_float_pressure.init(float_pressure);
|
_regalloc->_scratch_int_pressure.init(Matcher::int_pressure_limit());
|
||||||
_regalloc->_scratch_int_pressure.init(INTPRESSURE);
|
_regalloc->_scratch_float_pressure.init(Matcher::float_pressure_limit());
|
||||||
_regalloc->_scratch_float_pressure.init(float_pressure);
|
|
||||||
|
|
||||||
_regalloc->compute_entry_block_pressure(block);
|
_regalloc->compute_entry_block_pressure(block);
|
||||||
}
|
}
|
||||||
|
@ -233,6 +233,10 @@ public:
|
|||||||
// Maps from machine register to boolean; true if machine register holds
|
// Maps from machine register to boolean; true if machine register holds
|
||||||
// a spillable argument.
|
// a spillable argument.
|
||||||
static bool is_spillable_arg( int reg );
|
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 of IfFalse or IfTrue Nodes that indicate a taken null test.
|
||||||
// List is valid in the post-matching space.
|
// List is valid in the post-matching space.
|
||||||
@ -328,9 +332,6 @@ public:
|
|||||||
static const RegMask* predicate_reg_mask(void);
|
static const RegMask* predicate_reg_mask(void);
|
||||||
static const TypeVect* predicate_reg_type(const Type* elemTy, int length);
|
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
|
// Vector width in bytes
|
||||||
static const int vector_width_in_bytes(BasicType bt);
|
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;
|
// Bound live ranges will split at the binding points first;
|
||||||
// Intermediate splits should assume the live range's register set
|
// Intermediate splits should assume the live range's register set
|
||||||
// got "freed up" and that num_regs will become INT_PRESSURE.
|
// 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.
|
// Effective register pressure limit.
|
||||||
int lrg_pres = (lrg->get_invalid_mask_size() > lrg->num_regs())
|
int lrg_pres = (lrg->get_invalid_mask_size() > lrg->num_regs())
|
||||||
? (lrg->get_invalid_mask_size() >> (lrg->num_regs()-1)) : bound_pres;
|
? (lrg->get_invalid_mask_size() >> (lrg->num_regs()-1)) : bound_pres;
|
||||||
@ -800,12 +800,12 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assert( insidx > b->_ihrp_index ||
|
assert( insidx > b->_ihrp_index ||
|
||||||
(b->_reg_pressure < (uint)INTPRESSURE) ||
|
(b->_reg_pressure < Matcher::int_pressure_limit()) ||
|
||||||
b->_ihrp_index > 4000000 ||
|
b->_ihrp_index > 4000000 ||
|
||||||
b->_ihrp_index >= b->end_idx() ||
|
b->_ihrp_index >= b->end_idx() ||
|
||||||
!b->get_node(b->_ihrp_index)->is_Proj(), "" );
|
!b->get_node(b->_ihrp_index)->is_Proj(), "" );
|
||||||
assert( insidx > b->_fhrp_index ||
|
assert( insidx > b->_fhrp_index ||
|
||||||
(b->_freg_pressure < (uint)FLOATPRESSURE) ||
|
(b->_freg_pressure < Matcher::float_pressure_limit()) ||
|
||||||
b->_fhrp_index > 4000000 ||
|
b->_fhrp_index > 4000000 ||
|
||||||
b->_fhrp_index >= b->end_idx() ||
|
b->_fhrp_index >= b->end_idx() ||
|
||||||
!b->get_node(b->_fhrp_index)->is_Proj(), "" );
|
!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
|
// 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
|
// do not unroll more on pure vector loops which were not reduced so that we can
|
||||||
// program the post loop to single iteration execution.
|
// program the post loop to single iteration execution.
|
||||||
if (FLOATPRESSURE > 8) {
|
if (Matcher::float_pressure_limit() > 8) {
|
||||||
C->set_major_progress();
|
C->set_major_progress();
|
||||||
cl->mark_do_unroll_only();
|
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