Mercurial > hg > graal-compiler
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) {