Mercurial > hg > truffle
changeset 16454:973b5704b95d
GraphEffectList rework (with lambdas)
author | Lukas Stadler <lukas.stadler@oracle.com> |
---|---|
date | Thu, 10 Jul 2014 14:30:10 +0200 |
parents | 2824f2d25339 |
children | 59fdea1f9e36 |
files | graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java |
diffstat | 4 files changed, 167 insertions(+), 249 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Thu Jul 10 14:23:45 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Thu Jul 10 14:30:10 2014 +0200 @@ -25,6 +25,8 @@ import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -34,47 +36,27 @@ */ public class EffectList implements Iterable<EffectList.Effect> { - public abstract static class Effect { - - public boolean isVisible() { + public interface Effect { + default boolean isVisible() { return true; } - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - for (Field field : getClass().getDeclaredFields()) { - String name = field.getName(); - if (name.contains("$")) { - name = name.substring(name.indexOf('$') + 1); - } - if (!Modifier.isStatic(field.getModifiers()) && !name.equals("0")) { - try { - field.setAccessible(true); - str.append(str.length() > 0 ? ", " : "").append(name).append("=").append(format(field.get(this))); - } catch (SecurityException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - } - return name() + " [" + str + "]"; + void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes); + } + + public interface SimpleEffect extends Effect { + default void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { + apply(graph); } - private static String format(Object object) { - if (object != null && Object[].class.isAssignableFrom(object.getClass())) { - return Arrays.toString((Object[]) object); - } - return "" + object; - } - - public abstract String name(); - - public abstract void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes); + void apply(StructuredGraph graph); } private static final Effect[] EMPTY_ARRAY = new Effect[0]; + private static final String[] EMPTY_STRING_ARRAY = new String[0]; private Effect[] effects = EMPTY_ARRAY; + private String[] names = EMPTY_STRING_ARRAY; private int size; private void enlarge(int elements) { @@ -84,26 +66,31 @@ length = Math.max(length * 2, 4); } effects = Arrays.copyOf(effects, length); + if (Debug.isEnabled()) { + names = Arrays.copyOf(names, length); + } } } - public void add(Effect effect) { - assert effect != null; - enlarge(1); - effects[size++] = effect; + public void add(String name, SimpleEffect effect) { + add(name, (Effect) effect); } - public void addAll(Collection<? extends Effect> list) { - enlarge(list.size()); - for (Effect effect : list) { - assert effect != null; - effects[size++] = effect; + public void add(String name, Effect effect) { + assert effect != null; + enlarge(1); + if (Debug.isEnabled()) { + names[size] = name; } + effects[size++] = effect; } public void addAll(EffectList list) { enlarge(list.size); System.arraycopy(list.effects, 0, effects, size, list.size); + if (Debug.isEnabled()) { + System.arraycopy(list.names, 0, names, size, list.size); + } size += list.size; } @@ -112,6 +99,10 @@ enlarge(list.size); System.arraycopy(effects, position, effects, position + list.size, size - position); System.arraycopy(list.effects, 0, effects, position, list.size); + if (Debug.isEnabled()) { + System.arraycopy(names, position, names, position + list.size, size - position); + System.arraycopy(list.names, 0, names, position, list.size); + } size += list.size; } @@ -167,15 +158,65 @@ return size == 0; } + public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { + for (int i = 0; i < size(); i++) { + Effect effect = effects[i]; + try { + effect.apply(graph, obsoleteNodes); + } catch (Throwable t) { + StringBuilder str = new StringBuilder(); + toString(str, i); + throw new GraalInternalError(t).addContext("effect", str); + } + if (effect.isVisible() && Debug.isLogEnabled()) { + StringBuilder str = new StringBuilder(); + toString(str, i); + Debug.log(" %s", str); + } + } + } + + private void toString(StringBuilder str, int i) { + Effect effect = effects[i]; + str.append(getName(i)).append(" ["); + boolean first = true; + for (Field field : effect.getClass().getDeclaredFields()) { + try { + field.setAccessible(true); + str.append(first ? "" : ", ").append(format(field.get(effect))); + first = false; + } catch (SecurityException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + str.append(']'); + } + + private static String format(Object object) { + if (object != null && Object[].class.isAssignableFrom(object.getClass())) { + return Arrays.toString((Object[]) object); + } + return "" + object; + } + @Override public String toString() { StringBuilder str = new StringBuilder(); for (int i = 0; i < size(); i++) { Effect effect = get(i); if (effect.isVisible()) { - str.append(effect).append('\n'); + toString(str, i); + str.append('\n'); } } return str.toString(); } + + private String getName(int i) { + if (Debug.isEnabled()) { + return names[i]; + } else { + return ""; + } + } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Thu Jul 10 14:23:45 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Thu Jul 10 14:30:10 2014 +0200 @@ -38,7 +38,6 @@ import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.virtual.phases.ea.EffectList.Effect; public abstract class EffectsClosure<BlockT extends EffectsBlockState<BlockT>> extends EffectsPhase.Closure<BlockT> { @@ -81,12 +80,7 @@ private void apply(GraphEffectList effects, Object context) { if (!effects.isEmpty()) { Debug.log(" ==== effects for %s", context); - for (Effect effect : effects) { - effect.apply(graph, obsoleteNodes); - if (effect.isVisible()) { - Debug.log(" %s", effect); - } - } + effects.apply(graph, obsoleteNodes); if (TraceEscapeAnalysis.getValue()) { Debug.dump(graph, EffectsClosure.this.getClass().getSimpleName() + " - after processing %s", context); } @@ -228,6 +222,11 @@ @SuppressWarnings("unused") protected void commitEnds(List<BlockT> states) { } + + @Override + public String toString() { + return "MergeProcessor@" + merge; + } } public void addScalarAlias(ValueNode node, ValueNode alias) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Jul 10 14:23:45 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Jul 10 14:30:10 2014 +0200 @@ -26,9 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; @@ -36,35 +34,15 @@ public class GraphEffectList extends EffectList { public void addCounterBefore(final String group, final String name, final int increment, final boolean addContext, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addCounterBefore"; - } + add("add counter", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position)); + } - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert position.isAlive(); - DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position); - } - }); + public void addCounterAfter(final String group, final String name, final int increment, final boolean addContext, final FixedWithNextNode position) { + add("add counter after", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position.next())); } public void addWeakCounterCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addWeakCounterBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert position.isAlive(); - WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position); - } - }); + add("add weak counter", graph -> WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position)); } /** @@ -75,18 +53,9 @@ * @param position The fixed node before which the node should be added. */ public void addFixedNodeBefore(final FixedWithNextNode node, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addFixedNodeBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert !node.isAlive() && !node.isDeleted() && position.isAlive(); - graph.addBeforeFixed(position, graph.add(node)); - } + add("add fixed node", graph -> { + assert !node.isAlive() && !node.isDeleted() && position.isAlive(); + graph.addBeforeFixed(position, graph.add(node)); }); } @@ -95,20 +64,8 @@ * * @param node The floating node to be added. */ - public void addFloatingNode(final ValueNode node, final String cause) { - add(new Effect() { - - @Override - public String name() { - return "addFloatingNode " + cause; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert !node.isAlive() && !node.isDeleted() : node + " " + cause; - graph.addWithoutUnique(node); - } - }); + public void addFloatingNode(final ValueNode node, @SuppressWarnings("unused") final String cause) { + add("add floating node", graph -> graph.addWithoutUnique(node)); } /** @@ -118,18 +75,9 @@ * @param value The value that will be added to the phi node. */ public void addPhiInput(final PhiNode node, final ValueNode value) { - add(new Effect() { - - @Override - public String name() { - return "addPhiInput"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert node.isAlive() && value.isAlive() : node + " " + value; - node.addInput(value); - } + add("add phi input", graph -> { + assert node.isAlive() && value.isAlive() : node + " " + value; + node.addInput(value); }); } @@ -142,18 +90,9 @@ * @param value The new value for the phi input. */ public void initializePhiInput(final PhiNode node, final int index, final ValueNode value) { - add(new Effect() { - - @Override - public String name() { - return "setPhiInput"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert node.isAlive() && value.isAlive() && index >= 0; - node.initializeValueAt(index, value); - } + add("set phi input", (graph, obsoleteNodes) -> { + assert node.isAlive() && value.isAlive() && index >= 0; + node.initializeValueAt(index, value); }); } @@ -165,13 +104,7 @@ * @param state The virtual object state to add. */ public void addVirtualMapping(final FrameState node, final EscapeObjectState state) { - add(new Effect() { - - @Override - public String name() { - return "addVirtualMapping"; - } - + add("add virtual mapping", new Effect() { @Override public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { assert node.isAlive() && !state.isAlive() && !state.isDeleted(); @@ -197,20 +130,19 @@ * @param node The fixed node that should be deleted. */ public void deleteFixedNode(final FixedWithNextNode node) { - add(new Effect() { - - @Override - public String name() { - return "deleteFixedNode"; - } + add("delete fixed node", (graph, obsoleteNodes) -> { + GraphUtil.unlinkFixedNode(node); + assert obsoleteNodes.add(node); + }); + } - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert node.isAlive(); - GraphUtil.unlinkFixedNode(node); - assert obsoleteNodes.add(node); - } - }); + /** + * Removes the given fixed node from the control flow. + * + * @param node The fixed node that should be deleted. + */ + public void unlinkFixedNode(final FixedWithNextNode node) { + add("unlink fixed node", graph -> GraphUtil.unlinkFixedNode(node)); } /** @@ -224,25 +156,18 @@ * */ public void replaceAtUsages(final ValueNode node, final ValueNode replacement) { - add(new Effect() { - - @Override - public String name() { - return "replaceAtUsages"; + add("replace at usages", (graph, obsoleteNodes) -> { + assert node.isAlive() && replacement.isAlive(); + if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { + assert node instanceof FixedNode; + graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert node.isAlive() && replacement.isAlive(); - if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { - assert node instanceof FixedNode; - graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); - } - node.replaceAtUsages(replacement); - if (node instanceof FixedWithNextNode) { - GraphUtil.unlinkFixedNode((FixedWithNextNode) node); - assert obsoleteNodes.add(node); - } + node.replaceAtUsages(replacement); + if (node instanceof FixedWithNextNode) { + FixedNode next = ((FixedWithNextNode) node).next(); + ((FixedWithNextNode) node).setNext(null); + node.replaceAtPredecessor(next); + assert obsoleteNodes.add(node); } }); } @@ -255,13 +180,7 @@ * @param newInput The value to replace with. */ public void replaceFirstInput(final Node node, final Node oldInput, final Node newInput) { - add(new Effect() { - - @Override - public String name() { - return "replaceFirstInput"; - } - + add("replace first input", new Effect() { @Override public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { assert node.isAlive() && oldInput.isAlive() && newInput.isAlive(); @@ -281,83 +200,6 @@ * @param action The action that should be performed when the effects are applied. */ public void customAction(final Runnable action) { - add(new Effect() { - - @Override - public String name() { - return "customAction"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - action.run(); - } - }); - } - - /** - * Add the materialization node to the graph's control flow at the given position, and then sets - * its values. - * - * @param position The fixed node before which the materialization node should be added. - * @param objects The allocated objects. - * @param locks The lock depths for each object. - * @param values The values (field, elements) of all objects. - * @param otherAllocations A list of allocations that need to be added before the rest (used for - * boxing allocations). - */ - public void addMaterializationBefore(final FixedNode position, final List<AllocatedObjectNode> objects, final List<List<MonitorIdNode>> locks, final List<ValueNode> values, - final List<ValueNode> otherAllocations) { - add(new Effect() { - - @Override - public String name() { - return "addMaterializationBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - for (ValueNode otherAllocation : otherAllocations) { - graph.addWithoutUnique(otherAllocation); - if (otherAllocation instanceof FixedWithNextNode) { - graph.addBeforeFixed(position, (FixedWithNextNode) otherAllocation); - } else { - assert otherAllocation instanceof FloatingNode; - } - } - if (!objects.isEmpty()) { - CommitAllocationNode commit; - if (position.predecessor() instanceof CommitAllocationNode) { - commit = (CommitAllocationNode) position.predecessor(); - } else { - commit = graph.add(new CommitAllocationNode()); - graph.addBeforeFixed(position, commit); - } - for (AllocatedObjectNode obj : objects) { - graph.addWithoutUnique(obj); - commit.getVirtualObjects().add(obj.getVirtualObject()); - obj.setCommit(commit); - } - commit.getValues().addAll(values); - for (List<MonitorIdNode> monitorIds : locks) { - commit.addLocks(monitorIds); - } - - assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); - List<AllocatedObjectNode> materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); - for (int i = 0; i < commit.getValues().size(); i++) { - if (materializedValues.contains(commit.getValues().get(i))) { - commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject()); - } - } - - } - } - - @Override - public boolean isVisible() { - return true; - } - }); + add("customAction", graph -> action.run()); } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Thu Jul 10 14:23:45 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Thu Jul 10 14:30:10 2014 +0200 @@ -27,6 +27,7 @@ import java.util.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; @@ -75,7 +76,42 @@ List<ValueNode> otherAllocations = new ArrayList<>(2); materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state); - materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations); + materializeEffects.add("materializeBefore", (graph, obsoleteNodes) -> { + for (ValueNode otherAllocation : otherAllocations) { + graph.addWithoutUnique(otherAllocation); + if (otherAllocation instanceof FixedWithNextNode) { + graph.addBeforeFixed(fixed, (FixedWithNextNode) otherAllocation); + } else { + assert otherAllocation instanceof FloatingNode; + } + } + if (!objects.isEmpty()) { + CommitAllocationNode commit; + if (fixed.predecessor() instanceof CommitAllocationNode) { + commit = (CommitAllocationNode) fixed.predecessor(); + } else { + commit = graph.add(new CommitAllocationNode()); + graph.addBeforeFixed(fixed, commit); + } + for (AllocatedObjectNode obj : objects) { + graph.addWithoutUnique(obj); + commit.getVirtualObjects().add(obj.getVirtualObject()); + obj.setCommit(commit); + } + commit.getValues().addAll(values); + for (List<MonitorIdNode> monitorIds : locks) { + commit.addLocks(monitorIds); + } + + assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); + List<AllocatedObjectNode> materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); + for (int i = 0; i < commit.getValues().size(); i++) { + if (materializedValues.contains(commit.getValues().get(i))) { + commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject()); + } + } + } + }); } private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List<AllocatedObjectNode> objects, List<List<MonitorIdNode>> locks, List<ValueNode> values,