# HG changeset patch # User Christian Humer # Date 1373500602 -7200 # Node ID 062304c7435356e2e080f91d9e8688aa75caf3c9 # Parent 8c8e47cc101d93945bfdce4cc52feb50686487a4# Parent 31266ceb86ef5a2942ab8c7004f58a343d041e8d merge. diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Thu Jul 11 01:56:42 2013 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.graph.*; public class SPARCAddress extends AbstractAddress { @@ -34,7 +35,8 @@ private static final int STACK_BIAS = 0x7ff; private final Register base; - private final int displacement; // need Register offset / displacement CompositeValue? + private final Register index; + private final int displacement; /** * Creates an {@link SPARCAddress} with given base register, no scaling and a given @@ -45,17 +47,41 @@ */ public SPARCAddress(Register base, int displacement) { this.base = base; + this.index = Register.None; this.displacement = displacement; } + /** + * Creates an {@link SPARCAddress} with given base register, no scaling and a given index. + * + * @param base the base register + * @param index the index register + */ + public SPARCAddress(Register base, Register index) { + this.base = base; + this.index = index; + this.displacement = 0; + } + @Override public String toString() { StringBuilder s = new StringBuilder(); s.append("["); + String sep = ""; if (!getBase().equals(Register.None)) { s.append(getBase()); + sep = " + "; } - // later: displacement CompositeValue? + if (!getIndex().equals(Register.None)) { + s.append(sep).append(getIndex()); + sep = " + "; + } else { + if (getDisplacement() < 0) { + s.append(" - ").append(-getDisplacement()); + } else if (getDisplacement() > 0) { + s.append(sep).append(getDisplacement()); + } + } s.append("]"); return s.toString(); } @@ -69,9 +95,20 @@ } /** + * @return Index register, the value of which is added to {@link #getBase}. If not present, is + * denoted by {@link Register#None}. + */ + public Register getIndex() { + return index; + } + + /** * @return Optional additive displacement. */ public int getDisplacement() { + if (!getIndex().equals(Register.None)) { + throw GraalInternalError.shouldNotReachHere("address has index register"); + } // TODO Should we also hide the register save area size here? if (getBase() == sp || getBase() == fp) { return displacement + STACK_BIAS; diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Thu Jul 11 01:56:42 2013 +0200 @@ -22,14 +22,14 @@ */ package com.oracle.graal.asm.sparc; +import static com.oracle.graal.sparc.SPARC.*; + import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.Kind; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; -import com.oracle.graal.hotspot.HotSpotGraalRuntime; +import com.oracle.graal.hotspot.*; import com.oracle.graal.sparc.*; -import static com.oracle.graal.sparc.SPARC.*; - /** * This class implements an assembler that can encode most SPARC instructions. */ @@ -57,20 +57,66 @@ // @formatter:on public static class Fmt00a { + private static final int OP_SHIFT = 30; + private static final int RD_SHIFT = 25; + private static final int OP2_SHIFT = 22; + private static final int IMM22_SHIFT = 0; + + // @formatter:off + private static final int OP_MASK = 0b11000000000000000000000000000000; + private static final int RD_MASK = 0b00111110000000000000000000000000; + private static final int OP2_MASK = 0b00000001110000000000000000000000; + private static final int IMM22_MASK = 0b00000000001111111111111111111111; + // @formatter:on + private int rd; private int op2; private int imm22; + private Fmt00a(int rd, int op2, int imm22) { + this.rd = rd; + this.op2 = op2; + this.imm22 = imm22; + verify(); + } + public Fmt00a(Op2s op2, int imm22, Register rd) { - this.op2 = op2.getValue(); - this.imm22 = imm22; - this.rd = rd.encoding(); + this(rd.encoding(), op2.getValue(), hi22(imm22)); + } + + private int getInstructionBits() { + return Ops.BranchOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op2 << OP2_SHIFT | (imm22 & IMM22_MASK) << IMM22_SHIFT; + } + + public static Fmt00a read(SPARCAssembler masm, int pos) { + final int inst = masm.codeBuffer.getInt(pos); + + // Make sure it's the right instruction: + final int op = (inst & OP_MASK) >> OP_SHIFT; + assert op == Ops.BranchOp.getValue(); + + // Get the instruction fields: + final int rd = (inst & RD_MASK) >> RD_SHIFT; + final int op2 = (inst & OP2_MASK) >> OP2_SHIFT; + final int imm22 = (inst & IMM22_MASK) >> IMM22_SHIFT; + + return new Fmt00a(op2, imm22, rd); + } + + public void write(SPARCAssembler masm, int pos) { + verify(); + masm.codeBuffer.emitInt(getInstructionBits(), pos); } public void emit(SPARCAssembler masm) { - assert rd < 0x40; - assert op2 < 0x8; - masm.emitInt(Ops.BranchOp.getValue() << 30 | rd << 25 | op2 << 22 | (imm22 & 0x003fffff)); + verify(); + masm.emitInt(getInstructionBits()); + } + + public void verify() { + assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT); + assert ((op2 << OP2_SHIFT) & OP2_MASK) == (op2 << OP2_SHIFT); + assert ((imm22 << IMM22_SHIFT) & IMM22_MASK) == (imm22 << IMM22_SHIFT); } } @@ -623,7 +669,7 @@ assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT); assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT); assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT); - assert isSimm13(simm13); + assert isSimm13(simm13) : String.format("simm13: %d (%x)", simm13, simm13); } } @@ -1226,6 +1272,10 @@ return min13 <= src && src <= max13; } + public static boolean isSimm13(long src) { + return NumUtil.isInt(src) && min13 <= src && src <= max13; + } + public static final int hi22(int x) { return x >> 10; } @@ -2866,15 +2916,31 @@ public static class Stw extends Fmt11 { + public Stw(Register dst, Register src1, Register src2) { + super(Op3s.Stw, src1, src2, dst); + } + + public Stw(Register dst, Register src1, int simm13) { + super(Op3s.Stw, src1, simm13, dst); + } + public Stw(Register dst, SPARCAddress addr) { - super(Op3s.Stw, addr.getBase(), addr.getDisplacement(), dst); + this(dst, addr.getBase(), addr.getDisplacement()); } } public static class Stx extends Fmt11 { + public Stx(Register dst, Register src1, Register src2) { + super(Op3s.Stx, src1, src2, dst); + } + + public Stx(Register dst, Register src1, int simm13) { + super(Op3s.Stx, src1, simm13, dst); + } + public Stx(Register dst, SPARCAddress addr) { - super(Op3s.Stx, addr.getBase(), addr.getDisplacement(), dst); + this(dst, addr.getBase(), addr.getDisplacement()); } } diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Thu Jul 11 01:56:42 2013 +0200 @@ -107,14 +107,10 @@ } } - public static class Clr { + public static class Clr extends Or { - public Clr(SPARCAssembler asm, Register dst) { - new Or(g0, g0, dst).emit(asm); - } - - public Clr(SPARCAssembler asm, SPARCAddress addr) { - new Stw(g0, addr).emit(asm); + public Clr(Register dst) { + super(g0, g0, dst); } } @@ -279,12 +275,19 @@ } } - @SuppressWarnings("unused") public static class Setuw { - public Setuw(SPARCAssembler masm, int value, Register dst) { + private int value; + private Register dst; + + public Setuw(int value, Register dst) { + this.value = value; + this.dst = dst; + } + + public void emit(SPARCMacroAssembler masm) { if (value == 0) { - new Clr(masm, dst); + new Clr(dst).emit(masm); } else if (-4095 <= value && value <= 4096) { new Or(g0, value, dst).emit(masm); } else if (value >= 0 && ((value & 0x3FFF) == 0)) { @@ -298,41 +301,54 @@ public static class Setx { - public Setx(SPARCAssembler asm, long value, Register tmp, Register dst) { + private long value; + private Register tmp; + private Register dst; + + public Setx(long value, Register tmp, Register dst) { + this.value = value; + this.tmp = tmp; + this.dst = dst; + } + + public void emit(SPARCMacroAssembler masm) { int hi = (int) (value >> 32); int lo = (int) (value & ~0); if (isSimm13(lo) && value == lo) { - new Or(g0, lo, dst).emit(asm); + new Or(g0, lo, dst).emit(masm); } else if (hi == 0) { - new Sethi(lo, dst).emit(asm); // hardware version zero-extends to upper 32 + new Sethi(lo, dst).emit(masm); // hardware version zero-extends to upper 32 if (lo10(lo) != 0) { - new Or(dst, lo10(lo), dst).emit(asm); + new Or(dst, lo10(lo), dst).emit(masm); } } else if (hi == -1) { - new Sethi(~lo, dst).emit(asm); // hardware version zero-extends to upper 32 - new Xor(dst, lo10(lo) ^ ~lo10(~0), dst).emit(asm); + new Sethi(~lo, dst).emit(masm); // hardware version zero-extends to upper 32 + new Xor(dst, ~lo10(~0), dst).emit(masm); + new Add(dst, lo10(lo), dst).emit(masm); } else if (lo == 0) { if (isSimm13(hi)) { - new Or(g0, hi, dst).emit(asm); + new Or(g0, hi, dst).emit(masm); } else { - new Sethi(hi, dst).emit(asm); // hardware version zero-extends to upper 32 + new Sethi(hi, dst).emit(masm); // hardware version zero-extends to upper 32 if (lo10(hi) != 0) { - new Or(dst, lo10(hi), dst).emit(asm); + new Or(dst, lo10(hi), dst).emit(masm); } } - new Sllx(dst, 32, dst).emit(asm); + new Sllx(dst, 32, dst).emit(masm); } else { - new Sethi(hi, tmp).emit(asm); - new Sethi(lo, dst).emit(asm); // macro assembler version sign-extends + // TODO Use the same logic as in MacroAssembler::internal_sethi, which doesn't need +// a scratch register. + new Sethi(hi, tmp).emit(masm); + new Sethi(lo, dst).emit(masm); // macro assembler version sign-extends if (lo10(hi) != 0) { - new Or(tmp, lo10(hi), tmp).emit(asm); + new Or(tmp, lo10(hi), tmp).emit(masm); } if (lo10(lo) != 0) { - new Or(dst, lo10(lo), dst).emit(asm); + new Or(dst, lo10(lo), dst).emit(masm); } - new Sllx(tmp, 32, tmp).emit(asm); - new Or(dst, tmp, dst).emit(asm); + new Sllx(tmp, 32, tmp).emit(masm); + new Or(dst, tmp, dst).emit(masm); } } } diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Jul 11 01:56:42 2013 +0200 @@ -134,39 +134,22 @@ @Override public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { - Variable x; - Value y; - Condition condition; - if (LIRValueUtil.isVariable(right)) { - x = load(right); - y = loadNonConst(left); - condition = cond.mirror(); - } else { - x = load(left); - y = loadNonConst(right); - condition = cond; - } + boolean mirrored = emitCompare(left, right); + Condition finalCondition = mirrored ? cond.mirror() : cond; switch (left.getKind().getStackKind()) { case Int: - append(new CompareOp(ICMP, x, y)); - append(new BranchOp(condition, label)); - break; case Long: - append(new CompareOp(LCMP, x, y)); - append(new BranchOp(condition, label)); + case Object: + append(new BranchOp(finalCondition, label)); break; - case Float: - append(new CompareOp(FCMP, x, y)); - append(new BranchOp(condition, label)); - break; - case Double: - append(new CompareOp(DCMP, x, y)); - append(new BranchOp(condition, label)); - break; - case Object: - append(new CompareOp(ACMP, x, y)); - append(new BranchOp(condition, label)); - break; +// case Float: +// append(new CompareOp(FCMP, x, y)); +// append(new BranchOp(condition, label)); +// break; +// case Double: +// append(new CompareOp(DCMP, x, y)); +// append(new BranchOp(condition, label)); +// break; default: throw GraalInternalError.shouldNotReachHere("" + left.getKind()); } @@ -376,8 +359,7 @@ case Int: return SPARCAssembler.isSimm13(c.asInt()) && !runtime.needsDataPatch(c); case Long: - // return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c); - throw new InternalError("NYI"); + return SPARCAssembler.isSimm13(c.asLong()) && !runtime.needsDataPatch(c); case Object: return c.isNull(); default: @@ -407,21 +389,23 @@ baseRegister = asAllocatable(base); } - if (!Value.ILLEGAL.equals(index) && scale != 0) { + if (!index.equals(Value.ILLEGAL) && scale != 0) { if (isConstant(index)) { finalDisp += asConstant(index).asLong() * scale; } else { Value indexRegister; if (scale != 1) { - indexRegister = emitMul(index, Constant.forInt(scale)); + Variable longIndex = newVariable(Kind.Long); + emitMove(longIndex, index); + indexRegister = emitMul(longIndex, Constant.forLong(scale)); } else { indexRegister = index; } - if (Value.ILLEGAL.equals(baseRegister)) { + if (baseRegister.equals(Value.ILLEGAL)) { baseRegister = asAllocatable(indexRegister); } else { - Variable newBase = newVariable(Kind.Int); + Variable newBase = newVariable(Kind.Long); emitMove(newBase, baseRegister); baseRegister = newBase; baseRegister = emitAdd(baseRegister, indexRegister); @@ -807,11 +791,6 @@ } @Override - public void visitSafepointNode(SafepointNode i) { - throw new InternalError("NYI"); - } - - @Override public void visitBreakpointNode(BreakpointNode node) { JavaType[] sig = new JavaType[node.arguments().size()]; for (int i = 0; i < sig.length; i++) { diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Thu Jul 11 01:56:42 2013 +0200 @@ -75,7 +75,7 @@ if (field.getName().equals("x")) { Assert.assertTrue(rn.object() instanceof LocalNode); } else { - Assert.assertTrue(rn.object() instanceof UnsafeCastNode); + Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode); } counter++; } diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Thu Jul 11 01:56:42 2013 +0200 @@ -69,19 +69,26 @@ */ protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, boolean afterFrameInit) { if (StackShadowPages.getValue() > 0) { - // SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm; + SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm; final int frameSize = tasm.frameMap.frameSize(); if (frameSize > 0) { int lastFramePage = frameSize / unsafe.pageSize(); // emit multiple stack bangs for methods with frames larger than a page for (int i = 0; i <= lastFramePage; i++) { - // int disp = (i + StackShadowPages.getValue()) * unsafe.pageSize(); - // if (afterFrameInit) { - // disp -= frameSize; - // } + int disp = (i + StackShadowPages.getValue()) * unsafe.pageSize(); + if (afterFrameInit) { + disp -= frameSize; + } tasm.blockComment("[stack overflow check]"); - // FIXME currently doesn't work; maybe frame size is wrong - // new Ldx(new SPARCAddress(sp, -disp), g0).emit(masm); + // Use SPARCAddress to get the final displacement including the stack bias. + SPARCAddress address = new SPARCAddress(sp, -disp); + if (SPARCAssembler.isSimm13(address.getDisplacement())) { + new Stx(g0, address).emit(masm); + } else { + // TODO Can't use g3 as scratch here. + new Setx(address.getDisplacement(), g3, g3).emit(masm); + new Stx(g0, sp, g3).emit(masm); + } } } } @@ -193,7 +200,7 @@ if (unverifiedStub != null) { masm.bind(unverifiedStub); // SPARCCall.directJmp(tasm, asm, runtime().lookupForeignCall(IC_MISS_HANDLER)); - throw new InternalError("g0 must be scratch register"); + // throw new InternalError("g0 must be scratch register"); } } } diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Jul 11 01:56:42 2013 +0200 @@ -37,11 +37,25 @@ public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator { - public StackSlot deoptimizationRescueSlot; + private HotSpotRuntime runtime() { + return (HotSpotRuntime) runtime; + } public SPARCHotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { super(graph, runtime, target, frameMap, cc, lir); - // TODO Auto-generated constructor stub + } + + /** + * The slot reserved for storing the original return address when a frame is marked for + * deoptimization. The return address slot in the callee is overwritten with the address of a + * deoptimization stub. + */ + StackSlot deoptimizationRescueSlot; + + @Override + public void visitSafepointNode(SafepointNode i) { + LIRFrameState info = state(i); + append(new SPARCSafepointOp(info, runtime().config, this)); } @Override diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java Thu Jul 11 01:56:42 2013 +0200 @@ -35,18 +35,15 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -//import com.oracle.graal.replacements.sparc.*; - public class SPARCHotSpotRuntime extends HotSpotRuntime { public SPARCHotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) { super(config, graalRuntime); } -// private AMD64ConvertSnippets.Templates convertSnippets; - @Override public void registerReplacements(Replacements replacements) { Kind word = graalRuntime.getTarget().wordKind; @@ -60,23 +57,21 @@ register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); -// convertSnippets = new AMD64ConvertSnippets.Templates(this, replacements, -// graalRuntime.getTarget()); super.registerReplacements(replacements); } @Override public void lower(Node n, LoweringTool tool) { -// if (n instanceof ConvertNode) { -// convertSnippets.lower((ConvertNode) n, tool); -// } else { - super.lower(n, tool); -// } + if (n instanceof ConvertNode) { + // ConvertNodes are handled in SPARCLIRGenerator.emitConvert + } else { + super.lower(n, tool); + } } @Override public Register threadRegister() { - throw new InternalError("NYI: SPARC: Define thread register."); + return g2; } @Override diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java Thu Jul 11 01:56:42 2013 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.sparc; + +import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import static com.oracle.graal.sparc.SPARC.*; +import static com.oracle.graal.phases.GraalOptions.*; +import sun.misc.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Emits a safepoint poll. + */ +@Opcode("SAFEPOINT") +public class SPARCSafepointOp extends SPARCLIRInstruction { + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + + @State protected LIRFrameState state; + @Temp({OperandFlag.REG}) private AllocatableValue temp; + + private final HotSpotVMConfig config; + + public SPARCSafepointOp(LIRFrameState state, HotSpotVMConfig config, LIRGeneratorTool tool) { + this.state = state; + this.config = config; + temp = tool.newVariable(tool.target().wordKind); + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + final int pos = masm.codeBuffer.position(); + final int offset = SafepointPollOffset.getValue() % unsafe.pageSize(); + Register scratch = ((RegisterValue) temp).getRegister(); + new Setx(config.safepointPollingAddress + offset, scratch, scratch).emit(masm); + tasm.recordMark(config.isPollingPageFar ? Marks.MARK_POLL_FAR : Marks.MARK_POLL_NEAR); + tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); + new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm); + } +} diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Thu Jul 11 01:56:42 2013 +0200 @@ -82,21 +82,12 @@ private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long); private static void checkedCopy(Object src, int srcPos, Object dest, int destPos, int length, Kind baseKind) { - Object nonNullSrc = checkNonNull(src); - Object nonNullDest = checkNonNull(dest); + Object nonNullSrc = guardingNonNull(src); + Object nonNullDest = guardingNonNull(dest); checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length); UnsafeArrayCopyNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, baseKind); } - @Fold - private static Stamp nonNull() { - return StampFactory.objectNonNull(); - } - - public static Object checkNonNull(Object obj) { - return guardingPi(obj, isNull(obj), true, DeoptimizationReason.RuntimeConstraint, DeoptimizationAction.None, nonNull()); - } - public static int checkArrayType(Word hub) { int layoutHelper = readLayoutHelper(hub); if (layoutHelper >= 0) { @@ -191,8 +182,8 @@ @Snippet public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) { - Object nonNullSrc = checkNonNull(src); - Object nonNullDest = checkNonNull(dest); + Object nonNullSrc = guardingNonNull(src); + Object nonNullDest = guardingNonNull(dest); Word srcHub = loadHub(nonNullSrc); Word destHub = loadHub(nonNullDest); if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) { diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Thu Jul 11 01:56:42 2013 +0200 @@ -517,7 +517,7 @@ rk = result.getKind(); xsk = x.getKind().getStackKind(); ysk = y.getKind().getStackKind(); - assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int; + assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int : "opcode=" + opcode + ", rk=" + rk + ", xsk=" + xsk + ", ysk=" + ysk; break; case LADD: case LSUB: diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Thu Jul 11 01:56:42 2013 +0200 @@ -72,8 +72,8 @@ new Cmp(asLongReg(x), asLongReg(y)).emit(masm); break; case ACMP: - // masm.cmpptr(asObjectReg(x), asObjectReg(y)); - // break; +// new Cmp(asObjectReg(x), asObjectReg(y)).emit(masm); +// break; case FCMP: // masm.ucomiss(asFloatReg(x), asFloatReg(y)); // break; @@ -96,9 +96,8 @@ break; case ACMP: if (((Constant) y).isNull()) { - // masm.cmpq(asObjectReg(x), 0); - // break; - throw GraalInternalError.shouldNotReachHere(); + new Cmp(asObjectReg(x), 0).emit(masm); + break; } else { throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons"); } diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Thu Jul 11 01:56:42 2013 +0200 @@ -53,9 +53,12 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + // FIXME Using xcc is wrong! It depends on the compare. switch (condition) { + case EQ: + new Bpe(CC.Xcc, destination.label()).emit(masm); + break; case GT: - // FIXME xcc is wrong! It depends on the compare. new Bpg(CC.Xcc, destination.label()).emit(masm); break; default: diff -r 8c8e47cc101d -r 062304c74353 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 Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Thu Jul 11 01:56:42 2013 +0200 @@ -23,27 +23,13 @@ package com.oracle.graal.lir.sparc; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; -import com.oracle.graal.asm.sparc.SPARCAssembler.Membar; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stb; -import com.oracle.graal.asm.sparc.SPARCAssembler.Sth; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setuw; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.MoveOp; @@ -51,68 +37,6 @@ public class SPARCMove { - public static class LoadOp extends SPARCLIRInstruction { - - private final Kind kind; - @Def({REG}) protected AllocatableValue result; - @Use({COMPOSITE}) protected SPARCAddressValue address; - @State protected LIRFrameState state; - - public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) { - this.kind = kind; - this.result = result; - this.address = address; - this.state = state; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - SPARCAddress addr = address.toAddress(); - switch (kind) { - case Byte: - new Ldsb(addr, asRegister(result)).emit(masm); - break; - case Short: - new Ldsh(addr, asRegister(result)).emit(masm); - break; - case Char: - new Lduw(addr, asRegister(result)).emit(masm); - break; - case Int: - new Ldsw(addr, asRegister(result)).emit(masm); - break; - case Long: - new Ldx(addr, asRegister(result)).emit(masm); - break; - case Float: - new Ldf(addr, asRegister(result)).emit(masm); - break; - case Double: - new Lddf(addr, asRegister(result)).emit(masm); - break; - case Object: - new Ldx(addr, asRegister(result)).emit(masm); - break; - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - } - - public static class MembarOp extends SPARCLIRInstruction { - - private final int barriers; - - public MembarOp(final int barriers) { - this.barriers = barriers; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - new Membar(barriers).emit(masm); - } - } - @Opcode("MOVE") public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp { @@ -167,6 +91,86 @@ } } + public abstract static class MemOp extends SPARCLIRInstruction { + + protected final Kind kind; + @Use({COMPOSITE}) protected SPARCAddressValue address; + @State protected LIRFrameState state; + + public MemOp(Kind kind, SPARCAddressValue address, LIRFrameState state) { + this.kind = kind; + this.address = address; + this.state = state; + } + + protected abstract void emitMemAccess(SPARCMacroAssembler masm); + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + if (state != null) { + tasm.recordImplicitException(masm.codeBuffer.position(), state); + } + emitMemAccess(masm); + } + } + + public static class LoadOp extends MemOp { + + @Def({REG}) protected AllocatableValue result; + + public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) { + super(kind, address, state); + this.result = result; + } + + @Override + public void emitMemAccess(SPARCMacroAssembler masm) { + SPARCAddress addr = address.toAddress(); + switch (kind) { + case Byte: + new Ldsb(addr, asRegister(result)).emit(masm); + break; + case Short: + new Ldsh(addr, asRegister(result)).emit(masm); + break; + case Char: + new Lduw(addr, asRegister(result)).emit(masm); + break; + case Int: + new Ldsw(addr, asRegister(result)).emit(masm); + break; + case Long: + new Ldx(addr, asRegister(result)).emit(masm); + break; + case Float: + new Ldf(addr, asRegister(result)).emit(masm); + break; + case Double: + new Lddf(addr, asRegister(result)).emit(masm); + break; + case Object: + new Ldx(addr, asRegister(result)).emit(masm); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + public static class MembarOp extends SPARCLIRInstruction { + + private final int barriers; + + public MembarOp(final int barriers) { + this.barriers = barriers; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + new Membar(barriers).emit(masm); + } + } + public static class NullCheckOp extends SPARCLIRInstruction { @Use({REG}) protected AllocatableValue input; @@ -201,22 +205,17 @@ } } - public static class StoreOp extends SPARCLIRInstruction { + public static class StoreOp extends MemOp { - private final Kind kind; - @Use({COMPOSITE}) protected SPARCAddressValue address; @Use({REG}) protected AllocatableValue input; - @State protected LIRFrameState state; public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) { - this.kind = kind; - this.address = address; + super(kind, address, state); this.input = input; - this.state = state; } @Override - public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { + public void emitMemAccess(SPARCMacroAssembler masm) { assert isRegister(input); SPARCAddress addr = address.toAddress(); switch (kind) { @@ -318,27 +317,26 @@ } } - @SuppressWarnings("unused") private static void const2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Constant input) { switch (input.getKind().getStackKind()) { case Int: if (tasm.runtime.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); } - new Setuw(masm, input.asInt(), asRegister(result)); + new Setuw(input.asInt(), asRegister(result)).emit(masm); break; case Long: if (tasm.runtime.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); } - new Setx(masm, input.asLong(), null, asRegister(result)); + new Setx(input.asLong(), null, asRegister(result)).emit(masm); break; case Object: if (input.isNull()) { - new Setx(masm, 0x0L, null, asRegister(result)); + new Clr(asRegister(result)).emit(masm); } else if (tasm.target.inlineObjects) { tasm.recordDataReferenceInCode(input, 0, true); - new Setx(masm, 0xDEADDEADDEADDEADL, null, asRegister(result)); + new Setx(0xDEADDEADDEADDEADL, null, asRegister(result)).emit(masm); } else { throw new InternalError("NYI"); } diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Thu Jul 11 01:56:42 2013 +0200 @@ -46,13 +46,24 @@ return object; } - public GuardingPiNode(ValueNode object) { + /** + * Constructor for {@link #guardingNonNull(Object)} node intrinsic. + */ + private GuardingPiNode(ValueNode object) { this(object, object.graph().unique(new IsNullNode(object)), true, DeoptimizationReason.NullCheckException, DeoptimizationAction.None, object.stamp().join(StampFactory.objectNonNull())); } + /** + * Creates a guarding pi node. + * + * @param object the object whose type is refined if this guard succeeds + * @param condition the condition to test + * @param negateCondition the guard succeeds if {@code condition != negateCondition} + * @param stamp the refined type of the object if the guard succeeds + */ public GuardingPiNode(ValueNode object, ValueNode condition, boolean negateCondition, DeoptimizationReason reason, DeoptimizationAction action, Stamp stamp) { - super(object.stamp().join(stamp)); - assert stamp() != null; + super(stamp); + assert stamp != null; this.object = object; this.condition = (LogicNode) condition; this.reason = reason; diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Jul 11 01:56:42 2013 +0200 @@ -22,9 +22,13 @@ */ package com.oracle.graal.nodes.java; +import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -62,9 +66,48 @@ return forStoreCheck; } + /** + * Lowers a {@link CheckCastNode} to a {@link GuardingPiNode}. That is: + * + *
+     * 1: A a = ...
+     * 2: B b = (B) a;
+     * 
+ * + * is lowered to: + * + *
+     * 1: A a = ...
+     * 2: B b = guardingPi(a == null || a instanceof B, a, stamp(B))
+     * 
+ * + * or if a is known to be non-null: + * + *
+     * 1: A a = ...
+     * 2: B b = guardingPi(a instanceof B, a, stamp(B, non-null))
+     * 
+ * + * Note: we use {@link Graph#add} as opposed to {@link Graph#unique} for the new + * {@link InstanceOfNode} to maintain the invariant checked by + * {@code LoweringPhase.checkUsagesAreScheduled()}. + */ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - tool.getRuntime().lower(this, tool); + InstanceOfNode typeTest = graph().add(new InstanceOfNode(type, object, profile)); + Stamp stamp = object.stamp().join(StampFactory.declared(type)); + ValueNode condition; + if (stamp == null) { + // This is a check cast that will always fail + condition = LogicConstantNode.contradiction(graph()); + stamp = StampFactory.declared(type); + } else if (object.stamp().nonNull()) { + condition = typeTest; + } else { + condition = graph().unique(new LogicDisjunctionNode(graph().unique(new IsNullNode(object)), typeTest)); + } + GuardingPiNode checkedObject = graph().add(new GuardingPiNode(object, condition, false, forStoreCheck ? ArrayStoreException : ClassCastException, InvalidateReprofile, stamp)); + graph().replaceFixedWithFixed(this, checkedObject); } @Override diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Jul 11 01:56:42 2013 +0200 @@ -116,7 +116,8 @@ @Override public boolean verify() { for (Node usage : usages()) { - assertTrue(usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof ConditionalNode, "unsupported usage: ", usage); + assertTrue(usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof GuardingPiNode || usage instanceof ConditionalNode || usage instanceof LogicBinaryNode, + "unsupported usage: %s", usage); } return super.verify(); } diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Jul 11 01:56:42 2013 +0200 @@ -1441,7 +1441,8 @@ if (firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) { assert !firstParam.objectStamp().alwaysNull(); IsNullNode condition = graph.unique(new IsNullNode(firstParam)); - GuardingPiNode nonNullReceiver = graph.add(new GuardingPiNode(firstParam, condition, true, NullCheckException, InvalidateReprofile, objectNonNull())); + Stamp stamp = firstParam.stamp().join(objectNonNull()); + GuardingPiNode nonNullReceiver = graph.add(new GuardingPiNode(firstParam, condition, true, NullCheckException, InvalidateReprofile, stamp)); graph.addBeforeFixed(invoke.asNode(), nonNullReceiver); callTarget.replaceFirstInput(firstParam, nonNullReceiver); return nonNullReceiver; diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Jul 11 01:56:42 2013 +0200 @@ -253,11 +253,34 @@ } if (node instanceof Lowerable) { + assert checkUsagesAreScheduled(node); ((Lowerable) node).lower(loweringTool, loweringType); } loweringTool.setLastFixedNode((FixedWithNextNode) nextNode.predecessor()); } } + + /** + * Checks that all usages of a floating, lowerable node are scheduled. + *

+ * Given that the lowering of such nodes may introduce fixed nodes, they must be lowered in + * the context of a usage that dominates all other usages. The fixed nodes resulting from + * lowering are attached to the fixed node context of the dominating usage. This ensures the + * post-lowering graph still has a valid schedule. + * + * @param node a {@link Lowerable} node + */ + private boolean checkUsagesAreScheduled(Node node) { + if (node instanceof FloatingNode) { + for (Node usage : node.usages()) { + if (usage instanceof ScheduledNode) { + Block usageBlock = schedule.getCFG().blockFor(usage); + assert usageBlock != null : node.graph() + ": cannot lower floatable node " + node + " that has non-scheduled usage " + usage; + } + } + } + return true; + } } } diff -r 8c8e47cc101d -r 062304c74353 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Thu Jul 11 01:55:54 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Thu Jul 11 01:56:42 2013 +0200 @@ -65,13 +65,12 @@ public void lower(FloatingNode instanceOf, LoweringTool tool) { assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode; List usages = instanceOf.usages().snapshot(); - int nUsages = usages.size(); Instantiation instantiation = new Instantiation(); for (Node usage : usages) { final StructuredGraph graph = (StructuredGraph) usage.graph(); - InstanceOfUsageReplacer replacer = createReplacer(instanceOf, tool, nUsages, instantiation, usage, graph); + InstanceOfUsageReplacer replacer = createReplacer(instanceOf, instantiation, usage, graph); if (instantiation.isInitialized()) { // No need to re-instantiate the snippet - just re-use its result @@ -91,18 +90,15 @@ /** * Gets the specific replacer object used to replace the usage of an instanceof node with the * result of an instantiated instanceof snippet. - * - * @param nUsages - * @param tool */ - protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, LoweringTool tool, int nUsages, Instantiation instantiation, Node usage, final StructuredGraph graph) { + protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, Instantiation instantiation, Node usage, final StructuredGraph graph) { InstanceOfUsageReplacer replacer; - if (usage instanceof IfNode || usage instanceof FixedGuardNode) { - replacer = new IfUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, (FixedNode) usage); + if (usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof LogicBinaryNode || usage instanceof GuardingPiNode) { + replacer = new NonMaterializationUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, usage); } else { assert usage instanceof ConditionalNode : "unexpected usage of " + instanceOf + ": " + usage; ConditionalNode c = (ConditionalNode) usage; - replacer = new ConditionalUsageReplacer(instantiation, c.trueValue(), c.falseValue(), instanceOf, c); + replacer = new MaterializationUsageReplacer(instantiation, c.trueValue(), c.falseValue(), instanceOf, c); } return replacer; } @@ -192,14 +188,14 @@ } /** - * Replaces an {@link IfNode} usage of an {@link InstanceOfNode} or - * {@link InstanceOfDynamicNode}. + * Replaces the usage of an {@link InstanceOfNode} or {@link InstanceOfDynamicNode} that does + * not materialize the result of the type test. */ - public static class IfUsageReplacer extends InstanceOfUsageReplacer { + public static class NonMaterializationUsageReplacer extends InstanceOfUsageReplacer { - private final FixedNode usage; + private final Node usage; - public IfUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, FixedNode usage) { + public NonMaterializationUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, Node usage) { super(instantiation, instanceOf, trueValue, falseValue); this.usage = usage; } @@ -211,14 +207,6 @@ @Override public void replace(ValueNode oldNode, ValueNode newNode) { - if (newNode.isConstant()) { - LogicConstantNode logicConstant = LogicConstantNode.forBoolean(newNode.asConstant().asInt() != 0, newNode.graph()); - usage.replaceFirstInput(oldNode, logicConstant); - // PrintStream out = System.out; - // out.println(newNode.graph() + ": " + this); - GraalInternalError.shouldNotReachHere(instanceOf.graph().toString()); - return; - } assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); @@ -228,14 +216,14 @@ } /** - * Replaces a {@link ConditionalNode} usage of an {@link InstanceOfNode} or - * {@link InstanceOfDynamicNode}. + * Replaces the usage of an {@link InstanceOfNode} or {@link InstanceOfDynamicNode} that does + * materializes the result of the type test. */ - public static class ConditionalUsageReplacer extends InstanceOfUsageReplacer { + public static class MaterializationUsageReplacer extends InstanceOfUsageReplacer { public final ConditionalNode usage; - public ConditionalUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, ConditionalNode usage) { + public MaterializationUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, ConditionalNode usage) { super(instantiation, instanceOf, trueValue, falseValue); this.usage = usage; } @@ -251,14 +239,6 @@ @Override public void replace(ValueNode oldNode, ValueNode newNode) { - if (newNode.isConstant()) { - LogicConstantNode logicConstant = LogicConstantNode.forBoolean(newNode.asConstant().asInt() != 0, newNode.graph()); - usage.replaceFirstInput(oldNode, logicConstant); - // PrintStream out = System.out; - // out.println(newNode.graph() + ": " + this); - GraalInternalError.shouldNotReachHere(instanceOf.graph().toString()); - return; - } assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp();