src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java
Print this page
*** 31,42 ****
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.cfg.Loop;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
! import org.graalvm.compiler.debug.Debug;
! import org.graalvm.compiler.debug.DebugCounter;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeBitMap;
import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.graph.spi.Canonicalizable;
import org.graalvm.compiler.nodes.AbstractEndNode;
--- 31,42 ----
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.cfg.Loop;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
! import org.graalvm.compiler.debug.CounterKey;
! import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeBitMap;
import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.graph.spi.Canonicalizable;
import org.graalvm.compiler.nodes.AbstractEndNode;
*** 76,93 ****
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
public abstract class PartialEscapeClosure<BlockT extends PartialEscapeBlockState<BlockT>> extends EffectsClosure<BlockT> {
! public static final DebugCounter COUNTER_MATERIALIZATIONS = Debug.counter("Materializations");
! public static final DebugCounter COUNTER_MATERIALIZATIONS_PHI = Debug.counter("MaterializationsPhi");
! public static final DebugCounter COUNTER_MATERIALIZATIONS_MERGE = Debug.counter("MaterializationsMerge");
! public static final DebugCounter COUNTER_MATERIALIZATIONS_UNHANDLED = Debug.counter("MaterializationsUnhandled");
! public static final DebugCounter COUNTER_MATERIALIZATIONS_LOOP_REITERATION = Debug.counter("MaterializationsLoopReiteration");
! public static final DebugCounter COUNTER_MATERIALIZATIONS_LOOP_END = Debug.counter("MaterializationsLoopEnd");
! public static final DebugCounter COUNTER_ALLOCATION_REMOVED = Debug.counter("AllocationsRemoved");
! public static final DebugCounter COUNTER_MEMORYCHECKPOINT = Debug.counter("MemoryCheckpoint");
/**
* Nodes with inputs that were modified during analysis are marked in this bitset - this way
* nodes that are not influenced at all by analysis can be rejected quickly.
*/
--- 76,93 ----
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
public abstract class PartialEscapeClosure<BlockT extends PartialEscapeBlockState<BlockT>> extends EffectsClosure<BlockT> {
! public static final CounterKey COUNTER_MATERIALIZATIONS = DebugContext.counter("Materializations");
! public static final CounterKey COUNTER_MATERIALIZATIONS_PHI = DebugContext.counter("MaterializationsPhi");
! public static final CounterKey COUNTER_MATERIALIZATIONS_MERGE = DebugContext.counter("MaterializationsMerge");
! public static final CounterKey COUNTER_MATERIALIZATIONS_UNHANDLED = DebugContext.counter("MaterializationsUnhandled");
! public static final CounterKey COUNTER_MATERIALIZATIONS_LOOP_REITERATION = DebugContext.counter("MaterializationsLoopReiteration");
! public static final CounterKey COUNTER_MATERIALIZATIONS_LOOP_END = DebugContext.counter("MaterializationsLoopEnd");
! public static final CounterKey COUNTER_ALLOCATION_REMOVED = DebugContext.counter("AllocationsRemoved");
! public static final CounterKey COUNTER_MEMORYCHECKPOINT = DebugContext.counter("MemoryCheckpoint");
/**
* Nodes with inputs that were modified during analysis are marked in this bitset - this way
* nodes that are not influenced at all by analysis can be rejected quickly.
*/
*** 100,109 ****
--- 100,110 ----
/**
* The indexes into this array correspond to {@link VirtualObjectNode#getObjectId()}.
*/
public final ArrayList<VirtualObjectNode> virtualObjects = new ArrayList<>();
+ public final DebugContext debug;
@Override
public boolean needsApplyEffects() {
if (hasChanged()) {
return true;
*** 169,179 ****
super(schedule, metaAccess, constantReflection, constantFieldProvider, loweringProvider);
}
@Override
protected PartialEscapeBlockState.Final getInitialState() {
! return new PartialEscapeBlockState.Final(tool.getOptions());
}
@Override
protected PartialEscapeBlockState.Final cloneState(PartialEscapeBlockState.Final oldState) {
return new PartialEscapeBlockState.Final(oldState);
--- 170,180 ----
super(schedule, metaAccess, constantReflection, constantFieldProvider, loweringProvider);
}
@Override
protected PartialEscapeBlockState.Final getInitialState() {
! return new PartialEscapeBlockState.Final(tool.getOptions(), tool.getDebug());
}
@Override
protected PartialEscapeBlockState.Final cloneState(PartialEscapeBlockState.Final oldState) {
return new PartialEscapeBlockState.Final(oldState);
*** 187,197 ****
public PartialEscapeClosure(ScheduleResult schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
LoweringProvider loweringProvider) {
super(schedule, schedule.getCFG());
StructuredGraph graph = schedule.getCFG().graph;
this.hasVirtualInputs = graph.createNodeBitMap();
! this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, constantFieldProvider, this, graph.getAssumptions(), graph.getOptions(), loweringProvider);
}
/**
* @return true if the node was deleted, false otherwise
*/
--- 188,199 ----
public PartialEscapeClosure(ScheduleResult schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
LoweringProvider loweringProvider) {
super(schedule, schedule.getCFG());
StructuredGraph graph = schedule.getCFG().graph;
this.hasVirtualInputs = graph.createNodeBitMap();
! this.debug = graph.getDebug();
! this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, constantFieldProvider, this, graph.getAssumptions(), graph.getOptions(), debug, loweringProvider);
}
/**
* @return true if the node was deleted, false otherwise
*/
*** 210,237 ****
return processNodeInternal(node, state, effects, lastFixedNode);
}
private boolean processNodeInternal(Node node, BlockT state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
FixedNode nextFixedNode = lastFixedNode == null ? null : lastFixedNode.next();
! VirtualUtil.trace(node.getOptions(), "%s", node);
if (requiresProcessing(node)) {
if (processVirtualizable((ValueNode) node, nextFixedNode, state, effects) == false) {
return false;
}
if (tool.isDeleted()) {
! VirtualUtil.trace(node.getOptions(), "deleted virtualizable allocation %s", node);
return true;
}
}
if (hasVirtualInputs.isMarked(node) && node instanceof ValueNode) {
if (node instanceof Virtualizable) {
if (processVirtualizable((ValueNode) node, nextFixedNode, state, effects) == false) {
return false;
}
if (tool.isDeleted()) {
! VirtualUtil.trace(node.getOptions(), "deleted virtualizable node %s", node);
return true;
}
}
processNodeInputs((ValueNode) node, nextFixedNode, state, effects);
}
--- 212,239 ----
return processNodeInternal(node, state, effects, lastFixedNode);
}
private boolean processNodeInternal(Node node, BlockT state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
FixedNode nextFixedNode = lastFixedNode == null ? null : lastFixedNode.next();
! VirtualUtil.trace(node.getOptions(), debug, "%s", node);
if (requiresProcessing(node)) {
if (processVirtualizable((ValueNode) node, nextFixedNode, state, effects) == false) {
return false;
}
if (tool.isDeleted()) {
! VirtualUtil.trace(node.getOptions(), debug, "deleted virtualizable allocation %s", node);
return true;
}
}
if (hasVirtualInputs.isMarked(node) && node instanceof ValueNode) {
if (node instanceof Virtualizable) {
if (processVirtualizable((ValueNode) node, nextFixedNode, state, effects) == false) {
return false;
}
if (tool.isDeleted()) {
! VirtualUtil.trace(node.getOptions(), debug, "deleted virtualizable node %s", node);
return true;
}
}
processNodeInputs((ValueNode) node, nextFixedNode, state, effects);
}
*** 294,315 ****
effects.replaceAtUsages(node, alias, insertBefore);
addScalarAlias(node, alias);
}
} else {
if (!prepareCanonicalNode(canonicalizedValue, state, effects)) {
! VirtualUtil.trace(node.getOptions(), "replacement via canonicalization too complex: %s -> %s", node, canonicalizedValue);
return false;
}
if (canonicalizedValue instanceof ControlSinkNode) {
effects.replaceWithSink((FixedWithNextNode) node, (ControlSinkNode) canonicalizedValue);
state.markAsDead();
} else {
effects.replaceAtUsages(node, canonicalizedValue, insertBefore);
addScalarAlias(node, canonicalizedValue);
}
}
! VirtualUtil.trace(node.getOptions(), "replaced via canonicalization: %s -> %s", node, canonicalizedValue);
return true;
}
return false;
}
--- 296,317 ----
effects.replaceAtUsages(node, alias, insertBefore);
addScalarAlias(node, alias);
}
} else {
if (!prepareCanonicalNode(canonicalizedValue, state, effects)) {
! VirtualUtil.trace(node.getOptions(), debug, "replacement via canonicalization too complex: %s -> %s", node, canonicalizedValue);
return false;
}
if (canonicalizedValue instanceof ControlSinkNode) {
effects.replaceWithSink((FixedWithNextNode) node, (ControlSinkNode) canonicalizedValue);
state.markAsDead();
} else {
effects.replaceAtUsages(node, canonicalizedValue, insertBefore);
addScalarAlias(node, canonicalizedValue);
}
}
! VirtualUtil.trace(node.getOptions(), debug, "replaced via canonicalization: %s -> %s", node, canonicalizedValue);
return true;
}
return false;
}
*** 348,366 ****
* This replaces all inputs that point to virtual or materialized values with the actual value,
* materializing if necessary. Also takes care of frame states, adding the necessary
* {@link VirtualObjectState}.
*/
private void processNodeInputs(ValueNode node, FixedNode insertBefore, BlockT state, GraphEffectList effects) {
! VirtualUtil.trace(node.getOptions(), "processing nodewithstate: %s", node);
for (Node input : node.inputs()) {
if (input instanceof ValueNode) {
ValueNode alias = getAlias((ValueNode) input);
if (alias instanceof VirtualObjectNode) {
int id = ((VirtualObjectNode) alias).getObjectId();
ensureMaterialized(state, id, insertBefore, effects, COUNTER_MATERIALIZATIONS_UNHANDLED);
effects.replaceFirstInput(node, input, state.getObjectState(id).getMaterializedValue());
! VirtualUtil.trace(node.getOptions(), "replacing input %s at %s", input, node);
}
}
}
if (node instanceof NodeWithState) {
processNodeWithState((NodeWithState) node, state, effects);
--- 350,368 ----
* This replaces all inputs that point to virtual or materialized values with the actual value,
* materializing if necessary. Also takes care of frame states, adding the necessary
* {@link VirtualObjectState}.
*/
private void processNodeInputs(ValueNode node, FixedNode insertBefore, BlockT state, GraphEffectList effects) {
! VirtualUtil.trace(node.getOptions(), debug, "processing nodewithstate: %s", node);
for (Node input : node.inputs()) {
if (input instanceof ValueNode) {
ValueNode alias = getAlias((ValueNode) input);
if (alias instanceof VirtualObjectNode) {
int id = ((VirtualObjectNode) alias).getObjectId();
ensureMaterialized(state, id, insertBefore, effects, COUNTER_MATERIALIZATIONS_UNHANDLED);
effects.replaceFirstInput(node, input, state.getObjectState(id).getMaterializedValue());
! VirtualUtil.trace(node.getOptions(), debug, "replacing input %s at %s", input, node);
}
}
}
if (node instanceof NodeWithState) {
processNodeWithState((NodeWithState) node, state, effects);
*** 388,398 ****
return frameState;
}
private void addVirtualMappings(FrameState frameState, EconomicSet<VirtualObjectNode> virtual, BlockT state, GraphEffectList effects) {
for (VirtualObjectNode obj : virtual) {
! effects.addVirtualMapping(frameState, state.getObjectState(obj).createEscapeObjectState(obj));
}
}
private void collectReferencedVirtualObjects(BlockT state, EconomicSet<VirtualObjectNode> virtual) {
Iterator<VirtualObjectNode> iterator = virtual.iterator();
--- 390,400 ----
return frameState;
}
private void addVirtualMappings(FrameState frameState, EconomicSet<VirtualObjectNode> virtual, BlockT state, GraphEffectList effects) {
for (VirtualObjectNode obj : virtual) {
! effects.addVirtualMapping(frameState, state.getObjectState(obj).createEscapeObjectState(debug, obj));
}
}
private void collectReferencedVirtualObjects(BlockT state, EconomicSet<VirtualObjectNode> virtual) {
Iterator<VirtualObjectNode> iterator = virtual.iterator();
*** 425,437 ****
}
/**
* @return true if materialization happened, false if not.
*/
! protected boolean ensureMaterialized(PartialEscapeBlockState<?> state, int object, FixedNode materializeBefore, GraphEffectList effects, DebugCounter counter) {
if (state.getObjectState(object).isVirtual()) {
! counter.increment();
VirtualObjectNode virtual = virtualObjects.get(object);
state.materializeBefore(materializeBefore, virtual, effects);
assert !updateStatesForMaterialized(state, virtual, state.getObjectState(object).getMaterializedValue()) : "method must already have been called before";
return true;
} else {
--- 427,439 ----
}
/**
* @return true if materialization happened, false if not.
*/
! protected boolean ensureMaterialized(PartialEscapeBlockState<?> state, int object, FixedNode materializeBefore, GraphEffectList effects, CounterKey counter) {
if (state.getObjectState(object).isVirtual()) {
! counter.increment(debug);
VirtualObjectNode virtual = virtualObjects.get(object);
state.materializeBefore(materializeBefore, virtual, effects);
assert !updateStatesForMaterialized(state, virtual, state.getObjectState(object).getMaterializedValue()) : "method must already have been called before";
return true;
} else {
*** 564,574 ****
// nothing to do - will be handled in processNode
}
exitState.updateMaterializedValue(object, proxy);
} else {
if (initialObjState.getMaterializedValue() != exitObjState.getMaterializedValue()) {
! Debug.log("materialized value changes within loop: %s vs. %s at %s", initialObjState.getMaterializedValue(), exitObjState.getMaterializedValue(), exitNode);
}
}
}
private static void processVirtualAtLoopExit(LoopExitNode exitNode, GraphEffectList effects, int object, ObjectState exitObjState, ObjectState initialObjState,
--- 566,576 ----
// nothing to do - will be handled in processNode
}
exitState.updateMaterializedValue(object, proxy);
} else {
if (initialObjState.getMaterializedValue() != exitObjState.getMaterializedValue()) {
! exitNode.getDebug().log("materialized value changes within loop: %s vs. %s at %s", initialObjState.getMaterializedValue(), exitObjState.getMaterializedValue(), exitNode);
}
}
}
private static void processVirtualAtLoopExit(LoopExitNode exitNode, GraphEffectList effects, int object, ObjectState exitObjState, ObjectState initialObjState,
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File