# HG changeset patch # User Tom Rodriguez # Date 1426698467 25200 # Node ID f73a6e260e0c898e94526fa70f04020bed3eda36 # Parent 6a0692faf9fda6d343e188746958355d6dc5182c# Parent ed3e144ced296ad7f45719a842d9f957ab9b0441 Merge diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Wed Mar 18 10:07:47 2015 -0700 @@ -39,6 +39,9 @@ * patched. */ private static final SPARCAddress Placeholder = new SPARCAddress(g0, 0); + private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(g1), new ScratchRegister(g3)}; + // Points to the next free scratch register + private int nextFreeScratchRegister = 0; public SPARCMacroAssembler(TargetDescription target, RegisterConfig registerConfig) { super(target, registerConfig); @@ -389,4 +392,26 @@ public void signx(Register rd) { sra(rd, g0, rd); } + + public ScratchRegister getScratchRegister() { + return scratchRegister[nextFreeScratchRegister++]; + } + + public class ScratchRegister implements AutoCloseable { + private final Register register; + + public ScratchRegister(Register register) { + super(); + this.register = register; + } + + public Register getRegister() { + return register; + } + + public void close() { + assert nextFreeScratchRegister > 0 : "Close called too often"; + nextFreeScratchRegister--; + } + } } diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Wed Mar 18 10:07:47 2015 -0700 @@ -298,9 +298,6 @@ public static final OptionValue OptFloatingReads = new OptionValue<>(true); @Option(help = "", type = OptionType.Debug) - public static final OptionValue OptTailDuplication = new OptionValue<>(false); - - @Option(help = "", type = OptionType.Debug) public static final OptionValue OptEliminatePartiallyRedundantGuards = new OptionValue<>(true); @Option(help = "", type = OptionType.Debug) diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Wed Mar 18 10:07:47 2015 -0700 @@ -47,6 +47,7 @@ public FloatStamp(int bits, double lowerBound, double upperBound, boolean nonNaN) { super(bits, OPS); assert bits == 64 || (bits == 32 && (Double.isNaN(lowerBound) || (float) lowerBound == lowerBound) && (Double.isNaN(upperBound) || (float) upperBound == upperBound)); + assert Double.isNaN(lowerBound) == Double.isNaN(upperBound); this.lowerBound = lowerBound; this.upperBound = upperBound; this.nonNaN = nonNaN; @@ -130,6 +131,10 @@ return nonNaN; } + public boolean isNaN() { + return Double.isNaN(lowerBound); + } + public boolean isUnrestricted() { return lowerBound == Double.NEGATIVE_INFINITY && upperBound == Double.POSITIVE_INFINITY && !nonNaN; } @@ -629,6 +634,9 @@ @Override public Stamp foldStamp(Stamp s) { FloatStamp stamp = (FloatStamp) s; + if (stamp.isNaN()) { + return stamp; + } return new FloatStamp(stamp.getBits(), 0, Math.max(-stamp.lowerBound(), stamp.upperBound()), stamp.isNonNaN()); } }, @@ -666,8 +674,19 @@ @Override public Stamp foldStamp(Stamp stamp) { - assert stamp instanceof FloatStamp && ((FloatStamp) stamp).getBits() == 32; - return StampFactory.forKind(Kind.Int); + FloatStamp floatStamp = (FloatStamp) stamp; + assert floatStamp.getBits() == 32; + boolean mustHaveZero = !floatStamp.isNonNaN(); + int lowerBound = (int) floatStamp.lowerBound(); + int upperBound = (int) floatStamp.upperBound(); + if (mustHaveZero) { + if (lowerBound > 0) { + lowerBound = 0; + } else if (upperBound < 0) { + upperBound = 0; + } + } + return StampFactory.forInteger(Kind.Int, lowerBound, upperBound); } }, @@ -681,8 +700,19 @@ @Override public Stamp foldStamp(Stamp stamp) { - assert stamp instanceof FloatStamp && ((FloatStamp) stamp).getBits() == 32; - return StampFactory.forKind(Kind.Long); + FloatStamp floatStamp = (FloatStamp) stamp; + assert floatStamp.getBits() == 32; + boolean mustHaveZero = !floatStamp.isNonNaN(); + long lowerBound = (long) floatStamp.lowerBound(); + long upperBound = (long) floatStamp.upperBound(); + if (mustHaveZero) { + if (lowerBound > 0) { + lowerBound = 0; + } else if (upperBound < 0) { + upperBound = 0; + } + } + return StampFactory.forInteger(Kind.Long, lowerBound, upperBound); } }, @@ -696,8 +726,19 @@ @Override public Stamp foldStamp(Stamp stamp) { - assert stamp instanceof FloatStamp && ((FloatStamp) stamp).getBits() == 64; - return StampFactory.forKind(Kind.Int); + FloatStamp floatStamp = (FloatStamp) stamp; + assert floatStamp.getBits() == 64; + boolean mustHaveZero = !floatStamp.isNonNaN(); + int lowerBound = (int) floatStamp.lowerBound(); + int upperBound = (int) floatStamp.upperBound(); + if (mustHaveZero) { + if (lowerBound > 0) { + lowerBound = 0; + } else if (upperBound < 0) { + upperBound = 0; + } + } + return StampFactory.forInteger(Kind.Int, lowerBound, upperBound); } }, @@ -711,8 +752,19 @@ @Override public Stamp foldStamp(Stamp stamp) { - assert stamp instanceof FloatStamp && ((FloatStamp) stamp).getBits() == 64; - return StampFactory.forKind(Kind.Long); + FloatStamp floatStamp = (FloatStamp) stamp; + assert floatStamp.getBits() == 64; + boolean mustHaveZero = !floatStamp.isNonNaN(); + long lowerBound = (long) floatStamp.lowerBound(); + long upperBound = (long) floatStamp.upperBound(); + if (mustHaveZero) { + if (lowerBound > 0) { + lowerBound = 0; + } else if (upperBound < 0) { + upperBound = 0; + } + } + return StampFactory.forInteger(Kind.Long, lowerBound, upperBound); } }, @@ -726,8 +778,9 @@ @Override public Stamp foldStamp(Stamp stamp) { - assert stamp instanceof FloatStamp && ((FloatStamp) stamp).getBits() == 32; - return StampFactory.forKind(Kind.Double); + FloatStamp floatStamp = (FloatStamp) stamp; + assert floatStamp.getBits() == 32; + return StampFactory.forFloat(Kind.Double, floatStamp.lowerBound(), floatStamp.upperBound(), floatStamp.isNonNaN()); } }, @@ -741,8 +794,9 @@ @Override public Stamp foldStamp(Stamp stamp) { - assert stamp instanceof FloatStamp && ((FloatStamp) stamp).getBits() == 64; - return StampFactory.forKind(Kind.Float); + FloatStamp floatStamp = (FloatStamp) stamp; + assert floatStamp.getBits() == 64; + return StampFactory.forFloat(Kind.Float, (float) floatStamp.lowerBound(), (float) floatStamp.upperBound(), floatStamp.isNonNaN()); } }); } diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Wed Mar 18 10:07:47 2015 -0700 @@ -973,7 +973,9 @@ public Stamp foldStamp(Stamp input) { IntegerStamp stamp = (IntegerStamp) input; assert stamp.getBits() == 32; - return StampFactory.forKind(Kind.Float); + float lowerBound = stamp.lowerBound(); + float upperBound = stamp.upperBound(); + return StampFactory.forFloat(Kind.Float, lowerBound, upperBound, true); } }, @@ -989,7 +991,9 @@ public Stamp foldStamp(Stamp input) { IntegerStamp stamp = (IntegerStamp) input; assert stamp.getBits() == 64; - return StampFactory.forKind(Kind.Float); + float lowerBound = stamp.lowerBound(); + float upperBound = stamp.upperBound(); + return StampFactory.forFloat(Kind.Float, lowerBound, upperBound, true); } }, @@ -1005,7 +1009,9 @@ public Stamp foldStamp(Stamp input) { IntegerStamp stamp = (IntegerStamp) input; assert stamp.getBits() == 32; - return StampFactory.forKind(Kind.Double); + double lowerBound = stamp.lowerBound(); + double upperBound = stamp.upperBound(); + return StampFactory.forFloat(Kind.Double, lowerBound, upperBound, true); } }, @@ -1021,7 +1027,9 @@ public Stamp foldStamp(Stamp input) { IntegerStamp stamp = (IntegerStamp) input; assert stamp.getBits() == 64; - return StampFactory.forKind(Kind.Double); + double lowerBound = stamp.lowerBound(); + double upperBound = stamp.upperBound(); + return StampFactory.forFloat(Kind.Double, lowerBound, upperBound, true); } }); } diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Wed Mar 18 10:07:47 2015 -0700 @@ -75,10 +75,6 @@ appendPhase(new LoopFullUnrollPhase(canonicalizer)); } - if (OptTailDuplication.getValue()) { - appendPhase(new TailDuplicationPhase(canonicalizer)); - } - if (PartialEscapeAnalysis.getValue()) { appendPhase(new PartialEscapePhase(true, canonicalizer)); } diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Wed Mar 18 10:07:47 2015 -0700 @@ -40,6 +40,8 @@ @ServiceProvider(HotSpotBackendFactory.class) public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory { + private static final int PLUGIN_COUNT_ESTIMATE = 160; + protected Architecture createArchitecture(HotSpotVMConfig config) { return new AMD64(computeFeatures(config), computeFlags(config)); } @@ -171,7 +173,8 @@ wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); } try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { - plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch, + PLUGIN_COUNT_ESTIMATE); replacements.setGraphBuilderPlugins(plugins); } try (InitTimer rt = timer("create Suites provider")) { @@ -260,15 +263,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Mar 18 10:07:47 2015 -0700 @@ -38,6 +38,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.hotspot.*; @@ -52,7 +53,6 @@ import com.oracle.graal.lir.sparc.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.sparc.*; /** * HotSpot SPARC specific backend. @@ -113,7 +113,7 @@ if (SPARCAssembler.isSimm13(address.getDisplacement())) { masm.stx(g0, address); } else { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); new Setx(address.getDisplacement(), scratch).emit(masm); masm.stx(g0, new SPARCAddress(sp, scratch)); @@ -148,7 +148,7 @@ if (SPARCAssembler.isSimm13(stackpoinerChange)) { masm.save(sp, stackpoinerChange, sp); } else { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); new Setx(stackpoinerChange, scratch).emit(masm); masm.save(sp, scratch, sp); @@ -227,7 +227,7 @@ CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getProviders().getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false); Register inlineCacheKlass = g5; // see MacroAssembler::ic_call - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); Register receiver = asRegister(cc.getArgument(0)); SPARCAddress src = new SPARCAddress(receiver, config.hubOffset); @@ -261,7 +261,7 @@ if (unverifiedStub != null) { masm.bind(unverifiedStub); - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER)); } diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Wed Mar 18 10:07:47 2015 -0700 @@ -39,6 +39,8 @@ @ServiceProvider(HotSpotBackendFactory.class) public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory { + private static final int PLUGIN_COUNT_ESTIMATE = 155; + protected Architecture createArchitecture(HotSpotVMConfig config) { return new SPARC(computeFeatures(config)); } @@ -68,7 +70,8 @@ HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); - Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch, + PLUGIN_COUNT_ESTIMATE); replacements.setGraphBuilderPlugins(plugins); HotSpotSuitesProvider suites = createSuites(runtime, plugins); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection, diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCounterOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCounterOp.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCounterOp.java Wed Mar 18 10:07:47 2015 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; @@ -36,19 +37,12 @@ public class SPARCHotSpotCounterOp extends HotSpotCounterOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(SPARCHotSpotCounterOp.class); - @Temp({OperandFlag.REG}) private AllocatableValue scratch0; - @Temp({OperandFlag.REG}) private AllocatableValue scratch1; - - public SPARCHotSpotCounterOp(String name, String group, Value increment, HotSpotRegistersProvider registers, HotSpotVMConfig config, AllocatableValue scratch0, AllocatableValue scratch1) { + public SPARCHotSpotCounterOp(String name, String group, Value increment, HotSpotRegistersProvider registers, HotSpotVMConfig config) { super(TYPE, name, group, increment, registers, config); - this.scratch0 = scratch0; - this.scratch1 = scratch1; } - public SPARCHotSpotCounterOp(String[] names, String[] groups, Value[] increments, HotSpotRegistersProvider registers, HotSpotVMConfig config, AllocatableValue scratch0, AllocatableValue scratch1) { + public SPARCHotSpotCounterOp(String[] names, String[] groups, Value[] increments, HotSpotRegistersProvider registers, HotSpotVMConfig config) { super(TYPE, names, groups, increments, registers, config); - this.scratch0 = scratch0; - this.scratch1 = scratch1; } @Override @@ -58,27 +52,32 @@ // address for counters array SPARCAddress countersArrayAddr = new SPARCAddress(thread, config.graalCountersThreadOffset); - Register countersArrayReg = asRegister(scratch0); + try (ScratchRegister scratch = masm.getScratchRegister()) { + Register countersArrayReg = scratch.getRegister(); - // load counters array - masm.ldx(countersArrayAddr, countersArrayReg); + // load counters array + masm.ldx(countersArrayAddr, countersArrayReg); - forEachCounter((name, group, increment) -> emitIncrement(masm, target, countersArrayReg, name, group, increment)); + forEachCounter((name, group, increment) -> emitIncrement(masm, target, countersArrayReg, name, group, increment)); + } } private void emitIncrement(SPARCMacroAssembler masm, TargetDescription target, Register countersArrayReg, String name, String group, Value increment) { // address for counter SPARCAddress counterAddr = new SPARCAddress(countersArrayReg, getDisplacementForLongIndex(target, getIndex(name, group, increment))); - Register counterReg = asRegister(scratch1); - // load counter value - masm.ldx(counterAddr, counterReg); - // increment counter - if (isConstant(increment)) { - masm.add(counterReg, asInt(asConstant(increment)), counterReg); - } else { - masm.add(counterReg, asRegister(increment), counterReg); + + try (ScratchRegister scratch = masm.getScratchRegister()) { + Register counterReg = scratch.getRegister(); + // load counter value + masm.ldx(counterAddr, counterReg); + // increment counter + if (isConstant(increment)) { + masm.add(counterReg, asInt(asConstant(increment)), counterReg); + } else { + masm.add(counterReg, asRegister(increment), counterReg); + } + // store counter value + masm.stx(counterReg, counterAddr); } - // store counter value - masm.stx(counterReg, counterAddr); } } diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Wed Mar 18 10:07:47 2015 -0700 @@ -26,10 +26,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.sparc.*; /** * Removes the current frame and tail calls the uncommon trap routine. @@ -52,7 +52,7 @@ // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub); // frameContext.enter(crb); - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); SPARCCall.indirectJmp(crb, masm, scratch, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER)); } diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Wed Mar 18 10:07:47 2015 -0700 @@ -31,9 +31,9 @@ import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCAssembler.CC; import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -import com.oracle.graal.sparc.*; /** * Sets up the arguments for an exception handler in the callers frame, removes the current frame @@ -69,7 +69,7 @@ // Restore SP from L7 if the exception PC is a method handle call site. SPARCAddress dst = new SPARCAddress(thread, isMethodHandleReturnOffset); - try (SPARCScratchRegister scratch = SPARCScratchRegister.get()) { + try (ScratchRegister scratch = masm.getScratchRegister()) { Register scratchReg = scratch.getRegister(); masm.lduw(dst, scratchReg); masm.cmp(scratchReg, scratchReg); diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Mar 18 10:07:47 2015 -0700 @@ -49,7 +49,6 @@ import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp; import com.oracle.graal.lir.sparc.SPARCMove.StoreOp; -import com.oracle.graal.sparc.*; public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator { @@ -368,28 +367,18 @@ @Override public LIRInstruction createBenchmarkCounter(String name, String group, Value increment) { if (BenchmarkCounters.enabled) { - try (SPARCScratchRegister sc0 = SPARCScratchRegister.get()) { - RegisterValue scratch0 = sc0.getRegister().asValue(getLIRKindTool().getWordKind()); - try (SPARCScratchRegister sc1 = SPARCScratchRegister.get()) { - RegisterValue scratch1 = sc1.getRegister().asValue(getLIRKindTool().getWordKind()); - return new SPARCHotSpotCounterOp(name, group, increment, getProviders().getRegisters(), config, scratch0, scratch1); - } - } + return new SPARCHotSpotCounterOp(name, group, increment, getProviders().getRegisters(), config); + } else { + return null; } - return null; } @Override public LIRInstruction createMultiBenchmarkCounter(String[] names, String[] groups, Value[] increments) { if (BenchmarkCounters.enabled) { - try (SPARCScratchRegister sc0 = SPARCScratchRegister.get()) { - RegisterValue scratch0 = sc0.getRegister().asValue(getLIRKindTool().getWordKind()); - try (SPARCScratchRegister sc1 = SPARCScratchRegister.get()) { - RegisterValue scratch1 = sc1.getRegister().asValue(getLIRKindTool().getWordKind()); - return new SPARCHotSpotCounterOp(names, groups, increments, getProviders().getRegisters(), config, scratch0, scratch1); - } - } + return new SPARCHotSpotCounterOp(names, groups, increments, getProviders().getRegisters(), config); + } else { + return null; } - return null; } } diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Mar 18 10:07:47 2015 -0700 @@ -85,6 +85,8 @@ " dacapo = 'err, starting =====, PASSED in'%n" + " specjvm2008 = 'out,Iteration ~ (~s) begins:,Iteration ~ (~s) ends:'", type = OptionType.Debug) private static final OptionValue BenchmarkDynamicCounters = new OptionValue<>(null); + @Option(help = "Use grouping separators for number printing", type = OptionType.Debug) + private static final OptionValue DynamicCountersPrintGroupSeparator = new OptionValue<>(true); //@formatter:on } @@ -207,28 +209,29 @@ cnt--; } + String numFmt = Options.DynamicCountersPrintGroupSeparator.getValue() ? "%,19d" : "%19d"; if (staticCounter) { out.println("=========== " + group + " (static counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - out.format(Locale.US, "%,19d %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); + out.format(Locale.US, numFmt + " %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); } - out.format(Locale.US, "%,19d total\n", sum); + out.format(Locale.US, numFmt + " total\n", sum); } else { if (group.startsWith("~")) { out.println("=========== " + group + " (dynamic counters), time = " + seconds + " s:"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - out.format(Locale.US, "%,19d/s %3d%% %s\n", (long) (counter / seconds), percentage(counter, sum), entry.getValue()); + out.format(Locale.US, numFmt + "/s %3d%% %s\n", (long) (counter / seconds), percentage(counter, sum), entry.getValue()); } - out.format(Locale.US, "%,19d/s total\n", (long) (sum / seconds)); + out.format(Locale.US, numFmt + "/s total\n", (long) (sum / seconds)); } else { out.println("=========== " + group + " (dynamic counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - out.format(Locale.US, "%,19d %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); + out.format(Locale.US, numFmt + " %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); } - out.format(Locale.US, "%,19d total\n", sum); + out.format(Locale.US, numFmt + " total\n", sum); } } } diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Wed Mar 18 10:07:47 2015 -0700 @@ -109,15 +109,15 @@ } else if (n instanceof CheckCastDynamicNode) { checkcastDynamicSnippets.lower((CheckCastDynamicNode) n, tool); } else if (n instanceof InstanceOfNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + if (graph.getGuardsStage().areDeoptsFixed()) { instanceofSnippets.lower((InstanceOfNode) n, tool); } } else if (n instanceof InstanceOfDynamicNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + if (graph.getGuardsStage().areDeoptsFixed()) { instanceofSnippets.lower((InstanceOfDynamicNode) n, tool); } } else if (n instanceof ClassIsAssignableFromNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + if (graph.getGuardsStage().areDeoptsFixed()) { instanceofSnippets.lower((ClassIsAssignableFromNode) n, tool); } } else if (n instanceof NewInstanceNode) { diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Mar 18 10:07:47 2015 -0700 @@ -49,8 +49,6 @@ */ public class HotSpotGraphBuilderPlugins { - private static final int PLUGIN_COUNT_ESTIMATE = 160; - /** * Creates a {@link Plugins} object that should be used when running on HotSpot. * @@ -60,9 +58,9 @@ * @param stampProvider */ public static Plugins create(HotSpotVMConfig config, HotSpotWordTypes wordTypes, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, - SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider, ReplacementsImpl replacements, Architecture arch) { - - InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess, PLUGIN_COUNT_ESTIMATE); + SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider, ReplacementsImpl replacements, Architecture arch, + int pluginCountEstimate) { + InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess, pluginCountEstimate); Plugins plugins = new Plugins(invocationPlugins); NodeIntrinsificationPhase nodeIntrinsification = new NodeIntrinsificationPhase(metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider); @@ -81,8 +79,8 @@ StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, arch, invocationPlugins, !config.useHeapProfiler); int size = invocationPlugins.size(); - assert PLUGIN_COUNT_ESTIMATE >= size : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be above or equal to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); - assert PLUGIN_COUNT_ESTIMATE - size < 20 : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be closer to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); + assert pluginCountEstimate >= size : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be above or equal to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); + assert pluginCountEstimate - size < 20 : String.format("adjust %s.PLUGIN_COUNT_ESTIMATE to be closer to %d", HotSpotGraphBuilderPlugins.class.getSimpleName(), size); return plugins; } diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Wed Mar 18 10:07:47 2015 -0700 @@ -37,7 +37,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -371,7 +371,7 @@ masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IMULCC: - try (SPARCScratchRegister tmpScratch = SPARCScratchRegister.get()) { + try (ScratchRegister tmpScratch = masm.getScratchRegister()) { Register tmp = tmpScratch.getRegister(); masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)); Label noOverflow = new Label(); diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Wed Mar 18 10:07:47 2015 -0700 @@ -39,6 +39,7 @@ 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.SPARCMacroAssembler.ScratchRegister; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; @@ -47,7 +48,6 @@ import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure; import com.oracle.graal.lir.asm.*; import com.oracle.graal.sparc.SPARC.CPUFeature; -import com.oracle.graal.sparc.*; public class SPARCControlFlow { @@ -219,21 +219,14 @@ actualConditionFlag = actualConditionFlag.mirror(); } boolean isValidConstant = isConstant(actualY) && isSimm5(asConstant(actualY)); - SPARCScratchRegister scratch = null; - try { + try (ScratchRegister scratch = masm.getScratchRegister()) { if (isConstant(actualY) && !isValidConstant) { // Make sure, the y value is loaded - scratch = SPARCScratchRegister.get(); Value scratchValue = scratch.getRegister().asValue(actualY.getLIRKind()); SPARCMove.move(crb, masm, scratchValue, actualY, SPARCDelayedControlTransfer.DUMMY); actualY = scratchValue; } emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag); masm.nop(); - } finally { - if (scratch != null) { - // release the scratch if used - scratch.close(); - } } if (needJump) { masm.jmp(actualFalseTarget); @@ -481,14 +474,14 @@ if (isSimm13(lowKey)) { masm.sub(value, lowKey, scratchReg); } else { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch2 = sc.getRegister(); new Setx(lowKey, scratch2).emit(masm); masm.sub(value, scratch2, scratchReg); } } int upperLimit = highKey - lowKey; - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch2 = sc.getRegister(); if (isSimm13(upperLimit)) { masm.cmp(scratchReg, upperLimit); diff -r 6a0692faf9fd -r f73a6e260e0c 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 Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Wed Mar 18 10:07:47 2015 -0700 @@ -31,7 +31,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.ImplicitNullCheck; @@ -133,7 +133,7 @@ Kind inputKind = (Kind) input.getPlatformKind(); Kind resultKind = (Kind) result.getPlatformKind(); int resultKindSize = crb.target.getSizeInBytes(resultKind); - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); SPARCAddress tempAddress = generateSimm13OffsetLoad((SPARCAddress) crb.asAddress(temp), masm, scratch); switch (inputKind) { @@ -295,7 +295,7 @@ @Override public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); final SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch); final Register dst = asRegister(result); @@ -495,7 +495,7 @@ @Override public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) { assert isRegister(input); - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch); delayedControlTransfer.emitControlTransfer(crb, masm); @@ -548,7 +548,7 @@ @Override public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch); delayedControlTransfer.emitControlTransfer(crb, masm); @@ -604,7 +604,7 @@ if (constant.isDefaultForKind() || constant.isNull()) { reg2stack(crb, masm, result, g0.asValue(LIRKind.derive(input)), delaySlotLir); } else { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); long value = constant.asLong(); if (isSimm13(value)) { @@ -681,7 +681,7 @@ private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { SPARCAddress dst = (SPARCAddress) crb.asAddress(result); - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); dst = generateSimm13OffsetLoad(dst, masm, scratch); Register src = asRegister(input); @@ -716,7 +716,7 @@ private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { SPARCAddress src = (SPARCAddress) crb.asAddress(input); - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); src = generateSimm13OffsetLoad(src, masm, scratch); Register dst = asRegister(result); @@ -752,7 +752,7 @@ } private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, JavaConstant input, SPARCDelayedControlTransfer delaySlotLir) { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); boolean hasVIS3 = ((SPARC) masm.target.arch).getFeatures().contains(CPUFeature.VIS3); switch (input.getKind().getStackKind()) { diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Wed Mar 18 10:07:47 2015 -0700 @@ -79,6 +79,10 @@ public boolean areFrameStatesAtSideEffects() { return !this.areFrameStatesAtDeopts(); } + + public boolean areDeoptsFixed() { + return this.ordinal() >= FIXED_DEOPTS.ordinal(); + } } /** diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Mar 18 10:07:47 2015 -0700 @@ -260,7 +260,7 @@ canonical = ((BinaryCommutative) node).maybeCommuteInputs(); } } catch (Throwable e) { - throw Debug.handle(e); + throw new RuntimeException(e); } if (performReplacement(node, canonical)) { return true; diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Wed Mar 18 10:01:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,575 +0,0 @@ -/* - * Copyright (c) 2012, 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.phases.common; - -import static com.oracle.graal.compiler.common.GraalOptions.*; - -import java.util.*; -import java.util.function.*; - -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.graph.Graph.DuplicationReplacement; -import com.oracle.graal.graph.Graph.Mark; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.VirtualState.NodeClosure; -import com.oracle.graal.nodes.debug.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.graph.*; -import com.oracle.graal.phases.tiers.*; - -/** - * This class is a phase that looks for opportunities for tail duplication. The static method - * {@link #tailDuplicate(AbstractMergeNode, TailDuplicationDecision, List, PhaseContext, CanonicalizerPhase)} - * can also be used to drive tail duplication from other places, e.g., inlining. - */ -public class TailDuplicationPhase extends BasePhase { - - /* - * Various metrics on the circumstances in which tail duplication was/wasn't performed. - */ - private static final DebugMetric metricDuplicationConsidered = Debug.metric("DuplicationConsidered"); - private static final DebugMetric metricDuplicationPerformed = Debug.metric("DuplicationPerformed"); - - private final CanonicalizerPhase canonicalizer; - - @NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor}) - static final class DummyAnchorNode extends FixedWithNextNode implements GuardingNode, AnchoringNode { - public static final NodeClass TYPE = NodeClass.create(DummyAnchorNode.class); - - public DummyAnchorNode() { - super(TYPE, StampFactory.forVoid()); - } - - } - - /** - * This interface is used by tail duplication to let clients decide if tail duplication should - * be performed. - */ - public interface TailDuplicationDecision { - - /** - * Queries if tail duplication should be performed at the given merge. If this method - * returns true then the tail duplication will be performed, because all other checks have - * happened before. - * - * @param merge The merge at which tail duplication can be performed. - * @param fixedNodeCount The size of the set of fixed nodes that forms the base for the - * duplicated set of nodes. - * @return true if the tail duplication should be performed, false otherwise. - */ - boolean doTransform(AbstractMergeNode merge, int fixedNodeCount); - } - - /** - * A tail duplication decision closure that employs the default algorithm: Check if there are - * any phis on the merge whose stamps improve and that have usages within the duplicated set of - * fixed nodes. - */ - public static final TailDuplicationDecision DEFAULT_DECISION = new TailDuplicationDecision() { - - public boolean doTransform(AbstractMergeNode merge, int fixedNodeCount) { - if (fixedNodeCount < TailDuplicationTrivialSize.getValue()) { - return true; - } - ArrayList improvements = null; - for (PhiNode phi : merge.phis()) { - Stamp phiStamp = phi.stamp(); - for (ValueNode input : phi.values()) { - if (!input.stamp().equals(phiStamp)) { - if (improvements == null) { - improvements = new ArrayList<>(); - } - if (!improvements.contains(phi)) { - improvements.add(phi); - } - break; - } - } - } - if (improvements == null) { - return false; - } - FixedNode current = merge; - int opportunities = 0; - while (current instanceof FixedWithNextNode) { - current = ((FixedWithNextNode) current).next(); - if (current instanceof VirtualizableAllocation) { - return false; - } - for (PhiNode phi : improvements) { - for (Node input : current.inputs()) { - if (input == phi) { - opportunities++; - } - if (input.inputs().contains(phi)) { - opportunities++; - } - } - } - } - return opportunities > 0; - } - }; - - /** - * A tail duplication decision closure that always returns true. - */ - public static final TailDuplicationDecision TRUE_DECISION = new TailDuplicationDecision() { - - @Override - public boolean doTransform(AbstractMergeNode merge, int fixedNodeCount) { - return true; - } - }; - - public TailDuplicationPhase(CanonicalizerPhase canonicalizer) { - this.canonicalizer = canonicalizer; - } - - @Override - protected void run(StructuredGraph graph, PhaseContext phaseContext) { - if (graph.hasNode(AbstractMergeNode.TYPE)) { - ToDoubleFunction nodeProbabilities = new FixedNodeProbabilityCache(); - - // A snapshot is taken here, so that new MergeNode instances aren't considered for tail - // duplication. - for (AbstractMergeNode merge : graph.getNodes(AbstractMergeNode.TYPE).snapshot()) { - if (!(merge instanceof LoopBeginNode) && nodeProbabilities.applyAsDouble(merge) >= TailDuplicationProbability.getValue()) { - tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext, canonicalizer); - } - } - } - } - - /** - * This method attempts to duplicate the tail of the given merge. The merge must not be a - * {@link LoopBeginNode}. If the merge is eligible for duplication (at least one fixed node in - * its tail, no {@link MonitorEnterNode}/ {@link MonitorExitNode}, non-null - * {@link AbstractMergeNode#stateAfter()}) then the decision callback is used to determine - * whether the tail duplication should actually be performed. If replacements is non-null, then - * this list of {@link PiNode}s is used to replace one value per merge end. - * - * @param merge The merge whose tail should be duplicated. - * @param decision A callback that can make the final decision if tail duplication should occur - * or not. - * @param replacements A list of {@link PiNode}s, or null. If this list is non-null then its - * size needs to match the merge's end count. Each entry can either be null or a - * {@link PiNode}, and is used to replace {@link PiNode#object()} with the - * {@link PiNode} in the duplicated branch that corresponds to the entry. - * @param phaseContext - */ - public static boolean tailDuplicate(AbstractMergeNode merge, TailDuplicationDecision decision, List replacements, PhaseContext phaseContext, CanonicalizerPhase canonicalizer) { - assert !(merge instanceof LoopBeginNode); - assert replacements == null || replacements.size() == merge.forwardEndCount(); - FixedNode fixed = merge; - int fixedCount = 0; - while (fixed instanceof FixedWithNextNode) { - fixed = ((FixedWithNextNode) fixed).next(); - if (fixed instanceof CommitAllocationNode || fixed instanceof ControlFlowAnchorNode) { - return false; - } - fixedCount++; - } - if (fixedCount > 1) { - metricDuplicationConsidered.increment(); - if (decision.doTransform(merge, fixedCount)) { - metricDuplicationPerformed.increment(); - new DuplicationOperation(merge, replacements, canonicalizer).duplicate(phaseContext); - return true; - } - } - return false; - } - - /** - * This class encapsulates one tail duplication operation on a specific - * {@link AbstractMergeNode}. - */ - private static class DuplicationOperation { - - private final AbstractMergeNode merge; - private final StructuredGraph graph; - - private final Map bottomPhis = Node.newMap(); - private final List replacements; - - private final CanonicalizerPhase canonicalizer; - - /** - * Initializes the tail duplication operation without actually performing any work. - * - * @param merge The merge whose tail should be duplicated. - * @param replacements A list of replacement {@link PiNode}s, or null. If this is non-null, - * then the size of the list needs to match the number of end nodes at the merge. - */ - public DuplicationOperation(AbstractMergeNode merge, List replacements, CanonicalizerPhase canonicalizer) { - this.merge = merge; - this.replacements = replacements; - this.graph = merge.graph(); - this.canonicalizer = canonicalizer; - } - - /** - * Performs the actual tail duplication: - *
    - *
  • Creates a new {@link ValueAnchorNode} at the beginning of the duplicated area, an - * transfers all dependencies from the merge to this anchor.
  • - *
  • Determines the set of fixed nodes to be duplicated.
  • - *
  • Creates the new merge at the bottom of the duplicated area.
  • - *
  • Determines the complete set of duplicated nodes.
  • - *
  • Performs the actual duplication.
  • - *
