# HG changeset patch # User Josef Eisl # Date 1402491087 -7200 # Node ID ef641ba1fb69255fad34823580c07d5ea4e9d1f8 # Parent f0ac7457252a2c1dea1dcdccb61d4df9939b38b9 LSRA spill optimization: mark the correct frame locations. diff -r f0ac7457252a -r ef641ba1fb69 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Jun 11 14:49:59 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Jun 11 14:51:27 2014 +0200 @@ -1728,6 +1728,9 @@ // included in the oop map iw.walkBefore(op.id()); + // TODO(je) we could pass this as parameter + AbstractBlock block = blockForId(op.id()); + // Iterate through active intervals for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { Value operand = interval.operand; @@ -1750,11 +1753,25 @@ // Spill optimization: when the stack value is guaranteed to be always correct, // then it must be added to the oop map even if the interval is currently in a // register - if (interval.alwaysInMemory() && op.id() > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) { - assert interval.spillDefinitionPos() > 0 : "position not set correctly"; - assert interval.spillSlot() != null : "no spill slot assigned"; - assert !isRegister(interval.operand) : "interval is on stack : so stack slot is registered twice"; - info.markLocation(interval.spillSlot(), frameMap); + int spillPos = interval.spillDefinitionPos(); + if (interval.spillState() != SpillState.SpillInDominator) { + if (interval.alwaysInMemory() && op.id() > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) { + assert interval.spillDefinitionPos() > 0 : "position not set correctly"; + assert spillPos > 0 : "position not set correctly"; + assert interval.spillSlot() != null : "no spill slot assigned"; + assert !isRegister(interval.operand) : "interval is on stack : so stack slot is registered twice"; + info.markLocation(interval.spillSlot(), frameMap); + } + } else { + AbstractBlock spillBlock = blockForId(spillPos); + if (interval.alwaysInMemory() && !interval.location().equals(interval.spillSlot())) { + if ((spillBlock.equals(block) && op.id() > spillPos) || AbstractBlock.dominates(spillBlock, block)) { + assert spillPos > 0 : "position not set correctly"; + assert interval.spillSlot() != null : "no spill slot assigned"; + assert !isRegister(interval.operand) : "interval is on stack : so stack slot is registered twice"; + info.markLocation(interval.spillSlot(), frameMap); + } + } } } }