# HG changeset patch # User Josef Eisl # Date 1430401151 -7200 # Node ID a2430e146460b728fde6ee7a66e1f7e4d43cf952 # Parent bf5e055dbc9c9c50189ab9db2aa5e314f0288d20 SSALinearScan: add register hints to PHIs. diff -r bf5e055dbc9c -r a2430e146460 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScan.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScan.java Thu Apr 30 15:36:03 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScan.java Thu Apr 30 15:39:11 2015 +0200 @@ -32,9 +32,12 @@ import com.oracle.graal.compiler.common.alloc.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.Debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.StandardOp.LabelOp; +import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; import com.oracle.graal.lir.ssa.*; @@ -130,6 +133,40 @@ return false; } + @Override + void addRegisterHint(final LIRInstruction op, final Value targetValue, OperandMode mode, EnumSet flags, final boolean hintAtDef) { + super.addRegisterHint(op, targetValue, mode, flags, hintAtDef); + + if (hintAtDef && op instanceof LabelOp) { + LabelOp label = (LabelOp) op; + + Interval to = getOrCreateInterval((AllocatableValue) targetValue); + + SSAUtils.forEachPhiRegisterHint(ir, blockForId(label.id()), label, targetValue, mode, (ValueConsumer) (registerHint, valueMode, valueFlags) -> { + if (isVariableOrRegister(registerHint)) { + Interval from = getOrCreateInterval((AllocatableValue) registerHint); + + setHint(op, to, from); + setHint(op, from, to); + } + }); + } + } + + private static void setHint(final LIRInstruction op, Interval target, Interval source) { + Interval currentHint = target.locationHint(false); + if (currentHint == null || currentHint.from() > target.from()) { + /* + * Update hint if there was none or if the hint interval starts after the hinted + * interval. + */ + target.setLocationHint(source); + if (Debug.isLogEnabled()) { + Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), source.operandNumber, target.operandNumber); + } + } + } + private boolean isPhiResolutionMove(AbstractBlockBase block, MoveOp move, Interval toInterval) { if (!LinearScanPhase.SSA_LSRA.getValue()) { return false; diff -r bf5e055dbc9c -r a2430e146460 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ssa/SSAUtils.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ssa/SSAUtils.java Thu Apr 30 15:36:03 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ssa/SSAUtils.java Thu Apr 30 15:39:11 2015 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.StandardOp.LabelOp; @@ -53,14 +54,14 @@ * v0|i = ... * JUMP ~[v0|i, int[0|0x0]] destination: B0 -> B1 * ________________________________________________ - * + * * B2 -> B1 * ... * v1|i = ... * v2|i = ... * JUMP ~[v1|i, v2|i] destination: B2 -> B1 * ________________________________________________ - * + * * B1 <- B0,B2 * [v3|i, v4|i] = LABEL * ... @@ -144,6 +145,31 @@ } } + public static void forEachPhiRegisterHint(LIR lir, AbstractBlockBase block, LabelOp label, Value targetValue, OperandMode mode, ValueConsumer valueConsumer) { + assert mode == OperandMode.DEF : "Wrong operand mode: " + mode; + assert lir.getLIRforBlock(block).get(0).equals(label) : String.format("Block %s and Label %s do not match!", block, label); + if (!label.isPhiIn()) { + return; + } + int idx = indexOfValue(label, targetValue); + assert idx >= 0 : String.format("Value %s not in label %s", targetValue, label); + + for (AbstractBlockBase pred : block.getPredecessors()) { + JumpOp jump = phiOut(lir, pred); + Value sourceValue = jump.getOutgoingValue(idx); + valueConsumer.visitValue(jump, sourceValue, null, null); + } + + } + + private static int indexOfValue(LabelOp label, Value value) { + for (int i = 0; i < label.getIncomingSize(); i++) { + if (label.getIncomingValue(i).equals(value)) { + return i; + } + } + return -1; + } }