- * - * @param phaseContext - */ - private void duplicate(PhaseContext phaseContext) { - Debug.log("tail duplication at merge %s in %s", merge, graph.method()); - - Mark startMark = graph.getMark(); - - DummyAnchorNode anchor = addValueAnchor(); - - // determine the fixed nodes that should be duplicated (currently: all nodes up until - // the first control - // split, end node, deopt or return. - ArrayList fixedNodes = new ArrayList<>(); - FixedNode fixed = merge.next(); - FrameState stateAfter = merge.stateAfter(); - while (fixed instanceof FixedWithNextNode) { - fixedNodes.add(fixed); - if (fixed instanceof StateSplit && ((StateSplit) fixed).stateAfter() != null) { - stateAfter = ((StateSplit) fixed).stateAfter(); - } - fixed = ((FixedWithNextNode) fixed).next(); - } - - AbstractEndNode endAfter = createNewMerge(fixed, stateAfter); - AbstractMergeNode mergeAfter = endAfter.merge(); - fixedNodes.add(endAfter); - final Set duplicatedNodes = buildDuplicatedNodeSet(fixedNodes, stateAfter); - mergeAfter.clearEnds(); - expandDuplicated(duplicatedNodes, mergeAfter); - - List endSnapshot = merge.forwardEnds().snapshot(); - List phiSnapshot = merge.phis().snapshot(); - - int endIndex = 0; - for (final EndNode forwardEnd : merge.forwardEnds()) { - Map duplicates; - if (replacements == null || replacements.get(endIndex) == null) { - duplicates = graph.addDuplicates(duplicatedNodes, graph, duplicatedNodes.size(), (DuplicationReplacement) null); - } else { - Map replace = Node.newMap(); - replace.put(replacements.get(endIndex).object(), replacements.get(endIndex)); - duplicates = graph.addDuplicates(duplicatedNodes, graph, duplicatedNodes.size(), replace); - } - for (Map.Entry phi : bottomPhis.entrySet()) { - phi.getValue().initializeValueAt(merge.forwardEndIndex(forwardEnd), (ValueNode) duplicates.get(phi.getKey())); - } - mergeAfter.addForwardEnd((EndNode) duplicates.get(endAfter)); - - // re-wire the duplicated ValueAnchorNode to the predecessor of the corresponding - // EndNode - FixedWithNextNode anchorDuplicate = (FixedWithNextNode) duplicates.get(anchor); - // move dependencies on the ValueAnchorNode to the previous BeginNode - AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(forwardEnd); - anchorDuplicate.replaceAtUsages(InputType.Guard, prevBegin); - anchorDuplicate.replaceAtUsages(InputType.Anchor, prevBegin); - assert anchorDuplicate.hasNoUsages(); - - FixedNode next = anchorDuplicate.next(); - anchorDuplicate.setNext(null); - ((FixedWithNextNode) forwardEnd.predecessor()).setNext(next); - anchorDuplicate.safeDelete(); - - // re-wire the phi duplicates to the correct input - for (PhiNode phi : phiSnapshot) { - PhiNode phiDuplicate = (PhiNode) duplicates.get(phi); - phiDuplicate.replaceAtUsages(phi.valueAt(forwardEnd)); - phiDuplicate.safeDelete(); - } - endIndex++; - } - GraphUtil.killCFG(merge); - for (AbstractEndNode forwardEnd : endSnapshot) { - forwardEnd.safeDelete(); - } - for (PhiNode phi : phiSnapshot) { - // these phis should go away, but they still need to be anchored to a merge to be - // valid... - if (phi.isAlive()) { - phi.setMerge(mergeAfter); - } - } - canonicalizer.applyIncremental(graph, phaseContext, startMark); - Debug.dump(graph, "After tail duplication at %s", merge); - } - - /** - * Inserts a new ValueAnchorNode after the merge and transfers all dependency-usages (not - * phis) to this ValueAnchorNode. - * - * @return The new {@link ValueAnchorNode} that was created. - */ - private DummyAnchorNode addValueAnchor() { - DummyAnchorNode anchor = graph.add(new DummyAnchorNode()); - graph.addAfterFixed(merge, anchor); - merge.replaceAtUsages(InputType.Guard, anchor); - merge.replaceAtUsages(InputType.Anchor, anchor); - return anchor; - } - - /** - * Given a set of fixed nodes, this method determines the set of fixed and floating nodes - * that needs to be duplicated, i.e., all nodes that due to data flow and other dependencies - * needs to be duplicated. - * - * @param fixedNodes The set of fixed nodes that should be duplicated. - * @param stateAfter The frame state of the merge that follows the set of fixed nodes. All - * {@link ValueNode}s reachable from this state are considered to be reachable - * from within the duplicated set of nodes. - * @return The set of nodes that need to be duplicated. - */ - private Set buildDuplicatedNodeSet(final ArrayList fixedNodes, FrameState stateAfter) { - final NodeBitMap aboveBound = graph.createNodeBitMap(); - final NodeBitMap belowBound = graph.createNodeBitMap(); - - final Deque worklist = new ArrayDeque<>(); - - // Build the set of nodes that have (transitive) usages within the duplicatedNodes. - // This is achieved by iterating all nodes that are reachable via inputs from the the - // fixed nodes. - aboveBound.markAll(fixedNodes); - worklist.addAll(fixedNodes); - - // the phis at the original merge should always be duplicated - for (PhiNode phi : merge.phis()) { - aboveBound.mark(phi); - worklist.add(phi); - } - - NodeClosure aboveClosure = new NodeClosure() { - - @Override - public void apply(Node usage, Node node) { - if (node instanceof PhiNode && !fixedNodes.contains(((PhiNode) node).merge())) { - // stop iterating: phis belonging to outside merges are known to be outside. - } else if (node instanceof FixedNode) { - // stop iterating: fixed nodes within the given set are traversal roots - // anyway, and all other - // fixed nodes are known to be outside. - } else if (!aboveBound.isMarked(node)) { - worklist.add(node); - aboveBound.mark(node); - } - } - }; - - if (stateAfter != null) { - stateAfter.applyToNonVirtual(aboveClosure); - } - while (!worklist.isEmpty()) { - Node current = worklist.remove(); - for (Node input : current.inputs()) { - aboveClosure.apply(current, input); - } - } - - // Build the set of nodes that have (transitive) inputs within the duplicatedNodes. - // This is achieved by iterating all nodes that are reachable via usages from the fixed - // nodes. - belowBound.markAll(fixedNodes); - worklist.addAll(fixedNodes); - - // the phis at the original merge should always be duplicated - for (PhiNode phi : merge.phis()) { - belowBound.mark(phi); - worklist.add(phi); - } - - while (!worklist.isEmpty()) { - Node current = worklist.remove(); - for (Node usage : current.usages()) { - if (usage instanceof PhiNode && !fixedNodes.contains(((PhiNode) usage).merge())) { - // stop iterating: phis belonging to outside merges are known to be outside. - } else if (usage instanceof FixedNode) { - // stop iterating: fixed nodes within the given set are traversal roots - // anyway, and all other - // fixed nodes are known to be outside. - } else if (!belowBound.isMarked(usage)) { - worklist.add(usage); - belowBound.mark(usage); - } - } - } - - // build the intersection - belowBound.intersect(aboveBound); - Set result = Node.newSet(); - for (Node node : belowBound) { - result.add(node); - } - return result; - } - - /** - * Creates a new merge and end node construct at the end of the duplicated area. While it is - * useless in itself (merge with only one end) it simplifies the later duplication step. - * - * @param successor The successor of the duplicated set of nodes, i.e., the first node that - * should not be duplicated. - * @param stateAfterMerge The frame state that should be used for the merge. - * @return The newly created end node. - */ - private AbstractEndNode createNewMerge(FixedNode successor, FrameState stateAfterMerge) { - MergeNode newBottomMerge = graph.add(new MergeNode()); - EndNode newBottomEnd = graph.add(new EndNode()); - newBottomMerge.addForwardEnd(newBottomEnd); - newBottomMerge.setStateAfter(stateAfterMerge); - ((FixedWithNextNode) successor.predecessor()).setNext(newBottomEnd); - newBottomMerge.setNext(successor); - return newBottomEnd; - } - - /** - * Expands the set of nodes to be duplicated by looking at a number of conditions: - *
    - *
  • Inputs of type {@link InputType#Value} into the duplicated set will be rerouted to a - * new phi node.
  • - *
  • Inputs of type {@link InputType#Association}, {@link InputType#Condition} and - * {@link InputType#State} into the duplicated set will be rerouted to a duplicated version - * of the inside node.
  • - *
  • Dependencies into the duplicated nodes will be replaced with dependencies on the - * merge.
  • - *
  • Inputs of type {@link InputType#Association}, {@link InputType#Condition} and - * {@link InputType#State} to outside the duplicated set will cause the outside node to be - * pulled into the duplicated set.
  • - *
- * - * @param duplicatedNodes The set of duplicated nodes that will be modified (expanded). - * @param newBottomMerge The merge that follows the duplicated set of nodes. It will be used - * for newly created phis and to as a target for dependencies that pointed into - * the duplicated set of nodes. - */ - private void expandDuplicated(Set duplicatedNodes, AbstractMergeNode newBottomMerge) { - Deque worklist = new ArrayDeque<>(duplicatedNodes); - - while (!worklist.isEmpty()) { - Node duplicated = worklist.remove(); - processUsages(duplicated, duplicatedNodes, newBottomMerge, worklist); - processInputs(duplicated, duplicatedNodes, worklist); - } - } - - private void processUsages(Node duplicated, Set duplicatedNodes, AbstractMergeNode newBottomMerge, Deque worklist) { - Set unique = Node.newSet(); - duplicated.usages().snapshotTo(unique); - Node newOutsideClone = null; - for (Node usage : unique) { - if (!duplicatedNodes.contains(usage)) { - NodePosIterator iter = usage.inputs().iterator(); - while (iter.hasNext()) { - Position pos = iter.nextPosition(); - if (pos.get(usage) == duplicated) { - switch (pos.getInputType()) { - case Extension: - case Condition: - case State: - // clone the offending node to the outside - if (newOutsideClone == null) { - newOutsideClone = duplicated.copyWithInputs(); - // this might cause other nodes to have outside usages - for (Node input : newOutsideClone.inputs()) { - if (duplicatedNodes.contains(input)) { - worklist.add(input); - } - } - } - pos.set(usage, newOutsideClone); - break; - case Guard: - case Anchor: - // re-route dependencies to the merge - pos.set(usage, newBottomMerge); - break; - case Value: - // introduce a new phi - ValueNode node = (ValueNode) duplicated; - PhiNode newPhi = bottomPhis.get(node); - if (newPhi == null) { - newPhi = graph.addWithoutUnique(new ValuePhiNode(node.stamp().unrestricted(), newBottomMerge)); - bottomPhis.put(node, newPhi); - newPhi.addInput(node); - } - pos.set(usage, newPhi); - break; - case Association: - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - } - } - } - } - - private void processInputs(Node duplicated, Set duplicatedNodes, Deque worklist) { - // check if this node has an input that lies outside and cannot be shared - NodePosIterator iter = duplicated.inputs().iterator(); - while (iter.hasNext()) { - Position pos = iter.nextPosition(); - Node input = pos.get(duplicated); - if (input != null && !duplicatedNodes.contains(input)) { - switch (pos.getInputType()) { - case Extension: - case Condition: - case State: - if (input != merge) { - duplicatedNodes.add(input); - worklist.add(input); - } - break; - case Association: - case Guard: - case Anchor: - case Value: - // no change needed - break; - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - } - } - } -} diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Wed Mar 18 10:07:47 2015 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.phases.common.inlining.info; -import static com.oracle.graal.compiler.common.GraalOptions.*; - import java.util.*; import com.oracle.graal.api.meta.*; @@ -39,10 +37,8 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.common.inlining.info.elem.*; -import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; /** @@ -52,8 +48,6 @@ */ public class MultiTypeGuardInlineInfo extends AbstractInlineInfo { - private static final DebugMetric metricInliningTailDuplication = Debug.metric("InliningTailDuplication"); - private final List concretes; private final double[] methodProbabilities; private final double maximumMethodProbability; @@ -170,7 +164,6 @@ int numberOfMethods = concretes.size(); FixedNode continuation = invoke.next(); - ValueNode originalReceiver = ((MethodCallTargetNode) invoke.callTarget()).receiver(); // setup merge and phi nodes for results and exceptions AbstractMergeNode returnMerge = graph.add(new MergeNode()); returnMerge.setStateAfter(invoke.stateAfter()); @@ -257,35 +250,6 @@ replacementNodes.add(null); } - if (OptTailDuplication.getValue()) { - /* - * We might want to perform tail duplication at the merge after a type switch, if there - * are invokes that would benefit from the improvement in type information. - */ - FixedNode current = returnMerge; - int opportunities = 0; - do { - if (current instanceof InvokeNode && ((InvokeNode) current).callTarget() instanceof MethodCallTargetNode && - ((MethodCallTargetNode) ((InvokeNode) current).callTarget()).receiver() == originalReceiver) { - opportunities++; - } else if (current.inputs().contains(originalReceiver)) { - opportunities++; - } - current = ((FixedWithNextNode) current).next(); - } while (current instanceof FixedWithNextNode); - - if (opportunities > 0) { - metricInliningTailDuplication.increment(); - Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities); - PhaseContext phaseContext = new PhaseContext(providers); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); - if (ImmutableCode.getValue()) { - canonicalizer.disableReadCanonicalization(); - } - TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer); - } - } - Collection canonicalizeNodes = new ArrayList<>(); // do the actual inlining for every invoke for (int i = 0; i < numberOfMethods; i++) { diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java --- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java Wed Mar 18 10:01:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.sparc; - -import com.oracle.graal.api.code.*; - -public final class SPARCScratchRegister implements AutoCloseable { - private final ThreadLocal locked = new ThreadLocal<>(); - private final ThreadLocal where = new ThreadLocal<>(); - private final Register register; - private static final SPARCScratchRegister scratch1 = new SPARCScratchRegister(SPARC.g3); - private static final SPARCScratchRegister scratch2 = new SPARCScratchRegister(SPARC.g1); - private static final boolean LOG_REQUEST_STACK = false; - - private SPARCScratchRegister(Register register) { - super(); - this.register = register; - } - - public Register getRegister() { - if (locked.get() == null) { - locked.set(false); - } - boolean isLocked = locked.get(); - if (isLocked) { - if (LOG_REQUEST_STACK) { - where.get().printStackTrace(); - } - throw new RuntimeException("Temp Register is already taken!"); - } else { - if (LOG_REQUEST_STACK) { - where.set(new Exception()); - } - locked.set(true); - return register; - } - } - - public void close() { - boolean isLocked = locked.get(); - if (isLocked) { - locked.set(false); - } else { - throw new RuntimeException("Temp Register is not taken!"); - } - } - - public static SPARCScratchRegister get() { - if (scratch1.isLocked()) { - return scratch2; - } else { - return scratch1; - } - } - - public boolean isLocked() { - Boolean isLocked = locked.get(); - if (isLocked == null) { - return false; - } else { - return isLocked; - } - } -} diff -r 6a0692faf9fd -r f73a6e260e0c graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java --- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Wed Mar 18 10:01:25 2015 -0700 +++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Wed Mar 18 10:07:47 2015 -0700 @@ -35,11 +35,11 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.framemap.*; -import com.oracle.graal.sparc.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.hotspot.*; @@ -53,7 +53,7 @@ protected void injectTailCallCode(HotSpotVMConfig config, HotSpotRegistersProvider registers) { @SuppressWarnings("hiding") SPARCMacroAssembler asm = (SPARCMacroAssembler) this.asm; - try (SPARCScratchRegister scratch = SPARCScratchRegister.get()) { + try (ScratchRegister scratch = asm.getScratchRegister()) { Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(JavaCall, Object)[0]; Register spillRegister = scratch.getRegister(); Label doProlog = new Label();