# HG changeset patch # User Stefan Anzinger # Date 1435420964 -7200 # Node ID d9f3acb4a9a1fb6ed5a08d73d9954b85afd8948d # Parent 598c75a3d1d10ceda666a46462fb15099f5020bd [SPARC] Implement constant loads from constant table with base register diff -r 598c75a3d1d1 -r d9f3acb4a9a1 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 Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Sat Jun 27 18:02:44 2015 +0200 @@ -865,7 +865,21 @@ } public static boolean isSimm13(JavaConstant constant) { - return constant.isNull() || isSimm13(constant.asLong()); + long bits; + switch (constant.getKind()) { + case Double: + bits = Double.doubleToRawLongBits(constant.asDouble()); + break; + case Float: + bits = Float.floatToRawIntBits(constant.asFloat()); + break; + case Object: + return JavaConstant.NULL_POINTER.equals(constant); + default: + bits = constant.asLong(); + break; + } + return constant.isNull() || isSimm13(bits); } public static boolean isSimm13(long imm) { @@ -1640,6 +1654,44 @@ ld(Ldsh, src, dst); } + public void ld(SPARCAddress src, Register dst, int bytes, boolean signed) { + if (signed) { + switch (bytes) { + case 1: + ldub(src, dst); + break; + case 2: + lduh(src, dst); + break; + case 4: + lduw(src, dst); + break; + case 8: + ldx(src, dst); + break; + default: + throw new InternalError(); + } + } else { + switch (bytes) { + case 1: + ldsb(src, dst); + break; + case 2: + ldsh(src, dst); + break; + case 4: + ldsw(src, dst); + break; + case 8: + ldx(src, dst); + break; + default: + throw new InternalError(); + } + } + } + public void ldub(SPARCAddress src, Register dst) { assert isCPURegister(dst) : dst; ld(Ldub, src, dst); diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Sat Jun 27 18:02:44 2015 +0200 @@ -42,11 +42,23 @@ private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(g1), new ScratchRegister(g3)}; // Points to the next free scratch register private int nextFreeScratchRegister = 0; + /** + * Use ld [reg+simm13], reg for loading constants (User has to make sure, that the size of the + * constant table does not exceed simm13). + */ + private boolean immediateConstantLoad; public SPARCMacroAssembler(TargetDescription target, RegisterConfig registerConfig) { super(target, registerConfig); } + /** + * @see #immediateConstantLoad + */ + public void setImmediateConstantLoad(boolean immediateConstantLoad) { + this.immediateConstantLoad = immediateConstantLoad; + } + @Override public void align(int modulus) { while (position() % modulus != 0) { @@ -393,6 +405,10 @@ sra(rd, g0, rd); } + public boolean isImmediateConstantLoad() { + return immediateConstantLoad; + } + public ScratchRegister getScratchRegister() { return scratchRegister[nextFreeScratchRegister++]; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Sat Jun 27 18:02:44 2015 +0200 @@ -32,13 +32,15 @@ import jdk.internal.jvmci.common.*; import jdk.internal.jvmci.meta.*; import jdk.internal.jvmci.sparc.*; -import jdk.internal.jvmci.sparc.SPARC.*; +import jdk.internal.jvmci.sparc.SPARC.CPUFeature; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.NoOp; import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst; @@ -57,12 +59,9 @@ import com.oracle.graal.lir.sparc.SPARCMove.LoadDataAddressOp; import com.oracle.graal.lir.sparc.SPARCMove.LoadOp; import com.oracle.graal.lir.sparc.SPARCMove.MembarOp; +import com.oracle.graal.lir.sparc.SPARCMove.Move; import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp; -import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGpVIS3; -import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; -import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; -import com.oracle.graal.lir.sparc.SPARCMove.SPARCStackMove; import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; import com.oracle.graal.phases.util.*; @@ -73,6 +72,8 @@ private StackSlotValue tmpStackSlot; private SPARCSpillMoveFactory moveFactory; + private Variable constantTableBase; + private SPARCLoadConstantTableBaseOp loadConstantTableBaseOp; private class SPARCSpillMoveFactory implements LIRGeneratorTool.SpillMoveFactory { @@ -117,17 +118,28 @@ } protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) { + boolean srcIsSlot = isStackSlotValue(src); + boolean dstIsSlot = isStackSlotValue(dst); if (src instanceof SPARCAddressValue) { return new LoadAddressOp(dst, (SPARCAddressValue) src); - } else if (isRegister(src) || isStackSlotValue(dst)) { - return new MoveFromRegOp(dst, src); + } else if (src instanceof JavaConstant) { + JavaConstant javaConstant = (JavaConstant) src; + if (canInlineConstant(javaConstant)) { + return new SPARCMove.LoadInlineConstant(javaConstant, dst); + } else { + return new SPARCMove.LoadConstantFromTable(javaConstant, getConstantTableBase(), dst); + } + } else if (!srcIsSlot && !dstIsSlot) { + return new Move(dst, src); + } else if (srcIsSlot != dstIsSlot) { + return new Move(dst, src); } else { - return new MoveToRegOp(dst, src); + throw JVMCIError.shouldNotReachHere(src.getClass() + " " + dst.getClass()); } } protected LIRInstruction createStackMove(AllocatableValue result, Value input) { - return new SPARCStackMove(result, input); + return new SPARCMove.Move(result, input); } @Override @@ -265,6 +277,7 @@ CC conditionFlags; Value actualTrueValue = trueValue; Value actualFalseValue = falseValue; + // TODO: (sa) Review this loadSimm11 if it is really necessary switch ((Kind) left.getLIRKind().getPlatformKind()) { case Byte: case Short: @@ -367,6 +380,7 @@ throw JVMCIError.shouldNotReachHere(); } ConditionFlag flag = SPARCControlFlow.fromCondition(conditionCode, Condition.EQ, false); + // TODO: (sa) Review this loadSimm11 if it is really necessary append(new CondMoveOp(result, conditionCode, flag, loadSimm11(trueValue), loadSimm11(falseValue))); return result; } @@ -383,7 +397,15 @@ @Override public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { - append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, newVariable(key.getLIRKind()))); + Value scratchValue = newVariable(key.getLIRKind()); + AllocatableValue base = AllocatableValue.ILLEGAL; + for (JavaConstant c : strategy.keyConstants) { + if (!canInlineConstant(c)) { + base = getConstantTableBase(); + break; + } + } + append(new StrategySwitchOp(base, strategy, keyTargets, defaultTarget, key, scratchValue)); } @Override @@ -874,12 +896,13 @@ } private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) { - if (!getArchitecture().getFeatures().contains(CPUFeature.VIS3)) { - StackSlotValue tempSlot = getTempSlot(LIRKind.value(Kind.Long)); - append(new MoveFpGp(dst, src, tempSlot)); + AllocatableValue tempSlot; + if (getArchitecture().getFeatures().contains(CPUFeature.VIS3)) { + tempSlot = AllocatableValue.ILLEGAL; } else { - append(new MoveFpGpVIS3(dst, src)); + tempSlot = getTempSlot(LIRKind.value(Kind.Long)); } + append(new MoveFpGp(dst, src, tempSlot)); } private StackSlotValue getTempSlot(LIRKind kind) { @@ -1042,4 +1065,24 @@ assert kind == Kind.Object || kind == Kind.Long : address + " - " + kind + " not an object!"; append(new NullCheckOp(asAddressValue(address), state)); } + + public void emitLoadConstantTableBase() { + constantTableBase = newVariable(LIRKind.value(Kind.Long)); + int nextPosition = getResult().getLIR().getLIRforBlock(getCurrentBlock()).size(); + NoOp placeHolder = append(new NoOp(getCurrentBlock(), nextPosition)); + loadConstantTableBaseOp = new SPARCLoadConstantTableBaseOp(constantTableBase, placeHolder); + } + + boolean useConstantTableBase = false; + + protected Variable getConstantTableBase() { + useConstantTableBase = true; + return constantTableBase; + } + + @Override + public void beforeRegisterAllocation() { + LIR lir = getResult().getLIR(); + loadConstantTableBaseOp.setAlive(lir, useConstantTableBase); + } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Sat Jun 27 18:02:44 2015 +0200 @@ -121,4 +121,10 @@ public SPARCLIRGenerator getLIRGeneratorTool() { return (SPARCLIRGenerator) super.getLIRGeneratorTool(); } + + @Override + protected void emitPrologue(StructuredGraph graph) { + getLIRGeneratorTool().emitLoadConstantTableBase(); + super.emitPrologue(graph); + } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -33,11 +33,12 @@ @Opcode("DEOPT") final class SPARCDeoptimizeOp extends SPARCLIRInstruction implements BlockEndOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCDeoptimizeOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @State private LIRFrameState info; SPARCDeoptimizeOp(LIRFrameState info) { - super(TYPE); + super(TYPE, SIZE); this.info = info; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Sat Jun 27 18:02:44 2015 +0200 @@ -33,14 +33,18 @@ import static jdk.internal.jvmci.sparc.SPARC.*; import java.util.*; +import java.util.concurrent.*; import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.code.DataSection.Data; +import jdk.internal.jvmci.debug.*; import jdk.internal.jvmci.hotspot.*; import jdk.internal.jvmci.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.alloc.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.hotspot.*; @@ -52,6 +56,7 @@ import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.lir.sparc.SPARCLIRInstruction.SizeEstimate; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -60,10 +65,29 @@ */ public class SPARCHotSpotBackend extends HotSpotHostBackend { + private static final SizeEstimateStatistics CONSTANT_ESTIMATED_STATS = new SizeEstimateStatistics("ESTIMATE"); + private static final SizeEstimateStatistics CONSTANT_ACTUAL_STATS = new SizeEstimateStatistics("ACTUAL"); + public SPARCHotSpotBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { super(runtime, providers); } + private static class SizeEstimateStatistics { + private static final ConcurrentHashMap metrics = new ConcurrentHashMap<>(); + private final String suffix; + + public SizeEstimateStatistics(String suffix) { + super(); + this.suffix = suffix; + } + + public void add(Class c, int count) { + String name = SizeEstimateStatistics.class.getSimpleName() + "_" + c.getSimpleName() + "." + suffix; + DebugMetric m = metrics.computeIfAbsent(name, (n) -> Debug.metric(n)); + m.add(count); + } + } + @Override public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) { RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig; @@ -200,14 +224,67 @@ Map calleeSaveInfo = gen.getCalleeSaveInfo(); updateStub(stub, definedRegisters, calleeSaveInfo, frameMap); } + assert registerSizePredictionValidator(crb); + return crb; + } - return crb; + /** + * Registers a verifier which checks if the LIRInstructions estimate of constants size is + * greater or equal to the actual one. + */ + private static boolean registerSizePredictionValidator(final CompilationResultBuilder crb) { + /** + * Used to hold state between beforeOp and afterOp + */ + class ValidationState { + LIRInstruction op; + int constantSizeBefore; + + public void before(LIRInstruction before) { + assert op == null : "LIRInstruction " + op + " no after call received"; + op = before; + constantSizeBefore = calculateDataSectionSize(crb.compilationResult.getDataSection()); + } + + public void after(LIRInstruction after) { + assert after.equals(op) : "Instructions before/after don't match " + op + "/" + after; + int constantSizeAfter = calculateDataSectionSize(crb.compilationResult.getDataSection()); + int actual = constantSizeAfter - constantSizeBefore; + if (op instanceof SPARCLIRInstruction) { + SizeEstimate size = ((SPARCLIRInstruction) op).estimateSize(); + assert size != null : "No size prediction available for op: " + op; + Class c = op.getClass(); + CONSTANT_ESTIMATED_STATS.add(c, size.constantSize); + CONSTANT_ACTUAL_STATS.add(c, actual); + assert size.constantSize >= actual : "Op " + op + " exceeded estimated constant size; predicted: " + size.constantSize + " actual: " + actual; + } else { + assert actual == 0 : "Op " + op + " emitted to DataSection without any estimate."; + } + op = null; + constantSizeBefore = 0; + } + } + final ValidationState state = new ValidationState(); + crb.setOpCallback(op -> state.before(op), op -> state.after(op)); + return true; + } + + private static int calculateDataSectionSize(DataSection ds) { + int sum = 0; + for (Data d : ds) { + sum += d.getSize(); + } + return sum; } @Override public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod installedCodeOwner) { + SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; + // TODO: (sa) Fold the two traversals into one stuffDelayedControlTransfers(lir); - SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; + int constantSize = calculateConstantSize(lir); + boolean canUseImmediateConstantLoad = constantSize < (1 << 13) - 1; + masm.setImmediateConstantLoad(canUseImmediateConstantLoad); FrameMap frameMap = crb.frameMap; RegisterConfig regConfig = frameMap.getRegisterConfig(); HotSpotVMConfig config = getRuntime().getConfig(); @@ -272,6 +349,21 @@ } } + private static int calculateConstantSize(LIR lir) { + int size = 0; + for (AbstractBlockBase block : lir.codeEmittingOrder()) { + for (LIRInstruction inst : lir.getLIRforBlock(block)) { + if (inst instanceof SPARCLIRInstruction) { + SizeEstimate pred = ((SPARCLIRInstruction) inst).estimateSize(); + if (pred != null) { + size += pred.constantSize; + } + } + } + } + return size; + } + private static void resetDelayedControlTransfers(LIR lir) { for (AbstractBlockBase block : lir.codeEmittingOrder()) { for (LIRInstruction inst : lir.getLIRforBlock(block)) { @@ -321,12 +413,6 @@ // We have found a non overlapping LIR instruction which can be delayed ((SPARCTailDelayedLIRInstruction) inst).setDelayedControlTransfer(delayedTransfer); delayedTransfer = null; - // Removed the moving as it causes problems (Nullpointer exceptions) - // if (!adjacent) { - // // If not adjacent, we make it adjacent - // instructions.remove(i); - // instructions.add(delayTransferPosition - 1, inst); - // } } } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -35,6 +35,7 @@ @Opcode("CRUNTIME_CALL_EPILOGUE") final class SPARCHotSpotCRuntimeCallEpilogueOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotCRuntimeCallEpilogueOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(11); private final int threadLastJavaSpOffset; private final int threadLastJavaPcOffset; @@ -43,7 +44,7 @@ @Use({REG, STACK}) protected Value threadTemp; public SPARCHotSpotCRuntimeCallEpilogueOp(int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset, Register thread, Value threadTemp) { - super(TYPE); + super(TYPE, SIZE); this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; this.threadJavaFrameAnchorFlagsOffset = threadJavaFrameAnchorFlagsOffset; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -35,6 +35,7 @@ @Opcode("CRUNTIME_CALL_PROLOGUE") final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotCRuntimeCallPrologueOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(10); private final int threadLastJavaSpOffset; private final Register thread; @@ -42,7 +43,7 @@ @Def({REG, STACK}) protected Value threadTemp; public SPARCHotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread, Register stackPointer, Value threadTemp) { - super(TYPE); + super(TYPE, SIZE); this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.thread = thread; this.stackPointer = stackPointer; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -37,9 +37,10 @@ @Opcode("DEOPT_CALLER") final class SPARCHotSpotDeoptimizeCallerOp extends SPARCHotSpotEpilogueOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotDeoptimizeCallerOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(32); protected SPARCHotSpotDeoptimizeCallerOp() { - super(TYPE); + super(TYPE, SIZE); } @Override diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -33,8 +33,8 @@ abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction implements BlockEndOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotEpilogueOp.class); - protected SPARCHotSpotEpilogueOp(LIRInstructionClass c) { - super(c); + protected SPARCHotSpotEpilogueOp(LIRInstructionClass c, SizeEstimate size) { + super(c, size); } protected void leaveFrame(CompilationResultBuilder crb) { diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -42,6 +42,7 @@ final class SPARCHotSpotJumpToExceptionHandlerInCallerOp extends SPARCHotSpotEpilogueOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotJumpToExceptionHandlerInCallerOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(5); @Use(REG) AllocatableValue handlerInCallerPc; @Use(REG) AllocatableValue exception; @@ -50,7 +51,7 @@ private final int isMethodHandleReturnOffset; SPARCHotSpotJumpToExceptionHandlerInCallerOp(AllocatableValue handlerInCallerPc, AllocatableValue exception, AllocatableValue exceptionPc, int isMethodHandleReturnOffset, Register thread) { - super(TYPE); + super(TYPE, SIZE); this.handlerInCallerPc = handlerInCallerPc; this.exception = exception; this.exceptionPc = exceptionPc; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -43,11 +43,12 @@ @Opcode("JUMP_TO_EXCEPTION_HANDLER") final class SPARCHotSpotJumpToExceptionHandlerOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotJumpToExceptionHandlerOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); @Use(REG) AllocatableValue address; SPARCHotSpotJumpToExceptionHandlerOp(AllocatableValue address) { - super(TYPE); + super(TYPE, SIZE); this.address = address; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Sat Jun 27 18:02:44 2015 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static jdk.internal.jvmci.code.ValueUtil.*; +import static jdk.internal.jvmci.hotspot.HotSpotCompressedNullConstant.*; import static jdk.internal.jvmci.sparc.SPARC.*; import java.util.*; @@ -220,7 +221,7 @@ if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) { return true; } else if (c instanceof HotSpotObjectConstant) { - return ((HotSpotObjectConstant) c).isCompressed(); + return false; } else { return super.canInlineConstant(c); } @@ -261,11 +262,13 @@ @Override protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) { - if (src instanceof JavaConstant) { - return new SPARCHotSpotMove.HotSpotLoadConstantOp(dst, (JavaConstant) src); + Value usedSource; + if (COMPRESSED_NULL.equals(src)) { + usedSource = INT_0; } else { - return super.createMove(dst, src); + usedSource = src; } + return super.createMove(dst, usedSource); } @Override diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotMove.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotMove.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotMove.java Sat Jun 27 18:02:44 2015 +0200 @@ -22,130 +22,27 @@ */ package com.oracle.graal.hotspot.sparc; -import jdk.internal.jvmci.code.*; -import jdk.internal.jvmci.common.*; -import jdk.internal.jvmci.hotspot.*; -import jdk.internal.jvmci.hotspot.HotSpotVMConfig.*; -import jdk.internal.jvmci.meta.*; -import jdk.internal.jvmci.sparc.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static jdk.internal.jvmci.code.ValueUtil.*; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.hotspot.HotSpotVMConfig.CompressEncoding; +import jdk.internal.jvmci.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Annul; +import com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict; +import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; +import com.oracle.graal.asm.sparc.SPARCAssembler.RCondition; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; public class SPARCHotSpotMove { - - public static final class HotSpotLoadConstantOp extends SPARCLIRInstruction implements MoveOp { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(HotSpotLoadConstantOp.class); - - @Def({REG, STACK}) private AllocatableValue result; - private final JavaConstant input; - - public HotSpotLoadConstantOp(AllocatableValue result, JavaConstant input) { - super(TYPE); - this.result = result; - this.input = input; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - if (isStackSlot(result)) { - StackSlot ss = asStackSlot(result); - try (ScratchRegister s1 = masm.getScratchRegister()) { - Register sr1 = s1.getRegister(); - loadToRegister(crb, masm, sr1.asValue(), input); - try (ScratchRegister s2 = masm.getScratchRegister()) { - Register sr2 = s2.getRegister(); - int stackBias = HotSpotGraalRuntime.runtime().getConfig().stackBias; - int offset = crb.frameMap.offsetForStackSlot(ss); - new SPARCMacroAssembler.Setx(offset + stackBias, sr2).emit(masm); - SPARCAddress addr = new SPARCAddress(SPARC.sp, sr2); - Kind resultKind = (Kind) result.getPlatformKind(); - switch (resultKind) { - case Byte: - masm.stb(sr1, addr); - break; - case Short: - masm.sth(sr1, addr); - break; - case Int: - masm.stw(sr1, addr); - break; - case Long: - case Object: - masm.stx(sr1, addr); - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - } - } - } else { - loadToRegister(crb, masm, result, input); - } - } - - private static void loadToRegister(CompilationResultBuilder crb, SPARCMacroAssembler masm, AllocatableValue dest, JavaConstant constant) { - assert isRegister(dest); - if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(constant)) { - masm.mov(0, asRegister(dest)); - } else if (constant instanceof HotSpotObjectConstant) { - boolean compressed = ((HotSpotObjectConstant) constant).isCompressed(); - if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(constant); - if (compressed) { - masm.sethi(0xDEADDEAD >>> 10, asRegister(dest)); - masm.add(asRegister(dest), 0xAD & 0x3F, asRegister(dest)); - } else { - new SPARCMacroAssembler.Setx(0xDEADDEADDEADDEADL, asRegister(dest), true).emit(masm); - } - } else { - JVMCIError.unimplemented(); - } - } else if (constant instanceof HotSpotMetaspaceConstant) { - assert constant.getKind() == Kind.Int || constant.getKind() == Kind.Long; - boolean compressed = constant.getKind() == Kind.Int; - boolean isImmutable = GraalOptions.ImmutableCode.getValue(); - boolean generatePIC = GraalOptions.GeneratePIC.getValue(); - crb.recordInlineDataInCode(constant); - if (compressed) { - if (isImmutable && generatePIC) { - JVMCIError.unimplemented(); - } else { - new SPARCMacroAssembler.Setx(constant.asInt(), asRegister(dest), true).emit(masm); - } - } else { - if (isImmutable && generatePIC) { - JVMCIError.unimplemented(); - } else { - new SPARCMacroAssembler.Setx(constant.asLong(), asRegister(dest), true).emit(masm); - } - } - } else { - SPARCMove.move(crb, masm, dest, constant, SPARCDelayedControlTransfer.DUMMY); - } - } - - public Value getInput() { - return input; - } - - public AllocatableValue getResult() { - return result; - } - } - public static final class CompressPointer extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(CompressPointer.class); + public static final SizeEstimate SIZE = SizeEstimate.create(5); private final CompressEncoding encoding; private final boolean nonNull; @@ -155,7 +52,7 @@ @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { - super(TYPE); + super(TYPE, SIZE); this.result = result; this.input = input; this.baseRegister = baseRegister; @@ -165,26 +62,29 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCMove.move(crb, masm, result, input, SPARCDelayedControlTransfer.DUMMY); - + Register inputRegister = asRegister(input); Register resReg = asRegister(result); if (encoding.base != 0) { Register baseReg = asRegister(baseRegister); if (!nonNull) { - masm.cmp(resReg, baseReg); + masm.cmp(inputRegister, baseReg); masm.movcc(ConditionFlag.Equal, CC.Xcc, baseReg, resReg); + masm.sub(resReg, baseReg, resReg); + } else { + masm.sub(inputRegister, baseReg, resReg); } - masm.sub(resReg, baseReg, resReg); - } - - if (encoding.shift != 0) { - masm.srlx(resReg, encoding.shift, resReg); + if (encoding.shift != 0) { + masm.srlx(resReg, encoding.shift, resReg); + } + } else { + masm.srlx(inputRegister, encoding.shift, resReg); } } } public static final class UncompressPointer extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(UncompressPointer.class); + public static final SizeEstimate SIZE = SizeEstimate.create(4); private final CompressEncoding encoding; private final boolean nonNull; @@ -194,7 +94,7 @@ @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { - super(TYPE); + super(TYPE, SIZE); this.result = result; this.input = input; this.baseRegister = baseRegister; @@ -204,22 +104,23 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCMove.move(crb, masm, result, input, SPARCDelayedControlTransfer.DUMMY); - + Register inputRegister = asRegister(input); Register resReg = asRegister(result); + Register secondaryInput; if (encoding.shift != 0) { - masm.sll(resReg, encoding.shift, resReg); + masm.sll(inputRegister, encoding.shift, resReg); + secondaryInput = resReg; + } else { + secondaryInput = inputRegister; } if (encoding.base != 0) { if (nonNull) { - masm.add(resReg, asRegister(baseRegister), resReg); + masm.add(secondaryInput, asRegister(baseRegister), resReg); } else { - masm.cmp(resReg, resReg); - Label done = new Label(); - masm.bpr(RCondition.Rc_nz, Annul.ANNUL, done, BranchPredict.PREDICT_TAKEN, resReg); - masm.add(asRegister(baseRegister), resReg, resReg); + masm.bpr(RCondition.Rc_nz, Annul.ANNUL, done, BranchPredict.PREDICT_TAKEN, secondaryInput); + masm.add(asRegister(baseRegister), secondaryInput, resReg); masm.bind(done); } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -39,11 +39,12 @@ @Opcode("PATCH_RETURN") final class SPARCHotSpotPatchReturnAddressOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotPatchReturnAddressOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @Use(REG) AllocatableValue address; SPARCHotSpotPatchReturnAddressOp(AllocatableValue address) { - super(TYPE); + super(TYPE, SIZE); this.address = address; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -22,10 +22,10 @@ */ package com.oracle.graal.hotspot.sparc; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import jdk.internal.jvmci.hotspot.*; import jdk.internal.jvmci.meta.*; import jdk.internal.jvmci.sparc.*; -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.lir.*; @@ -38,13 +38,14 @@ @Opcode("RETURN") final class SPARCHotSpotReturnOp extends SPARCHotSpotEpilogueOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotReturnOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); @Use({REG, ILLEGAL}) protected Value value; private final boolean isStub; private final HotSpotVMConfig config; SPARCHotSpotReturnOp(Value value, boolean isStub, HotSpotVMConfig config) { - super(TYPE); + super(TYPE, SIZE); this.value = value; this.isStub = isStub; this.config = config; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -40,6 +40,7 @@ @Opcode("SAFEPOINT") public class SPARCHotSpotSafepointOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotSafepointOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(9); @State protected LIRFrameState state; @SuppressFBWarnings(value = "BC_IMPOSSIBLE_CAST", justification = "changed by the register allocator") @Temp({OperandFlag.REG}) private AllocatableValue temp; @@ -47,7 +48,7 @@ private final HotSpotVMConfig config; public SPARCHotSpotSafepointOp(LIRFrameState state, HotSpotVMConfig config, LIRGeneratorTool tool) { - super(TYPE); + super(TYPE, SIZE); this.state = state; this.config = config; this.temp = tool.newVariable(LIRKind.value(tool.target().wordKind)); diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -40,11 +40,12 @@ @Opcode("UNWIND") final class SPARCHotSpotUnwindOp extends SPARCHotSpotEpilogueOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotUnwindOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(32); @Use({REG}) protected RegisterValue exception; SPARCHotSpotUnwindOp(RegisterValue exception) { - super(TYPE); + super(TYPE, SIZE); this.exception = exception; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -38,12 +38,13 @@ @Opcode("CALL_DIRECT") final class SPARCHotspotDirectStaticCallOp extends DirectCallOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotspotDirectStaticCallOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(8); private final InvokeKind invokeKind; private final HotSpotVMConfig config; SPARCHotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, HotSpotVMConfig config) { - super(TYPE, target, result, parameters, temps, state); + super(TYPE, SIZE, target, result, parameters, temps, state); assert invokeKind.isDirect(); this.invokeKind = invokeKind; this.config = config; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -41,12 +41,13 @@ @Opcode("CALL_DIRECT") final class SPARCHotspotDirectVirtualCallOp extends DirectCallOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotspotDirectVirtualCallOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(8); private final InvokeKind invokeKind; private final HotSpotVMConfig config; SPARCHotspotDirectVirtualCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, HotSpotVMConfig config) { - super(TYPE, target, result, parameters, temps, state); + super(TYPE, SIZE, target, result, parameters, temps, state); this.invokeKind = invokeKind; this.config = config; assert invokeKind.isIndirect(); diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -44,6 +44,7 @@ @Opcode("CALL_INDIRECT") final class SPARCIndirectCallOp extends IndirectCallOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCIndirectCallOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); /** * Vtable stubs expect the metaspace Method in g5. @@ -55,7 +56,7 @@ private final HotSpotVMConfig config; SPARCIndirectCallOp(ResolvedJavaMethod targetMethod, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state, HotSpotVMConfig config) { - super(TYPE, targetMethod, result, parameters, temps, targetAddress, state); + super(TYPE, SIZE, targetMethod, result, parameters, temps, targetAddress, state); this.metaspaceMethod = metaspaceMethod; this.config = config; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -32,12 +32,13 @@ public final class SPARCPrefetchOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCPrefetchOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); private final int instr; // AllocatePrefetchInstr @Alive({COMPOSITE}) protected SPARCAddressValue address; public SPARCPrefetchOp(SPARCAddressValue address, int instr) { - super(TYPE); + super(TYPE, SIZE); this.address = address; this.instr = instr; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/LargeConstantSectionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/LargeConstantSectionTest.java Sat Jun 27 18:02:44 2015 +0200 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 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.jtt.backend; + +import static jdk.internal.org.objectweb.asm.Opcodes.*; +import jdk.internal.jvmci.options.*; +import jdk.internal.jvmci.options.OptionValue.OverrideScope; +import jdk.internal.org.objectweb.asm.*; + +import org.junit.*; + +import com.oracle.graal.api.directives.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.jtt.*; + +public class LargeConstantSectionTest extends JTTTest { + private static final String NAME = "LargeConstantSection"; + private static final long LARGE_CONSTANT = 0xF0F0F0F0F0L; + private static LargeConstantClassLoader LOADER; + + @BeforeClass + public static void before() { + LOADER = new LargeConstantClassLoader(LargeConstantSectionTest.class.getClassLoader()); + } + + public abstract static class LargeConstantAbstract { + public abstract long run(long i); + } + + public static long test(LargeConstantAbstract a, long i) throws Exception { + return a.run(GraalDirectives.opaque(i)); + } + + public static class LargeConstantClassLoader extends ClassLoader { + public LargeConstantClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + if (name.equals(NAME)) { + int numberIfBlocks = 1100; // Each if block contains three constants + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + String abstractClassName = Type.getInternalName(LargeConstantAbstract.class); + cw.visit(52, ACC_PUBLIC + ACC_SUPER, NAME, null, abstractClassName, null); + + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, abstractClassName, "", "()V", false); + mv.visitInsn(RETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + mv = cw.visitMethod(ACC_PUBLIC, "run", "(J)J", null, null); + mv.visitCode(); + Label nextIf = new Label(); + for (int i = 0; i < numberIfBlocks; i++) { + mv.visitLabel(nextIf); + mv.visitFrame(Opcodes.F_NEW, 2, new Object[]{abstractClassName, Opcodes.LONG}, 0, new Object[]{}); + mv.visitVarInsn(LLOAD, 1); + mv.visitLdcInsn(new Long(LARGE_CONSTANT + i)); + mv.visitInsn(LCMP); + nextIf = new Label(); + mv.visitJumpInsn(IFNE, nextIf); + mv.visitLdcInsn(new Long(LARGE_CONSTANT + i + numberIfBlocks)); + mv.visitMethodInsn(INVOKESTATIC, "com/oracle/graal/api/directives/GraalDirectives", "opaque", "(J)J", false); + mv.visitLdcInsn(new Long(LARGE_CONSTANT + i + numberIfBlocks * 2)); + mv.visitMethodInsn(INVOKESTATIC, "com/oracle/graal/api/directives/GraalDirectives", "opaque", "(J)J", false); + mv.visitInsn(LADD); + mv.visitInsn(LRETURN); + } + mv.visitLabel(nextIf); + mv.visitFrame(Opcodes.F_NEW, 2, new Object[]{abstractClassName, Opcodes.LONG}, 0, new Object[]{}); + mv.visitInsn(LCONST_0); + mv.visitInsn(LRETURN); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitMaxs(4, 6); + mv.visitEnd(); + + cw.visitEnd(); + + byte[] bytes = cw.toByteArray(); + return defineClass(name, bytes, 0, bytes.length); + } else { + return super.findClass(name); + } + } + } + + @Test + public void run0() throws Exception { + try (OverrideScope os = OptionValue.override(GraalOptions.InlineEverything, true)) { + runTest("test", LOADER.findClass(NAME).newInstance(), 0L); + } + } +} diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Sat Jun 27 18:02:44 2015 +0200 @@ -64,6 +64,8 @@ */ public static final class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(Unary2Op.class); + public static final SizeEstimate SIZE_1 = SizeEstimate.create(1); + public static final SizeEstimate SIZE_5 = SizeEstimate.create(5); @Opcode private final SPARCArithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @@ -80,6 +82,19 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { emitUnary(crb, masm, opcode, result, x, null, delayedControlTransfer); } + + @Override + public SizeEstimate estimateSize() { + switch (opcode) { + case F2L: + case F2I: + case D2L: + case D2I: + return SIZE_5; + default: + return SIZE_1; + } + } } /** @@ -88,6 +103,9 @@ */ public static final class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(BinaryRegReg.class); + public static final SizeEstimate SIZE_1 = SizeEstimate.create(1); + public static final SizeEstimate SIZE_3 = SizeEstimate.create(3); + public static final SizeEstimate SIZE_7 = SizeEstimate.create(7); @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected Value result; @@ -118,6 +136,19 @@ super.verify(); verifyKind(opcode, result, x, y); } + + @Override + public SizeEstimate estimateSize() { + switch (opcode) { + case IMULCC: + return SIZE_7; + case IUDIV: + case IDIV: + return SIZE_3; + default: + return SIZE_1; + } + } } /** @@ -125,6 +156,7 @@ */ public static final class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(BinaryRegConst.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected AllocatableValue result; @@ -137,7 +169,7 @@ } public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, JavaConstant y, LIRFrameState state) { - super(TYPE); + super(TYPE, SIZE); this.opcode = opcode; this.result = result; this.x = x; @@ -162,6 +194,7 @@ */ public static final class RemOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(RemOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(4); @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected Value result; @@ -172,7 +205,7 @@ @State protected LIRFrameState state; public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) { - super(TYPE); + super(TYPE, SIZE); this.opcode = opcode; this.result = result; this.x = x; @@ -199,6 +232,8 @@ */ public static final class SPARCLMulccOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCLMulccOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(13); + @Def({REG}) protected Value result; @Alive({REG}) protected Value x; @Alive({REG}) protected Value y; @@ -206,7 +241,7 @@ @Temp({REG}) protected Value scratch2; public SPARCLMulccOp(Value result, Value x, Value y, LIRGeneratorTool gen) { - super(TYPE); + super(TYPE, SIZE); this.result = result; this.x = x; this.y = y; @@ -856,6 +891,7 @@ public static final class MulHighOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MulHighOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(4); @Opcode private final SPARCArithmetic opcode; @Def({REG}) public AllocatableValue result; @@ -864,7 +900,7 @@ @Temp({REG}) public AllocatableValue scratch; public MulHighOp(SPARCArithmetic opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) { - super(TYPE); + super(TYPE, SIZE); this.opcode = opcode; this.x = x; this.y = y; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -53,6 +53,7 @@ @Opcode("ARRAY_EQUALS") public final class SPARCArrayEqualsOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCArrayEqualsOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(32); private final Kind kind; private final int arrayBaseOffset; @@ -69,7 +70,7 @@ @Temp({REG}) protected Value temp5; public SPARCArrayEqualsOp(LIRGeneratorTool tool, Kind kind, Value result, Value array1, Value array2, Value length) { - super(TYPE); + super(TYPE, SIZE); this.kind = kind; Class arrayClass = Array.newInstance(kind.toJavaClass(), 0).getClass(); diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -39,11 +39,17 @@ public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCBitManipulationOp.class); public enum IntrinsicOpcode { - IPOPCNT, - LPOPCNT, - IBSR, - LBSR, - BSF; + IPOPCNT(SizeEstimate.create(2)), + LPOPCNT(SizeEstimate.create(1)), + IBSR(SizeEstimate.create(13)), + LBSR(SizeEstimate.create(14)), + BSF(SizeEstimate.create(4)); + + final SizeEstimate size; + + private IntrinsicOpcode(SizeEstimate size) { + this.size = size; + } } @Opcode private final IntrinsicOpcode opcode; @@ -52,7 +58,7 @@ @Temp({REG}) protected Value scratch; public SPARCBitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input, LIRGeneratorTool gen) { - super(TYPE); + super(TYPE, opcode.size); this.opcode = opcode; this.result = result; this.input = input; @@ -148,5 +154,4 @@ throw JVMCIError.shouldNotReachHere(); } } - } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -35,6 +35,7 @@ @Opcode("BREAKPOINT") public final class SPARCBreakpointOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCBreakpointOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); // historical - from hotspot src/cpu/sparc/vm // promises that the system will not use traps 16-31 @@ -47,7 +48,7 @@ @Use({REG, STACK}) protected Value[] parameters; public SPARCBreakpointOp(Value[] parameters) { - super(TYPE); + super(TYPE, SIZE); this.parameters = parameters; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -37,14 +37,14 @@ @Opcode("BSWAP") public final class SPARCByteSwapOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCByteSwapOp.class); - + public static final SizeEstimate SIZE = SizeEstimate.create(3); @Def({REG, HINT}) protected Value result; @Use({REG}) protected Value input; @Temp({REG}) protected Value tempIndex; @Use({STACK}) protected StackSlotValue tmpSlot; public SPARCByteSwapOp(LIRGeneratorTool tool, Value result, Value input) { - super(TYPE); + super(TYPE, SIZE); this.result = result; this.input = input; this.tmpSlot = tool.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(Kind.Long)); @@ -53,7 +53,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCMove.move(crb, masm, tmpSlot, input, SPARCDelayedControlTransfer.DUMMY); + SPARCMove.reg2stack(crb, masm, tmpSlot, input, SPARCDelayedControlTransfer.DUMMY); SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot); if (addr.getIndex().equals(Register.None)) { Register tempReg = ValueUtil.asLongReg(tempIndex); diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Sat Jun 27 18:02:44 2015 +0200 @@ -37,15 +37,13 @@ public class SPARCCall { public abstract static class CallOp extends SPARCLIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(CallOp.class); - @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @Temp protected Value[] temps; @State protected LIRFrameState state; - protected CallOp(LIRInstructionClass c, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(c); + protected CallOp(LIRInstructionClass c, SizeEstimate size, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, size); this.result = result; this.parameters = parameters; this.state = state; @@ -60,28 +58,23 @@ } public abstract static class MethodCallOp extends CallOp { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MethodCallOp.class); protected final ResolvedJavaMethod callTarget; - protected MethodCallOp(LIRInstructionClass c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(c, result, parameters, temps, state); + protected MethodCallOp(LIRInstructionClass c, SizeEstimate size, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, size, result, parameters, temps, state); this.callTarget = callTarget; } } @Opcode("CALL_DIRECT") - public abstract static class DirectCallOp extends MethodCallOp /* - * implements - * SPARCDelayedControlTransfer - */{ - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(DirectCallOp.class); + public abstract static class DirectCallOp extends MethodCallOp { private boolean emitted = false; private int before = -1; - public DirectCallOp(LIRInstructionClass c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(c, callTarget, result, parameters, temps, state); + public DirectCallOp(LIRInstructionClass c, SizeEstimate size, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, size, callTarget, result, parameters, temps, state); } @Override @@ -126,13 +119,11 @@ @Opcode("CALL_INDIRECT") public abstract static class IndirectCallOp extends MethodCallOp { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(IndirectCallOp.class); - @Use({REG}) protected Value targetAddress; - protected IndirectCallOp(LIRInstructionClass c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value targetAddress, - LIRFrameState state) { - super(c, callTarget, result, parameters, temps, state); + protected IndirectCallOp(LIRInstructionClass c, SizeEstimate size, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, + Value targetAddress, LIRFrameState state) { + super(c, size, callTarget, result, parameters, temps, state); this.targetAddress = targetAddress; } @@ -153,8 +144,8 @@ protected final ForeignCallLinkage callTarget; - public ForeignCallOp(LIRInstructionClass c, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(c, result, parameters, temps, state); + public ForeignCallOp(LIRInstructionClass c, SizeEstimate size, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, size, result, parameters, temps, state); this.callTarget = callTarget; } @@ -167,9 +158,10 @@ @Opcode("NEAR_FOREIGN_CALL") public static final class DirectNearForeignCallOp extends ForeignCallOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(DirectNearForeignCallOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); public DirectNearForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(TYPE, linkage, result, parameters, temps, state); + super(TYPE, SIZE, linkage, result, parameters, temps, state); } @Override @@ -181,9 +173,10 @@ @Opcode("FAR_FOREIGN_CALL") public static final class DirectFarForeignCallOp extends ForeignCallOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(DirectFarForeignCallOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); public DirectFarForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(TYPE, callTarget, result, parameters, temps, state); + super(TYPE, SIZE, callTarget, result, parameters, temps, state); } @Override diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Sat Jun 27 18:02:44 2015 +0200 @@ -44,13 +44,14 @@ public static final class CompareOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(CompareOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @Opcode private final SPARCCompare opcode; @Use({REG}) protected Value x; @Use({REG, CONST}) protected Value y; public CompareOp(SPARCCompare opcode, Value x, Value y) { - super(TYPE); + super(TYPE, SIZE); this.opcode = opcode; this.x = x; this.y = y; @@ -74,7 +75,6 @@ (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double) : "Name; " + name() + " x: " + x + " y: " + y; - // @formatter:on } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 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 Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Sat Jun 27 18:02:44 2015 +0200 @@ -28,6 +28,7 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.lir.sparc.SPARCMove.*; import static jdk.internal.jvmci.code.ValueUtil.*; import static jdk.internal.jvmci.sparc.SPARC.*; @@ -56,11 +57,12 @@ public static final class ReturnOp extends SPARCLIRInstruction implements BlockEndOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ReturnOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); @Use({REG, ILLEGAL}) protected Value x; public ReturnOp(Value x) { - super(TYPE); + super(TYPE, SIZE); this.x = x; } @@ -78,6 +80,7 @@ public static final class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(CompareBranchOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(3); static final EnumSet SUPPORTED_KINDS = EnumSet.of(Kind.Long, Kind.Int, Kind.Object, Kind.Float, Kind.Double); private final SPARCCompare opcode; @@ -99,7 +102,7 @@ public CompareBranchOp(SPARCCompare opcode, Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue, double trueDestinationProbability) { - super(TYPE); + super(TYPE, SIZE); this.opcode = opcode; this.x = x; this.y = y; @@ -328,6 +331,7 @@ public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(BranchOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); protected final ConditionFlag conditionFlag; protected final LabelRef trueDestination; protected final LabelRef falseDestination; @@ -335,7 +339,7 @@ protected final double trueDestinationProbability; public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, Kind kind, double trueDestinationProbability) { - super(TYPE); + super(TYPE, SIZE); this.trueDestination = trueDestination; this.falseDestination = falseDestination; this.kind = kind; @@ -396,15 +400,17 @@ private final LabelRef[] keyTargets; private LabelRef defaultTarget; @Alive({REG}) protected Value key; + @Alive({REG, ILLEGAL}) protected Value constantTableBase; @Temp({REG}) protected Value scratch; private final SwitchStrategy strategy; - public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { + public StrategySwitchOp(Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { super(TYPE); this.strategy = strategy; this.keyConstants = strategy.keyConstants; this.keyTargets = keyTargets; this.defaultTarget = defaultTarget; + this.constantTableBase = constantTableBase; this.key = key; this.scratch = scratch; assert keyConstants.length == keyTargets.length; @@ -414,11 +420,11 @@ @Override public void emitCode(final CompilationResultBuilder crb, final SPARCMacroAssembler masm) { final Register keyRegister = asRegister(key); - + final Register constantBaseRegister = AllocatableValue.ILLEGAL.equals(constantTableBase) ? g0 : asRegister(constantTableBase); BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) { @Override protected void conditionalJump(int index, Condition condition, Label target) { - SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); + const2reg(crb, masm, scratch, constantBaseRegister, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); CC conditionCode; Register scratchRegister; switch (key.getKind()) { @@ -450,6 +456,17 @@ }; strategy.run(closure); } + + @Override + public SizeEstimate estimateSize() { + int constantBytes = 0; + for (JavaConstant v : keyConstants) { + if (!SPARCAssembler.isSimm13(v)) { + constantBytes += v.getKind().getByteCount(); + } + } + return new SizeEstimate(4 * keyTargets.length, constantBytes); + } } public static final class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp { @@ -522,6 +539,11 @@ masm.nop(); // delay slot } } + + @Override + public SizeEstimate estimateSize() { + return SizeEstimate.create(17 + targets.length * 2); + } } @Opcode("CMOVE") @@ -563,6 +585,18 @@ cmove(masm, cc, result, actualCondition, actualTrueValue); } } + + @Override + public SizeEstimate estimateSize() { + int constantSize = 0; + if (isConstant(trueValue) && !SPARCAssembler.isSimm13(asConstant(trueValue))) { + constantSize += trueValue.getKind().getByteCount(); + } + if (isConstant(falseValue) && !SPARCAssembler.isSimm13(asConstant(falseValue))) { + constantSize += trueValue.getKind().getByteCount(); + } + return SizeEstimate.create(3, constantSize); + } } private static void cmove(SPARCMacroAssembler masm, CC cc, Value result, ConditionFlag cond, Value other) { diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -29,9 +29,12 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.sparc.SPARCLIRInstruction.*; public final class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCJumpOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); + private boolean emitDone = false; private int delaySlotPosition = -1; @@ -56,11 +59,16 @@ masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label()); masm.nop(); } else { - assert crb.asm.position() - delaySlotPosition == 4; + int disp = crb.asm.position() - delaySlotPosition; + assert disp == 4 : disp; } } } + public static SizeEstimate getSize() { + return SIZE; + } + public void resetState() { delaySlotPosition = -1; emitDone = false; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Sat Jun 27 18:02:44 2015 +0200 @@ -31,9 +31,15 @@ */ public abstract class SPARCLIRInstruction extends LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCLIRInstruction.class); + private final SizeEstimate size; protected SPARCLIRInstruction(LIRInstructionClass c) { + this(c, null); + } + + protected SPARCLIRInstruction(LIRInstructionClass c, SizeEstimate size) { super(c); + this.size = size; } protected SPARCDelayedControlTransfer delayedControlTransfer = SPARCDelayedControlTransfer.DUMMY; @@ -52,4 +58,48 @@ public void setDelayedControlTransfer(SPARCDelayedControlTransfer holder) { this.delayedControlTransfer = holder; } + + public SizeEstimate estimateSize() { + return size; + } + + /** + * This class represents a size estimation of a particular LIR instruction. It contains a + * pessimistic estimate of emitted SPARC instructions and emitted bytes into the constant + * section. + */ + public static class SizeEstimate { + /** + * Cache the first size definition (with just 0 as constant size). + */ + private static final SizeEstimate[] cache = new SizeEstimate[5]; + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new SizeEstimate(i, 0); + } + } + public final int instructionSize; + public final int constantSize; + + public SizeEstimate(int instructionSize, int constantSize) { + this.instructionSize = instructionSize; + this.constantSize = constantSize; + } + + public static SizeEstimate create(int instructionSize, int constantSize) { + if (constantSize == 0 && instructionSize < cache.length) { + return cache[instructionSize]; + } else { + return new SizeEstimate(instructionSize, constantSize); + } + } + + public static SizeEstimate create(int instructionSize) { + if (instructionSize < cache.length) { + return cache[instructionSize]; + } else { + return new SizeEstimate(instructionSize, 0); + } + } + } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLoadConstantTableBaseOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLoadConstantTableBaseOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2009, 2012, 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 static jdk.internal.jvmci.code.ValueUtil.*; +import jdk.internal.jvmci.code.CompilationResult.DataSectionReference; +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.meta.*; + +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.NoOp; +import com.oracle.graal.lir.asm.*; + +/** + * Loads the constant section base into a register. + * + *

