changeset 6361:ccdf43a09204

PartialEscapeAnalysis: fix for bailout, better metrics, small renaming
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 12 Sep 2012 16:22:44 +0200
parents e5203e5843fc
children 75199c01d2b3 f3dcc071d696
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/DeadCodeEliminationPhase.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ea/PartialEscapeAnalysisPhase.java
diffstat 2 files changed, 64 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/DeadCodeEliminationPhase.java	Wed Sep 12 12:57:27 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/DeadCodeEliminationPhase.java	Wed Sep 12 16:22:44 2012 +0200
@@ -29,6 +29,9 @@
 
 public class DeadCodeEliminationPhase extends Phase {
 
+    // Metrics
+    private static final DebugMetric metricNodesRemoved = Debug.metric("NodesRemoved");
+
     private NodeFlood flood;
 
     @Override
@@ -101,6 +104,7 @@
         }
         for (Node node : graph.getNodes()) {
             if (!flood.isMarked(node)) {
+                metricNodesRemoved.increment();
                 node.safeDelete();
             }
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ea/PartialEscapeAnalysisPhase.java	Wed Sep 12 12:57:27 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ea/PartialEscapeAnalysisPhase.java	Wed Sep 12 16:22:44 2012 +0200
@@ -68,11 +68,13 @@
 
     // Metrics
     private static final DebugMetric metricAllocationRemoved = Debug.metric("AllocationRemoved");
+    private static final DebugMetric metricAllocationFieldsRemoved = Debug.metric("AllocationFieldsRemoved");
     private static final DebugMetric metricStoreRemoved = Debug.metric("StoreRemoved");
     private static final DebugMetric metricLoadRemoved = Debug.metric("LoadRemoved");
     private static final DebugMetric metricLockRemoved = Debug.metric("LockRemoved");
     private static final DebugMetric metricOtherRemoved = Debug.metric("OtherRemoved");
     private static final DebugMetric metricMaterializations = Debug.metric("Materializations");
+    private static final DebugMetric metricMaterializationFields = Debug.metric("MaterializationFields");
 
     private static final ValueNode DUMMY_NODE = new ValueNode(null) {
     };
@@ -96,20 +98,22 @@
 
     private final boolean changeGraph;
 
+    private final HashSet<ValueNode> allocations;
     private final ArrayList<ValueNode> obsoleteNodes = new ArrayList<>();
     private int virtualIds = 0;
 
-    public EscapeAnalysisIteration(StructuredGraph graph, SchedulePhase schedule, MetaAccessProvider runtime, boolean changeGraph) {
+    public EscapeAnalysisIteration(StructuredGraph graph, SchedulePhase schedule, MetaAccessProvider runtime, HashSet<ValueNode> allocations, boolean changeGraph) {
         this.graph = graph;
         this.schedule = schedule;
         this.runtime = runtime;
+        this.allocations = allocations;
         this.changeGraph = changeGraph;
         this.visitedNodes = graph.createNodeBitMap();
         this.usages = graph.createNodeBitMap();
     }
 
     public void run() {
-        new MyIterator(graph, schedule.getCFG().getStartBlock()).apply();
+        new PartialEscapeIterator(graph, schedule.getCFG().getStartBlock()).apply();
 
         if (changeGraph) {
             Debug.dump(graph, "after PartialEscapeAnalysis");
@@ -192,15 +196,15 @@
         }
     }
 
-    private class MyState implements MergeableBlockState<MyState> {
+    private class BlockState implements MergeableBlockState<BlockState> {
 
         private final HashMap<EscapeRecord, ObjectState> recordStates = new HashMap<>();
         private final HashMap<ValueNode, EscapeRecord> recordAliases = new HashMap<>();
 
-        public MyState() {
+        public BlockState() {
         }
 
-        public MyState(MyState other) {
+        public BlockState(BlockState other) {
             for (Map.Entry<EscapeRecord, ObjectState> entry : other.recordStates.entrySet()) {
                 recordStates.put(entry.getKey(), entry.getValue().clone());
             }
@@ -220,8 +224,8 @@
         }
 
         @Override
-        public MyState clone() {
-            return new MyState(this);
+        public BlockState clone() {
+            return new BlockState(this);
         }
 
         public void materializeBefore(FixedNode fixed, EscapeRecord record) {
@@ -271,9 +275,10 @@
             }
 
             MaterializeObjectNode materialize = graph.add(new MaterializeObjectNode(record.type, record.fields));
-            metricMaterializations.increment();
             materialize.setProbability(fixed.probability());
             ValueNode[] fieldState = obj.fieldState;
+            metricMaterializations.increment();
+            metricMaterializationFields.add(fieldState.length);
             obj.fieldState = null;
             obj.materializedValue = materialize;
             deferred.add(record);
@@ -343,14 +348,14 @@
         }
     }
 
-    private class MyIterator extends PostOrderBlockIterator<MyState> {
+    private class PartialEscapeIterator extends PostOrderBlockIterator<BlockState> {
 
-        public MyIterator(StructuredGraph graph, Block start) {
-            super(graph, start, new MyState());
+        public PartialEscapeIterator(StructuredGraph graph, Block start) {
+            super(graph, start, new BlockState());
         }
 
         @Override
-        protected void processBlock(Block block, MyState state) {
+        protected void processBlock(Block block, BlockState state) {
             trace("\nBlock: %s (", block);
             List<ScheduledNode> nodeList = schedule.getBlockToNodesMap().get(block);
 
@@ -360,13 +365,12 @@
                 if (node instanceof EscapeAnalyzable) {
                     op = ((EscapeAnalyzable) node).getEscapeOp();
                 }
-
-// if (op != null) {
-// String typeName = op.type(node).toString();
-// if (typeName.contains("ArrayList") || typeName.contains("Object") || typeName.contains("$")) {
-// op = null;
-// }
-// }
+                if (op != null) {
+                    // only escape analyze allocations that were escape analyzed during the first iteration
+                    if (changeGraph && !allocations.contains(node)) {
+                        op = null;
+                    }
+                }
 
                 if (op != null) {
                     changed = true;
@@ -380,11 +384,14 @@
                         for (int i = 0; i < fields.length; i++) {
                             fieldState[i] = ConstantNode.defaultForKind(fields[i].type().kind(), virtualObject.graph());
                         }
+                        metricAllocationRemoved.increment();
+                        metricAllocationFieldsRemoved.add(fieldState.length);
+                    } else {
+                        allocations.add((ValueNode) node);
                     }
                     state.addRecord(record, new ObjectState(record, fieldState, 0));
                     state.addAndMarkAlias(record, (ValueNode) node);
                     virtualIds++;
-                    metricAllocationRemoved.increment();
                 } else {
                     visitedNodes.mark(node);
 
@@ -419,7 +426,7 @@
             trace(")\n    end state: %s\n", state);
         }
 
-        private void processNode(final ValueNode node, FixedNode insertBefore, final MyState state) {
+        private void processNode(final ValueNode node, FixedNode insertBefore, final BlockState state) {
             boolean usageFound = false;
             if (node instanceof PiNode || node instanceof ValueProxyNode) {
                 ValueNode value = node instanceof PiNode ? ((PiNode) node).object() : ((ValueProxyNode) node).value();
@@ -457,9 +464,9 @@
                 assert obj != null : x;
                 if (changeGraph) {
                     graph.replaceFloating(x, graph.unique(ConstantNode.forBoolean(false, graph)));
+                    metricOtherRemoved.increment();
                 }
                 usageFound = true;
-                metricOtherRemoved.increment();
             } else if (node instanceof IsTypeNode) {
                 throw new GraalInternalError("a newly created object can never be an object hub");
             } else if (node instanceof AccessMonitorNode) {
@@ -504,7 +511,9 @@
                             graph.removeFixed(x);
                         }
                     }
-                    metricLoadRemoved.increment();
+                    if (changeGraph) {
+                        metricLoadRemoved.increment();
+                    }
                 } else {
                     if (changeGraph) {
                         x.replaceFirstInput(x.object(), obj.materializedValue);
@@ -526,8 +535,8 @@
                         obj.fieldState[index] = value;
                         if (changeGraph) {
                             graph.removeFixed(x);
+                            metricStoreRemoved.increment();
                         }
-                        metricStoreRemoved.increment();
                     } else {
                         if (changeGraph) {
                             x.replaceFirstInput(object, obj.materializedValue);
@@ -566,7 +575,9 @@
                                     graph.removeFixed(x);
                                 }
                             }
-                            metricLoadRemoved.increment();
+                            if (changeGraph) {
+                                metricLoadRemoved.increment();
+                            }
                         }
                     } else {
                         if (changeGraph) {
@@ -592,8 +603,8 @@
                             arrayObj.fieldState[index] = value;
                             if (changeGraph) {
                                 graph.removeFixed(x);
+                                metricStoreRemoved.increment();
                             }
-                            metricStoreRemoved.increment();
                         }
                     } else {
                         if (changeGraph) {
@@ -621,9 +632,9 @@
                 assert obj != null : x;
                 if (changeGraph) {
                     graph.replaceFixedWithFloating(x, ConstantNode.forInt(obj.record.fields.length, graph));
+                    metricOtherRemoved.increment();
                 }
                 usageFound = true;
-                metricOtherRemoved.increment();
             } else if (node instanceof ReadHubNode) {
                 ReadHubNode x = (ReadHubNode) node;
                 ObjectState obj = state.objectState(x.object());
@@ -631,9 +642,9 @@
                 if (changeGraph) {
                     ConstantNode hub = ConstantNode.forConstant(obj.record.type.getEncoding(Representation.ObjectHub), runtime, graph);
                     graph.replaceFixedWithFloating(x, hub);
+                    metricOtherRemoved.increment();
                 }
                 usageFound = true;
-                metricOtherRemoved.increment();
             } else if (node instanceof ReturnNode) {
                 ReturnNode x = (ReturnNode) node;
                 ObjectState obj = state.objectState(x.result());
@@ -777,7 +788,7 @@
             }
         }
 
-        private void ensureMaterialized(MyState state, ObjectState obj, FixedNode materializeBefore) {
+        private void ensureMaterialized(BlockState state, ObjectState obj, FixedNode materializeBefore) {
             assert obj != null;
             if (obj.materializedValue == null) {
                 state.materializeBefore(materializeBefore, obj.record);
@@ -785,14 +796,14 @@
             assert obj.materializedValue != null;
         }
 
-        private void replaceWithMaterialized(ValueNode value, FixedNode usage, MyState state, ObjectState obj) {
+        private void replaceWithMaterialized(ValueNode value, FixedNode usage, BlockState state, ObjectState obj) {
             ensureMaterialized(state, obj, usage);
             if (changeGraph) {
                 usage.replaceFirstInput(value, obj.materializedValue);
             }
         }
 
-        private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, MyState state, ObjectState obj) {
+        private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockState state, ObjectState obj) {
             ensureMaterialized(state, obj, materializeBefore);
             if (changeGraph) {
                 usage.replaceFirstInput(value, obj.materializedValue);
@@ -800,12 +811,12 @@
         }
 
         @Override
-        protected MyState merge(MergeNode merge, List<MyState> states) {
-            MyState newState = new MyState();
+        protected BlockState merge(MergeNode merge, List<BlockState> states) {
+            BlockState newState = new BlockState();
 
             newState.recordAliases.putAll(states.get(0).recordAliases);
             for (int i = 1; i < states.size(); i++) {
-                MyState state = states.get(i);
+                BlockState state = states.get(i);
                 for (Map.Entry<ValueNode, EscapeRecord> entry : states.get(0).recordAliases.entrySet()) {
                     if (state.recordAliases.containsKey(entry.getKey())) {
                         assert state.recordAliases.get(entry.getKey()) == entry.getValue();
@@ -828,7 +839,7 @@
                     if (resultState == null || resultState.materializedValue == null) {
                         int virtual = 0;
                         int lockCount = states.get(0).objectState(record).lockCount;
-                        for (MyState state : states) {
+                        for (BlockState state : states) {
                             ObjectState obj = state.objectState(record);
                             if (obj.materializedValue == null) {
                                 virtual++;
@@ -839,7 +850,7 @@
                         if (virtual < states.size()) {
                             ValueNode materializedValuePhi = changeGraph ? graph.add(new PhiNode(Kind.Object, merge)) : DUMMY_NODE;
                             for (int i = 0; i < states.size(); i++) {
-                                MyState state = states.get(i);
+                                BlockState state = states.get(i);
                                 ObjectState obj = state.objectState(record);
                                 materialized |= obj.materializedValue == null;
                                 ensureMaterialized(state, obj, merge.forwardEndAt(i));
@@ -855,7 +866,7 @@
                             boolean[] phiCreated = new boolean[values.length];
                             int mismatch = 0;
                             for (int i = 1; i < states.size(); i++) {
-                                MyState state = states.get(i);
+                                BlockState state = states.get(i);
                                 ValueNode[] fields = state.objectState(record).fieldState;
                                 for (int index = 0; index < values.length; index++) {
                                     if (!phiCreated[index] && values[index] != fields[index]) {
@@ -869,7 +880,7 @@
                             }
                             if (mismatch > 0) {
                                 for (int i = 0; i < states.size(); i++) {
-                                    MyState state = states.get(i);
+                                    BlockState state = states.get(i);
                                     ValueNode[] fields = state.objectState(record).fieldState;
                                     for (int index = 0; index < values.length; index++) {
                                         if (phiCreated[index]) {
@@ -907,7 +918,7 @@
             return newState;
         }
 
-        private boolean processPhi(MyState newState, MergeNode merge, PhiNode phi, List<MyState> states) {
+        private boolean processPhi(BlockState newState, MergeNode merge, PhiNode phi, List<BlockState> states) {
             assert states.size() == phi.valueCount();
             int virtualInputs = 0;
             boolean materialized = false;
@@ -972,8 +983,8 @@
         }
 
         @Override
-        protected MyState loopBegin(LoopBeginNode loopBegin, MyState beforeLoopState) {
-            MyState state = beforeLoopState;
+        protected BlockState loopBegin(LoopBeginNode loopBegin, BlockState beforeLoopState) {
+            BlockState state = beforeLoopState;
             for (ObjectState obj : state.states()) {
                 if (obj.fieldState != null) {
                     for (int i = 0; obj.fieldState != null && i < obj.fieldState.length; i++) {
@@ -1016,13 +1027,13 @@
         }
 
         @Override
-        protected MyState loopEnds(LoopBeginNode loopBegin, MyState loopBeginState, List<MyState> loopEndStates) {
-            MyState state = loopBeginState.clone();
+        protected BlockState loopEnds(LoopBeginNode loopBegin, BlockState loopBeginState, List<BlockState> loopEndStates) {
+            BlockState state = loopBeginState.clone();
             List<LoopEndNode> loopEnds = loopBegin.orderedLoopEnds();
             for (ObjectState obj : state.states()) {
                 if (obj.fieldState != null) {
                     Iterator<LoopEndNode> iter = loopEnds.iterator();
-                    for (MyState loopEndState : loopEndStates) {
+                    for (BlockState loopEndState : loopEndStates) {
                         LoopEndNode loopEnd = iter.next();
                         ObjectState endObj = loopEndState.objectState(obj.record);
                         if (endObj.fieldState == null) {
@@ -1053,7 +1064,7 @@
                 } else {
                     assert phi.valueCount() == loopEndStates.size() + 1;
                     for (int i = 0; i < loopEndStates.size(); i++) {
-                        MyState loopEndState = loopEndStates.get(i);
+                        BlockState loopEndState = loopEndStates.get(i);
                         ObjectState obj = loopEndState.objectState(phi.valueAt(i + 1));
                         if (obj != null) {
                             ensureMaterialized(loopEndState, obj, loopEnds.get(i));
@@ -1068,7 +1079,7 @@
         }
 
         @Override
-        protected MyState afterSplit(FixedNode node, MyState oldState) {
+        protected BlockState afterSplit(FixedNode node, BlockState oldState) {
             return oldState.clone();
         }
     }
@@ -1088,16 +1099,17 @@
 
     @Override
     protected void run(StructuredGraph graph) {
+        HashSet<ValueNode> allocations = new HashSet<>();
         SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph, false);
         try {
-            new EscapeAnalysisIteration(graph, schedule, runtime, false).run();
+            new EscapeAnalysisIteration(graph, schedule, runtime, allocations, false).run();
         } catch (BailoutException e) {
             // do nothing if the if the escape analysis bails out during the analysis iteration...
             return;
         }
         try {
-            new EscapeAnalysisIteration(graph, schedule, runtime, true).run();
+            new EscapeAnalysisIteration(graph, schedule, runtime, allocations, true).run();
             new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
         } catch (BailoutException e) {
             throw new GraalInternalError(e);