RFR(S): 8087128 C2: Disallow definition split on MachCopySpill nodes
Nils Eliasson
nils.eliasson at oracle.com
Wed Jan 30 09:23:18 UTC 2019
Thank you Vladimir,
// Nils
On 2019-01-29 23:48, Vladimir Kozlov wrote:
> Thank you, Nils
>
> Looks good to me.
>
> Please run hs-precheckin-comp testing too.
>
> Vladimir
>
> On 1/28/19 7:15 AM, Nils Eliasson wrote:
>> Hi,
>>
>> We have a problem that we sometimes hit an assert in reg_split.cpp.
>>
>> https://bugs.openjdk.java.net/browse/JDK-8087128
>>
>> http://cr.openjdk.java.net/~neliasso/8087128/webrev.01/
>>
>> We have a block that looks like this:
>>
>> 1262: # B1264 B1263 <- N7283 Freq: 0,0927179
>> 7282 Region === 7282 1704 [[ 7282 1702 1715 ]]
>> 11500 MemToRegSpillCopy === _ 11190 [[ 9184 ]]
>> Oop:com/sun/tools/javac/$
>> 9184 DefinitionSpillCopy === _ 11500 [[ 9185 1702 11503
>> 11505 ]] Oop:$
>> 11501 MemToRegSpillCopy === _ 9169 [[ 11665 11506 11504
>> 11502 ]] Oop$
>> 11645 MemToRegSpillCopy === _ 9167 [[ 9182 ]]
>> Oop:com/sun/tools/javac/c$
>> 9182 DefinitionSpillCopy === _ 11645 [[ 1702 11646 11647
>> 11648 ]] Oop$
>> 1715 checkCastPP === 7282 1716 [[ 1702 ]]
>> java/util/HashMap$TreeNode:NotN$
>> 9185 BoundSpillCopy === _ 9184 [[ 1702 ]]
>> Oop:com/sun/tools/javac/code/Symb$
>> 11665 RegToMemSpillCopy === _ 11501 [[ 1702 ]]
>> Oop:com/sun/tools/javac/$
>> 1702 CallStaticJavaDirect === 7282 185 182 16 0 1715 187
>> 9185 11665 $
>> 1703 MachProj === 1702 [[]] #10006/fat
>>
>>
>> 11501 "MemToRegSpillCopy" has one use in this block, "11665
>> RegToMemSpillCopy", and three uses in other blocks. The use "11665
>> RegToMemSpillCopy" is used by "1702 CallStaticJavaDirect".
>>
>> We hit the assert when processing 11501 in PhaseChaitin::Split.
>>
>> We are in the "Handle DEFS" section of the split routine. We only get
>> here if the live range has been marked as spilled when the coloring
>> have ran out of colors. There are two code paths, one default, where
>> we just record the def and updates the side tables, and one where we
>> do a definition split on the live range. This split is guarded by
>> several conditions. In this case we get here by having a register
>> mask that is only regs (UP) and by being in a high pressure region.
>> Everything seems ok, so why don't we end up with MachSpillCopies here
>> more often?
>>
>> Also - one of the 4 uses is in this block (11655) and it's a
>> reg-to-mem already. It doesn't make much sense to add even more
>> spills here. Why does this happen?
>>
>> UseFPUForSpilling added a restriction to coalesing - it skips
>> coalescing when the two live ranges have different pressure. The
>> reason for this is that with FPU spilling, the possible extra
>> spilling is for "free". (I can't find any documentation on benchmarks
>> where this is beneficial though.) The downside is that we get longer
>> spill chains like: DefSpill-memToReg-RegToMem-MemToReg, that doesn't
>> collapse, because of pressure changes. This may cause the live ranges
>> defined by memToReg-nodes to become spilled, and if we are in a
>> high-pressure region - we hit the assert.
>>
>> So my conclusion is that nothing is really wrong. Everything still
>> works without the assert. The spill-chains are unnecessary long, but
>> only because we have chosen to restrict the coalescing. But we
>> shouldn't split the spill-nodes even more. In the next iteration the
>> coalescing within the block will have reduced the chains, and later a
>> proper coloring will be found.
>>
>> My solution is that we prevent the MachSpillCopies (only Mem-To-Regs
>> can end up here) from being split again. This is ok - because this is
>> exactly what would have happened if we would have been in a low
>> pressure region.
>>
>> I have done some measurements and it doesn't increase the number of
>> spill-iterations.
>>
>> Regards,
>>
>> Nils
>>
>>
>>
More information about the hotspot-compiler-dev
mailing list