Mercurial > hg > truffle
changeset 17207:5a7b82c1514e
[SPARC] Add functionality to be able to do assembly in two passes (knowing offsets of forward branches)
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Wed Sep 24 16:13:34 2014 -0700 @@ -785,4 +785,14 @@ public String getName() { return name; } + + public void reset() { + infopoints.clear(); + dataReferences.clear(); + exceptionHandlers.clear(); + marks.clear(); + if (annotations != null) { + annotations.clear(); + } + } }
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Wed Sep 24 16:13:34 2014 -0700 @@ -687,6 +687,9 @@ public void setDisp10(int disp10) { this.disp10 = disp10 >> 2; + if (!isSimm10(this.disp10)) { + throw GraalInternalError.shouldNotReachHere("" + this.disp10); + } assert isSimm10(this.disp10) : this.disp10; } @@ -2273,7 +2276,11 @@ } public static boolean isSimm11(Constant constant) { - return isSimm11(constant.asLong()); + return constant.isNull() || isSimm11(constant.asLong()); + } + + public static boolean isSimm5(Constant constant) { + return constant.isNull() || isSimm(constant.asLong(), 5); } public static boolean isSimm13(int imm) { @@ -2426,6 +2433,12 @@ /* VIS1 only */ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Array8, src1, src2, dst); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS1); + super.emit(masm); + } } public static class Array16 extends Fmt3p { @@ -2434,6 +2447,12 @@ /* VIS1 only */ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Array16, src1, src2, dst); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS1); + super.emit(masm); + } } public static class Array32 extends Fmt3p { @@ -2442,6 +2461,12 @@ /* VIS1 only */ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Array32, src1, src2, dst); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS2); + super.emit(masm); + } } public static class Bmask extends Fmt3p { @@ -2450,6 +2475,12 @@ /* VIS2 only */ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Bmask, src1, src2, dst); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS2); + super.emit(masm); + } } public static class Movwtos extends Fmt3p { @@ -2458,6 +2489,12 @@ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movwtos, g0, src, dst); assert isSingleFloatRegister(dst); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS3); + super.emit(masm); + } } public static class Umulxhi extends Fmt3p { @@ -2465,6 +2502,12 @@ /* VIS3 only */ super(Ops.ArithOp, Op3s.Impdep1, Opfs.UMulxhi, src1, src2, dst); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS3); + super.emit(masm); + } } public static class Movxtod extends Fmt3p { @@ -2473,6 +2516,12 @@ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movxtod, g0, src, dst); assert isDoubleFloatRegister(dst); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS3); + super.emit(masm); + } } public static class Movdtox extends Fmt3p { @@ -2481,6 +2530,12 @@ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movdtox, g0, src, dst); assert isDoubleFloatRegister(src); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS3); + super.emit(masm); + } } public static class Movstosw extends Fmt3p { @@ -2489,6 +2544,12 @@ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movstosw, g0, src, dst); assert isSingleFloatRegister(src); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS3); + super.emit(masm); + } } public static class Movstouw extends Fmt3p { @@ -2497,11 +2558,16 @@ super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movstouw, g0, src, dst); assert isSingleFloatRegister(src); } + + @Override + public void emit(SPARCAssembler masm) { + assert masm.hasFeature(CPUFeature.VIS3); + super.emit(masm); + } } public static class Fdtos extends Fmt3p { public Fdtos(Register src, Register dst) { - /* VIS3 only */ super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdtos, g0, src, dst); assert isSingleFloatRegister(dst); assert isDoubleFloatRegister(src);
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java Wed Sep 24 16:13:34 2014 -0700 @@ -33,6 +33,7 @@ public abstract class Assembler { public final TargetDescription target; + private Set<LabelHint> jumpDisplacementHints; /** * Backing code buffer. @@ -50,7 +51,7 @@ /** * Returns the current position of the underlying code buffer. - * + * * @return current position in code buffer */ public int position() { @@ -123,7 +124,7 @@ /** * Closes this assembler. No extra data can be written to this assembler after this call. - * + * * @param trimmedCopy if {@code true}, then a copy of the underlying byte array up to (but not * including) {@code position()} is returned * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} is {@code true} @@ -148,7 +149,7 @@ /** * Creates a name for a label. - * + * * @param l the label for which a name is being created * @param id a label identifier that is unique with the scope of this assembler * @return a label name in the form of "L123" @@ -188,4 +189,59 @@ * Emits a NOP instruction to advance the current PC. */ public abstract void ensureUniquePC(); + + public void reset() { + codeBuffer.reset(); + captureLabelPositions(); + } + + private void captureLabelPositions() { + if (jumpDisplacementHints == null) { + return; + } + for (LabelHint request : this.jumpDisplacementHints) { + request.capture(); + } + } + + public LabelHint requestLabelHint(Label label) { + if (jumpDisplacementHints == null) { + jumpDisplacementHints = new HashSet<>(); + } + LabelHint hint = new LabelHint(label, position()); + this.jumpDisplacementHints.add(hint); + return hint; + } + + public static class LabelHint { + private Label label; + private int forPosition; + private int capturedTarget; + private boolean captured = false; + + protected LabelHint(Label label, int lastPosition) { + super(); + this.label = label; + this.forPosition = lastPosition; + } + + protected void capture() { + this.capturedTarget = label.position(); + this.captured = true; + } + + public int getTarget() { + assert isValid(); + return capturedTarget; + } + + public int getPosition() { + assert isValid(); + return forPosition; + } + + public boolean isValid() { + return captured; + } + } }
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java Wed Sep 24 16:13:34 2014 -0700 @@ -232,4 +232,8 @@ return (data[pos + 3] & 0xff) << 24 | (data[pos + 2] & 0xff) << 16 | (data[pos + 1] & 0xff) << 8 | (data[pos + 0] & 0xff) << 0; } } + + public void reset() { + position = 0; + } }
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java Wed Sep 24 16:13:34 2014 -0700 @@ -40,7 +40,7 @@ /** * Returns the position of this label in the code buffer. - * + * * @return the position */ public int position() { @@ -61,7 +61,7 @@ /** * Binds the label to the specified position. - * + * * @param pos the position */ protected void bind(int pos) { @@ -92,6 +92,13 @@ } } + public void reset() { + if (this.patchPositions != null) { + this.patchPositions.clear(); + } + this.position = -1; + } + @Override public String toString() { return isBound() ? String.valueOf(position()) : "?";
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Sep 24 16:13:34 2014 -0700 @@ -215,32 +215,40 @@ HotSpotVMConfig config = getRuntime().getConfig(); Label unverifiedStub = installedCodeOwner == null || installedCodeOwner.isStatic() ? null : new Label(); - // Emit the prefix + int i = 0; + do { + if (i > 0) { + crb.reset(); + lir.resetLabels(); + resetDelayedControlTransfers(lir); + } - if (unverifiedStub != null) { - MarkId.recordMark(crb, MarkId.UNVERIFIED_ENTRY); - // We need to use JavaCall here because we haven't entered the frame yet. - 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()) { - Register scratch = sc.getRegister(); - Register receiver = asRegister(cc.getArgument(0)); - SPARCAddress src = new SPARCAddress(receiver, config.hubOffset); + // Emit the prefix + if (unverifiedStub != null) { + MarkId.recordMark(crb, MarkId.UNVERIFIED_ENTRY); + // We need to use JavaCall here because we haven't entered the frame yet. + CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getProviders().getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false); + Register inlineCacheKlass = g5; // see MacroAssembler::ic_call - new Ldx(src, scratch).emit(masm); - new Cmp(scratch, inlineCacheKlass).emit(masm); - } - new Bpne(CC.Xcc, unverifiedStub).emit(masm); - new Nop().emit(masm); // delay slot - } + try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + Register scratch = sc.getRegister(); + Register receiver = asRegister(cc.getArgument(0)); + SPARCAddress src = new SPARCAddress(receiver, config.hubOffset); - masm.align(config.codeEntryAlignment); - MarkId.recordMark(crb, MarkId.OSR_ENTRY); - MarkId.recordMark(crb, MarkId.VERIFIED_ENTRY); + new Ldx(src, scratch).emit(masm); + new Cmp(scratch, inlineCacheKlass).emit(masm); + } + new Bpne(CC.Xcc, unverifiedStub).emit(masm); + new Nop().emit(masm); // delay slot + } - // Emit code for the LIR - crb.emit(lir); + masm.align(config.codeEntryAlignment); + MarkId.recordMark(crb, MarkId.OSR_ENTRY); + MarkId.recordMark(crb, MarkId.VERIFIED_ENTRY); + + // Emit code for the LIR + crb.emit(lir); + } while (i++ < 1); HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext; HotSpotForeignCallsProvider foreignCalls = getProviders().getForeignCalls(); @@ -263,6 +271,16 @@ } } + private static void resetDelayedControlTransfers(LIR lir) { + for (AbstractBlock<?> block : lir.codeEmittingOrder()) { + for (LIRInstruction inst : lir.getLIRforBlock(block)) { + if (inst instanceof SPARCDelayedControlTransfer) { + ((SPARCDelayedControlTransfer) inst).resetState(); + } + } + } + } + /** * Fix-up over whole LIR. * @@ -299,7 +317,7 @@ delayTransferPosition = i; } else if (delayedTransfer != null) { boolean overlap = acc.add(inst); - if (inst instanceof SPARCTailDelayedLIRInstruction && !overlap) { + if (!overlap && inst instanceof SPARCTailDelayedLIRInstruction) { // We have found a non overlapping LIR instruction which can be delayed ((SPARCTailDelayedLIRInstruction) inst).setDelayedControlTransfer(delayedTransfer); delayedTransfer = null;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Wed Sep 24 16:13:34 2014 -0700 @@ -73,7 +73,7 @@ } @Opcode("CALL_DIRECT") - public static class DirectCallOp extends MethodCallOp implements SPARCDelayedControlTransfer { + public static class DirectCallOp extends MethodCallOp /* implements SPARCDelayedControlTransfer */{ private boolean emitted = false; private int before = -1; @@ -114,6 +114,11 @@ new Call(0).emit(masm); emitted = true; } + + public void resetState() { + emitted = false; + before = -1; + } } @Opcode("CALL_INDIRECT")
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Wed Sep 24 16:13:34 2014 -0700 @@ -69,12 +69,17 @@ @Use({REG, CONST}) protected Value y; protected final Condition condition; protected final LabelRef trueDestination; + protected LabelHint trueDestinationHint; protected final LabelRef falseDestination; + protected LabelHint falseDestinationHint; protected final Kind kind; protected final boolean unorderedIsTrue; private boolean emitted = false; private int delaySlotPosition = -1; private double trueDestinationProbability; + // This describes the maximum offset between the first emitted (load constant in to scratch, + // if does not fit into simm5 of cbcond) instruction and the final branch instruction + private static int maximumSelfOffsetInstructions = 4; public CompareBranchOp(SPARCCompare opcode, Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue, double trueDestinationProbability) { @@ -95,16 +100,159 @@ assert masm.position() - delaySlotPosition == 4 : "Only one instruction can be stuffed into the delay slot"; } if (!emitted) { - SPARCCompare.emit(crb, masm, opcode, x, y); - emitted = emitBranch(crb, masm, true); + requestHints(masm); + if (canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) { + emitted = emitShortCompareBranch(crb, masm); + } + if (!emitted) { + SPARCCompare.emit(crb, masm, opcode, x, y); + emitted = emitBranch(crb, masm, true); + } } assert emitted; } public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCCompare.emit(crb, masm, opcode, x, y); - emitted = emitBranch(crb, masm, false); + requestHints(masm); + // When we use short branches, no delay slot is available + if (!canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) { + SPARCCompare.emit(crb, masm, opcode, x, y); + emitted = emitBranch(crb, masm, false); + } + } + + private void requestHints(SPARCMacroAssembler masm) { + if (trueDestinationHint == null) { + this.trueDestinationHint = masm.requestLabelHint(trueDestination.label()); + } + if (falseDestinationHint == null) { + this.falseDestinationHint = masm.requestLabelHint(falseDestination.label()); + } + + } + + /** + * Tries to use the emit the compare/branch instruction. + * <p> + * CBcond has follwing limitations + * <ul> + * <li>Immediate field is only 5 bit and is on the right + * <li>Jump offset is maximum of -+512 instruction + * + * <p> + * We get from outside + * <ul> + * <li>at least one of trueDestination falseDestination is within reach of +-512 + * instructions + * <li>two registers OR one register and a constant which fits simm13 + * + * <p> + * We do: + * <ul> + * <li>find out which target needs to be branched conditionally + * <li>find out if fall-through is possible, if not, a unconditional branch is needed after + * cbcond (needJump=true) + * <li>if no fall through: we need to put the closer jump into the cbcond branch and the + * farther into the jmp (unconditional branch) + * <li>if constant on the left side, mirror to be on the right + * <li>if constant on right does not fit into simm5, put it into a scratch register + * + * @param crb + * @param masm + * @return true if the branch could be emitted + */ + private boolean emitShortCompareBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + Value tmpValue; + Value actualX = x; + Value actualY = y; + Condition actualCondition = condition; + Label actualTrueTarget = trueDestination.label(); + Label actualFalseTarget = falseDestination.label(); + Label tmpTarget; + boolean needJump; + if (crb.isSuccessorEdge(trueDestination)) { + actualCondition = actualCondition.negate(); + tmpTarget = actualTrueTarget; + actualTrueTarget = actualFalseTarget; + actualFalseTarget = tmpTarget; + needJump = false; + } else { + needJump = !crb.isSuccessorEdge(falseDestination); + if (needJump && !isShortBranch(masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize, trueDestinationHint, actualTrueTarget)) { + // we have to jump in either way, so we must put the shorter + // branch into the actualTarget as only one of the two jump targets + // is guaranteed to be simm10 + actualCondition = actualCondition.negate(); + tmpTarget = actualTrueTarget; + actualTrueTarget = actualFalseTarget; + actualFalseTarget = tmpTarget; + } + } + // Keep the constant on the right + if (isConstant(actualX)) { + tmpValue = actualX; + actualX = actualY; + actualY = tmpValue; + actualCondition = actualCondition.mirror(); + } + ConditionFlag conditionFlag = ConditionFlag.fromCondtition(CC.Icc, actualCondition, false); + boolean isValidConstant = isConstant(actualY) && isSimm5(asConstant(actualY)); + SPARCScratchRegister scratch = null; + try { + 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, conditionFlag); + new Nop().emit(masm); + } finally { + if (scratch != null) {// release the scratch if used + scratch.close(); + } + } + if (needJump) { + masm.jmp(actualFalseTarget); + new Nop().emit(masm); + } + return true; + } + + private static void emitCBCond(SPARCMacroAssembler masm, Value actualX, Value actualY, Label actualTrueTarget, ConditionFlag conditionFlag) { + switch ((Kind) actualX.getLIRKind().getPlatformKind()) { + case Byte: + case Char: + case Short: + case Int: + if (isConstant(actualY)) { + int constantY = asConstant(actualY).asInt(); + new CBcondw(conditionFlag, asIntReg(actualX), constantY, actualTrueTarget).emit(masm); + } else { + new CBcondw(conditionFlag, asIntReg(actualX), asIntReg(actualY), actualTrueTarget).emit(masm); + } + break; + case Long: + if (isConstant(actualY)) { + int constantY = (int) asConstant(actualY).asLong(); + new CBcondx(conditionFlag, asLongReg(actualX), constantY, actualTrueTarget).emit(masm); + } else { + new CBcondx(conditionFlag, asLongReg(actualX), asLongReg(actualY), actualTrueTarget).emit(masm); + } + break; + case Object: + if (isConstant(actualY)) { + // Object constant valid can only be null + assert asConstant(actualY).isNull(); + new CBcondx(conditionFlag, asObjectReg(actualX), 0, actualTrueTarget).emit(masm); + } else { // this is already loaded + new CBcondx(conditionFlag, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget).emit(masm); + } + break; + default: + GraalInternalError.shouldNotReachHere(); + } } public boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, boolean withDelayedNop) { @@ -146,10 +294,61 @@ } return true; // emitted } + + private boolean canUseShortBranch(CompilationResultBuilder crb, SPARCAssembler asm, int position) { + if (!asm.hasFeature(CPUFeature.CBCOND)) { + return false; + } + switch ((Kind) x.getPlatformKind()) { + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + break; + default: + return false; + } + boolean hasShortJumpTarget = false; + if (!crb.isSuccessorEdge(trueDestination)) { + hasShortJumpTarget |= isShortBranch(asm, position, trueDestinationHint, trueDestination.label()); + } + if (!crb.isSuccessorEdge(falseDestination)) { + hasShortJumpTarget |= isShortBranch(asm, position, falseDestinationHint, falseDestination.label()); + } + return hasShortJumpTarget; + } + + private static boolean isShortBranch(SPARCAssembler asm, int position, LabelHint hint, Label label) { + int disp = 0; + if (label.isBound()) { + disp = label.position() - position; + + } else if (hint != null && hint.isValid()) { + disp = hint.getTarget() - hint.getPosition(); + } + if (disp != 0) { + if (disp < 0) { + disp -= maximumSelfOffsetInstructions * asm.target.wordSize; + } else { + disp += maximumSelfOffsetInstructions * asm.target.wordSize; + } + return isSimm10(disp >> 2); + } else if (hint == null) { + asm.requestLabelHint(label); + } + return false; + } + + public void resetState() { + emitted = false; + delaySlotPosition = -1; + } } public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { - // TODO: Conditioncode/flag handling needs to be improved; + // TODO: Condition code/flag handling needs to be improved; protected final Condition condition; protected final ConditionFlag conditionFlag; protected final LabelRef trueDestination;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCDelayedControlTransfer.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCDelayedControlTransfer.java Wed Sep 24 16:13:34 2014 -0700 @@ -43,6 +43,9 @@ public String toString() { return "null"; } + + public void resetState() { + } }; /** @@ -53,4 +56,6 @@ * @param masm */ public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm); + + public void resetState(); }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Wed Sep 24 16:13:34 2014 -0700 @@ -41,21 +41,26 @@ assert !emitDone; if (!crb.isSuccessorEdge(destination())) { new Bpa(destination().label()).emit(masm); + delaySlotPosition = masm.position(); } - delaySlotPosition = masm.position(); emitDone = true; } @Override public void emitCode(CompilationResultBuilder crb) { - if (!emitDone) { - SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; - if (!crb.isSuccessorEdge(destination())) { + if (!crb.isSuccessorEdge(destination())) { + if (!emitDone) { + SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; new Bpa(destination().label()).emit(masm); new Nop().emit(masm); + } else { + assert crb.asm.position() - delaySlotPosition == 4; } - } else { - assert crb.asm.position() - delaySlotPosition == 4; } } + + public void resetState() { + delaySlotPosition = -1; + emitDone = false; + } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Wed Sep 24 16:13:34 2014 -0700 @@ -26,7 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.cfg.*; -import com.oracle.graal.lir.StandardOp.BlockEndOp; +import com.oracle.graal.lir.StandardOp.*; /** * This class implements the overall container for the LIR graph and directs its construction, @@ -210,4 +210,15 @@ public void setSpillMoveFactory(SpillMoveFactory spillMoveFactory) { this.spillMoveFactory = spillMoveFactory; } + + public void resetLabels() { + + for (AbstractBlock<?> block : codeEmittingOrder()) { + for (LIRInstruction inst : lirInstructions.get(block)) { + if (inst instanceof LabelOp) { + ((LabelOp) inst).getLabel().reset(); + } + } + } + } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Tue Sep 23 12:12:26 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Wed Sep 24 16:13:34 2014 -0700 @@ -358,4 +358,9 @@ throw new GraalInternalError(t); } } + + public void reset() { + asm.reset(); + compilationResult.reset(); + } }