# HG changeset patch # User Thomas Wuerthinger # Date 1358271580 -3600 # Node ID 3207ee96b6593dcbb06e171fe87b763ec2a9039f # Parent 0cc86f2309beac364b339d6b2ca5eaf2d09efb04 Added possibility for platform-specific peephole optimizations. Added combining div/rem optimization. diff -r 0cc86f2309be -r 3207ee96b659 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- 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); diff -r 0cc86f2309be -r 3207ee96b659 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- 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) {