# HG changeset patch # User Thomas Wuerthinger # Date 1366984721 -7200 # Node ID fa188fbfe3fe4b2943ee227ae1c46a1195e69509 # Parent aff0f54d9a4a30fa3fa401bf8463ac8af50dfab3 Perform only targeted canonicalization after tail duplication. diff -r aff0f54d9a4a -r fa188fbfe3fe graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- 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) { diff -r aff0f54d9a4a -r fa188fbfe3fe graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- 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 workingSet; public interface CustomCanonicalizer { @@ -60,12 +60,17 @@ } public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer) { + this(customCanonicalizer, null); + } + + public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer, Iterable 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 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 diff -r aff0f54d9a4a -r fa188fbfe3fe graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- 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)); } } } diff -r aff0f54d9a4a -r fa188fbfe3fe graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- 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 { /* * 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 replacements) { + public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List 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 @@ *
  • Determines the complete set of duplicated nodes.
  • *
  • Performs the actual duplication.
  • * + * + * @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); }