# HG changeset patch # User Lukas Stadler # Date 1365093699 -7200 # Node ID 5cf8471a40343f0c3248f4dca6e7b520e137b69b # Parent 54a373881da6a1b650c5633051ef9f83123c2653 small PEA refactoring diff -r 54a373881da6 -r 5cf8471a4034 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Thu Apr 04 16:58:59 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Thu Apr 04 18:41:39 2013 +0200 @@ -486,15 +486,10 @@ effects.incLevel(); LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, state.cloneState()); - List loopEndStates = info.endStates; - List predecessors = loop.header.getPredecessors(); HashSet additionalMaterializations = new HashSet<>(); HashSet additionalKilledReads = new HashSet<>(); int oldPhiCount = phis.size(); - for (int i = 1; i < predecessors.size(); i++) { - processLoopEnd(loop.loopBegin(), (LoopEndNode) predecessors.get(i).getEndNode(), state, loopEndStates.get(i - 1), successEffects, additionalMaterializations, additionalKilledReads, - phis); - } + processLoopEnds(loop, state, info.endStates, successEffects, additionalMaterializations, additionalKilledReads, phis); if (additionalMaterializations.isEmpty() && additionalKilledReads.isEmpty() && oldPhiCount == phis.size()) { effects.addAll(successEffects); @@ -610,18 +605,98 @@ } } - private void processLoopEnd(LoopBeginNode loopBegin, LoopEndNode loopEnd, BlockState initialState, BlockState loopEndState, GraphEffectList successEffects, - Set additionalMaterializations, HashSet additionalKilledReads, HashSet phis) { - assert loopEnd.loopBegin() == loopBegin; + private void processLoopEnds(Loop loop, BlockState initialState, List loopEndStates, GraphEffectList successEffects, Set additionalMaterializations, + HashSet additionalKilledReads, HashSet phis) { + LoopBeginNode loopBegin = loop.loopBegin(); + int loopEndCount = loop.header.getPredecessorCount() - 1; + boolean materialized; do { materialized = false; for (ObjectState state : initialState.getStates()) { + for (int loopEndIndex = 0; loopEndIndex < loopEndCount; loopEndIndex++) { + BlockState loopEndState = loopEndStates.get(loopEndIndex); + + ObjectState endState = loopEndState.getObjectState(state.virtual); + if (state.isVirtual()) { + if (endState.isVirtual()) { + assert state.getEntries().length == endState.getEntries().length; + for (int i = 0; endState.isVirtual() && i < state.getEntries().length; i++) { + ValueNode value = state.getEntry(i); + ValueNode endValue = endState.getEntry(i); + ObjectState valueObj = initialState.getObjectState(value); + ObjectState endValueObj = loopEndState.getObjectState(endValue); + + if (valueObj != null) { + if (valueObj.isVirtual()) { + if (endValueObj == null || !endValueObj.isVirtual() || valueObj.virtual != endValueObj.virtual) { + additionalMaterializations.add(valueObj.virtual); + } else { + /* + * endValue is also virtual and refers to the same + * virtual object, so we're good. + */ + } + } + } else { + if (value instanceof PhiNode && ((PhiNode) value).merge() == loopBegin) { + if (endValueObj != null) { + if (endValueObj.isVirtual()) { + METRIC_MATERIALIZATIONS_LOOP_END.increment(); + FixedNode endNode = loop.header.getPredecessors().get(loopEndIndex + 1).getEndNode(); + loopEndState.materializeBefore(endNode, endValueObj.virtual, EscapeState.Global, successEffects); + materialized = true; + } + } + } + } + } + } else { + additionalMaterializations.add(state.virtual); + } + } + } + } + + for (PhiNode phi : loopBegin.phis()) { + if (usages.isMarked(phi) && phi.type() == PhiType.Value) { + ObjectState initialObj = initialState.getObjectState(phi.valueAt(0)); + boolean initialMaterialized = initialObj == null || !initialObj.isVirtual(); + + for (int loopEndIndex = 0; loopEndIndex < loopEndCount; loopEndIndex++) { + BlockState loopEndState = loopEndStates.get(loopEndIndex); + LoopEndNode endNode = (LoopEndNode) loop.header.getPredecessors().get(loopEndIndex + 1).getEndNode(); + ObjectState loopEndObj = loopEndState.getObjectState(phi.valueAt(endNode)); + if (loopEndObj == null || !loopEndObj.isVirtual()) { + if (loopEndObj != null) { + successEffects.setPhiInput(phi, loopBegin.phiPredecessorIndex(endNode), loopEndObj.getMaterializedValue()); + } + if (!initialMaterialized) { + additionalMaterializations.add(initialObj.virtual); + } + } else { + if (initialMaterialized) { + loopEndState.materializeBefore(endNode, loopEndObj.virtual, EscapeState.Global, successEffects); + materialized = true; + } else { + if (loopEndObj.virtual != initialObj.virtual) { + additionalMaterializations.add(initialObj.virtual); + } + } + } + } + } + } + + } while (materialized); + + for (ObjectState state : initialState.getStates()) { + for (BlockState loopEndState : loopEndStates) { ObjectState endState = loopEndState.getObjectState(state.virtual); if (state.isVirtual()) { if (endState.isVirtual()) { assert state.getEntries().length == endState.getEntries().length; - for (int i = 0; endState.isVirtual() && i < state.getEntries().length; i++) { + for (int i = 0; i < state.getEntries().length; i++) { ValueNode value = state.getEntry(i); ValueNode endValue = endState.getEntry(i); ObjectState valueObj = initialState.getObjectState(value); @@ -630,123 +705,69 @@ if (valueObj != null) { if (valueObj.isVirtual()) { if (endValueObj == null || !endValueObj.isVirtual() || valueObj.virtual != endValueObj.virtual) { - additionalMaterializations.add(valueObj.virtual); + assert !additionalMaterializations.isEmpty(); } else { - // endValue is also virtual and refers to the same virtual - // object, so we're - // good. + /* + * endValue is also virtual and refers to the same virtual + * object, so we're good. + */ + } + } else { + if ((endValueObj != null && endValueObj.getMaterializedValue() != valueObj.getMaterializedValue()) || + (endValueObj == null && valueObj.getMaterializedValue() != endValue)) { + phis.add(new PhiDesc(state.virtual, i)); + } else { + /* + * either endValue has the same materialized value as value + * or endValue is the same as the materialized value, so + * we're good. + */ } } } else { if (value instanceof PhiNode && ((PhiNode) value).merge() == loopBegin) { if (endValueObj != null) { if (endValueObj.isVirtual()) { - METRIC_MATERIALIZATIONS_LOOP_END.increment(); - loopEndState.materializeBefore(loopEnd, endValueObj.virtual, EscapeState.Global, successEffects); - materialized = true; + assert !additionalMaterializations.isEmpty(); } + successEffects.addPhiInput((PhiNode) value, endValueObj.getMaterializedValue()); + } else { + successEffects.addPhiInput((PhiNode) value, endValue); } + } else if (value != endValue) { + phis.add(new PhiDesc(state.virtual, i)); } } } } else { - additionalMaterializations.add(state.virtual); - } - } - } - for (PhiNode phi : loopBegin.phis()) { - if (usages.isMarked(phi) && phi.type() == PhiType.Value) { - ObjectState initialObj = initialState.getObjectState(phi.valueAt(0)); - boolean initialMaterialized = initialObj == null || !initialObj.isVirtual(); - - ObjectState loopEndObj = loopEndState.getObjectState(phi.valueAt(loopEnd)); - if (loopEndObj == null || !loopEndObj.isVirtual()) { - if (loopEndObj != null) { - successEffects.setPhiInput(phi, loopBegin.phiPredecessorIndex(loopEnd), loopEndObj.getMaterializedValue()); - } - if (!initialMaterialized) { - additionalMaterializations.add(initialObj.virtual); - } - } else { - if (initialMaterialized) { - loopEndState.materializeBefore(loopEnd, loopEndObj.virtual, EscapeState.Global, successEffects); - materialized = true; - } else { - if (loopEndObj.virtual != initialObj.virtual) { - additionalMaterializations.add(initialObj.virtual); - } - } - } - } - } - } while (materialized); - - for (ObjectState state : initialState.getStates()) { - ObjectState endState = loopEndState.getObjectState(state.virtual); - if (state.isVirtual()) { - if (endState.isVirtual()) { - assert state.getEntries().length == endState.getEntries().length; - for (int i = 0; i < state.getEntries().length; i++) { - ValueNode value = state.getEntry(i); - ValueNode endValue = endState.getEntry(i); - ObjectState valueObj = initialState.getObjectState(value); - ObjectState endValueObj = loopEndState.getObjectState(endValue); - - if (valueObj != null) { - if (valueObj.isVirtual()) { - if (endValueObj == null || !endValueObj.isVirtual() || valueObj.virtual != endValueObj.virtual) { - assert !additionalMaterializations.isEmpty(); - } else { - // endValue is also virtual and refers to the same virtual - // object, so we're - // good. - } - } else { - if ((endValueObj != null && endValueObj.getMaterializedValue() != valueObj.getMaterializedValue()) || - (endValueObj == null && valueObj.getMaterializedValue() != endValue)) { - phis.add(new PhiDesc(state.virtual, i)); - } else { - // either endValue has the same materialized value as value or - // endValue is the - // same as the materialized value, so we're good. - } - } - } else { - if (value instanceof PhiNode && ((PhiNode) value).merge() == loopBegin) { - if (endValueObj != null) { - if (endValueObj.isVirtual()) { - assert !additionalMaterializations.isEmpty(); - } - successEffects.addPhiInput((PhiNode) value, endValueObj.getMaterializedValue()); - } else { - successEffects.addPhiInput((PhiNode) value, endValue); - } - } else if (value != endValue) { - phis.add(new PhiDesc(state.virtual, i)); - } - } + // endState.materializedValue != null + assert !additionalMaterializations.isEmpty(); } } else { - // endState.materializedValue != null - assert !additionalMaterializations.isEmpty(); - } - } else { - // state.materializedValue != null - if (endState.isVirtual()) { - // throw new GraalInternalError("un-materialized object state at %s", loopEnd); - } else { - if (state.getMaterializedValue() != endState.getMaterializedValue()) { - // throw new - // GraalInternalError("changed materialized value during loop: %s vs %s", - // state.materializedValue, endState.materializedValue); + // state.materializedValue != null + if (endState.isVirtual()) { + /* + * throw new GraalInternalError("un-materialized object state at %s", + * loopEnd); + */ + } else { + if (state.getMaterializedValue() != endState.getMaterializedValue()) { + /* + * throw new + * GraalInternalError("changed materialized value during loop: %s vs %s" + * , state.materializedValue, endState.materializedValue); + */ + } } } } } for (Map.Entry entry : initialState.getReadCache().entrySet()) { - if (loopEndState.getReadCache().get(entry.getKey()) != entry.getValue()) { - additionalKilledReads.add(entry.getKey()); + for (BlockState loopEndState : loopEndStates) { + if (loopEndState.getReadCache().get(entry.getKey()) != entry.getValue()) { + additionalKilledReads.add(entry.getKey()); + } } } }