changeset 9329:fa188fbfe3fe

Perform only targeted canonicalization after tail duplication.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 26 Apr 2013 15:58:41 +0200
parents aff0f54d9a4a
children e162d9e32830
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java
diffstat 4 files changed, 27 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Fri Apr 26 15:32:58 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Fri Apr 26 15:58:41 2013 +0200
@@ -34,16 +34,10 @@
     public HighTier() {
         if (GraalOptions.FullUnroll) {
             addPhase(new LoopFullUnrollPhase());
-            if (GraalOptions.OptCanonicalizer) {
-                addPhase(new CanonicalizerPhase());
-            }
         }
 
         if (GraalOptions.OptTailDuplication) {
             addPhase(new TailDuplicationPhase());
-            if (GraalOptions.OptCanonicalizer) {
-                addPhase(new CanonicalizerPhase());
-            }
         }
 
         if (GraalOptions.PartialEscapeAnalysis) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Apr 26 15:32:58 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Apr 26 15:58:41 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.phases.common;
 
-import java.util.*;
 import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
@@ -49,6 +48,7 @@
     public static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits");
 
     private final CustomCanonicalizer customCanonicalizer;
+    private final Iterable<Node> workingSet;
 
     public interface CustomCanonicalizer {
 
@@ -60,12 +60,17 @@
     }
 
     public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer) {
+        this(customCanonicalizer, null);
+    }
+
+    public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer, Iterable<Node> workingSet) {
         this.customCanonicalizer = customCanonicalizer;
+        this.workingSet = workingSet;
     }
 
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
-        new Instance(context.getRuntime(), context.getAssumptions(), null, customCanonicalizer).run(graph);
+        new Instance(context.getRuntime(), context.getAssumptions(), workingSet, customCanonicalizer).run(graph);
     }
 
     public static class Instance extends Phase {
@@ -78,7 +83,6 @@
 
         private NodeWorkList workList;
         private Tool tool;
-        private List<Node> snapshotTemp;
 
         public Instance(MetaAccessProvider runtime, Assumptions assumptions) {
             this(runtime, assumptions, null, 0, null);
@@ -110,7 +114,6 @@
             this.runtime = runtime;
             this.customCanonicalizer = customCanonicalizer;
             this.initWorkingSet = workingSet;
-            this.snapshotTemp = new ArrayList<>();
         }
 
         @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Apr 26 15:32:58 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Apr 26 15:58:41 2013 +0200
@@ -42,6 +42,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
 
 public class InliningUtil {
 
@@ -450,7 +451,7 @@
             if (hasSingleMethod()) {
                 inlineSingleMethod(graph, callback, replacements, assumptions);
             } else {
-                inlineMultipleMethods(graph, callback, replacements, assumptions);
+                inlineMultipleMethods(graph, callback, replacements, assumptions, runtime);
             }
         }
 
@@ -462,7 +463,7 @@
             return notRecordedTypeProbability > 0;
         }
 
-        private void inlineMultipleMethods(StructuredGraph graph, InliningCallback callback, Replacements replacements, Assumptions assumptions) {
+        private void inlineMultipleMethods(StructuredGraph graph, InliningCallback callback, Replacements replacements, Assumptions assumptions, MetaAccessProvider runtime) {
             int numberOfMethods = concretes.size();
             FixedNode continuation = invoke.next();
 
@@ -564,7 +565,7 @@
                 if (opportunities > 0) {
                     metricInliningTailDuplication.increment();
                     Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities);
-                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes);
+                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new HighTierContext(runtime, assumptions, replacements));
                 }
             }
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Apr 26 15:32:58 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Apr 26 15:58:41 2013 +0200
@@ -36,13 +36,14 @@
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.tiers.*;
 
 /**
  * This class is a phase that looks for opportunities for tail duplication. The static method
- * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List)} can also be used to drive tail
- * duplication from other places, e.g., inlining.
+ * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List, PhaseContext)} can also be used
+ * to drive tail duplication from other places, e.g., inlining.
  */
-public class TailDuplicationPhase extends Phase {
+public class TailDuplicationPhase extends BasePhase<PhaseContext> {
 
     /*
      * Various metrics on the circumstances in which tail duplication was/wasn't performed.
@@ -129,14 +130,14 @@
     };
 
     @Override
-    protected void run(StructuredGraph graph) {
+    protected void run(StructuredGraph graph, PhaseContext phaseContext) {
         NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply();
 
         // A snapshot is taken here, so that new MergeNode instances aren't considered for tail
         // duplication.
         for (MergeNode merge : graph.getNodes(MergeNode.class).snapshot()) {
             if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= GraalOptions.TailDuplicationProbability) {
-                tailDuplicate(merge, DEFAULT_DECISION, null);
+                tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext);
             }
         }
     }
@@ -156,8 +157,9 @@
      *            size needs to match the merge's end count. Each entry can either be null or a
      *            {@link PiNode}, and is used to replace {@link PiNode#object()} with the
      *            {@link PiNode} in the duplicated branch that corresponds to the entry.
+     * @param phaseContext
      */
-    public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List<PiNode> replacements) {
+    public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List<PiNode> replacements, PhaseContext phaseContext) {
         assert !(merge instanceof LoopBeginNode);
         assert replacements == null || replacements.size() == merge.forwardEndCount();
         FixedNode fixed = merge;
@@ -171,14 +173,14 @@
                 metricDuplicationEnd.increment();
                 if (decision.doTransform(merge, fixedCount)) {
                     metricDuplicationEndPerformed.increment();
-                    new DuplicationOperation(merge, replacements).duplicate();
+                    new DuplicationOperation(merge, replacements).duplicate(phaseContext);
                     return true;
                 }
             } else if (merge.stateAfter() != null) {
                 metricDuplicationOther.increment();
                 if (decision.doTransform(merge, fixedCount)) {
                     metricDuplicationOtherPerformed.increment();
-                    new DuplicationOperation(merge, replacements).duplicate();
+                    new DuplicationOperation(merge, replacements).duplicate(phaseContext);
                     return true;
                 }
             }
@@ -220,10 +222,14 @@
          * <li>Determines the complete set of duplicated nodes.</li>
          * <li>Performs the actual duplication.</li>
          * </ul>
+         * 
+         * @param phaseContext
          */
-        private void duplicate() {
+        private void duplicate(PhaseContext phaseContext) {
             Debug.log("tail duplication at merge %s in %s", merge, graph.method());
 
+            int startMark = graph.getMark();
+
             ValueAnchorNode anchor = addValueAnchor();
 
             // determine the fixed nodes that should be duplicated (currently: all nodes up until
@@ -297,6 +303,7 @@
                     phi.setMerge(mergeAfter);
                 }
             }
+            new CanonicalizerPhase(null, graph.getNewNodes(startMark)).apply(graph, phaseContext);
             Debug.dump(graph, "After tail duplication at %s", merge);
         }