changeset 21216:04339fd2c863

Create SSA LIR.
author Josef Eisl <josef.eisl@jku.at>
date Mon, 20 Apr 2015 14:14:09 +0200
parents e11eb6ec180e
children 7223cb16dfa6
files graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java
diffstat 3 files changed, 59 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Mon May 04 23:15:42 2015 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Mon Apr 20 14:14:09 2015 +0200
@@ -315,6 +315,9 @@
     @Option(help = "Mark well-known stable fields as such.", type = OptionType.Debug)
     public static final OptionValue<Boolean> ImplicitStableValues = new OptionValue<>(true);
 
+    @Option(help = "Generate SSA LIR.", type = OptionType.Debug)
+    public static final OptionValue<Boolean> SSA_LIR = new OptionValue<>(false);
+
     /**
      * Counts the various paths taken through snippets.
      */
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Mon May 04 23:15:42 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Mon Apr 20 14:14:09 2015 +0200
@@ -40,8 +40,10 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
+import com.oracle.graal.lir.StandardOp.LabelOp;
 import com.oracle.graal.lir.debug.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.gen.LIRGenerator.Options;
@@ -192,6 +194,31 @@
         gen.append(op);
     }
 
+    private static NodeIterable<ValuePhiNode> valuePhis(AbstractMergeNode merge) {
+        return merge.usages().filter(ValuePhiNode.class).filter(merge::isPhiAtMerge);
+    }
+
+    protected Value[] createPhiIn(AbstractMergeNode merge) {
+        List<Value> values = new ArrayList<>();
+        for (ValuePhiNode phi : valuePhis(merge)) {
+            assert getOperand(phi) == null;
+            Variable value = gen.newVariable(getPhiKind(phi));
+            values.add(value);
+            setResult(phi, value);
+        }
+        return values.toArray(new Value[values.size()]);
+    }
+
+    private Value[] createPhiOut(AbstractMergeNode merge, AbstractEndNode pred) {
+        List<Value> values = new ArrayList<>();
+        for (PhiNode phi : valuePhis(merge)) {
+            Value value = operand(phi.valueAt(pred));
+            assert value != null;
+            values.add(value);
+        }
+        return values.toArray(new Value[values.size()]);
+    }
+
     public void doBlock(Block block, StructuredGraph graph, BlockMap<List<Node>> blockMap) {
         try (BlockScope blockScope = gen.getBlockScope(block)) {
 
@@ -200,6 +227,15 @@
                 emitPrologue(graph);
             } else {
                 assert block.getPredecessorCount() > 0;
+                if (SSA_LIR.getValue()) {
+                    // create phi-in value array
+                    AbstractBeginNode begin = block.getBeginNode();
+                    if (begin instanceof AbstractMergeNode) {
+                        AbstractMergeNode merge = (AbstractMergeNode) begin;
+                        LabelOp label = (LabelOp) gen.getResult().getLIR().getLIRforBlock(block).get(0);
+                        label.setIncomingValues(createPhiIn(merge));
+                    }
+                }
             }
 
             List<Node> nodes = blockMap.get(block);
@@ -211,6 +247,9 @@
             for (int i = 0; i < nodes.size(); i++) {
                 Node node = nodes.get(i);
                 if (node instanceof ValueNode) {
+                    if (node instanceof ValuePhiNode) {
+                        assert node != null;
+                    }
                     ValueNode valueNode = (ValueNode) node;
                     if (Options.TraceLIRGeneratorLevel.getValue() >= 3) {
                         TTY.println("LIRGen for " + valueNode);
@@ -347,8 +386,13 @@
     @Override
     public void visitEndNode(AbstractEndNode end) {
         AbstractMergeNode merge = end.merge();
-        moveToPhi(merge, end);
-        append(newJumpOp(getLIRBlock(merge)));
+        JumpOp jump = newJumpOp(getLIRBlock(merge));
+        if (SSA_LIR.getValue()) {
+            jump.setOutgoingValues(createPhiOut(merge, end));
+        } else {
+            moveToPhi(merge, end);
+        }
+        append(jump);
     }
 
     /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Mon May 04 23:15:42 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Mon Apr 20 14:14:09 2015 +0200
@@ -109,10 +109,15 @@
     public static class JumpOp extends LIRInstruction implements BlockEndOp {
         public static final LIRInstructionClass<JumpOp> TYPE = LIRInstructionClass.create(JumpOp.class);
 
+        private static final Value[] NO_VALUES = new Value[0];
+
+        @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
+
         private final LabelRef destination;
 
         public JumpOp(LabelRef destination) {
             this(TYPE, destination);
+            this.outgoingValues = NO_VALUES;
         }
 
         protected JumpOp(LIRInstructionClass<? extends JumpOp> c, LabelRef destination) {
@@ -120,6 +125,11 @@
             this.destination = destination;
         }
 
+        public void setOutgoingValues(Value[] values) {
+            assert outgoingValues.length == 0;
+            outgoingValues = values;
+        }
+
         @Override
         public void emitCode(CompilationResultBuilder crb) {
             if (!crb.isSuccessorEdge(destination)) {