changeset 15867:23f45bae453a

read elimination without schedule
author Lukas Stadler <lukas.stadler@oracle.com>
date Fri, 23 May 2014 17:43:07 +0200
parents 0456d9b10322
children e626b112aa3d
files graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.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/EffectsPhase.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java
diffstat 6 files changed, 67 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java	Fri May 23 14:51:59 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java	Fri May 23 17:43:07 2014 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
@@ -32,7 +33,7 @@
 public class EarlyReadEliminationPhase extends EffectsPhase<PhaseContext> {
 
     public EarlyReadEliminationPhase(CanonicalizerPhase canonicalizer) {
-        super(1, canonicalizer);
+        super(1, canonicalizer, true);
     }
 
     @Override
@@ -43,7 +44,8 @@
     }
 
     @Override
-    protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule) {
-        return new ReadEliminationClosure(schedule);
+    protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule, ControlFlowGraph cfg) {
+        assert schedule == null;
+        return new ReadEliminationClosure(cfg);
     }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Fri May 23 14:51:59 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Fri May 23 17:43:07 2014 +0200
@@ -42,6 +42,7 @@
 
 public abstract class EffectsClosure<BlockT extends EffectsBlockState<BlockT>> extends EffectsPhase.Closure<BlockT> {
 
+    private final ControlFlowGraph cfg;
     private final SchedulePhase schedule;
 
     protected final NodeMap<ValueNode> aliases;
@@ -51,11 +52,12 @@
 
     private boolean changed;
 
-    public EffectsClosure(SchedulePhase schedule) {
+    public EffectsClosure(SchedulePhase schedule, ControlFlowGraph cfg) {
         this.schedule = schedule;
-        this.aliases = schedule.getCFG().graph.createNodeMap();
-        this.blockEffects = new BlockMap<>(schedule.getCFG());
-        for (Block block : schedule.getCFG().getBlocks()) {
+        this.cfg = cfg;
+        this.aliases = cfg.graph.createNodeMap();
+        this.blockEffects = new BlockMap<>(cfg);
+        for (Block block : cfg.getBlocks()) {
             blockEffects.put(block, new GraphEffectList());
         }
     }
@@ -67,7 +69,7 @@
 
     @Override
     public void applyEffects() {
-        final StructuredGraph graph = schedule.getCFG().graph;
+        final StructuredGraph graph = cfg.graph;
         final ArrayList<Node> obsoleteNodes = new ArrayList<>(0);
         BlockIteratorClosure<Void> closure = new BlockIteratorClosure<Void>() {
 
@@ -114,7 +116,7 @@
                 return info.exitStates;
             }
         };
-        ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
+        ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
         assert VirtualUtil.assertNonReachable(graph, obsoleteNodes);
     }
 
@@ -124,7 +126,8 @@
 
         GraphEffectList effects = blockEffects.get(block);
         FixedWithNextNode lastFixedNode = null;
-        for (Node node : schedule.getBlockToNodesMap().get(block)) {
+        Iterable<? extends Node> nodes = schedule != null ? schedule.getBlockToNodesMap().get(block) : block.getNodes();
+        for (Node node : nodes) {
             aliases.set(node, null);
             if (node instanceof LoopExitNode) {
                 LoopExitNode loopExit = (LoopExitNode) node;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Fri May 23 14:51:59 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Fri May 23 17:43:07 2014 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.util.*;
@@ -49,10 +50,16 @@
 
     private final int maxIterations;
     protected final CanonicalizerPhase canonicalizer;
+    private final boolean unscheduled;
 
-    public EffectsPhase(int maxIterations, CanonicalizerPhase canonicalizer) {
+    protected EffectsPhase(int maxIterations, CanonicalizerPhase canonicalizer) {
+        this(maxIterations, canonicalizer, false);
+    }
+
+    protected EffectsPhase(int maxIterations, CanonicalizerPhase canonicalizer, boolean unscheduled) {
         this.maxIterations = maxIterations;
         this.canonicalizer = canonicalizer;
+        this.unscheduled = unscheduled;
     }
 
     @Override
@@ -64,10 +71,19 @@
         boolean changed = false;
         for (int iteration = 0; iteration < maxIterations; iteration++) {
             try (Scope s = Debug.scope(isEnabled() ? "iteration " + iteration : null)) {
-                SchedulePhase schedule = new SchedulePhase();
-                schedule.apply(graph, false);
-                Closure<?> closure = createEffectsClosure(context, schedule);
-                ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
+                SchedulePhase schedule;
+                ControlFlowGraph cfg;
+                if (unscheduled) {
+                    schedule = null;
+                    cfg = ControlFlowGraph.compute(graph, true, true, false, false);
+                } else {
+                    schedule = new SchedulePhase();
+                    schedule.apply(graph, false);
+                    cfg = schedule.getCFG();
+                }
+
+                Closure<?> closure = createEffectsClosure(context, schedule, cfg);
+                ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
 
                 if (!closure.hasChanged()) {
                     break;
@@ -106,5 +122,5 @@
         }
     }
 
-    protected abstract Closure<?> createEffectsClosure(PhaseContextT context, SchedulePhase schedule);
+    protected abstract Closure<?> createEffectsClosure(PhaseContextT context, SchedulePhase schedule, ControlFlowGraph cfg);
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri May 23 14:51:59 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri May 23 17:43:07 2014 +0200
@@ -79,7 +79,7 @@
     }
 
     public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
-        super(schedule);
+        super(schedule, schedule.getCFG());
         this.usages = schedule.getCFG().graph.createNodeBitMap();
         this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, assumptions, this);
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Fri May 23 14:51:59 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Fri May 23 17:43:07 2014 +0200
@@ -30,6 +30,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.virtual.*;
@@ -84,7 +85,8 @@
     }
 
     @Override
-    protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule) {
+    protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule, ControlFlowGraph cfg) {
+        assert schedule != null;
         if (readElimination) {
             return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions());
         } else {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Fri May 23 14:51:59 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Fri May 23 17:43:07 2014 +0200
@@ -34,15 +34,14 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.CacheEntry;
 import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.LoadCacheEntry;
 import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.ReadCacheEntry;
 
 public class ReadEliminationClosure extends EffectsClosure<ReadEliminationBlockState> {
 
-    public ReadEliminationClosure(SchedulePhase schedule) {
-        super(schedule);
+    public ReadEliminationClosure(ControlFlowGraph cfg) {
+        super(null, cfg);
     }
 
     @Override
@@ -53,38 +52,33 @@
     @Override
     protected boolean processNode(Node node, ReadEliminationBlockState state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
         boolean deleted = false;
-        if (node instanceof LoadFieldNode) {
-            LoadFieldNode load = (LoadFieldNode) node;
-            if (!load.isVolatile()) {
-                ValueNode object = GraphUtil.unproxify(load.object());
-                LoadCacheEntry identifier = new LoadCacheEntry(object, load.field());
-                ValueNode cachedValue = state.getCacheEntry(identifier);
-                if (cachedValue != null) {
-                    effects.replaceAtUsages(load, cachedValue);
-                    addScalarAlias(load, cachedValue);
-                    deleted = true;
-                } else {
-                    state.addCacheEntry(identifier, load);
-                }
-            } else {
+        if (node instanceof AccessFieldNode) {
+            AccessFieldNode access = (AccessFieldNode) node;
+            if (access.isVolatile()) {
                 processIdentity(state, ANY_LOCATION);
-            }
-        } else if (node instanceof StoreFieldNode) {
-            StoreFieldNode store = (StoreFieldNode) node;
-            if (!store.isVolatile()) {
-                ValueNode object = GraphUtil.unproxify(store.object());
-                LoadCacheEntry identifier = new LoadCacheEntry(object, store.field());
+            } else {
+                ValueNode object = GraphUtil.unproxify(access.object());
+                LoadCacheEntry identifier = new LoadCacheEntry(object, access.field());
                 ValueNode cachedValue = state.getCacheEntry(identifier);
-
-                ValueNode value = getScalarAlias(store.value());
-                if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
-                    effects.deleteFixedNode(store);
-                    deleted = true;
+                if (node instanceof LoadFieldNode) {
+                    if (cachedValue != null) {
+                        effects.replaceAtUsages(access, cachedValue);
+                        addScalarAlias(access, cachedValue);
+                        deleted = true;
+                    } else {
+                        state.addCacheEntry(identifier, access);
+                    }
+                } else {
+                    assert node instanceof StoreFieldNode;
+                    StoreFieldNode store = (StoreFieldNode) node;
+                    ValueNode value = getScalarAlias(store.value());
+                    if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
+                        effects.deleteFixedNode(store);
+                        deleted = true;
+                    }
+                    state.killReadCache(store.field());
+                    state.addCacheEntry(identifier, value);
                 }
-                state.killReadCache(store.field());
-                state.addCacheEntry(identifier, value);
-            } else {
-                processIdentity(state, ANY_LOCATION);
             }
         } else if (node instanceof ReadNode) {
             ReadNode read = (ReadNode) node;