# HG changeset patch # User Stefan Anzinger # Date 1429534216 -7200 # Node ID b4b103d7f46f4af6ca161342034185926e7e3fdc # Parent 98e0b349a796920c6f060111b025adba4f7cacea [SPARC] Fix performance regression with CBcond; Do not use short branch, when constant fits into simm13 but not in simm5 diff -r 98e0b349a796 -r b4b103d7f46f graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Apr 20 10:24:40 2015 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Apr 20 14:50:16 2015 +0200 @@ -918,6 +918,10 @@ return isSimm(imm, 13); } + public static boolean isSimm13(JavaConstant constant) { + return constant.isNull() || isSimm13(constant.asLong()); + } + public static boolean isSimm13(long imm) { return NumUtil.isInt(imm) && isSimm(imm, 13); } diff -r 98e0b349a796 -r b4b103d7f46f graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Apr 20 10:24:40 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Apr 20 14:50:16 2015 +0200 @@ -91,7 +91,7 @@ private double trueDestinationProbability; // This describes the maximum offset between the first emitted (load constant in to scratch, // if does not fit into simm5 of cbcond) instruction and the final branch instruction - private static int maximumSelfOffsetInstructions = 4; + private static int maximumSelfOffsetInstructions = 2; public CompareBranchOp(SPARCCompare opcode, Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue, double trueDestinationProbability) { @@ -218,19 +218,9 @@ actualY = tmpValue; actualConditionFlag = actualConditionFlag.mirror(); } - boolean isValidConstant = isConstant(actualY) && isSimm5(asConstant(actualY)); try (ScratchRegister scratch = masm.getScratchRegister()) { - if (isConstant(actualY) && !isValidConstant) { // Make sure, the y value is loaded - Value scratchValue = scratch.getRegister().asValue(actualY.getLIRKind()); - SPARCMove.move(crb, masm, scratchValue, actualY, SPARCDelayedControlTransfer.DUMMY); - actualY = scratchValue; - } - // Test if the previous instruction was cbcond, if so, put a nop inbetween (See - // SPARC Architecture 2011 manual) - if (masm.isCbcond(masm.getInt(masm.position() - 1))) { - masm.nop(); - } emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag); + masm.nop(); } if (needJump) { masm.jmp(actualFalseTarget); @@ -289,6 +279,12 @@ default: return false; } + // Do not use short branch, if the y value is a constant and does not fit into simm5 but + // fits into simm13; this means the code with CBcond would be longer as the code without + // CBcond. + if (isConstant(y) && !isSimm5(asConstant(y)) && isSimm13(asConstant(y))) { + return false; + } boolean hasShortJumpTarget = false; if (!crb.isSuccessorEdge(trueDestination)) { hasShortJumpTarget |= isShortBranch(asm, position, trueDestinationHint, trueDestination.label()); @@ -303,7 +299,6 @@ int disp = 0; if (label.isBound()) { disp = label.position() - position; - } else if (hint != null && hint.isValid()) { disp = hint.getTarget() - hint.getPosition(); } @@ -370,7 +365,6 @@ // We cannot make use of the delay slot when we jump in true-case and false-case return false; } - if (kind == Kind.Double || kind == Kind.Float) { masm.fbpcc(actualConditionFlag, NOT_ANNUL, actualTarget, CC.Fcc0, predictTaken); } else {