+ * Layout: + * + *

+ * +----constant section----+--pad--+---code section--+
+ * |<-------------------_------------------->|
+ *                      ^- Constant section base pointer
+ * 
+ * + * The constant section base pointer is placed as such that the lowest offset -4096 points to the + * start of the constant section. + *

+ * If the constant section grows beyond 8k size, the immediate addressing cannot be used anymore; in + * this case absolute addressing (without using the base pointer is used). See also: + * CodeInstaller::pd_patch_DataSectionReference + * + * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, Kind, + * Register, Register, SPARCDelayedControlTransfer, Runnable) + */ +public class SPARCLoadConstantTableBaseOp extends SPARCLIRInstruction { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCLoadConstantTableBaseOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(9); + + private final NoOp placeHolder; + @Def({REG}) private AllocatableValue base; + + public SPARCLoadConstantTableBaseOp(Variable base, NoOp placeHolder) { + super(TYPE, SIZE); + this.base = base; + this.placeHolder = placeHolder; + } + + @Override + public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + Register baseRegister = asRegister(base); + DataSectionReference ref = new DataSectionReference(); + ref.setOffset(0); + crb.compilationResult.recordDataPatch(masm.position(), ref); + // TODO: (sa) Make this relocation shorter (right now it takes always 8 instructions) + new SPARCMacroAssembler.Setx(0, baseRegister, true).emit(masm); + /** + * Place the base register into the center of the reachable 8k range. This bias is reflected + * in CodeInstaller::pd_patch_DataSectionReference (jvmciCodeInstaller_sparc.cpp) + */ + masm.sub(baseRegister, -1 & ~((1 << 12) - 1), baseRegister); + } + + public AllocatableValue getResult() { + return base; + } + + public void setAlive(LIR lir, boolean alive) { + if (alive) { + placeHolder.replace(lir, this); + } else { + placeHolder.remove(lir); + } + } +} diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -32,6 +32,7 @@ public final class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCMathIntrinsicOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); public enum IntrinsicOpcode { SQRT, @@ -43,7 +44,7 @@ @Use protected Value input; public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) { - super(TYPE); + super(TYPE, SIZE); this.opcode = opcode; this.result = result; this.input = input; diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Sat Jun 27 18:02:44 2015 +0200 @@ -27,6 +27,9 @@ import static jdk.internal.jvmci.code.ValueUtil.*; import static jdk.internal.jvmci.meta.Kind.*; import static jdk.internal.jvmci.sparc.SPARC.*; + +import java.util.*; + import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.common.*; import jdk.internal.jvmci.meta.*; @@ -35,6 +38,7 @@ import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Sethix; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.ImplicitNullCheck; @@ -44,22 +48,110 @@ public class SPARCMove { - @Opcode("MOVE_TOREG") - public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MoveToRegOp.class); + public static class LoadInlineConstant extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction, MoveOp { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(LoadInlineConstant.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); + private JavaConstant constant; + @Def({REG, STACK}) AllocatableValue result; + + public LoadInlineConstant(JavaConstant constant, AllocatableValue result) { + super(TYPE, SIZE); + this.constant = constant; + this.result = result; + } + + @Override + public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + if (isRegister(result)) { + const2reg(crb, masm, result, g0, constant, delayedControlTransfer); + } else if (isStackSlot(result)) { + StackSlot slot = asStackSlot(result); + const2stack(crb, masm, slot, g0, constant, delayedControlTransfer, constant); + } + } + + public Value getInput() { + return constant; + } + + public AllocatableValue getResult() { + return result; + } + } + + public static class LoadConstantFromTable extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(LoadConstantFromTable.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1, 8); + + private JavaConstant constant; + @Def({REG, STACK}) AllocatableValue result; + @Use({REG}) private AllocatableValue constantTableBase; + + public LoadConstantFromTable(JavaConstant constant, AllocatableValue constantTableBase, AllocatableValue result) { + super(TYPE, SIZE); + this.constant = constant; + this.result = result; + this.constantTableBase = constantTableBase; + } - @Def({REG, HINT}) protected AllocatableValue result; - @Use({REG, STACK, CONST}) protected Value input; + @Override + public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + final Runnable recordReference; + final Kind constantKind = constant.getKind().equals(Object) ? Kind.Long : constant.getKind(); + switch (constantKind) { + case Object: + case Float: + case Double: + case Char: + case Short: + case Int: + case Long: + recordReference = () -> crb.recordDataReferenceInCode(constant, constantKind.getByteCount()); + break; + case Byte: + case Boolean: // Byte and Boolean always fits into simm13 + throw JVMCIError.shouldNotReachHere("Byte/Boolean must not be loaded via constant table"); + default: + throw JVMCIError.shouldNotReachHere("Unimplemented constant type: " + constant); + } + Register baseRegister = asRegister(constantTableBase); + if (isRegister(result)) { + Register resultRegister = asRegister(result); + loadFromConstantTable(crb, masm, constantKind, baseRegister, resultRegister, delayedControlTransfer, recordReference); + } else if (isStackSlot(result)) { + try (ScratchRegister scratch = masm.getScratchRegister()) { + Register scratchRegister = scratch.getRegister(); + loadFromConstantTable(crb, masm, constantKind, baseRegister, scratchRegister, delayedControlTransfer, recordReference); + StackSlot slot = asStackSlot(result); + delayedControlTransfer.emitControlTransfer(crb, masm); + masm.stx(scratchRegister, (SPARCAddress) crb.asAddress(slot)); + } + } + } + } - public MoveToRegOp(AllocatableValue result, Value input) { - super(TYPE); + @Opcode("MOVE") + public static class Move extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(Move.class); + public static final SizeEstimate SIZE = SizeEstimate.create(8); + + @Def({REG, STACK}) protected AllocatableValue result; + @Use({REG, STACK}) protected Value input; + + public Move(AllocatableValue result, Value input) { + super(TYPE, SIZE); this.result = result; this.input = input; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - move(crb, masm, getResult(), getInput(), delayedControlTransfer); + assert !isConstant(input); + if (isStackSlot(input) && isStackSlot(result)) { + stack2stack(crb, masm, reInterpret(asStackSlot(result)), reInterpret(asStackSlot(input)), delayedControlTransfer); + } else { + move(crb, masm, getResult(), getInput(), delayedControlTransfer); + } } @Override @@ -71,54 +163,44 @@ public AllocatableValue getResult() { return result; } - } - @Opcode("MOVE_FROMREG") - public static final class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MoveFromRegOp.class); - - @Def({REG, STACK}) protected AllocatableValue result; - @Use({REG, CONST, HINT}) protected Value input; - - public MoveFromRegOp(AllocatableValue result, Value input) { - super(TYPE); - this.result = result; - this.input = input; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - move(crb, masm, getResult(), getInput(), delayedControlTransfer); - } - - @Override - public Value getInput() { - return input; - } - - @Override - public AllocatableValue getResult() { - return result; + private static StackSlot reInterpret(StackSlot slot) { + switch ((Kind) slot.getPlatformKind()) { + case Boolean: + case Byte: + case Short: + case Char: + case Int: + case Long: + case Object: + return slot; + case Float: + return StackSlot.get(LIRKind.value(Kind.Int), slot.getRawOffset(), slot.getRawAddFrameSize()); + case Double: + return StackSlot.get(LIRKind.value(Kind.Long), slot.getRawOffset(), slot.getRawAddFrameSize()); + default: + throw JVMCIError.shouldNotReachHere(); + } } } /** - * Move between floating-point and general purpose register domain (WITHOUT VIS3). + * Move between floating-point and general purpose register domain. */ - @Opcode("MOVE") + @Opcode("MOVE_FPGP") public static final class MoveFpGp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MoveFpGp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; - @Use({STACK}) protected StackSlotValue temp; + @Use({STACK, ILLEGAL}) protected AllocatableValue temp; - public MoveFpGp(AllocatableValue result, AllocatableValue input, StackSlotValue temp) { - super(TYPE); + public MoveFpGp(AllocatableValue result, AllocatableValue input, AllocatableValue temp) { + super(TYPE, SIZE); this.result = result; this.input = input; this.temp = temp; - assert this.temp.getPlatformKind() == Kind.Long; } public Value getInput() { @@ -133,6 +215,43 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { Kind inputKind = (Kind) input.getPlatformKind(); Kind resultKind = (Kind) result.getPlatformKind(); + if (AllocatableValue.ILLEGAL.equals(temp)) { + moveDirect(crb, masm, inputKind, resultKind); + } else { + moveViaStack(crb, masm, inputKind, resultKind); + } + } + + private void moveDirect(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind inputKind, Kind resultKind) { + delayedControlTransfer.emitControlTransfer(crb, masm); + if (resultKind == Float) { + if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { + masm.movwtos(asIntReg(input), asFloatReg(result)); + } else { + throw JVMCIError.shouldNotReachHere(); + } + } else if (resultKind == Double) { + if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { + masm.movxtod(asIntReg(input), asDoubleReg(result)); + } else { + masm.movxtod(asLongReg(input), asDoubleReg(result)); + } + } else if (inputKind == Float) { + if (resultKind == Int || resultKind == Short || resultKind == Byte) { + masm.movstosw(asFloatReg(input), asIntReg(result)); + } else { + masm.movstouw(asFloatReg(input), asIntReg(result)); + } + } else if (inputKind == Double) { + if (resultKind == Long) { + masm.movdtox(asDoubleReg(input), asLongReg(result)); + } else { + throw JVMCIError.shouldNotReachHere(); + } + } + } + + private void moveViaStack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind inputKind, Kind resultKind) { int resultKindSize = crb.target.getSizeInBytes(resultKind); try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); @@ -197,118 +316,6 @@ } } - /** - * Move between floating-point and general purpose register domain (WITH VIS3). - */ - @Opcode("MOVE") - public static final class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MoveFpGpVIS3.class); - - @Def({REG}) protected AllocatableValue result; - @Use({REG}) protected AllocatableValue input; - - public MoveFpGpVIS3(AllocatableValue result, AllocatableValue input) { - super(TYPE); - this.result = result; - this.input = input; - } - - public Value getInput() { - return input; - } - - public AllocatableValue getResult() { - return result; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - Kind inputKind = (Kind) input.getPlatformKind(); - Kind resultKind = (Kind) result.getPlatformKind(); - delayedControlTransfer.emitControlTransfer(crb, masm); - if (resultKind == Float) { - if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { - masm.movwtos(asIntReg(input), asFloatReg(result)); - } else { - throw JVMCIError.shouldNotReachHere(); - } - } else if (resultKind == Double) { - if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { - masm.movxtod(asIntReg(input), asDoubleReg(result)); - } else { - masm.movxtod(asLongReg(input), asDoubleReg(result)); - } - } else if (inputKind == Float) { - if (resultKind == Int || resultKind == Short || resultKind == Byte) { - masm.movstosw(asFloatReg(input), asIntReg(result)); - } else { - masm.movstouw(asFloatReg(input), asIntReg(result)); - } - } else if (inputKind == Double) { - if (resultKind == Long) { - masm.movdtox(asDoubleReg(input), asLongReg(result)); - } else { - throw JVMCIError.shouldNotReachHere(); - } - } - } - } - - @Opcode("STACKMOVE") - public static final class SPARCStackMove extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCStackMove.class); - - @Def({STACK}) protected AllocatableValue result; - @Use({STACK, HINT}) protected Value input; - - public SPARCStackMove(AllocatableValue result, Value input) { - super(TYPE); - this.result = result; - this.input = input; - } - - @Override - public Value getInput() { - return input; - } - - @Override - public AllocatableValue getResult() { - return result; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - try (ScratchRegister scratchReg = masm.getScratchRegister()) { - Register scratch = scratchReg.getRegister(); - StackSlot intInput = reInterpret(asStackSlot(getInput())); - StackSlot intResult = reInterpret(asStackSlot(getResult())); - // move stack slot - move(crb, masm, scratch.asValue(intInput.getLIRKind()), intInput, SPARCDelayedControlTransfer.DUMMY); - move(crb, masm, intResult, scratch.asValue(intResult.getLIRKind()), delayedControlTransfer); - } - } - - private static StackSlot reInterpret(StackSlot slot) { - switch ((Kind) slot.getPlatformKind()) { - case Boolean: - case Byte: - case Short: - case Char: - case Int: - case Long: - case Object: - return slot; - case Float: - return StackSlot.get(LIRKind.value(Kind.Int), slot.getRawOffset(), slot.getRawAddFrameSize()); - case Double: - return StackSlot.get(LIRKind.value(Kind.Long), slot.getRawOffset(), slot.getRawAddFrameSize()); - default: - throw JVMCIError.shouldNotReachHere(); - } - } - } - public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MemOp.class); @@ -316,8 +323,8 @@ @Use({COMPOSITE}) protected SPARCAddressValue address; @State protected LIRFrameState state; - public MemOp(LIRInstructionClass c, PlatformKind kind, SPARCAddressValue address, LIRFrameState state) { - super(c); + public MemOp(LIRInstructionClass c, SizeEstimate size, PlatformKind kind, SPARCAddressValue address, LIRFrameState state) { + super(c, size); this.kind = kind; this.address = address; this.state = state; @@ -341,6 +348,7 @@ public static final class LoadOp extends MemOp implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(LoadOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @Def({REG}) protected AllocatableValue result; protected boolean signExtend; @@ -350,25 +358,26 @@ } public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state, boolean signExtend) { - super(TYPE, kind, address, state); + super(TYPE, SIZE, kind, address, state); this.result = result; this.signExtend = signExtend; } @Override public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitLoad(address.toAddress(), result, signExtend, kind, delayedControlTransfer, state, crb, masm); + emitLoad(crb, masm, address.toAddress(), result, signExtend, kind, delayedControlTransfer, state); } } public static final class LoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(LoadAddressOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(8); @Def({REG}) protected AllocatableValue result; @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue addressValue; public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) { - super(TYPE); + super(TYPE, SIZE); this.result = result; this.addressValue = address; } @@ -394,21 +403,27 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(data, 16); + SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(data, 8); assert addr == masm.getPlaceholder(); final boolean forceRelocatable = true; Register dstReg = asRegister(result); new Setx(0, dstReg, forceRelocatable).emit(masm); } + + @Override + public SizeEstimate estimateSize() { + return SizeEstimate.create(8, data.length); + } } public static final class MembarOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MembarOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); private final int barriers; public MembarOp(final int barriers) { - super(TYPE); + super(TYPE, SIZE); this.barriers = barriers; } @@ -421,12 +436,13 @@ public static final class NullCheckOp extends SPARCLIRInstruction implements NullCheck, SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(NullCheckOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @Use({COMPOSITE}) protected SPARCAddressValue input; @State protected LIRFrameState state; public NullCheckOp(SPARCAddressValue input, LIRFrameState state) { - super(TYPE); + super(TYPE, SIZE); this.input = input; this.state = state; } @@ -453,6 +469,7 @@ @Opcode("CAS") public static final class CompareAndSwapOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(CompareAndSwapOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); @Def({REG, HINT}) protected AllocatableValue result; @Alive({REG}) protected AllocatableValue address; @@ -460,7 +477,7 @@ @Use({REG}) protected AllocatableValue newValue; public CompareAndSwapOp(AllocatableValue result, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue) { - super(TYPE); + super(TYPE, SIZE); this.result = result; this.address = address; this.cmpValue = cmpValue; @@ -476,12 +493,13 @@ public static final class StackLoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(StackLoadAddressOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); @Def({REG}) protected AllocatableValue result; @Use({STACK, UNINITIALIZED}) protected StackSlotValue slot; public StackLoadAddressOp(AllocatableValue result, StackSlotValue address) { - super(TYPE); + super(TYPE, SIZE); this.result = result; this.slot = address; } @@ -513,11 +531,12 @@ public static class StoreOp extends MemOp implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(StoreOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @Use({REG}) protected AllocatableValue input; public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) { - super(TYPE, kind, address, state); + super(TYPE, SIZE, kind, address, state); this.input = input; } @@ -529,11 +548,12 @@ public static final class StoreConstantOp extends MemOp implements SPARCTailDelayedLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(StoreConstantOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(2); protected final JavaConstant input; public StoreConstantOp(Kind kind, SPARCAddressValue address, JavaConstant input, LIRFrameState state) { - super(TYPE, kind, address, state); + super(TYPE, SIZE, kind, address, state); this.input = input; if (!input.isDefaultForKind()) { throw JVMCIError.shouldNotReachHere("Can only store null constants to memory"); @@ -576,43 +596,33 @@ } public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { + move(crb, masm, result, g0, input, delaySlotLir); + } + + public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Register constantTableBase, Value input, SPARCDelayedControlTransfer delaySlotLir) { if (isRegister(input)) { if (isRegister(result)) { reg2reg(crb, masm, result, input, delaySlotLir); } else if (isStackSlot(result)) { - SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result); - emitStore(input, resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm); + reg2stack(crb, masm, result, input, delaySlotLir); } else { - throw JVMCIError.shouldNotReachHere(); + throw JVMCIError.shouldNotReachHere("Result is a: " + result); } } else if (isStackSlot(input)) { if (isRegister(result)) { SPARCAddress inputAddress = (SPARCAddress) crb.asAddress(input); - emitLoad(inputAddress, result, false, input.getPlatformKind(), delaySlotLir, null, crb, masm); + emitLoad(crb, masm, inputAddress, result, false, input.getPlatformKind(), delaySlotLir, null); + } else if (isStackSlot(result)) { + stack2stack(crb, masm, result, input, delaySlotLir); } else { - throw JVMCIError.shouldNotReachHere(); + throw JVMCIError.shouldNotReachHere("Result is a: " + result); } } else if (isConstant(input)) { JavaConstant constant = asConstant(input); if (isRegister(result)) { - const2reg(crb, masm, result, constant, delaySlotLir); + const2reg(crb, masm, result, constantTableBase, constant, delaySlotLir); } else if (isStackSlot(result)) { - if (constant.isDefaultForKind() || constant.isNull()) { - SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result); - emitStore(g0.asValue(LIRKind.derive(input)), resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm); - } else { - try (ScratchRegister sc = masm.getScratchRegister()) { - Register scratch = sc.getRegister(); - long value = constant.asLong(); - if (isSimm13(value)) { - masm.or(g0, (int) value, scratch); - } else { - new Setx(value, scratch).emit(masm); - } - SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result); - emitStore(scratch.asValue(LIRKind.derive(input)), resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm); - } - } + const2stack(crb, masm, result, constantTableBase, input, delaySlotLir, constant); } else { throw JVMCIError.shouldNotReachHere("Result is a: " + result); } @@ -621,7 +631,37 @@ } } - private static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { + public static void const2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Register constantTableBase, Value input, SPARCDelayedControlTransfer delaySlotLir, + JavaConstant constant) { + if (constant.isDefaultForKind() || constant.isNull()) { + SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result); + emitStore(g0.asValue(LIRKind.derive(input)), resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm); + } else { + try (ScratchRegister sc = masm.getScratchRegister()) { + Value scratchRegisterValue = sc.getRegister().asValue(LIRKind.derive(constant)); + const2reg(crb, masm, scratchRegisterValue, constantTableBase, constant, SPARCDelayedControlTransfer.DUMMY); + SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result); + emitStore(scratchRegisterValue, resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm); + } + } + } + + public static void stack2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { + try (ScratchRegister sc = masm.getScratchRegister()) { + SPARCAddress inputAddress = (SPARCAddress) crb.asAddress(input); + Value scratchRegisterValue = sc.getRegister().asValue(LIRKind.derive(input)); + emitLoad(crb, masm, inputAddress, scratchRegisterValue, false, input.getPlatformKind(), SPARCDelayedControlTransfer.DUMMY, null); + SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result); + emitStore(scratchRegisterValue, resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm); + } + } + + public static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { + SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result); + emitStore(input, resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm); + } + + public static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { final Register src = asRegister(input); final Register dst = asRegister(result); if (src.equals(dst)) { @@ -677,24 +717,28 @@ } } - private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, JavaConstant input, SPARCDelayedControlTransfer delaySlotLir) { + public static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Register constantTableBase, JavaConstant input, SPARCDelayedControlTransfer delaySlotLir) { try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); - boolean hasVIS3 = ((SPARC) masm.target.arch).getFeatures().contains(CPUFeature.VIS3); + Set cpuFeatures = ((SPARC) masm.target.arch).getFeatures(); + boolean hasVIS1 = cpuFeatures.contains(CPUFeature.VIS1); + boolean hasVIS3 = cpuFeatures.contains(CPUFeature.VIS3); Register resultRegister = asRegister(result); switch (input.getKind().getStackKind()) { case Int: if (input.isDefaultForKind()) { delaySlotLir.emitControlTransfer(crb, masm); masm.clr(resultRegister); - } else if (isSimm13(input.asLong())) { + } else if (isSimm13(input.asInt())) { delaySlotLir.emitControlTransfer(crb, masm); masm.or(g0, input.asInt(), resultRegister); } else { - Setx set = new Setx(input.asLong(), resultRegister, false, true); - set.emitFirstPartOfDelayed(masm); - delaySlotLir.emitControlTransfer(crb, masm); - set.emitSecondPartOfDelayed(masm); + if (constantTableBase.equals(g0)) { + throw JVMCIError.shouldNotReachHere(); + } else { + Runnable recordReference = () -> crb.recordDataReferenceInCode(input, input.getKind().getByteCount()); + loadFromConstantTable(crb, masm, input.getKind(), constantTableBase, resultRegister, delaySlotLir, recordReference); + } } break; case Long: @@ -705,35 +749,25 @@ delaySlotLir.emitControlTransfer(crb, masm); masm.or(g0, (int) input.asLong(), resultRegister); } else { - Setx setx = new Setx(input.asLong(), resultRegister, false, true); - setx.emitFirstPartOfDelayed(masm); - delaySlotLir.emitControlTransfer(crb, masm); - setx.emitSecondPartOfDelayed(masm); + Runnable recordReference = () -> crb.asLongConstRef(input); + loadFromConstantTable(crb, masm, Long, constantTableBase, resultRegister, delaySlotLir, recordReference); } break; case Float: { float constant = input.asFloat(); int constantBits = java.lang.Float.floatToIntBits(constant); - if (constantBits == 0) { + if (hasVIS1 && constantBits == 0) { delaySlotLir.emitControlTransfer(crb, masm); masm.fzeros(resultRegister); } else { - if (hasVIS3) { - if (isSimm13(constantBits)) { - masm.or(g0, constantBits, scratch); - } else { - new Setx(constantBits, scratch, false).emit(masm); - } + if (hasVIS3 && isSimm13(constantBits)) { + masm.or(g0, constantBits, scratch); delaySlotLir.emitControlTransfer(crb, masm); - // Now load the float value masm.movwtos(scratch, resultRegister); } else { - crb.asFloatConstRef(input); + Runnable recordReference = () -> crb.asFloatConstRef(input); // First load the address into the scratch register - new Setx(0, scratch, true).emit(masm); - // Now load the float value - delaySlotLir.emitControlTransfer(crb, masm); - masm.ldf(new SPARCAddress(scratch, 0), resultRegister); + loadFromConstantTable(crb, masm, Float, constantTableBase, resultRegister, delaySlotLir, recordReference); } } break; @@ -741,26 +775,17 @@ case Double: { double constant = input.asDouble(); long constantBits = java.lang.Double.doubleToRawLongBits(constant); - if (constantBits == 0) { + if (hasVIS1 && constantBits == 0) { delaySlotLir.emitControlTransfer(crb, masm); masm.fzerod(resultRegister); } else { - if (hasVIS3) { - if (isSimm13(constantBits)) { - masm.or(g0, (int) constantBits, scratch); - } else { - new Setx(constantBits, scratch, false).emit(masm); - } + if (hasVIS3 && isSimm13(constantBits)) { + masm.or(g0, (int) constantBits, scratch); delaySlotLir.emitControlTransfer(crb, masm); - // Now load the float value masm.movxtod(scratch, resultRegister); } else { - crb.asDoubleConstRef(input); - // First load the address into the scratch register - new Setx(0, scratch, true).emit(masm); - delaySlotLir.emitControlTransfer(crb, masm); - // Now load the float value - masm.lddf(new SPARCAddress(scratch, 0), resultRegister); + Runnable recordReference = () -> crb.asDoubleConstRef(input); + loadFromConstantTable(crb, masm, Double, constantTableBase, resultRegister, delaySlotLir, recordReference); } } break; @@ -769,11 +794,9 @@ if (input.isNull()) { delaySlotLir.emitControlTransfer(crb, masm); masm.clr(resultRegister); - } else if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(input); // relocatable cannot be delayed - new Setx(0xDEADDEADDEADDEADL, resultRegister, true).emit(masm); } else { - throw JVMCIError.unimplemented(); + Runnable recordReference = () -> crb.recordDataReferenceInCode(input, 8); + loadFromConstantTable(crb, masm, Long, constantTableBase, resultRegister, delaySlotLir, recordReference); } break; default: @@ -798,8 +821,8 @@ } } - private static void emitLoad(SPARCAddress address, Value result, boolean signExtend, PlatformKind kind, SPARCDelayedControlTransfer delayedControlTransfer, LIRFrameState state, - CompilationResultBuilder crb, SPARCMacroAssembler masm) { + private static void emitLoad(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Value result, boolean signExtend, PlatformKind kind, + SPARCDelayedControlTransfer delayedControlTransfer, LIRFrameState state) { try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); final SPARCAddress addr = generateSimm13OffsetLoad(address, masm, scratch); @@ -856,7 +879,7 @@ } } - private static void emitStore(Value input, SPARCAddress address, PlatformKind kind, SPARCDelayedControlTransfer delayedControlTransfer, LIRFrameState state, CompilationResultBuilder crb, + public static void emitStore(Value input, SPARCAddress address, PlatformKind kind, SPARCDelayedControlTransfer delayedControlTransfer, LIRFrameState state, CompilationResultBuilder crb, SPARCMacroAssembler masm) { try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); @@ -894,4 +917,58 @@ } } } + + /** + * This method creates a load from the constant section. It automatically respects the different + * patterns used for small constant sections (<8k) and large constant sections (>=8k). The + * generated patterns by this method must be understood by + * CodeInstaller::pd_patch_DataSectionReference (jvmciCodeInstaller_sparc.cpp). + */ + public static void loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind kind, Register constantTableBase, Register dest, + SPARCDelayedControlTransfer delaySlotInstruction, Runnable recordReference) { + SPARCAddress address; + ScratchRegister scratch = null; + try { + if (masm.isImmediateConstantLoad()) { + address = new SPARCAddress(constantTableBase, 0); + // Make delayed only, when using immediate constant load. + delaySlotInstruction.emitControlTransfer(crb, masm); + recordReference.run(); + } else { + scratch = masm.getScratchRegister(); + Register sr = scratch.getRegister(); + recordReference.run(); + new Sethix(0, sr, true).emit(masm); + address = new SPARCAddress(sr, 0); + } + switch (kind) { + case Boolean: + case Byte: + masm.ldub(address, dest); + break; + case Short: + case Char: + masm.lduh(address, dest); + break; + case Int: + masm.lduw(address, dest); + break; + case Long: + masm.ldx(address, dest); + break; + case Float: + masm.ldf(address, dest); + break; + case Double: + masm.lddf(address, dest); + break; + default: + throw new InternalError("Unknown constant load kind: " + kind); + } + } finally { + if (scratch != null) { + scratch.close(); + } + } + } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.lir.sparc; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.lir.sparc.SPARCDelayedControlTransfer.*; import static jdk.internal.jvmci.code.ValueUtil.*; import java.util.*; @@ -43,6 +44,7 @@ public class SPARCSaveRegistersOp extends SPARCLIRInstruction implements SaveRegistersOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCSaveRegistersOp.class); public static final Register RETURN_REGISTER_STORAGE = SPARC.d62; + public static final SizeEstimate SIZE = SizeEstimate.create(32); /** * The registers (potentially) saved by this operation. */ @@ -66,18 +68,13 @@ * @param supportsRemove determines if registers can be {@linkplain #remove(Set) pruned} */ public SPARCSaveRegistersOp(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) { - super(TYPE); + super(TYPE, SIZE); assert Arrays.asList(savedRegisterLocations).stream().allMatch(ValueUtil::isVirtualStackSlot); this.savedRegisters = savedRegisters; this.slots = savedRegisterLocations; this.supportsRemove = supportsRemove; } - private static void saveRegister(CompilationResultBuilder crb, SPARCMacroAssembler masm, StackSlot result, Register register) { - RegisterValue input = register.asValue(result.getLIRKind()); - SPARCMove.move(crb, masm, result, input, SPARCDelayedControlTransfer.DUMMY); - } - @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Can be used with VIS3 @@ -92,7 +89,11 @@ for (int i = 0; i < savedRegisters.length; i++) { if (savedRegisters[i] != null) { assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i]; - saveRegister(crb, masm, asStackSlot(slots[i]), savedRegisters[i]); + Register savedRegister = savedRegisters[i]; + StackSlot slot = asStackSlot(slots[i]); + SPARCAddress slotAddress = (SPARCAddress) crb.asAddress(slot); + RegisterValue input = savedRegister.asValue(slot.getLIRKind()); + SPARCMove.emitStore(input, slotAddress, slot.getPlatformKind(), DUMMY, null, crb, masm); } } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -34,12 +34,13 @@ public class SPARCTestOp extends SPARCLIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCTestOp.class); + public static final SizeEstimate SIZE = SizeEstimate.create(1); @Use({REG}) protected Value x; @Use({REG, CONST}) protected Value y; public SPARCTestOp(Value x, Value y) { - super(TYPE); + super(TYPE, SIZE); this.x = x; this.y = y; } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Sat Jun 27 18:02:44 2015 +0200 @@ -265,6 +265,12 @@ instructions.set(index, replacement); } + public void remove(LIR lir) { + List instructions = lir.getLIRforBlock(block); + assert instructions.get(index).equals(this) : String.format("Removing the wrong instruction: %s instead of %s", instructions.get(index), this); + instructions.remove(index); + } + @Override public void emitCode(CompilationResultBuilder crb) { if (block != null) { diff -r 598c75a3d1d1 -r d9f3acb4a9a1 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Sat Jun 27 17:59:37 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Sat Jun 27 18:02:44 2015 +0200 @@ -25,6 +25,7 @@ import static jdk.internal.jvmci.code.ValueUtil.*; import java.util.*; +import java.util.function.*; import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.code.CompilationResult.*; @@ -88,6 +89,9 @@ private final IdentityHashMap dataCache; + private Consumer beforeOp; + private Consumer afterOp; + public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext, CompilationResult compilationResult) { this.target = codeCache.getTarget(); this.codeCache = codeCache; @@ -368,7 +372,13 @@ } try { + if (beforeOp != null) { + beforeOp.accept(op); + } emitOp(this, op); + if (afterOp != null) { + afterOp.accept(op); + } } catch (JVMCIError e) { throw e.addContext("lir instruction", block + "@" + op.id() + " " + op + "\n" + lir.codeEmittingOrder()); } @@ -395,4 +405,9 @@ dataCache.clear(); } } + + public void setOpCallback(Consumer beforeOp, Consumer afterOp) { + this.beforeOp = beforeOp; + this.afterOp = afterOp; + } } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 jvmci/jdk.internal.jvmci.hotspot.sparc/src/jdk/internal/jvmci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java --- a/jvmci/jdk.internal.jvmci.hotspot.sparc/src/jdk/internal/jvmci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Sat Jun 27 17:59:37 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot.sparc/src/jdk/internal/jvmci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Sat Jun 27 18:02:44 2015 +0200 @@ -43,7 +43,7 @@ protected TargetDescription createTarget(HotSpotVMConfig config) { final int stackFrameAlignment = 16; final int implicitNullCheckLimit = 4096; - final boolean inlineObjects = true; + final boolean inlineObjects = false; return new HotSpotTargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); } diff -r 598c75a3d1d1 -r d9f3acb4a9a1 src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp --- a/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Sat Jun 27 17:59:37 2015 +0200 +++ b/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Sat Jun 27 18:02:44 2015 +0200 @@ -66,12 +66,22 @@ void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) { address pc = _instructions->start() + pc_offset; - address const_start = _constants->start(); - address dest = _constants->start() + data_offset; - - _instructions->relocate(pc + NativeMovConstReg::sethi_offset, internal_word_Relocation::spec((address) dest)); - _instructions->relocate(pc + NativeMovConstReg::add_offset, internal_word_Relocation::spec((address) dest)); - TRACE_jvmci_3("relocating at %p with destination at %p (%d)", pc, dest, data_offset); + NativeInstruction* inst = nativeInstruction_at(pc); + NativeInstruction* inst1 = nativeInstruction_at(pc + 4); + if(inst->is_sethi() && inst1->is_nop()) { + address const_start = _constants->start(); + address dest = _constants->start() + data_offset; + if(_constants_size > 0) { + _instructions->relocate(pc + NativeMovConstReg::sethi_offset, internal_word_Relocation::spec((address) dest)); + _instructions->relocate(pc + NativeMovConstReg::add_offset, internal_word_Relocation::spec((address) dest)); + } + TRACE_jvmci_3("relocating at %p (+%d) with destination at %d", pc, pc_offset, data_offset); + } else { + NativeMovRegMem* load = nativeMovRegMem_at(pc); + // The base pointer is set 4k off (see SPARCLoadConstantTableBaseOp) + load->set_offset(data_offset - (1<<12)); + TRACE_jvmci_3("relocating ld at %p (+%d) with destination at %d", pc, pc_offset, data_offset); + } } void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {