changeset 7380:3207ee96b659

Added possibility for platform-specific peephole optimizations. Added combining div/rem optimization.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 15 Jan 2013 18:39:40 +0100
parents 0cc86f2309be
children 6761a8f854a4
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java
diffstat 2 files changed, 59 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Jan 15 18:27:01 2013 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Jan 15 18:39:40 2013 +0100
@@ -340,7 +340,49 @@
     }
 
     @Override
-    public Variable emitDiv(Value a, Value b) {
+    protected boolean peephole(ValueNode valueNode) {
+        if ((valueNode instanceof IntegerDivNode) || (valueNode instanceof IntegerRemNode)) {
+            FixedBinaryNode divRem = (FixedBinaryNode) valueNode;
+            FixedNode node = divRem.next();
+            while (node instanceof FixedWithNextNode) {
+                FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node;
+                if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) {
+                    FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode;
+                    if (otherDivRem.x() == divRem.x() && otherDivRem.y() == divRem.y() && operand(otherDivRem) == null) {
+                        Value[] results = emitIntegerDivRem(operand(divRem.x()), operand(divRem.y()));
+                        if (divRem instanceof IntegerDivNode) {
+                            setResult(divRem, results[0]);
+                            setResult(otherDivRem, results[1]);
+                        } else {
+                            setResult(divRem, results[1]);
+                            setResult(otherDivRem, results[0]);
+                        }
+                        return true;
+                    }
+                }
+                node = fixedWithNextNode.next();
+            }
+        }
+        return false;
+    }
+
+    public Value[] emitIntegerDivRem(Value a, Value b) {
+        switch(a.getKind()) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivRemOp(IDIVREM, RAX_I, load(b), state()));
+                return new Value[]{emitMove(RAX_I), emitMove(RDX_I)};
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivRemOp(LDIVREM, RAX_L, load(b), state()));
+                return new Value[]{emitMove(RAX_L), emitMove(RDX_L)};
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Value emitDiv(Value a, Value b) {
         switch(a.getKind()) {
             case Int:
                 emitMove(a, RAX_I);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Jan 15 18:27:01 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Jan 15 18:39:40 2013 +0100
@@ -373,12 +373,20 @@
                 stateAfter = ((StateSplit) instr).stateAfter();
             }
             if (instr instanceof ValueNode) {
-                try {
-                    doRoot((ValueNode) instr);
-                } catch (GraalInternalError e) {
-                    throw e.addContext(instr);
-                } catch (Throwable e) {
-                    throw new GraalInternalError(e).addContext(instr);
+
+                ValueNode valueNode = (ValueNode) instr;
+                if (operand(valueNode) == null) {
+                    if (!peephole(valueNode)) {
+                        try {
+                            doRoot((ValueNode) instr);
+                        } catch (GraalInternalError e) {
+                            throw e.addContext(instr);
+                        } catch (Throwable e) {
+                            throw new GraalInternalError(e).addContext(instr);
+                        }
+                    }
+                } else {
+                    // There can be cases in which the result of an instruction is already set before by other instructions.
                 }
             }
             if (stateAfter != null) {
@@ -416,6 +424,8 @@
         }
     }
 
+    protected abstract boolean peephole(ValueNode valueNode);
+
     private boolean checkStateReady(FrameState state) {
         FrameState fs = state;
         while (fs != null) {