Mercurial > hg > graal-jvmci-8
changeset 22310:24db9b5a9f04
Introduce AbstractBlockEndOp and add methods to BlockEndOp.
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -31,7 +31,7 @@ import com.oracle.graal.lir.asm.*; @Opcode("DEOPT") -final class AMD64DeoptimizeOp extends AMD64LIRInstruction implements BlockEndOp { +final class AMD64DeoptimizeOp extends AMD64BlockEndOp implements BlockEndOp { public static final LIRInstructionClass<AMD64DeoptimizeOp> TYPE = LIRInstructionClass.create(AMD64DeoptimizeOp.class); @State private LIRFrameState info;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -23,19 +23,19 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.hotspot.HotSpotHostBackend.*; -import jdk.internal.jvmci.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; +import jdk.internal.jvmci.meta.*; + /** * Removes the current frame and tail calls the uncommon trap routine. */ @Opcode("DEOPT_CALLER") -final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { +final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueBlockEndOp { public static final LIRInstructionClass<AMD64HotSpotDeoptimizeCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotDeoptimizeCallerOp.class);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueBlockEndOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; + +import jdk.internal.jvmci.meta.*; + +/** + * @see AMD64HotSpotEpilogueOp + */ +abstract class AMD64HotSpotEpilogueBlockEndOp extends AMD64BlockEndOp { + + protected AMD64HotSpotEpilogueBlockEndOp(LIRInstructionClass<? extends AMD64HotSpotEpilogueBlockEndOp> c, AllocatableValue savedRbp) { + super(c); + this.savedRbp = savedRbp; + } + + @Use({REG, STACK}) private AllocatableValue savedRbp; + + protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + AMD64HotSpotEpilogueOp.leaveFrameAndRestoreRbp(savedRbp, crb, masm); + } + +}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -46,6 +46,10 @@ @Use({REG, STACK}) private AllocatableValue savedRbp; protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + leaveFrameAndRestoreRbp(savedRbp, crb, masm); + } + + static void leaveFrameAndRestoreRbp(AllocatableValue savedRbp, CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isStackSlot(savedRbp)) { // Restoring RBP from the stack must be done before the frame is removed masm.movq(rbp, (AMD64Address) crb.asAddress(savedRbp));
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.amd64; -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.meta.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static jdk.internal.jvmci.amd64.AMD64.*; import static jdk.internal.jvmci.code.ValueUtil.*; @@ -31,15 +29,17 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.asm.*; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.meta.*; + /** * Sets up the arguments for an exception handler in the callers frame, removes the current frame * and jumps to the handler. */ @Opcode("JUMP_TO_EXCEPTION_HANDLER_IN_CALLER") -final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { +final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueBlockEndOp { public static final LIRInstructionClass<AMD64HotSpotJumpToExceptionHandlerInCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotJumpToExceptionHandlerInCallerOp.class);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -23,20 +23,20 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.hotspot.*; import jdk.internal.jvmci.meta.*; -import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; -import com.oracle.graal.lir.asm.*; - /** * Returns from a function. */ @Opcode("RETURN") -final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { +final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueBlockEndOp { public static final LIRInstructionClass<AMD64HotSpotReturnOp> TYPE = LIRInstructionClass.create(AMD64HotSpotReturnOp.class); @Use({REG, ILLEGAL}) protected Value value;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -26,21 +26,21 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static jdk.internal.jvmci.amd64.AMD64.*; import static jdk.internal.jvmci.code.ValueUtil.*; -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.meta.*; + /** * Removes the current frame and jumps to the {@link UnwindExceptionToCallerStub}. */ @Opcode("UNWIND") -final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { +final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueBlockEndOp { public static final LIRInstructionClass<AMD64HotSpotUnwindOp> TYPE = LIRInstructionClass.create(AMD64HotSpotUnwindOp.class); @Use({REG}) protected RegisterValue exception;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -28,12 +28,11 @@ import com.oracle.graal.asm.sparc.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; @Opcode("DEOPT") -final class SPARCDeoptimizeOp extends SPARCLIRInstruction implements BlockEndOp { +final class SPARCDeoptimizeOp extends SPARCBlockEndOp { public static final LIRInstructionClass<SPARCDeoptimizeOp> TYPE = LIRInstructionClass.create(SPARCDeoptimizeOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(1); @Temp AllocatableValue pcRegister;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -23,17 +23,16 @@ package com.oracle.graal.hotspot.sparc; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; /** * Superclass for operations that leave a method's frame. */ -abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction implements BlockEndOp { +abstract class SPARCHotSpotEpilogueOp extends SPARCBlockEndOp { public static final LIRInstructionClass<SPARCHotSpotEpilogueOp> TYPE = LIRInstructionClass.create(SPARCHotSpotEpilogueOp.class); - protected SPARCHotSpotEpilogueOp(LIRInstructionClass<? extends LIRInstruction> c, SizeEstimate size) { + protected SPARCHotSpotEpilogueOp(LIRInstructionClass<? extends SPARCHotSpotEpilogueOp> c, SizeEstimate size) { super(c, size); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BlockEndOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.amd64; + +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.asm.*; + +public abstract class AMD64BlockEndOp extends AbstractBlockEndOp { + + public static final LIRInstructionClass<AMD64BlockEndOp> TYPE = LIRInstructionClass.create(AMD64BlockEndOp.class); + + protected AMD64BlockEndOp(LIRInstructionClass<? extends AMD64BlockEndOp> c) { + super(c); + } + + @Override + public final void emitCode(CompilationResultBuilder crb) { + emitCode(crb, (AMD64MacroAssembler) crb.asm); + } + + public abstract void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm); +}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Jul 03 10:35:09 2015 +0200 @@ -42,7 +42,7 @@ public class AMD64ControlFlow { - public static final class ReturnOp extends AMD64LIRInstruction implements BlockEndOp { + public static final class ReturnOp extends AMD64BlockEndOp implements BlockEndOp { public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class); @Use({REG, ILLEGAL}) protected Value x; @@ -58,7 +58,7 @@ } } - public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp { + public static class BranchOp extends AMD64BlockEndOp implements StandardOp.BranchOp { public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class); protected final ConditionFlag condition; protected final LabelRef trueDestination; @@ -125,7 +125,7 @@ } } - public static final class StrategySwitchOp extends AMD64LIRInstruction implements BlockEndOp { + public static final class StrategySwitchOp extends AMD64BlockEndOp { public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class); @Use({CONST}) protected JavaConstant[] keyConstants; private final LabelRef[] keyTargets; @@ -181,7 +181,7 @@ } } - public static final class TableSwitchOp extends AMD64LIRInstruction implements BlockEndOp { + public static final class TableSwitchOp extends AMD64BlockEndOp { public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class); private final int lowKey; private final LabelRef defaultTarget;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBlockEndOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; + +import jdk.internal.jvmci.meta.*; + +public abstract class SPARCBlockEndOp extends SPARCLIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<SPARCBlockEndOp> TYPE = LIRInstructionClass.create(SPARCBlockEndOp.class); + + @Alive({REG, STACK, CONST}) private Value[] outgoingValues; + private int size; + + protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c) { + this(c, null); + } + + protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c, SizeEstimate sizeEstimate) { + super(c, sizeEstimate); + this.outgoingValues = Value.NO_VALUES; + this.size = 0; + } + + public void setOutgoingValues(Value[] values) { + assert outgoingValues.length == 0; + assert values != null; + outgoingValues = values; + size = values.length; + } + + public int getOutgoingSize() { + return size; + } + + public Value getOutgoingValue(int idx) { + assert checkRange(idx); + return outgoingValues[idx]; + } + + private boolean checkRange(int idx) { + return idx < size; + } + + public void clearOutgoingValues() { + outgoingValues = Value.NO_VALUES; + size = 0; + } + + public int addOutgoingValues(Value[] v) { + + int t = size + v.length; + if (t >= outgoingValues.length) { + Value[] newArray = new Value[t]; + System.arraycopy(outgoingValues, 0, newArray, 0, size); + outgoingValues = newArray; + } + System.arraycopy(v, 0, outgoingValues, size, v.length); + size = t; + return t; + + } +}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Fri Jul 03 10:35:09 2015 +0200 @@ -38,7 +38,6 @@ import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.common.*; import jdk.internal.jvmci.meta.*; -import jdk.internal.jvmci.sparc.*; import jdk.internal.jvmci.sparc.SPARC.CPUFeature; import com.oracle.graal.asm.*; @@ -51,7 +50,6 @@ import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure; import com.oracle.graal.lir.asm.*; @@ -60,7 +58,7 @@ // if does not fit into simm5 of cbcond) instruction and the final branch instruction private static final int maximumSelfOffsetInstructions = 2; - public static final class ReturnOp extends SPARCLIRInstruction implements BlockEndOp { + public static final class ReturnOp extends SPARCBlockEndOp { public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(2); @@ -83,7 +81,7 @@ } } - public static final class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer { + public static final class CompareBranchOp extends SPARCBlockEndOp implements SPARCDelayedControlTransfer { public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(3); static final EnumSet<Kind> SUPPORTED_KINDS = EnumSet.of(Kind.Long, Kind.Int, Kind.Object, Kind.Float, Kind.Double); @@ -312,15 +310,12 @@ private static boolean isShortBranch(SPARCAssembler asm, int position, LabelHint hint, Label label) { int disp = 0; - boolean dispValid = true; if (label.isBound()) { disp = label.position() - position; } else if (hint != null && hint.isValid()) { disp = hint.getTarget() - hint.getPosition(); - } else { - dispValid = false; } - if (dispValid) { + if (disp != 0) { if (disp < 0) { disp -= maximumSelfOffsetInstructions * asm.target.wordSize; } else { @@ -333,7 +328,7 @@ return false; } - public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { + public static final class BranchOp extends SPARCBlockEndOp implements StandardOp.BranchOp { public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class); public static final SizeEstimate SIZE = SizeEstimate.create(2); protected final ConditionFlag conditionFlag; @@ -398,7 +393,7 @@ return true; } - public static final class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp { + public static final class StrategySwitchOp extends SPARCBlockEndOp { public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class); @Use({CONST}) protected JavaConstant[] keyConstants; private final LabelRef[] keyTargets; @@ -407,8 +402,7 @@ @Alive({REG, ILLEGAL}) protected Value constantTableBase; @Temp({REG}) protected Value scratch; private final SwitchStrategy strategy; - private final Map<Label, LabelHint> labelHints; - private final List<Label> conditionalLabels = new ArrayList<>(); + private final LabelHint[] labelHints; public StrategySwitchOp(Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { super(TYPE); @@ -419,7 +413,7 @@ this.constantTableBase = constantTableBase; this.key = key; this.scratch = scratch; - this.labelHints = new HashMap<>(); + this.labelHints = new LabelHint[keyTargets.length]; assert keyConstants.length == keyTargets.length; assert keyConstants.length == strategy.keyProbabilities.length; } @@ -429,31 +423,9 @@ final Register keyRegister = asRegister(key); final Register constantBaseRegister = AllocatableValue.ILLEGAL.equals(constantTableBase) ? g0 : asRegister(constantTableBase); BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) { - int conditionalLabelPointer = 0; - - /** - * This method caches the generated labels over two assembly passes to get - * information about branch lengths. - */ - @Override - public Label conditionalJump(int index, Condition condition) { - Label label; - if (conditionalLabelPointer <= conditionalLabels.size()) { - label = new Label(); - conditionalLabels.add(label); - conditionalLabelPointer = conditionalLabels.size(); - } else { - // TODO: (sa) We rely here on the order how the labels are generated during - // code generation; if the order is not stable ower two assembly passes, the - // result can be wrong - label = conditionalLabels.get(conditionalLabelPointer++); - } - conditionalJump(index, condition, label); - return label; - } - @Override protected void conditionalJump(int index, Condition condition, Label target) { + requestHint(masm, index); JavaConstant constant = keyConstants[index]; CC conditionCode; Long bits; @@ -479,15 +451,10 @@ throw new JVMCIError("switch only supported for int, long and object"); } ConditionFlag conditionFlag = fromCondition(conditionCode, condition, false); - LabelHint hint = requestHint(masm, target); - boolean isShortConstant = isSimm5(constant); - int cbCondPosition = masm.position(); - if (!isShortConstant) { // Load constant takes one instruction - cbCondPosition += SPARC.INSTRUCTION_SIZE; - } - boolean canUseShortBranch = masm.hasFeature(CBCOND) && isShortBranch(masm, cbCondPosition, hint, target); + LabelHint hint = labelHints[index]; + boolean canUseShortBranch = masm.hasFeature(CBCOND) && hint.isValid() && isShortBranch(masm, masm.position(), hint, target); if (bits != null && canUseShortBranch) { - if (isShortConstant) { + if (isSimm5(constant)) { if (conditionCode == Icc) { masm.cbcondw(conditionFlag, keyRegister, (int) (long) bits, target); } else { @@ -518,13 +485,8 @@ strategy.run(closure); } - private LabelHint requestHint(SPARCMacroAssembler masm, Label label) { - LabelHint hint = labelHints.get(label); - if (hint == null) { - hint = masm.requestLabelHint(label); - labelHints.put(label, hint); - } - return hint; + private void requestHint(SPARCMacroAssembler masm, int index) { + labelHints[index] = masm.requestLabelHint(keyTargets[index].label()); } @Override @@ -539,7 +501,7 @@ } } - public static final class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp { + public static final class TableSwitchOp extends SPARCBlockEndOp { public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class); private final int lowKey;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Thu Jul 23 12:12:45 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Jul 03 10:35:09 2015 +0200 @@ -27,15 +27,15 @@ import java.util.*; -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.common.*; -import jdk.internal.jvmci.meta.*; - import com.oracle.graal.asm.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.framemap.*; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.common.*; +import jdk.internal.jvmci.meta.*; + /** * A collection of machine-independent LIR operations, as well as interfaces to be implemented for * specific kinds or LIR operations. @@ -47,6 +47,15 @@ * must be the last operation in the block. */ public interface BlockEndOp { + void setOutgoingValues(Value[] values); + + int getOutgoingSize(); + + Value getOutgoingValue(int idx); + + int addOutgoingValues(Value[] values); + + void clearOutgoingValues(); } public interface NullCheck { @@ -74,6 +83,7 @@ * instruction of a block, the registers are defined here in the label. */ @Def({REG, STACK}) private Value[] incomingValues; + private int size; private final Label label; private final boolean align; @@ -83,24 +93,43 @@ this.label = label; this.align = align; this.incomingValues = Value.NO_VALUES; + size = 0; } public void setIncomingValues(Value[] values) { - assert incomingValues.length == 0; + assert this.incomingValues.length == 0; assert values != null; - incomingValues = values; + this.incomingValues = values; + size = values.length; } public int getIncomingSize() { - return incomingValues.length; + return size; } public Value getIncomingValue(int idx) { + assert checkRange(idx); return incomingValues[idx]; } public void clearIncomingValues() { incomingValues = Value.NO_VALUES; + size = 0; + } + + public void addIncomingValues(Value[] values) { + int t = size + values.length; + if (t >= incomingValues.length) { + Value[] newArray = new Value[t]; + System.arraycopy(incomingValues, 0, newArray, 0, size); + incomingValues = newArray; + } + System.arraycopy(values, 0, incomingValues, size, values.length); + size = t; + } + + private boolean checkRange(int idx) { + return idx < size; } @Override @@ -123,14 +152,62 @@ } } + public abstract static class AbstractBlockEndOp extends LIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<AbstractBlockEndOp> TYPE = LIRInstructionClass.create(AbstractBlockEndOp.class); + + @Alive({REG, STACK, CONST}) private Value[] outgoingValues; + private int size; + + protected AbstractBlockEndOp(LIRInstructionClass<? extends AbstractBlockEndOp> c) { + super(c); + this.outgoingValues = Value.NO_VALUES; + size = 0; + } + + public void setOutgoingValues(Value[] values) { + assert this.outgoingValues.length == 0; + assert values != null; + this.outgoingValues = values; + size = values.length; + } + + public int getOutgoingSize() { + return size; + } + + public Value getOutgoingValue(int idx) { + assert checkRange(idx); + return outgoingValues[idx]; + } + + public void clearOutgoingValues() { + outgoingValues = Value.NO_VALUES; + size = 0; + } + + public int addOutgoingValues(Value[] values) { + int t = size + values.length; + if (t >= outgoingValues.length) { + Value[] newArray = new Value[t]; + System.arraycopy(outgoingValues, 0, newArray, 0, size); + outgoingValues = newArray; + } + System.arraycopy(values, 0, outgoingValues, size, values.length); + size = t; + return t; + } + + private boolean checkRange(int idx) { + return idx < size; + } + } + /** * LIR operation that is an unconditional jump to a {@link #destination()}. */ - public static class JumpOp extends LIRInstruction implements BlockEndOp { + public static class JumpOp extends AbstractBlockEndOp { public static final LIRInstructionClass<JumpOp> TYPE = LIRInstructionClass.create(JumpOp.class); - @Alive({REG, STACK, CONST}) private Value[] outgoingValues; - private final LabelRef destination; public JumpOp(LabelRef destination) { @@ -140,25 +217,6 @@ protected JumpOp(LIRInstructionClass<? extends JumpOp> c, LabelRef destination) { super(c); this.destination = destination; - this.outgoingValues = Value.NO_VALUES; - } - - public void setOutgoingValues(Value[] values) { - assert outgoingValues.length == 0; - assert values != null; - outgoingValues = values; - } - - public int getOutgoingSize() { - return outgoingValues.length; - } - - public Value getOutgoingValue(int idx) { - return outgoingValues[idx]; - } - - public void clearOutgoingValues() { - outgoingValues = Value.NO_VALUES; } @Override