Mercurial > hg > truffle
changeset 19783:69b7ad0a3fda
Merge.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 10 Mar 2015 21:26:02 +0100 |
parents | 86f2cb32cd64 (current diff) 39315508f1b6 (diff) |
children | e968986402dc |
files | graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionBase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/RewriteEvent.java |
diffstat | 790 files changed, 12097 insertions(+), 9435 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java Tue Mar 03 14:20:58 2015 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java Tue Mar 10 21:26:02 2015 +0100 @@ -65,9 +65,6 @@ } } - public void visitValueLocation(Address valueAddr) { - } - public void visitNarrowOopLocation(Address narrowOopAddr) { addressVisitor.visitCompOopAddress(narrowOopAddr); } @@ -198,9 +195,9 @@ } } - // We want narow oop, value and oop oop_types + // We want narow oop and oop oop_types OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] { - OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE + OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE }; { @@ -213,8 +210,6 @@ // to detect in the debugging system // assert(Universe::is_heap_or_null(*loc), "found non oop pointer"); visitor.visitOopLocation(loc); - } else if (omv.getType() == OopMapValue.OopTypes.VALUE_VALUE) { - visitor.visitValueLocation(loc); } else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) { visitor.visitNarrowOopLocation(loc); }
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java Tue Mar 03 14:20:58 2015 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java Tue Mar 10 21:26:02 2015 +0100 @@ -49,7 +49,6 @@ // Types of OopValues static int UNUSED_VALUE; static int OOP_VALUE; - static int VALUE_VALUE; static int NARROWOOP_VALUE; static int CALLEE_SAVED_VALUE; static int DERIVED_OOP_VALUE; @@ -73,7 +72,6 @@ REGISTER_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::register_mask_in_place").intValue(); UNUSED_VALUE = db.lookupIntConstant("OopMapValue::unused_value").intValue(); OOP_VALUE = db.lookupIntConstant("OopMapValue::oop_value").intValue(); - VALUE_VALUE = db.lookupIntConstant("OopMapValue::value_value").intValue(); NARROWOOP_VALUE = db.lookupIntConstant("OopMapValue::narrowoop_value").intValue(); CALLEE_SAVED_VALUE = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue(); DERIVED_OOP_VALUE = db.lookupIntConstant("OopMapValue::derived_oop_value").intValue(); @@ -82,7 +80,6 @@ public static abstract class OopTypes { public static final OopTypes UNUSED_VALUE = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE; }}; public static final OopTypes OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE; }}; - public static final OopTypes VALUE_VALUE = new OopTypes() { int getValue() { return OopMapValue.VALUE_VALUE; }}; public static final OopTypes NARROWOOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.NARROWOOP_VALUE; }}; public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }}; public static final OopTypes DERIVED_OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.DERIVED_OOP_VALUE; }}; @@ -105,7 +102,6 @@ // Querying public boolean isOop() { return (getValue() & TYPE_MASK_IN_PLACE) == OOP_VALUE; } - public boolean isValue() { return (getValue() & TYPE_MASK_IN_PLACE) == VALUE_VALUE; } public boolean isNarrowOop() { return (getValue() & TYPE_MASK_IN_PLACE) == NARROWOOP_VALUE; } public boolean isCalleeSaved() { return (getValue() & TYPE_MASK_IN_PLACE) == CALLEE_SAVED_VALUE; } public boolean isDerivedOop() { return (getValue() & TYPE_MASK_IN_PLACE) == DERIVED_OOP_VALUE; } @@ -117,7 +113,6 @@ int which = (getValue() & TYPE_MASK_IN_PLACE); if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE; else if (which == OOP_VALUE) return OopTypes.OOP_VALUE; - else if (which == VALUE_VALUE) return OopTypes.VALUE_VALUE; else if (which == NARROWOOP_VALUE) return OopTypes.NARROWOOP_VALUE; else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE; else if (which == DERIVED_OOP_VALUE) return OopTypes.DERIVED_OOP_VALUE;
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java Tue Mar 03 14:20:58 2015 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,6 +31,5 @@ public interface OopMapVisitor { public void visitOopLocation(Address oopAddr); public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr); - public void visitValueLocation(Address valueAddr); public void visitNarrowOopLocation(Address narrowOopAddr); }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java Tue Mar 03 14:20:58 2015 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java Tue Mar 10 21:26:02 2015 +0100 @@ -544,9 +544,6 @@ } } - public void visitValueLocation(Address valueAddr) { - } - public void visitNarrowOopLocation(Address compOopAddr) { addressVisitor.visitCompOopAddress(compOopAddr); }
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Tue Mar 10 21:26:02 2015 +0100 @@ -1222,9 +1222,6 @@ oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE); buf.append(omvIterator.iterate(oms, "NarrowOops:", false)); - oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE); - buf.append(omvIterator.iterate(oms, "Values:", false)); - oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); buf.append(omvIterator.iterate(oms, "Callee saved:", true));
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BailoutException.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BailoutException.java Tue Mar 10 21:26:02 2015 +0100 @@ -48,6 +48,17 @@ /** * Creates a new {@link BailoutException}. * + * + * @param args parameters to the formatter + */ + public BailoutException(Throwable cause, String format, Object... args) { + super(String.format(Locale.ENGLISH, format, args), cause); + this.permanent = true; + } + + /** + * Creates a new {@link BailoutException}. + * * @param permanent specifies whether this exception will occur again if compilation is retried * @param args parameters to the formatter */
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Tue Mar 10 21:26:02 2015 +0100 @@ -66,7 +66,7 @@ * Note that the number of locals and the number of stack slots may be smaller than the maximum * number of locals and stack slots as specified in the compiled method. */ - public final JavaValue[] values; + public final Value[] values; /** * The number of locals in the values array. @@ -144,7 +144,7 @@ * @param numStack the depth of the stack * @param numLocks the number of locked objects */ - public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, JavaValue[] values, int numLocals, int numStack, int numLocks) { + public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, Value[] values, int numLocals, int numStack, int numLocks) { super(caller, method, bci); assert values != null; this.rethrowException = rethrowException; @@ -161,17 +161,18 @@ * slot following a double word item. This should really be checked in FrameState itself but * because of Word type rewriting and alternative backends that can't be done. */ - public boolean validateFormat() { + public boolean validateFormat(boolean derivedOk) { if (caller() != null) { - caller().validateFormat(); + caller().validateFormat(derivedOk); } for (int i = 0; i < numLocals + numStack; i++) { if (values[i] != null) { Kind kind = values[i].getKind(); if (kind.needsTwoSlots()) { assert values.length > i + 1 : String.format("missing second word %s", this); - assert values[i + 1] == null || values[i + 1].getKind() == Kind.Illegal; + assert values[i + 1] == null || values[i + 1].getKind() == Kind.Illegal : this; } + assert derivedOk || ValueUtil.isIllegal(values[i]) || !values[i].getLIRKind().isDerivedReference() : "Unexpected derived value: " + values[i]; } } return true; @@ -183,7 +184,7 @@ * @param i the local variable index * @return the value that can be used to reconstruct the local's current value */ - public JavaValue getLocalValue(int i) { + public Value getLocalValue(int i) { return values[i]; } @@ -193,7 +194,7 @@ * @param i the stack index * @return the value that can be used to reconstruct the stack slot's current value */ - public JavaValue getStackValue(int i) { + public Value getStackValue(int i) { return values[i + numLocals]; } @@ -203,7 +204,7 @@ * @param i the lock index * @return the value that can be used to reconstruct the lock's current value */ - public JavaValue getLockValue(int i) { + public Value getLockValue(int i) { return values[i + numLocals + numStack]; }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java Tue Mar 10 21:26:02 2015 +0100 @@ -64,7 +64,7 @@ /** * Creates a CSA layout. - * + * * @param size size (in bytes) of the CSA. If this is {@code -1}, then the CSA size will be * computed from {@code registers}. * @param slotSize the size (in bytes) of an {@linkplain #registerAt(int) indexable} slot in the @@ -113,7 +113,7 @@ /** * Gets the offset of a given register in the CSA. - * + * * @return the offset (in bytes) of {@code reg} in the CSA * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA */ @@ -123,7 +123,7 @@ /** * Gets the index of a given register in the CSA. - * + * * @return the index of {@code reg} in the CSA * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA */ @@ -136,7 +136,7 @@ /** * Gets the offset of a given register in the CSA. - * + * * @return the offset (in bytes) of {@code reg} in the CSA * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA */ @@ -146,7 +146,7 @@ /** * Determines if the CSA includes a slot for a given register. - * + * * @param reg the register to test * @return true if the CSA contains a slot for {@code reg} */ @@ -156,7 +156,7 @@ /** * Gets the register whose slot in the CSA is at a given index. - * + * * @param index an index of a slot in the CSA * @return the register whose slot in the CSA is at {@code index} or {@code null} if * {@code index} does not denote a slot in the CSA aligned with a register
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java Tue Mar 10 21:26:02 2015 +0100 @@ -78,7 +78,7 @@ /** * Creates a description of the registers and stack locations used by a call. - * + * * @param stackSize amount of stack space (in bytes) required for the stack-based arguments of * the call * @param returnLocation the location for the return value or {@link Value#ILLEGAL} if a void
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DisassemblerProvider.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DisassemblerProvider.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ /** * Gets a textual disassembly of some given installed code. - * + * * @return a non-zero length string containing a disassembly of {@code code} or null if * {@code code} is {@link InstalledCode#isValid() invalid} or it could not be * disassembled for some other reason
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java Tue Mar 10 21:26:02 2015 +0100 @@ -57,7 +57,7 @@ /** * Determines if the foreign call target destroys all registers. - * + * * @return {@code true} if the register allocator must save all live registers around a call to * this target */
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/MemoryBarriers.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/MemoryBarriers.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,7 +24,7 @@ /** * Constants and intrinsic definition for memory barriers. - * + * * The documentation for each constant is taken from Doug Lea's <a * href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler * Writers</a>. @@ -32,14 +32,14 @@ * The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory * Model with respect to volatile field accesses. Their values are explained by this comment from * templateTable_i486.cpp in the HotSpot source code: - * + * * <pre> * Volatile variables demand their effects be made known to all CPU's in * order. Store buffers on most chips allow reads & writes to reorder; the * JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of * memory barrier (i.e., it's not sufficient that the interpreter does not * reorder volatile references, the hardware also must not reorder them). - * + * * According to the new Java Memory Model (JMM): * (1) All volatiles are serialized wrt to each other. * ALSO reads & writes act as acquire & release, so: @@ -50,7 +50,7 @@ * that happen BEFORE the write float down to after the write. It's OK for * non-volatile memory refs that happen after the volatile write to float up * before it. - * + * * We only put in barriers around volatile refs (they are expensive), not * _between_ memory refs (which would require us to track the flavor of the * previous memory refs). Requirements (2) and (3) require some barriers
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterAttributes.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterAttributes.java Tue Mar 10 21:26:02 2015 +0100 @@ -47,7 +47,7 @@ * Creates a map from register {@linkplain Register#number numbers} to register * {@linkplain RegisterAttributes attributes} for a given register configuration and set of * registers. - * + * * @param registerConfig a register configuration * @param registers a set of registers * @return an array whose length is the max register number in {@code registers} plus 1. An
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SourceStackTrace.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.code; + +/** + * Class representing a exception with a stack trace of the currently processed position in the + * compiled Java program instead of the stack trace of the compiler. The exception of the compiler + * is saved as the cause of this exception. + */ +public abstract class SourceStackTrace extends BailoutException { + private static final long serialVersionUID = 2144811793442316776L; + + public static SourceStackTrace create(Throwable cause, String format, StackTraceElement[] elements) { + return new SourceStackTrace(cause, format) { + + private static final long serialVersionUID = 6279381376051787907L; + + @Override + public final synchronized Throwable fillInStackTrace() { + assert elements != null; + setStackTrace(elements); + return this; + } + }; + } + + private SourceStackTrace(Throwable cause, String format) { + super(cause, format); + } +}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ /** * Manages a list of unique deoptimization reasons. - * + * */ public abstract class SpeculationLog { private volatile Object lastFailed;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011, 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.api.code; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.meta.*; + +/** + * Represents lock information in the debug information. + */ +public final class StackLockValue extends AbstractValue implements JavaValue { + + private static final long serialVersionUID = 8241681800464483691L; + + private Value owner; + private StackSlotValue slot; + private final boolean eliminated; + + public StackLockValue(Value object, StackSlotValue slot, boolean eliminated) { + super(LIRKind.Illegal); + this.owner = object; + this.slot = slot; + this.eliminated = eliminated; + } + + public Value getOwner() { + return owner; + } + + public void setOwner(Value newOwner) { + this.owner = newOwner; + } + + public Value getSlot() { + return slot; + } + + public boolean isEliminated() { + return eliminated; + } + + @Override + public String toString() { + return "monitor[" + owner + (slot != null ? ", " + slot : "") + (eliminated ? ", eliminated" : "") + "]"; + } + + @Override + public int hashCode() { + final int prime = 43; + int result = super.hashCode(); + result = prime * result + (eliminated ? 1231 : 1237); + result = prime * result + owner.hashCode(); + result = prime * result + slot.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof StackLockValue) { + StackLockValue other = (StackLockValue) obj; + return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot); + } + return false; + } + + public void setSlot(StackSlotValue stackSlot) { + assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot); + slot = stackSlot; + } +}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ public static boolean isIllegal(Value value) { assert value != null; - return value.equals(Value.ILLEGAL); + return Value.ILLEGAL.equals(value); } public static boolean isLegal(Value value) {
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ private static final long serialVersionUID = -2907197776426346021L; private final ResolvedJavaType type; - private JavaValue[] values; + private Value[] values; private final int id; /** @@ -54,18 +54,18 @@ * position in the compiled code. * @return a new {@link VirtualObject} instance. */ - public static VirtualObject get(ResolvedJavaType type, JavaValue[] values, int id) { + public static VirtualObject get(ResolvedJavaType type, Value[] values, int id) { return new VirtualObject(type, values, id); } - private VirtualObject(ResolvedJavaType type, JavaValue[] values, int id) { + private VirtualObject(ResolvedJavaType type, Value[] values, int id) { super(LIRKind.reference(Kind.Object)); this.type = type; this.values = values; this.id = id; } - private static StringBuilder appendValue(StringBuilder buf, JavaValue value, Set<VirtualObject> visited) { + private static StringBuilder appendValue(StringBuilder buf, Value value, Set<VirtualObject> visited) { if (value instanceof VirtualObject) { VirtualObject vo = (VirtualObject) value; buf.append("vobject:").append(vo.type.toJavaName(false)).append(':').append(vo.id); @@ -120,7 +120,7 @@ /** * Returns an array containing all the values to be stored into the object when it is recreated. */ - public JavaValue[] getValues() { + public Value[] getValues() { return values; } @@ -132,7 +132,7 @@ return id; } - private static boolean checkValues(ResolvedJavaType type, JavaValue[] values) { + private static boolean checkValues(ResolvedJavaType type, Value[] values) { if (values != null) { if (!type.isArray()) { ResolvedJavaField[] fields = type.getInstanceFields(true); @@ -140,8 +140,8 @@ for (int i = 0; i < values.length; i++) { ResolvedJavaField field = fields[fieldIndex++]; Kind valKind = values[i].getKind().getStackKind(); - if (field.getKind() == Kind.Object && values[i] instanceof Value) { - assert ((Value) values[i]).getLIRKind().isReference(0) : field + ": " + valKind + " != " + field.getKind(); + if (field.getKind() == Kind.Object) { + assert values[i].getLIRKind().isReference(0) : field + ": " + valKind + " != " + field.getKind(); } else { if ((valKind == Kind.Double || valKind == Kind.Long) && field.getKind() == Kind.Int) { assert fields[fieldIndex].getKind() == Kind.Int; @@ -156,9 +156,7 @@ Kind componentKind = type.getComponentType().getKind().getStackKind(); if (componentKind == Kind.Object) { for (int i = 0; i < values.length; i++) { - if (values[i] instanceof Value) { - assert ((Value) values[i]).getLIRKind().isReference(0) : values[i].getKind() + " != " + componentKind; - } + assert values[i].getLIRKind().isReference(0) : values[i].getKind() + " != " + componentKind; } } else { for (int i = 0; i < values.length; i++) { @@ -177,7 +175,7 @@ * @param values an array containing all the values to be stored into the object when it is * recreated. */ - public void setValues(JavaValue[] values) { + public void setValues(Value[] values) { assert checkValues(type, values); this.values = values; }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/BytecodeDisassemblerProvider.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/BytecodeDisassemblerProvider.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ /** * Gets a textual disassembly of the bytecode for a given method. In the absence of bytecode * rewriting, disassembling a method will produce the same result. - * + * * @return a non-zero length string containing a disassembly of {@code method}'s bytecode or * null if {@code method} has no bytecode (i.e., {@code method.getCodeSize() == 0}) */
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ExceptionHandler.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ExceptionHandler.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ /** * Creates a new exception handler with the specified ranges. - * + * * @param startBCI the start index of the protected range * @param endBCI the end index of the protected range * @param catchBCI the index of the handler @@ -83,7 +83,7 @@ /** * Checks whether this handler catches all exceptions. - * + * * @return {@code true} if this handler catches all exceptions */ public boolean isCatchAll() {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,7 +25,6 @@ import java.util.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; /** * This profile object represents the type profile at a specific BCI. The precision of the supplied
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,34 +31,6 @@ public interface ProfilingInfo { /** - * Represents the three possibilities that an exception was seen at a specific BCI. - */ - public enum TriState { - TRUE, - FALSE, - UNKNOWN; - - public static TriState get(boolean value) { - return value ? TRUE : FALSE; - } - - /** - * This is optimistic about {@link #UNKNOWN} (it prefers known values over {@link #UNKNOWN}) - * and pesimistic about known (it perfers {@link #TRUE} over {@link #FALSE}). - */ - public static TriState merge(TriState a, TriState b) { - if (a == TRUE || b == TRUE) { - return TRUE; - } - if (a == FALSE || b == FALSE) { - return FALSE; - } - assert a == UNKNOWN && b == UNKNOWN; - return UNKNOWN; - } - } - - /** * Returns the length of the bytecodes associated with this profile. */ int getCodeSize();
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Tue Mar 10 21:26:02 2015 +0100 @@ -282,7 +282,7 @@ /** * Checks whether the method has a receiver parameter - i.e., whether it is not static. - * + * * @return whether the method has a receiver parameter */ default boolean hasReceiver() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,77 @@ +/* + * 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.api.meta; + +/** + * Represents the three possibilities that an exception was seen at a specific BCI. + */ +public enum TriState { + TRUE, + FALSE, + UNKNOWN; + + public static TriState get(boolean value) { + return value ? TRUE : FALSE; + } + + /** + * This is optimistic about {@link #UNKNOWN} (it prefers known values over {@link #UNKNOWN}) and + * pesimistic about known (it perfers {@link #TRUE} over {@link #FALSE}). + */ + public static TriState merge(TriState a, TriState b) { + if (a == TRUE || b == TRUE) { + return TRUE; + } + if (a == FALSE || b == FALSE) { + return FALSE; + } + assert a == UNKNOWN && b == UNKNOWN; + return UNKNOWN; + } + + public boolean isTrue() { + return this == TRUE; + } + + public boolean isFalse() { + return this == FALSE; + } + + public boolean isUnknown() { + return this == UNKNOWN; + } + + public boolean isKnown() { + return this != UNKNOWN; + } + + public boolean toBoolean() { + if (isTrue()) { + return true; + } else if (isFalse()) { + return false; + } else { + throw new IllegalStateException("Cannot convert to boolean, TriState is in an unknown state"); + } + } +}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,6 +34,13 @@ public String toString() { return "-"; } + + @Override + public boolean equals(Object other) { + // Due to de-serialization this object may exist multiple times. So we compare classes + // instead of the individual objects. (This anonymous class has always the same meaning) + return other != null && this.getClass() == other.getClass(); + } }; LIRKind getLIRKind();
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ /** * Creates an {@link AMD64Address} with given base register, no scaling and no displacement. - * + * * @param base the base register */ public AMD64Address(Register base) { @@ -48,7 +48,7 @@ /** * Creates an {@link AMD64Address} with given base register, no scaling and a given * displacement. - * + * * @param base the base register * @param displacement the displacement */ @@ -59,7 +59,7 @@ /** * Creates an {@link AMD64Address} with given base and index registers, scaling and * displacement. This is the most general constructor. - * + * * @param base the base register * @param index the index register * @param scale the scaling factor
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,11 @@ */ package com.oracle.graal.asm.sparc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.sparc.SPARC.*; @@ -31,6 +36,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.sparc.*; +import com.oracle.graal.sparc.SPARC.CPUFeature; /** * This class implements an assembler that can encode most SPARC instructions. @@ -49,10 +55,6 @@ super(target); } - public interface AssemblerEmittable { - void emit(SPARCAssembler masm); - } - public static final int CCR_ICC_SHIFT = 0; public static final int CCR_XCC_SHIFT = 4; public static final int CCR_C_SHIFT = 0; @@ -60,1437 +62,32 @@ public static final int CCR_Z_SHIFT = 2; public static final int CCR_N_SHIFT = 3; - // @formatter:off - /** - * Instruction format for Fmt00 instructions. This abstraction is needed as it - * makes the patching easier later on. - * <pre> - * | 00 | ?? | op2 | ?? | - * |31 30|29 25|24 22|21 0| - * </pre> - */ - // @formatter:on - public abstract static class Fmt00 implements AssemblerEmittable { - - protected static final int OP_SHIFT = 30; - protected static final int CBCOND_SHIFT = 28; - protected static final int OP2_SHIFT = 22; - protected static final int A_SHIFT = 29; - - // @formatter:off - protected static final int A_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000; - protected static final int OP_MASK = 0b1100_0000_0000_0000_0000_0000_0000_0000; - protected static final int CBCOND_MASK = 0b0001_0000_0000_0000_0000_0000_0000_0000; // Used for distinguish CBcond and BPr instructions - protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000; - // @formatter:off - - private int op2; - - public Fmt00(int op2) { - this.op2 = op2; - } - - public static Fmt00 read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - Op2s op2 = Op2s.byValue((inst & OP2_MASK) >> OP2_SHIFT); - switch(op2) { - case Br: - case Fb: - return Fmt00b.read(masm, op2, pos); - case Sethi: - case Illtrap: - return Fmt00a.read(masm, pos); - case Bp: - return Fmt00c.read(masm, pos); - case Bpr: - boolean isCBcond = (inst & CBCOND_MASK) != 0; - if (isCBcond) { - return Fmt00e.read(masm, pos); - } else { - return Fmt00d.read(masm, pos); - } - default: - throw GraalInternalError.shouldNotReachHere("Unknown op2 " + op2); - } - } - - public void write(SPARCAssembler masm, int pos) { - verify(); - masm.emitInt(getInstructionBits(), pos); - } - - public Op2s getOp2s() { - return Op2s.byValue(op2); - } - - protected int getInstructionBits() { - return Ops.BranchOp.getValue() << OP_SHIFT | op2 << OP2_SHIFT; - } - - public void verify() { - assert ((op2 << OP2_SHIFT) & OP2_MASK) == (op2 << OP2_SHIFT) : Integer.toHexString(op2); - assert Op2s.byValue(op2) != null : op2; - } - /** - * Sets the immediate (displacement) value on this instruction. - * - * @see SPARCAssembler#patchJumpTarget(int, int) - * @param imm Displacement/imediate value. Can either be a 22 or 19 bit immediate (dependent on the instruction) - */ - public abstract void setImm(int imm); - - public abstract void emit(SPARCAssembler masm); - - public boolean hasDelaySlot() { - return true; - } - - public int getA() { - throw GraalInternalError.shouldNotReachHere(); - } - public void setA(@SuppressWarnings("unused") int a) { - throw GraalInternalError.shouldNotReachHere(); - } - } - - // @formatter:off - /** - * Instruction format for sethi. - * <pre> - * | 00 | rd | op2 | imm22 | - * |31 30|29 25|24 22|21 0| - * </pre> - */ - // @formatter:on - public static class Fmt00a extends Fmt00 implements AssemblerEmittable { - - private static final int RD_SHIFT = 25; - private static final int IMM22_SHIFT = 0; - - // @formatter:off - private static final int RD_MASK = 0b00111110000000000000000000000000; - private static final int IMM22_MASK = 0b00000000001111111111111111111111; - // @formatter:on - - private int rd; - private int imm22; - - private Fmt00a(int rd, int op2, int imm22) { - super(op2); - this.rd = rd; - this.imm22 = imm22; - verify(); - } - - public Fmt00a(Op2s op2, int imm22, Register rd) { - this(rd.encoding(), op2.getValue(), imm22); - } - - @Override - protected int getInstructionBits() { - return super.getInstructionBits() | rd << RD_SHIFT | (imm22 & IMM22_MASK) << IMM22_SHIFT; - } - - public static Fmt00a read(SPARCAssembler masm, int pos) { - final int inst = masm.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); - } - - @Override - public void emit(SPARCAssembler masm) { - verify(); - masm.emitInt(getInstructionBits()); - } - - @Override - public void verify() { - super.verify(); - assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT); - assert ((imm22 << IMM22_SHIFT) & IMM22_MASK) == (imm22 << IMM22_SHIFT) : String.format("imm22: %d (%x)", imm22, imm22); - } - - @Override - public void setImm(int imm) { - setImm22(imm); - } - - public void setImm22(int imm22) { - this.imm22 = imm22; - } - - @Override - public boolean hasDelaySlot() { - return false; - } - } - - // @formatter:off - /** - * Instruction format for branches. - * <pre> - * | 00 |a | cond | op2 | disp22 | - * |31 30|29|28 25|24 22|21 0| - * </pre> - */ - // @formatter:on - public static class Fmt00b extends Fmt00 { - private int a; - private int cond; - private int disp22; - private Label label; - - private static final int COND_SHIFT = 25; - private static final int DISP22_SHIFT = 0; - - // @formatter:off - private static final int COND_MASK = 0b00011110000000000000000000000000; - private static final int DISP22_MASK = 0b00000000001111111111111111111111; - // @formatter:on - - public Fmt00b(boolean annul, ConditionFlag cond, Op2s op2, Label label) { - this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label); - } - - public Fmt00b(boolean annul, FCond cond, Op2s op2, Label label) { - this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label); - } - - public Fmt00b(int annul, int cond, int op2, Label label) { - this(annul, cond, op2, 0, label); - } - - public Fmt00b(boolean annul, FCond cond, Op2s op2, int disp22) { - this(annul ? 1 : 0, cond.getValue(), op2.getValue(), disp22, null); - } - - public Fmt00b(int annul, int cond, int op2, int disp22) { - this(annul, cond, op2, disp22, null); - } - - public Fmt00b(int a, int cond, int op2, int disp22, Label label) { - super(op2); - setA(a); - setCond(cond); - setDisp22(disp22); - setLabel(label); - } - - @Override - public void emit(SPARCAssembler masm) { - if (label != null) { - final int pos = label.isBound() ? label.position() : patchUnbound(masm, label); - final int disp = pos - masm.position(); - setDisp22(disp); - } - verify(); - masm.emitInt(getInstructionBits()); - } - - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.position()); - return 0; - } - - @Override - protected int getInstructionBits() { - int inst = super.getInstructionBits() | a << A_SHIFT | cond << COND_SHIFT | (disp22 & DISP22_MASK) << DISP22_SHIFT; - return inst; - } - - protected static Fmt00b read(SPARCAssembler masm, Op2s op2, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - assert op == Ops.BranchOp.getValue(); - final int op2Read = (inst & OP2_MASK) >> OP2_SHIFT; - assert op2Read == op2.getValue() : "Op2 value read: " + op2Read + " Required op2: " + op2; - - // Get the instruction fields: - final int a = (inst & A_MASK) >> A_SHIFT; - final int cond = (inst & COND_MASK) >> COND_SHIFT; - final int disp22 = (inst & DISP22_MASK) >> DISP22_SHIFT << 2; - - Fmt00b fmt = new Fmt00b(a, cond, op2.getValue(), disp22); - fmt.verify(); - return fmt; - } - - @Override - public int getA() { - return a; - } - - @Override - public void setA(int a) { - this.a = a; - } - - public int getCond() { - return cond; - } - - public void setCond(int cond) { - this.cond = cond; - } - - public int getDisp22() { - return disp22 << 2; - } - - @Override - public void setImm(int imm) { - setDisp22(imm); - } - - public void setDisp22(int disp22) { - this.disp22 = disp22 >> 2; - } - - public Label getLabel() { - return label; - } - - public void setLabel(Label label) { - this.label = label; - } - - @Override - public void verify() { - super.verify(); - assert (getA() << A_SHIFT & ~A_MASK) == 0 : getA(); - assert (getCond() << COND_SHIFT & ~COND_MASK) == 0 : getCond(); - } - } - - // @formatter:off - /** - * Instruction format for conditional branches. - * <pre> - * | 00 |a | cond | op2 |cc1|cc0|p | disp19 | - * |31 30|29|28 25|24 22|21 |20 |19| 0| - * </pre> - */ - // @formatter:on - public static class Fmt00c extends Fmt00 { - - private static final int COND_SHIFT = 25; - private static final int CC_SHIFT = 20; - private static final int P_SHIFT = 19; - private static final int DISP19_SHIFT = 0; - - // @formatter:off - private static final int COND_MASK = 0b00011110000000000000000000000000; - private static final int CC_MASK = 0b00000000001100000000000000000000; - private static final int P_MASK = 0b00000000000010000000000000000000; - private static final int DISP19_MASK = 0b00000000000001111111111111111111; - // @formatter:on - - private int a; - private int cond; - private int cc; - private int p; - private int disp19; - private Label label; - - private Fmt00c(int a, int cond, int op2, int cc, int p, int disp19) { - super(op2); - setA(a); - setCond(cond); - setCc(cc); - setP(p); - setDisp19(disp19); - verify(); - } + protected static final int OP_SHIFT = 30; + protected static final int CBCOND_SHIFT = 28; + protected static final int OP2_SHIFT = 22; + protected static final int A_SHIFT = 29; - public Fmt00c(int a, ConditionFlag cond, Op2s op2, CC cc, int p, int disp19) { - this(a, cond.getValue(), op2.getValue(), cc.getValue(), p, disp19); - } - - public Fmt00c(int a, ConditionFlag cond, Op2s op2, CC cc, int p, Label label) { - this(a, cond.getValue(), op2.getValue(), cc.getValue(), p, 0); - this.label = label; - } - - @Override - public int getA() { - return a; - } - - @Override - public void setA(int a) { - this.a = a; - } - - public int getCond() { - return cond; - } - - public void setCond(int cond) { - this.cond = cond; - } - - public int getCc() { - return cc; - } - - public void setCc(int cc) { - this.cc = cc; - } - - public int getP() { - return p; - } - - public void setP(int p) { - this.p = p; - } - - /** - * Return the displacement in bytes. - */ - public int getDisp19() { - return disp19 << 2; - } - - /** - * The instructions requires displacements to be word-sized. - */ - public void setDisp19(int disp19) { - this.disp19 = disp19 >> 2; - } - - @Override - public void setImm(int imm) { - setDisp19(imm); - } - - @Override - protected int getInstructionBits() { - return super.getInstructionBits() | a << A_SHIFT | cond << COND_SHIFT | cc << CC_SHIFT | p << P_SHIFT | (disp19 & DISP19_MASK) << DISP19_SHIFT; - } - - public static Fmt00c read(SPARCAssembler masm, int pos) { - final int inst = masm.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 a = (inst & A_MASK) >> A_SHIFT; - final int cond = (inst & COND_MASK) >> COND_SHIFT; - final int op2 = (inst & OP2_MASK) >> OP2_SHIFT; - final int cc = (inst & CC_MASK) >> CC_SHIFT; - final int p = (inst & P_MASK) >> P_SHIFT; - final int disp19 = (inst & DISP19_MASK) >> DISP19_SHIFT << 2; - - Fmt00c fmt = new Fmt00c(a, cond, op2, cc, p, disp19); - fmt.verify(); - return fmt; - } - - @Override - public void emit(SPARCAssembler masm) { - if (label != null) { - final int pos = label.isBound() ? label.position() : patchUnbound(masm, label); - final int disp = pos - masm.position(); - setDisp19(disp); - } - verify(); - masm.emitInt(getInstructionBits()); - } - - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.position()); - return 0; - } - - @Override - public void verify() { - super.verify(); - assert p < 2; - assert cond < 0x10; - } - - @Override - public String toString() { - return "Fmt00c [a=" + a + ", cond=" + cond + ", cc=" + cc + ", p=" + p + ", disp19=" + disp19 + ", label=" + label + "]"; - } - } - - // @formatter:off - /** - * Instruction format for Branch on Integer Register with Prediction. - * <pre> - * |00 |a |- |rcond | 011 |d16hi|p | rs1 | d16lo | - * |31 30|29|28|27 25|24 22|21 20|19|18 14| 0| - * </pre> - */ - // @formatter:on - public static class Fmt00d extends Fmt00 { - - private static final int RCOND_SHIFT = 25; - private static final int D16HI_SHIFT = 20; - private static final int P_SHIFT = 19; - private static final int RS1_SHIFT = 14; - private static final int D16LO_SHIFT = 0; - - // @formatter:off - private static final int RCOND_MASK = 0b0000_1110_0000_0000_0000_0000_0000_0000; - private static final int D16HI_MASK = 0b0000_0000_0011_0000_0000_0000_0000_0000; - private static final int P_MASK = 0b0000_0000_0000_1000_0000_0000_0000_0000; - private static final int RS1_MASK = 0b0000_0000_0000_0111_1100_0000_0000_0000; - private static final int D16LO_MASK = 0b0000_0000_0000_0000_0011_1111_1111_1111; - // @formatter:on - - private int annul; - private int rCondition; - private int disp16; - private int predictTaken; - private int rs1; - private Label label; - - public Fmt00d(int op2, int rCondition, int predictTaken, int annul, int d16, int rs1, Label label) { - super(op2); - this.annul = annul; - this.rCondition = rCondition; - setDisp16(d16); - this.predictTaken = predictTaken; - this.rs1 = rs1; - this.label = label; - } - - @Override - public void setImm(int imm) { - setDisp16(imm); - } - - public void setDisp16(int disp16) { - this.disp16 = disp16 >> 2; - } - - @Override - public int getA() { - return annul; - } - - @Override - public void emit(SPARCAssembler masm) { - if (label != null) { - final int pos = label.isBound() ? label.position() : patchUnbound(masm, label); - final int disp = pos - masm.position(); - setDisp16(disp); - } - verify(); - masm.emitInt(getInstructionBits()); - } - - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.position()); - return 0; - } - - @Override - protected int getInstructionBits() { - int d16Split = 0; - d16Split |= (disp16 & 0b1100_0000_0000_0000) << D16HI_SHIFT - 14; - d16Split |= (disp16 & 0b0011_1111_1111_1111) << D16LO_SHIFT; - return super.getInstructionBits() | annul << A_SHIFT | rCondition << RCOND_SHIFT | d16Split | predictTaken << P_SHIFT | rs1 << RS1_SHIFT; - } - - public static Fmt00d read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - final int op2 = (inst & OP2_MASK) >> OP2_SHIFT; - final int condFlag = (inst & CBCOND_MASK) >> CBCOND_SHIFT; - assert op2 == Op2s.Bpr.getValue() && op == Ops.BranchOp.getValue() && condFlag == 0 : "0x" + Integer.toHexString(inst); - - // Get the instruction fields: - final int a = (inst & A_MASK) >> A_SHIFT; - final int cond = (inst & RCOND_MASK) >> RCOND_SHIFT; - final int p = (inst & P_MASK) >> P_SHIFT; - final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT; - final int d16hi = (inst & D16HI_MASK) >> D16HI_SHIFT; - assert (d16hi & ~0b11) == 0; - final int d16lo = (inst & D16LO_MASK) >> D16LO_SHIFT; - assert (d16lo & ~((1 << 14) - 1)) == 0; - final int d16 = (short) (((d16hi << 14) | d16lo) << 2); // times 4 and sign extend - Fmt00d fmt = new Fmt00d(op2, cond, p, a, d16, rs1, null); - fmt.verify(); - return fmt; - } - - @Override - public void verify() { - super.verify(); - assert (annul & ~1) == 0 : annul; - assert (rCondition & ~0b111) == 0 : rCondition; - assert isSimm(disp16, 16) : disp16; - assert (predictTaken & ~1) == 0 : predictTaken; - assert (rs1 & ~((1 << 5) - 1)) == 0 : rs1; - } - } - - // @formatter:off - /** - * Instruction format CBcond. - * <pre> - * |00 |chi|1 | clo | 011 |cc2|d10hi|rs1 |i |d10lo|rs2/simm5| - * |31 30|29 |28|27 25|24 22|21 |20 19|18 14|13|12 5|4 0| - * </pre> - */ - // @formatter:on - public static class Fmt00e extends Fmt00 { - private static final int CHI_SHIFT = 29; - private static final int CLO_SHIFT = 25; - private static final int CC2_SHIFT = 21; - private static final int D10HI_SHIFT = 19; - private static final int RS1_SHIFT = 14; - private static final int I_SHIFT = 13; - private static final int D10LO_SHIFT = 5; - private static final int RS2_SHIFT = 0; - - // @formatter:off - private static final int CHI_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000; - private static final int CLO_MASK = 0b0000_1110_0000_0000_0000_0000_0000_0000; - private static final int CC2_MASK = 0b0000_0000_0010_0000_0000_0000_0000_0000; - private static final int D10HI_MASK = 0b0000_0000_0001_1000_0000_0000_0000_0000; - private static final int RS1_MASK = 0b0000_0000_0000_0111_1100_0000_0000_0000; - private static final int I_MASK = 0b0000_0000_0000_0000_0010_0000_0000_0000; - private static final int D10LO_MASK = 0b0000_0000_0000_0000_0001_1111_1110_0000; - private static final int RS2_MASK = 0b0000_0000_0000_0000_0000_0000_0001_1111; - // @formatter:on - - private int c; - private int cc2; - private int disp10; - private int rs1; - private int i; - private int regOrImmediate; - private Label label; - - public Fmt00e(int c, int cc2, int rs1, int disp10, int i, int regOrImmediate, Label label) { - super(Op2s.Bpr.getValue()); - this.c = c; - this.cc2 = cc2; - this.rs1 = rs1; - setDisp10(disp10); - this.i = i; - this.regOrImmediate = regOrImmediate; - this.label = label; - } - - @Override - public void setImm(int imm) { - setDisp10(imm); - } - - public void setDisp10(int disp10) { - this.disp10 = disp10 >> 2; - if (!isSimm10(this.disp10)) { - throw GraalInternalError.shouldNotReachHere("" + this.disp10); - } - assert isSimm10(this.disp10) : this.disp10; - } - - @Override - public void emit(SPARCAssembler masm) { - assert masm.hasFeature(CPUFeature.CBCOND); - if (label != null) { - if (label.isBound()) { - final int disp = label.position() - masm.position(); - setDisp10(disp); - } else { - patchUnbound(masm, label); - setDisp10(0); - } - } - verify(); - masm.emitInt(getInstructionBits()); - } - - private static int patchUnbound(SPARCAssembler masm, Label label) { - label.addPatchAt(masm.position()); - return 0; - } - - @Override - protected int getInstructionBits() { - int cSplit = 0; - cSplit |= (c & 0b1000) << CHI_SHIFT - 3; - cSplit |= (c & 0b0111) << CLO_SHIFT; - int d10Split = 0; - d10Split |= (disp10 & 0b11_0000_0000) << D10HI_SHIFT - 8; - d10Split |= (disp10 & 0b00_1111_1111) << D10LO_SHIFT; - int bits = super.getInstructionBits() | 1 << 28 | cSplit | cc2 << CC2_SHIFT | d10Split | rs1 << RS1_SHIFT | i << I_SHIFT | (regOrImmediate & 0b1_1111) << RS2_SHIFT; - int hibits = (bits & 0xFF000000); - if (hibits == 0xFF000000 || hibits == 0) { - throw GraalInternalError.shouldNotReachHere(); - } - return bits; - } - - public static Fmt00e read(SPARCAssembler masm, int pos) { - assert masm.hasFeature(CPUFeature.CBCOND); - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - final int op2 = (inst & OP2_MASK) >> OP2_SHIFT; - final int condFlag = (inst & CBCOND_MASK) >> CBCOND_SHIFT; - assert op2 == Op2s.Bpr.getValue() && op == Ops.BranchOp.getValue() && condFlag == 1 : "0x" + Integer.toHexString(inst); - - // @formatter:off - // Get the instruction fields: - final int chi = (inst & CHI_MASK) >> CHI_SHIFT; - final int clo = (inst & CLO_MASK) >> CLO_SHIFT; - final int cc2 = (inst & CC2_MASK) >> CC2_SHIFT; - final int d10hi = (inst & D10HI_MASK) >> D10HI_SHIFT; - final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT; - final int i = (inst & I_MASK) >> I_SHIFT; - final int d10lo = (inst & D10LO_MASK) >> D10LO_SHIFT; - int regOrImmediate = (inst & RS2_MASK) >> RS2_SHIFT; - // @formatter:on - if (i == 1) { // if immediate, we do sign extend - int shiftcnt = 31 - 4; - regOrImmediate = (regOrImmediate << shiftcnt) >> shiftcnt; - } - int c = chi << 3 | clo; + protected static final int A_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000; + protected static final int OP_MASK = 0b1100_0000_0000_0000_0000_0000_0000_0000; + protected static final int CBCOND_MASK = 0b0001_0000_0000_0000_0000_0000_0000_0000; // Used for + // distinguish CBcond and BPr instructions + protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000; - assert (d10lo & ~((1 << 8) - 1)) == 0; - final int d10 = ((short) (((d10hi << 8) | d10lo) << 6)) >> 4; // Times 4 and sign extend - Fmt00e fmt = new Fmt00e(c, cc2, rs1, d10, i, regOrImmediate, null); - fmt.verify(); - return fmt; - } - - @Override - public void verify() { - super.verify(); - assert (c & ~0b1111) == 0 : c; - assert (cc2 & ~1) == 0 : cc2; - assert isSimm(disp10, 10) : disp10; - assert (rs1 & ~0b1_1111) == 0 : rs1; - assert (i & ~1) == 0 : i; - if (i == 1) { - assert isSimm(regOrImmediate, 5) : regOrImmediate; - } else { - assert (regOrImmediate & ~0b1_1111) == 0 : regOrImmediate; - } - } - - @Override - public boolean hasDelaySlot() { - return false; - } - } - - // @formatter:off - /** - * Instruction format for calls. - * <pre> - * | 01 | disp30 | - * |31 30|29 0| - * </pre> - */ - // @formatter:on - public static class Fmt01 { - - private static final int OP_SHIFT = 30; - private static final int DISP30_SHIFT = 0; - - // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; - private static final int DISP30_MASK = 0b00111111111111111111111111111111; - // @formatter:on - - private int disp30; - - public Fmt01(int disp30) { - setDisp30(disp30); - } - - /** - * Return the displacement in bytes. - */ - public int getDisp30() { - return disp30 << 2; - } - - /** - * The instructions requires displacements to be word-sized. - */ - public void setDisp30(int disp30) { - this.disp30 = disp30 >> 2; - } - - private int getInstructionBits() { - return Ops.CallOp.getValue() << OP_SHIFT | (disp30 & DISP30_MASK) << DISP30_SHIFT; - } - - public static Fmt01 read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - assert op == Ops.CallOp.getValue(); - - // Get the instruction fields: - final int disp30 = (inst & DISP30_MASK) >> DISP30_SHIFT << 2; - - Fmt01 fmt = new Fmt01(disp30); - fmt.verify(); - return fmt; - } - - public void write(SPARCAssembler masm, int pos) { - verify(); - masm.emitInt(getInstructionBits(), pos); - } - - public void emit(SPARCAssembler masm) { - verify(); - masm.emitInt(getInstructionBits()); - } - - public void verify() { - assert isDisp30(disp30) : disp30; - } - } - - public static class Fmt3f { - - public Fmt3f(SPARCAssembler masm, int op, int op3, int rcond, int rs1, int simm10, int rd) { - assert op == 2 || op == 3; - assert op3 >= 0 && op3 < 0x40; - assert rs1 >= 0 && rs1 < 0x20; - assert rd >= 0 && rd < 0x20; - - masm.emitInt(op << 30 | rd << 25 | op3 << 19 | ImmedTrue | rs1 << 14 | rcond << 10 | (simm10 & 0x000003ff)); - } - } - - public static class Fmt3n { - private int op; - private int op3; - private int opf; - private int rs2; - private int rd; - - public Fmt3n(int op, int op3, int opf, int rs2, int rd) { - this.op = op; - this.op3 = op3; - this.opf = opf; - this.rs2 = rs2; - this.rd = rd; - } - - public void emit(SPARCAssembler masm) { - verify(); - masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2); - } - - public void verify() { - assert op == 2 || op == 3; - assert op3 >= 0 && op3 < 0x40; - assert opf >= 0 && opf < 0x200; - assert rs2 >= 0 && rs2 < 0x20; - assert rd >= 0 && rd < 0x20; - } - } - - public static class Fmt3p { - - private int op; - private int op3; - private int opf; - private int rs1; - private int rs2; - private int rd; - - public Fmt3p(Ops op, Op3s op3, Opfs opf, Register rs1, Register rs2, Register rd) { - this.op = op.getValue(); - this.op3 = op3.getValue(); - this.opf = opf.getValue(); - this.rs1 = rs1.encoding(); - this.rs2 = rs2.encoding(); - this.rd = rd.encoding(); - } - - public void emit(SPARCAssembler masm) { - assert op == 2 || op == 3 : op; - assert op3 >= 0 && op3 < 0x40 : op3; - assert opf >= 0 && opf < 0x200 : opf; - assert rs1 >= 0 && rs1 < 0x20 : rs1; - assert rs2 >= 0 && rs2 < 0x20 : rs2; - assert rd >= 0 && rd < 0x20 : rd; - - masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | opf << 5 | rs2); - } - } + protected static final int DISP22_SHIFT = 0; + protected static final int DISP22_MASK = 0b00000000001111111111111111111111; - // @formatter:off - /** - * Instruction format for fcmp. - * <pre> - * | 10 | --- |cc1|cc0|desc | rs1 | opf | rs2 | - * |31 30|29 27|26 |25 |24 19|18 14|13 5|4 0| - * </pre> - */ - // @formatter:on - public static class Fmt3c { - private int op; - private int cc; - private int desc; - private int opf; - private int rs1; - private int rs2; - - public Fmt3c(Ops op, CC cc, int desc, Opfs opf, Register rs1, Register rs2) { - this.op = op.getValue(); - this.opf = opf.getValue(); - this.desc = desc; - this.rs1 = rs1.encoding(); - this.rs2 = rs2.encoding(); - this.cc = cc.getValue(); - } - - public void emit(SPARCAssembler masm) { - assert op == 2 || op == 3; - assert cc >= 0 && cc < 0x4; - assert opf >= 0 && opf < 0x200; - assert rs1 >= 0 && rs1 < 0x20; - assert rs2 >= 0 && rs2 < 0x20; - assert desc >= 0 && desc < 0x40; - - masm.emitInt(op << 30 | cc << 25 | desc << 19 | rs1 << 14 | opf << 5 | rs2); - } - } - - // @formatter:off - /** - * Instruction format for Arithmetic, Logical, Moves, Tcc, Prefetch, and Misc. - * <pre> - * | 10 | rd | op3 | rs1 | i| imm_asi | rs2 | - * | 10 | rd | op3 | rs1 | i| simm13 | - * | 10 | rd | op3 | rs1 | i| x| | rs2 | - * | 10 | rd | op3 | rs1 | i| x| | shcnt32 | - * | 10 | rd | op3 | rs1 | i| x| | shcnt64 | - * |31 30|29 25|24 19|18 14|13|12|11 5|4 0| - * </pre> - */ - // @formatter:on - public static class Fmt10 implements AssemblerEmittable { - - private static final int OP_SHIFT = 30; - private static final int RD_SHIFT = 25; - private static final int OP3_SHIFT = 19; - private static final int RS1_SHIFT = 14; - private static final int I_SHIFT = 13; - private static final int X_SHIFT = 12; - private static final int IMM_ASI_SHIFT = 5; - private static final int RS2_SHIFT = 0; - private static final int SIMM13_SHIFT = 0; - - // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; - private static final int RD_MASK = 0b00111110000000000000000000000000; - private static final int OP3_MASK = 0b00000001111110000000000000000000; - private static final int RS1_MASK = 0b00000000000001111100000000000000; - private static final int I_MASK = 0b00000000000000000010000000000000; - private static final int X_MASK = 0b00000000000000000001000000000000; - private static final int IMM_ASI_MASK = 0b00000000000000000001111111100000; - private static final int RS2_MASK = 0b00000000000000000000000000011111; - private static final int SIMM13_MASK = 0b00000000000000000001111111111111; - // @formatter:on - - private int rd; - private int op3; - private int rs1; - private int i; - private int x; - private int immAsi; - private int rs2; - private int simm13; - - private Fmt10(int rd, int op3, int rs1, int i, int x, int immAsi, int rs2, int simm13) { - this.rd = rd; - this.op3 = op3; - this.rs1 = rs1; - this.i = i; - this.x = x; - this.immAsi = immAsi; - this.rs2 = rs2; - this.simm13 = simm13; - verify(); - } - - public Fmt10(Op3s op3, Register rs1, Register rs2, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, getXBit(op3), 0, rs2.encoding(), 0); - } - - public Fmt10(Op3s op3, Register rs1, int simm13, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, getXBit(op3), 0, 0, simm13); - } - - /** - * Used for trap on Integer Condition Codes (Tcc). - * - * @param op3 - * @param rs1 - * @param simm13 - * @param cf - */ - public Fmt10(Op3s op3, Register rs1, int simm13, ConditionFlag cf) { - this(cf.getValue(), op3.getValue(), rs1.encoding(), 1, getXBit(op3), 0, 0, simm13); - } - - public Fmt10(Op3s op3) { - this(0, op3.getValue(), 0, 0, getXBit(op3), 0, 0, 0); - } - - public Fmt10(Op3s op3, Register rs1, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, getXBit(op3), 0, 0, 0); - } - - /** - * Helper method to determine if the instruction needs the X bit set. - */ - private static int getXBit(Op3s op3) { - switch (op3) { - case Sllx: - case Srax: - case Srlx: - return 1; - default: - return 0; - } - } - - private int getInstructionBits() { - if (i == 0) { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | x << X_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT; - } else { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | x << X_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK); - } - } - - public static Fmt10 read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - assert op == Ops.ArithOp.getValue(); - - // Get the instruction fields: - final int rd = (inst & RD_MASK) >> RD_SHIFT; - final int op3 = (inst & OP3_MASK) >> OP3_SHIFT; - final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT; - final int i = (inst & I_MASK) >> I_SHIFT; - final int x = (inst & X_MASK) >> X_SHIFT; - final int immAsi = (inst & IMM_ASI_MASK) >> IMM_ASI_SHIFT; - final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT; - final int simm13 = (inst & SIMM13_MASK) >> SIMM13_SHIFT; - - return new Fmt10(rd, op3, rs1, i, x, immAsi, rs2, simm13); - } - - public void write(SPARCAssembler masm, int pos) { - verify(); - masm.emitInt(getInstructionBits(), pos); - } - - public void emit(SPARCAssembler masm) { - verify(); - masm.emitInt(getInstructionBits()); - } - - public void verify() { - assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT) : this; - assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT) : this; - assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT) : this; - assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT) : this; - assert ((x << X_SHIFT) & X_MASK) == (x << X_SHIFT) : this; - assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT) : this; - assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT) : this; - assert isSimm13(simm13) : this; - } + protected static final int DISP19_SHIFT = 0; + protected static final int DISP19_MASK = 0b00000000000001111111111111111111; - @Override - public String toString() { - return String.format("%s: [rd: 0x%x, op3: 0x%x, rs1: 0x%x, i: 0x%x, x: 0x%x, immAsi: 0x%x, rs2: 0x%x, simm13: 0x%x", getClass().getName(), rd, op3, rs1, i, x, immAsi, rs2, simm13); - } - } - - // @formatter:off - /** - * Instruction format for Loads, Stores and Misc. - * <pre> - * | 11 | rd | op3 | rs1 | i| imm_asi | rs2 | - * | 11 | rd | op3 | rs1 | i| simm13 | - * |31 30|29 25|24 19|18 14|13|12 5|4 0| - * </pre> - */ - // @formatter:on - public static class Fmt11 { - - private static final int OP_SHIFT = 30; - private static final int RD_SHIFT = 25; - private static final int OP3_SHIFT = 19; - private static final int RS1_SHIFT = 14; - private static final int I_SHIFT = 13; - private static final int IMM_ASI_SHIFT = 5; - private static final int RS2_SHIFT = 0; - private static final int SIMM13_SHIFT = 0; - - // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; - private static final int RD_MASK = 0b00111110000000000000000000000000; - private static final int OP3_MASK = 0b00000001111110000000000000000000; - private static final int RS1_MASK = 0b00000000000001111100000000000000; - private static final int I_MASK = 0b00000000000000000010000000000000; - private static final int IMM_ASI_MASK = 0b00000000000000000001111111100000; - private static final int RS2_MASK = 0b00000000000000000000000000011111; - private static final int SIMM13_MASK = 0b00000000000000000001111111111111; - // @formatter:on - - private int rd; - private int op3; - private int rs1; - private int i; - private int immAsi; - private int rs2; - private int simm13; - - private Fmt11(int rd, int op3, int rs1, int i, int immAsi, int rs2, int simm13) { - this.rd = rd; - this.op3 = op3; - this.rs1 = rs1; - this.i = i; - this.immAsi = immAsi; - this.rs2 = rs2; - this.simm13 = simm13; - verify(); - } - - public Fmt11(Op3s op3, Register rs1, Register rs2, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, rs2.encoding(), 0); - } - - public Fmt11(Op3s op3, Register rs1, int simm13, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, 0, 0, simm13); - } - - public Fmt11(Op3s op3, Register rs1, Register rd) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, 0, 0); - } - - /** - * Special constructor for {@link Casa} and {@link Casxa}. - */ - public Fmt11(Op3s op3, Register rs1, Register rs2, Register rd, Asi asi) { - this(rd.encoding(), op3.getValue(), rs1.encoding(), asi.isValid() ? 0 : 1, asi.isValid() ? asi.getValue() : 0, rs2.encoding(), 0); - assert asi.isValid() : "default asi is not supported yet"; - } - - /** - * Special constructor for loads and stores. - */ - public Fmt11(Op3s op3, SPARCAddress addr, Register rd) { - this(rd.encoding(), op3.getValue(), addr.getBase().encoding(), 0, 0, 0, 0); - decodeAddress(addr); - } - - /** - * Special constructor for {@link Prefetch} and Prefetcha. - */ - public Fmt11(Op3s op3, SPARCAddress addr, Prefetch.Fcn fcn) { - this(fcn.getValue(), op3.getValue(), addr.getBase().encoding(), 0, 0, 0, 0); - decodeAddress(addr); - } - - private void decodeAddress(SPARCAddress addr) { - if (!addr.getIndex().equals(Register.None)) { - this.rs2 = addr.getIndex().encoding(); - } else { - this.simm13 = addr.getDisplacement(); - this.i = 1; - } - verify(); - } - - private int getInstructionBits() { - if (i == 0) { - return Ops.LdstOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT; - } else { - return Ops.LdstOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK); - } - } - - public static Fmt11 read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - assert op == Ops.LdstOp.getValue(); - - // Get the instruction fields: - final int rd = (inst & RD_MASK) >> RD_SHIFT; - final int op3 = (inst & OP3_MASK) >> OP3_SHIFT; - final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT; - final int i = (inst & I_MASK) >> I_SHIFT; - final int immAsi = (inst & IMM_ASI_MASK) >> IMM_ASI_SHIFT; - final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT; - final int simm13 = (inst & SIMM13_MASK) >> SIMM13_SHIFT; - - return new Fmt11(rd, op3, rs1, i, immAsi, rs2, simm13); - } - - public void write(SPARCAssembler masm, int pos) { - verify(); - masm.emitInt(getInstructionBits(), pos); - } - - public void emit(SPARCAssembler masm) { - verify(); - masm.emitInt(getInstructionBits()); - } - - public void verify() { - assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT) : rd; - assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT) : op3; - assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT) : rs1; - 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) : String.format("simm13: %d (%x)", simm13, simm13); - } - } - - // @formatter:off - /** - * Instruction format for Movcc. - * <pre> - * | 10 | rd | op3 |cc2| cond | i|cc1|cc0| - | rs2 | - * | 10 | rd | op3 |cc2| cond | i|cc1|cc0| simm11 | - * |31 30|29 25|24 19| 18|17 14|13| 12| 11|10 5|4 0| - * </pre> - */ - // @formatter:on - public static class Fmt10c { - - private static final int OP_SHIFT = 30; - private static final int RD_SHIFT = 25; - private static final int OP3_SHIFT = 19; - private static final int CC2_SHIFT = 18; - private static final int COND_SHIFT = 14; - private static final int I_SHIFT = 13; - private static final int CC1_SHIFT = 12; - private static final int CC0_SHIFT = 11; - private static final int RS2_SHIFT = 0; - private static final int SIMM11_SHIFT = 0; + protected static final int D16HI_SHIFT = 20; + protected static final int D16HI_MASK = 0b0000_0000_0011_0000_0000_0000_0000_0000; + protected static final int D16LO_SHIFT = 0; + protected static final int D16LO_MASK = 0b0000_0000_0000_0000_0011_1111_1111_1111; - // @formatter:off - private static final int OP_MASK = 0b11000000000000000000000000000000; - private static final int RD_MASK = 0b00111110000000000000000000000000; - private static final int OP3_MASK = 0b00000001111110000000000000000000; - private static final int CC2_MASK = 0b00000000000001000000000000000000; - private static final int COND_MASK = 0b00000000000000111100000000000000; - private static final int I_MASK = 0b00000000000000000010000000000000; - private static final int CC1_MASK = 0b00000000000000000001000000000000; - private static final int CC0_MASK = 0b00000000000000000000100000000000; - private static final int RS2_MASK = 0b00000000000000000000000000011111; - private static final int SIMM11_MASK = 0b00000000000000000000011111111111; - // @formatter:on - - private int rd; - private int op3; - private int cond; - private int i; - private int cc; - private int rs2; - private int simm11; - - private Fmt10c(int rd, int op3, int cond, int i, int cc, int rs2, int simm11) { - this.rd = rd; - this.op3 = op3; - this.cond = cond; - this.i = i; - this.cc = cc; - this.rs2 = rs2; - this.simm11 = simm11; - verify(); - } - - public Fmt10c(Op3s op3, ConditionFlag cond, CC cc, Register rs2, Register rd) { - this(rd.encoding(), op3.getValue(), cond.getValue(), 0, getCC(cc), rs2.encoding(), 0); - } - - public Fmt10c(Op3s op3, ConditionFlag cond, CC cc, int simm11, Register rd) { - this(rd.encoding(), op3.getValue(), cond.getValue(), 1, getCC(cc), 0, simm11); - } - - /** - * Converts regular CC codes to CC codes used by Movcc instructions. - */ - public static int getCC(CC cc) { - switch (cc) { - case Icc: - case Xcc: - return 0b100 + cc.getValue(); - default: - return cc.getValue(); - } - } - - private int getInstructionBits() { - if (i == 0) { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << (CC2_SHIFT - 2)) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT | - ((cc << (CC1_SHIFT - 1)) & CC1_MASK) | ((cc << CC0_SHIFT) & CC0_MASK) | rs2 << RS2_SHIFT; - } else { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << (CC2_SHIFT - 2)) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT | - ((cc << (CC1_SHIFT - 1)) & CC1_MASK) | ((cc << CC0_SHIFT) & CC0_MASK) | ((simm11 << SIMM11_SHIFT) & SIMM11_MASK); - } - } - - public static Fmt10c read(SPARCAssembler masm, int pos) { - final int inst = masm.getInt(pos); - - // Make sure it's the right instruction: - final int op = (inst & OP_MASK) >> OP_SHIFT; - assert op == Ops.ArithOp.getValue(); - - // Get the instruction fields: - final int rd = (inst & RD_MASK) >> RD_SHIFT; - final int op3 = (inst & OP3_MASK) >> OP3_SHIFT; - final int cond = (inst & COND_MASK) >> COND_SHIFT; - final int i = (inst & I_MASK) >> I_SHIFT; - final int cc = (inst & CC2_MASK) >> CC2_SHIFT | (inst & CC1_MASK) >> CC1_SHIFT | (inst & CC0_MASK) >> CC0_SHIFT; - final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT; - final int simm11 = (inst & SIMM11_MASK) >> SIMM11_SHIFT; - - return new Fmt10c(rd, op3, cond, i, cc, rs2, simm11); - } - - public void write(SPARCAssembler masm, int pos) { - verify(); - masm.emitInt(getInstructionBits(), pos); - } - - public void emit(SPARCAssembler masm) { - verify(); - masm.emitInt(getInstructionBits()); - } - - public void verify() { - assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT); - assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT); - assert ((cond << COND_SHIFT) & COND_MASK) == (cond << COND_SHIFT); - assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT); - // assert cc >= 0 && cc < 0x8; - assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT); - assert isSimm11(simm11); - } - } - - // @formatter:off - /** - * Instruction format for Fmovcc. - * <pre> - * | 10 | rd | op3 | -| cond | opfcc | opf_low | rs2 | - * |31 30|29 25|24 19|18|17 14|13 11|10 5|4 0| - * </pre> - */ - // @formatter:on - public static class Fmt10d implements AssemblerEmittable { - - private static final int OP_SHIFT = 30; - private static final int RD_SHIFT = 25; - private static final int OP3_SHIFT = 19; - private static final int COND_SHIFT = 14; - private static final int OPFCC_SHIFT = 12; - private static final int OPF_LOW_SHIFT = 11; - private static final int RS2_SHIFT = 0; - - // @formatter:off - private static final int RD_MASK = 0b0011_1110_0000_0000_0000_0000_0000_0000; - private static final int OP3_MASK = 0b0000_0001_1111_1000_0000_0000_0000_0000; - private static final int COND_MASK = 0b0000_0000_0000_0011_1100_0000_0000_0000; - private static final int OPFCC_MASK = 0b0000_0000_0000_0000_0011_1000_0000_0000; - private static final int OPF_LOW_MASK = 0b0000_0000_0000_0000_0000_0111_1110_0000; - private static final int RS2_MASK = 0b0000_0000_0000_0000_0000_0000_0001_1111; - // @formatter:on - - private int rd; - private int op3; - private int cond; - private int opfcc; - private int opfLow; - private int rs2; - - public Fmt10d(Op3s op3, Opfs opf, ConditionFlag cond, CC cc, Register rs2, Register rd) { - this(rd.encoding(), op3.getValue(), cond.getValue(), Fmt10c.getCC(cc), opf.getValue(), rs2.encoding()); - } - - public Fmt10d(int rd, int op3, int cond, int opfcc, int opfLow, int rs2) { - super(); - this.rd = rd; - this.op3 = op3; - this.cond = cond; - this.opfcc = opfcc; - this.opfLow = opfLow; - this.rs2 = rs2; - } - - public void emit(SPARCAssembler masm) { - verify(); - masm.emitInt(getInstructionBits()); - } - - private int getInstructionBits() { - return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | cond << COND_SHIFT | opfcc << OPFCC_SHIFT | opfLow << OPF_LOW_SHIFT | rs2 << RS2_SHIFT; - - } - - public void verify() { - assert ((RD_MASK >> RD_SHIFT) & rd) == rd; - assert ((OP3_MASK >> OP3_SHIFT) & op3) == op3; - assert ((COND_MASK >> COND_SHIFT) & cond) == cond; - assert ((OPFCC_MASK >> OPFCC_SHIFT) & opfcc) == opfcc; - assert ((OPF_LOW_MASK >> OPF_LOW_SHIFT) & opfLow) == opfLow; - assert ((RS2_MASK >> RS2_SHIFT) & rs2) == rs2; - } - } - - public static class Fmt5a { - - public Fmt5a(SPARCAssembler masm, int op, int op3, int op5, int rs1, int rs2, int rs3, int rd) { - assert op == 2; - assert op3 >= 0 && op3 < 0x40; - assert op5 >= 0 && op5 < 0x10; - assert rs1 >= 0 && rs1 < 0x20; - assert rs2 >= 0 && rs2 < 0x20; - assert rs3 >= 0 && rs3 < 0x20; - assert rd >= 0 && rd < 0x20; - - masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rs3 << 9 | op5 << 5 | rs2); - } - } - - public static final int ImmedTrue = 0x00002000; + protected static final int D10LO_MASK = 0b0000_0000_0000_0000_0001_1111_1110_0000; + protected static final int D10HI_MASK = 0b0000_0000_0001_1000_0000_0000_0000_0000; + protected static final int D10LO_SHIFT = 5; + protected static final int D10HI_SHIFT = 19; public enum Ops { // @formatter:off @@ -1518,6 +115,18 @@ } } + public enum Op { + Op00(0b00), + Op01(0b01), + Op10(0b10), + Op11(0b11); + int op; + + Op(int op) { + this.op = op; + } + } + public enum Op2s { // @formatter:off @@ -1556,117 +165,114 @@ public enum Op3s { // @formatter:off - Add(0x00, "add"), - And(0x01, "and"), - Or(0x02, "or"), - Xor(0x03, "xor"), - Sub(0x04, "sub"), - Andn(0x05, "andn"), - Orn(0x06, "orn"), - Xnor(0x07, "xnor"), - Addc(0x08, "addc"), - Mulx(0x09, "mulx"), - Umul(0x0A, "umul"), - Smul(0x0B, "smul"), - Subc(0x0C, "subc"), - Udivx(0x0D, "udivx"), - Udiv(0x0E, "udiv"), - Sdiv(0x0F, "sdiv"), + Add(0x00, "add", Op10), + And(0x01, "and", Op10), + Or(0x02, "or", Op10), + Xor(0x03, "xor", Op10), + Sub(0x04, "sub", Op10), + Andn(0x05, "andn", Op10), + Orn(0x06, "orn", Op10), + Xnor(0x07, "xnor", Op10), + Addc(0x08, "addc", Op10), + Mulx(0x09, "mulx", Op10), + Umul(0x0A, "umul", Op10), + Smul(0x0B, "smul", Op10), + Subc(0x0C, "subc", Op10), + Udivx(0x0D, "udivx", Op10), + Udiv(0x0E, "udiv", Op10), + Sdiv(0x0F, "sdiv", Op10), - Addcc(0x10, "addcc"), - Andcc(0x11, "andcc"), - Orcc(0x12, "orcc"), - Xorcc(0x13, "xorcc"), - Subcc(0x14, "subcc"), - Andncc(0x15, "andncc"), - Orncc(0x16, "orncc"), - Xnorcc(0x17, "xnorcc"), - Addccc(0x18, "addccc"), - // dos not exist - // Mulxcc(0x19, "mulxcc"), - Umulcc(0x1A, "umulcc"), - Smulcc(0x1B, "smulcc"), - Subccc(0x1C, "subccc"), - Udivcc(0x1E, "udivcc"), - Sdivcc(0x1F, "sdivcc"), + Addcc(0x10, "addcc", Op10), + Andcc(0x11, "andcc", Op10), + Orcc(0x12, "orcc", Op10), + Xorcc(0x13, "xorcc", Op10), + Subcc(0x14, "subcc", Op10), + Andncc(0x15, "andncc", Op10), + Orncc(0x16, "orncc", Op10), + Xnorcc(0x17, "xnorcc", Op10), + Addccc(0x18, "addccc", Op10), - Taddcc(0x20, "taddcc"), - Tsubcc(0x21, "tsubcc"), - Taddcctv(0x22, "taddcctv"), - Tsubcctv(0x23, "tsubcctv"), - Mulscc(0x24, "mulscc"), - Sll(0x25, "sll"), - Sllx(0x25, "sllx"), - Srl(0x26, "srl"), - Srlx(0x26, "srlx"), - Sra(0x27, "srax"), - Srax(0x27, "srax"), - Rdreg(0x28, "rdreg"), - Membar(0x28, "membar"), + Umulcc(0x1A, "umulcc", Op10), + Smulcc(0x1B, "smulcc", Op10), + Subccc(0x1C, "subccc", Op10), + Udivcc(0x1E, "udivcc", Op10), + Sdivcc(0x1F, "sdivcc", Op10), + + Taddcc(0x20, "taddcc", Op10), + Tsubcc(0x21, "tsubcc", Op10), + Taddcctv(0x22, "taddcctv", Op10), + Tsubcctv(0x23, "tsubcctv", Op10), + Mulscc(0x24, "mulscc", Op10), + Sll(0x25, "sll", Op10), + Sllx(0x25, "sllx", Op10), + Srl(0x26, "srl", Op10), + Srlx(0x26, "srlx", Op10), + Sra(0x27, "srax", Op10), + Srax(0x27, "srax", Op10), + Membar(0x28, "membar", Op10), - Flushw(0x2B, "flushw"), - Movcc(0x2C, "movcc"), - Sdivx(0x2D, "sdivx"), - Popc(0x2E, "popc"), - Movr(0x2F, "movr"), - - Sir(0x30, "sir"), - Wrreg(0x30, "wrreg"), - Saved(0x31, "saved"), + Flushw(0x2B, "flushw", Op10), + Movcc(0x2C, "movcc", Op10), + Sdivx(0x2D, "sdivx", Op10), + Popc(0x2E, "popc", Op10), + Movr(0x2F, "movr", Op10), - Fpop1(0b11_0100, "fpop1"), - Fpop2(0b11_0101, "fpop2"), - Impdep1(0b11_0110, "impdep1"), - Impdep2(0b11_0111, "impdep2"), - Jmpl(0x38, "jmpl"), - Rett(0x39, "rett"), - Trap(0x3a, "trap"), - Flush(0x3b, "flush"), - Save(0x3c, "save"), - Restore(0x3d, "restore"), - Done(0x3e, "done"), - Retry(0x3e, "retry"), - Casa(0b111100, "casa"), - Casxa(0b111110, "casxa"), - Prefetch(0b101101, "prefetch"), - Prefetcha(0b111101, "prefetcha"), + Fpop1(0b11_0100, "fpop1", Op10), + Fpop2(0b11_0101, "fpop2", Op10), + Impdep1(0b11_0110, "impdep1", Op10), + Impdep2(0b11_0111, "impdep2", Op10), + Jmpl(0x38, "jmpl", Op10), + Rett(0x39, "rett", Op10), + Trap(0x3a, "trap", Op10), + Flush(0x3b, "flush", Op10), + Save(0x3c, "save", Op10), + Restore(0x3d, "restore", Op10), + Retry(0x3e, "retry", Op10), + + + Casa(0b111100, "casa", Op11), + Casxa(0b111110, "casxa", Op11), + Prefetch(0b101101, "prefetch", Op11), + Prefetcha(0b111101, "prefetcha", Op11), - Lduw (0b00_0000, "lduw"), - Ldub (0b00_0001, "ldub"), - Lduh (0b00_0010, "lduh"), - Stw (0b00_0100, "stw"), - Stb (0b00_0101, "stb"), - Sth (0b00_0110, "sth"), - Ldsw (0b00_1000, "ldsw"), - Ldsb (0b00_1001, "ldsb"), - Ldsh (0b00_1010, "ldsh"), - Ldx (0b00_1011, "ldx"), - Stx (0b00_1110, "stx"), + Lduw (0b00_0000, "lduw", Op11), + Ldub (0b00_0001, "ldub", Op11), + Lduh (0b00_0010, "lduh", Op11), + Stw (0b00_0100, "stw", Op11), + Stb (0b00_0101, "stb", Op11), + Sth (0b00_0110, "sth", Op11), + Ldsw (0b00_1000, "ldsw", Op11), + Ldsb (0b00_1001, "ldsb", Op11), + Ldsh (0b00_1010, "ldsh", Op11), + Ldx (0b00_1011, "ldx", Op11), + Stx (0b00_1110, "stx", Op11), - Ldf (0b10_0000, "ldf"), - Ldfsr (0b10_0001, "ldfsr"), - Ldaf (0b10_0010, "ldaf"), - Lddf (0b10_0011, "lddf"), - Stf (0b10_0100, "stf"), - Stfsr (0b10_0101, "stfsr"), - Staf (0x10_0110, "staf"), - Rd (0b10_1000, "rd"), - Stdf (0b10_0111, "stdf"), + Ldf (0b10_0000, "ldf", Op11), + Ldfsr (0b10_0001, "ldfsr", Op11), + Ldaf (0b10_0010, "ldaf", Op11), + Lddf (0b10_0011, "lddf", Op11), + Stf (0b10_0100, "stf", Op11), + Stfsr (0b10_0101, "stfsr", Op11), + Staf (0x10_0110, "staf", Op11), + Stdf (0b10_0111, "stdf", Op11), - Wr (0b11_0000, "wr"), - Fcmp (0b11_0101, "fcmp"), + Rd (0b10_1000, "rd", Op10), + Wr (0b11_0000, "wr", Op10), + Fcmp (0b11_0101, "fcmp", Op10), - Ldxa (0b01_1011, "ldxa"), - Lduwa (0b01_0000, "lduwa"); + Ldxa (0b01_1011, "ldxa", Op11), + Lduwa (0b01_0000, "lduwa", Op11); // @formatter:on private final int value; private final String operator; + private final Op op; - private Op3s(int value, String op) { + private Op3s(int value, String name, Op op) { this.value = value; - this.operator = op; + this.operator = name; + this.op = op; } public int getValue() { @@ -1682,31 +288,6 @@ } } - public enum Op5s { - // @formatter:off - - Fmadds(0x1), - Fmaddd(0x2), - Fmsubs(0x5), - Fmsubd(0x6), - Fnmsubs(0x9), - Fnmsubd(0xA), - Fnmadds(0xD), - Fnmaddd(0xE); - - // @formatter:on - - private final int value; - - private Op5s(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - } - public enum Opfs { // @formatter:off @@ -1895,6 +476,26 @@ } } + public enum Annul { + ANNUL(1), + NOT_ANNUL(0); + public final int flag; + + Annul(int flag) { + this.flag = flag; + } + } + + public enum BranchPredict { + PREDICT_TAKEN(1), + PREDICT_NOT_TAKEN(0); + public final int flag; + + BranchPredict(int flag) { + this.flag = flag; + } + } + public enum MembarMask { // @formatter:off @@ -1933,25 +534,27 @@ /** * Condition is considered as 32bit operation condition. */ - Icc(0b00, "icc"), + Icc(0b00, "icc", false), /** * Condition is considered as 64bit operation condition. */ - Xcc(0b10, "xcc"), - Ptrcc(getHostWordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"), - Fcc0(0b00, "fcc0"), - Fcc1(0b01, "fcc1"), - Fcc2(0b10, "fcc2"), - Fcc3(0b11, "fcc3"); + Xcc(0b10, "xcc", false), + Ptrcc(getHostWordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc", false), + Fcc0(0b00, "fcc0", true), + Fcc1(0b01, "fcc1", true), + Fcc2(0b10, "fcc2", true), + Fcc3(0b11, "fcc3", true); // @formatter:on private final int value; private final String operator; + private boolean isFloat; - private CC(int value, String op) { + private CC(int value, String op, boolean isFloat) { this.value = value; this.operator = op; + this.isFloat = isFloat; } public int getValue() { @@ -1961,40 +564,21 @@ public String getOperator() { return operator; } - } - public enum FCond { - Fba(0x8, "fba"), - Fbn(0x0, "fbn"), - Fbu(0x7, "fbu"), - Fbg(0x6, "fbg"), - Fbug(0x5, "fbug"), - Fbl(0x4, "fbl"), - Fbul(0x3, "fbul"), - Fblg(0x2, "fblg"), - Fbne(0x1, "fbne"), - Fbe(0x9, "fbe"), - Fbue(0xA, "fbue"), - Fbge(0xB, "fbge"), - Fbuge(0xC, "fbuge"), - Fble(0xD, "fble"), - Fbule(0xE, "fbule"), - Fbo(0xF, "fbo"); - private final int value; - private final String operator; - - private FCond(int value, String op) { - assert value >= 0 && value < 1 << 5 : value; // 4 bits - this.value = value; - this.operator = op; - } - - public int getValue() { - return value; - } - - public String getOperator() { - return operator; + public static CC forKind(Kind kind) { + boolean isInt = kind == Kind.Boolean || kind == Kind.Byte || kind == Kind.Char || kind == Kind.Short || kind == Kind.Int; + boolean isFloat = kind == Kind.Float || kind == Kind.Double; + boolean isLong = kind == Kind.Long || kind == Kind.Object; + assert isInt || isFloat || isLong; + if (isLong) { + return Xcc; + } else if (isInt) { + return Icc; + } else if (isFloat) { + return Fcc0; + } else { + throw GraalInternalError.shouldNotReachHere(); + } } } @@ -2115,31 +699,56 @@ return null; } + public ConditionFlag mirror() { + switch (this) { + //@formatter:off + case F_Less : return F_Greater; + case F_Greater : return F_Less; + case F_LessOrEqual : return F_GreaterOrEqual; + case F_UnorderedGreaterOrEqual: return F_UnorderedOrLessOrEqual; + case F_UnorderedOrGreater : return F_UnorderedOrLess; + case F_UnorderedOrLessOrEqual : return F_UnorderedGreaterOrEqual; + case F_GreaterOrEqual : return F_LessOrEqual; + case F_UnorderedOrLess : return F_UnorderedOrGreater; + case LessEqual : return GreaterEqual; + case Greater : return Less; + case Less : return Greater; + case GreaterEqual : return LessEqual; + case LessEqualUnsigned : return GreaterEqualUnsigned; + case GreaterUnsigned : return LessUnsigned; + case LessUnsigned : return GreaterUnsigned; + case GreaterEqualUnsigned : return LessEqualUnsigned; + default: + return this; + //@formatter:on + } + } + public static ConditionFlag fromCondtition(CC conditionFlagsRegister, Condition cond, boolean unorderedIsTrue) { switch (conditionFlagsRegister) { case Xcc: case Icc: switch (cond) { case EQ: - return ConditionFlag.Equal; + return Equal; case NE: - return ConditionFlag.NotEqual; + return NotEqual; case BT: - return ConditionFlag.LessUnsigned; + return LessUnsigned; case LT: - return ConditionFlag.Less; + return Less; case BE: - return ConditionFlag.LessEqualUnsigned; + return LessEqualUnsigned; case LE: - return ConditionFlag.LessEqual; + return LessEqual; case AE: - return ConditionFlag.GreaterEqualUnsigned; + return GreaterEqualUnsigned; case GE: - return ConditionFlag.GreaterEqual; + return GreaterEqual; case AT: - return ConditionFlag.GreaterUnsigned; + return GreaterUnsigned; case GT: - return ConditionFlag.Greater; + return Greater; } throw GraalInternalError.shouldNotReachHere("Unimplemented for: " + cond); case Fcc0: @@ -2148,17 +757,17 @@ case Fcc3: switch (cond) { case EQ: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrEqual : ConditionFlag.F_Equal; + return unorderedIsTrue ? F_UnorderedOrEqual : F_Equal; case NE: return ConditionFlag.F_NotEqual; case LT: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrLess : ConditionFlag.F_Less; + return unorderedIsTrue ? F_UnorderedOrLess : F_Less; case LE: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrLessOrEqual : ConditionFlag.F_LessOrEqual; + return unorderedIsTrue ? F_UnorderedOrLessOrEqual : F_LessOrEqual; case GE: - return unorderedIsTrue ? ConditionFlag.F_UnorderedGreaterOrEqual : ConditionFlag.F_GreaterOrEqual; + return unorderedIsTrue ? F_UnorderedGreaterOrEqual : F_GreaterOrEqual; case GT: - return unorderedIsTrue ? ConditionFlag.F_UnorderedOrGreater : ConditionFlag.F_Greater; + return unorderedIsTrue ? F_UnorderedOrGreater : F_Greater; } throw GraalInternalError.shouldNotReachHere("Unkown condition: " + cond); } @@ -2228,34 +837,43 @@ } } + public enum Fcn { + SeveralWritesAndPossiblyReads(2), + SeveralReadsWeak(0), + OneRead(1), + OneWrite(3), + Page(4), + NearestUnifiedCache(17), + SeveralReadsStrong(20), + OneReadStrong(21), + SeveralWritesAndPossiblyReadsStrong(22), + OneWriteStrong(23); + + private final int value; + + private Fcn(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + public boolean hasFeature(CPUFeature feature) { return ((SPARC) this.target.arch).features.contains(feature); } - public static int getFloatEncoding(int reg) { - assert reg < 32; - return reg; - } - - public static int getDoubleEncoding(int reg) { - assert reg < 64 && ((reg & 1) == 0); - // ignore v8 assertion for now - return (reg & 0x1e) | ((reg & 0x20) >> 5); - } - - public static int getQuadEncoding(int reg) { - assert reg < 64 && ((reg & 3) == 0); - // ignore v8 assertion for now - return (reg & 0x1c) | ((reg & 0x20) >> 5); - } - - public static final int sx1 = 0x00001000; - public static final int simm(int x, int nbits) { // assert_signed_range(x, nbits); return x & ((1 << nbits) - 1); } + public static final boolean isImm(int x, int nbits) { + // assert_signed_range(x, nbits); + return simm(x, nbits) == x; + } + /** * Minimum value for signed immediate ranges. */ @@ -2301,10 +919,6 @@ return NumUtil.isInt(imm) && isSimm(imm, 13); } - public static boolean isDisp30(long imm) { - return isSimm(imm, 30); - } - public static boolean isWordDisp30(long imm) { return isSimm(imm, 30 + 2); } @@ -2317,2238 +931,814 @@ return x & ((1 << 10) - 1); } - public static class Add extends Fmt10 { - - public Add(Register src1, int simm13, Register dst) { - super(Op3s.Add, src1, simm13, dst); - } - - public Add(Register src1, Register src2, Register dst) { - super(Op3s.Add, src1, src2, dst); - } - } - - public static class Addc extends Fmt10 { - - public Addc(Register src1, int simm13, Register dst) { - super(Op3s.Addc, src1, simm13, dst); - } - - public Addc(Register src1, Register src2, Register dst) { - super(Op3s.Addc, src1, src2, dst); - } - } - - public static class Addcc extends Fmt10 { - - public Addcc(Register src1, int simm13, Register dst) { - super(Op3s.Addcc, src1, simm13, dst); - } - - public Addcc(Register src1, Register src2, Register dst) { - super(Op3s.Addcc, src1, src2, dst); - } + // @formatter:off + /** + * Instruction format for Fmt00 instructions. This abstraction is needed as it + * makes the patching easier later on. + * <pre> + * | 00 | a | op2 | b | + * |31 30|29 25|24 22|21 0| + * </pre> + */ + // @formatter:on + protected void fmt00(int a, int op2, int b) { + assert isImm(a, 5) && isImm(op2, 3) && isImm(b, 22) : String.format("a: 0x%x op2: 0x%x b: 0x%x", a, op2, b); + this.emitInt(a << 25 | op2 << 22 | b); } - public static class Addccc extends Fmt10 { - - public Addccc(Register src1, int simm13, Register dst) { - super(Op3s.Addccc, src1, simm13, dst); - } - - public Addccc(Register src1, Register src2, Register dst) { - super(Op3s.Addccc, src1, src2, dst); - } - } - - public static class Addxc extends Fmt3p { - - public Addxc(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Addxc, src1, src2, dst); - } + private void op3(Op3s op3, Opfs opf, Register rs1, Register rs2, Register rd) { + int b = opf.value << 5 | (rs2 == null ? 0 : rs2.encoding); + fmt(op3.op.op, rd.encoding, op3.value, rs1 == null ? 0 : rs1.encoding, b); } - public static class Addxccc extends Fmt3p { - - public Addxccc(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Addxccc, src1, src2, dst); - } + protected void op3(Op3s op3, Register rs1, Register rs2, Register rd) { + int b = rs2 == null ? 0 : rs2.encoding; + int xBit = getXBit(op3); + fmt(op3.op.op, rd.encoding, op3.value, rs1 == null ? 0 : rs1.encoding, b | xBit); } - public static class Alignaddr extends Fmt3p { - - public Alignaddr(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.AlignAddress, src1, src2, dst); - } - } - - public static class Alignaddrl extends Fmt3p { - - public Alignaddrl(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.AlignAddressLittle, src1, src2, dst); - } - } - - public static class Lzcnt extends Fmt3p { - - public Lzcnt(Register src1, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Lzcnt, g0, src1, dst); - } + protected void op3(Op3s op3, Register rs1, int simm13, Register rd) { + assert isSimm13(simm13); + int i = 1 << 13; + int simm13WithX = simm13 | getXBit(op3); + fmt(op3.op.op, rd.encoding, op3.value, rs1.encoding, i | simm13WithX & ((1 << 13) - 1)); } - public static class And extends Fmt10 { - - public And(Register src1, int simm13, Register dst) { - super(Op3s.And, src1, simm13, dst); - } - - public And(Register src1, Register src2, Register dst) { - super(Op3s.And, src1, src2, dst); - } - } - - public static class Andcc extends Fmt10 { - - public Andcc(Register src1, int simm13, Register dst) { - super(Op3s.Andcc, src1, simm13, dst); - } - - public Andcc(Register src1, Register src2, Register dst) { - super(Op3s.Andcc, src1, src2, dst); - } - } - - public static class Andn extends Fmt10 { - - public Andn(Register src1, int simm13, Register dst) { - super(Op3s.Andn, src1, simm13, dst); - } - - public Andn(Register src1, Register src2, Register dst) { - super(Op3s.Andn, src1, src2, dst); - } + // @formatter:off + /** + * Branch on Integer Condition Codes. + * <pre> + * | 00 |annul| cond| 010 | disp22 | + * |31 30|29 |28 25|24 22|21 0| + * </pre> + */ + // @formatter:on + public void bicc(ConditionFlag cond, Annul annul, Label l) { + bcc(Op2s.Br, cond, annul, l); } - public static class Andncc extends Fmt10 { - - public Andncc(Register src1, int simm13, Register dst) { - super(Op3s.Andncc, src1, simm13, dst); - } - - public Andncc(Register src1, Register src2, Register dst) { - super(Op3s.Andncc, src1, src2, dst); - } - } - - public static class Array8 extends Fmt3p { - - public Array8(Register src1, Register src2, Register dst) { - /* 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); - } + // @formatter:off + /** + * Branch on Floating-Point Condition Codes. + * <pre> + * | 00 |annul| cond| 110 | disp22 | + * |31 30|29 |28 25|24 22|21 0| + * </pre> + */ + // @formatter:on + public void fbcc(ConditionFlag cond, Annul annul, Label l) { + bcc(Op2s.Fb, cond, annul, l); } - public static class Array16 extends Fmt3p { - - public Array16(Register src1, Register src2, Register dst) { - /* 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 { - - public Array32(Register src1, Register src2, Register dst) { - /* 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); - } + // @formatter:off + /** + * Branch on (Integer|Floatingpoint) Condition Codes. + * <pre> + * | 00 |annul| cond| op2 | disp22 | + * |31 30|29 |28 25|24 22|21 0| + * </pre> + */ + // @formatter:on + private void bcc(Op2s op2, ConditionFlag cond, Annul annul, Label l) { + int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; + final int disp = 22; + assert isSimm(pos, disp); + pos &= (1 << disp) - 1; + int a = (annul.flag << 4) | cond.getValue(); + fmt00(a, op2.getValue(), pos); } - public static class Bmask extends Fmt3p { - - public Bmask(Register src1, Register src2, Register dst) { - /* 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 { - public Movwtos(Register src, Register dst) { - /* VIS3 only */ - 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 { - public Umulxhi(Register src1, Register src2, Register dst) { - /* 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); - } + // @formatter:off + /** + * Branch on Integer Condition Codes with Prediction. + * <pre> + * | 00 |an|cond | 001 |cc1 2|p | disp19 | + * |31 30|29|28 25|24 22|21 20|19| 0| + * </pre> + */ + // @formatter:on + public void bpcc(ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) { + bpcc(Op2s.Bp, cond, annul, l, cc, predictTaken); } - public static class Movxtod extends Fmt3p { - public Movxtod(Register src, Register dst) { - /* VIS3 only */ - 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 { - public Movdtox(Register src, Register dst) { - /* VIS3 only */ - 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 { - public Movstosw(Register src, Register dst) { - /* VIS3 only */ - 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); - } + // @formatter:off + /** + * Branch on Integer Condition Codes with Prediction. + * <pre> + * | 00 |an|cond | 101 |cc1 2|p | disp19 | + * |31 30|29|28 25|24 22|21 20|19| 0| + * </pre> + */ + // @formatter:on + public void fbpcc(ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) { + bpcc(Op2s.Fbp, cond, annul, l, cc, predictTaken); } - public static class Movstouw extends Fmt3p { - public Movstouw(Register src, Register dst) { - /* VIS3 only */ - 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) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdtos, g0, src, dst); - assert isSingleFloatRegister(dst); - assert isDoubleFloatRegister(src); - } - } - - public static class Bpr extends Fmt00d { - public Bpr(RCondition rcond, boolean annul, boolean predictTaken, Register rs1, Label label) { - super(Op2s.Bpr.getValue(), rcond.getValue(), predictTaken ? 1 : 0, annul ? 1 : 0, 0, rs1.encoding(), label); - } - } - - public static class Bpa extends Fmt00c { - - public Bpa(int simm19) { - super(0, ConditionFlag.Always, Op2s.Bp, CC.Icc, 1, simm19); - } - - public Bpa(Label label) { - super(0, ConditionFlag.Always, Op2s.Bp, CC.Icc, 1, label); - } + // @formatter:off + /** + * Used for fbpcc (Float) and bpcc (Integer). + * <pre> + * | 00 |an|cond | op2 |cc1 2|p | disp19 | + * |31 30|29|28 25|24 22|21 20|19| 0| + * </pre> + */ + // @formatter:on + private void bpcc(Op2s op2, ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) { + int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; + final int disp = 19; + assert isSimm(pos, disp); + pos &= (1 << disp) - 1; + int a = (annul.flag << 4) | cond.getValue(); + int b = (cc.getValue() << 20) | ((predictTaken.flag) << 19) | pos; + fmt00(a, op2.getValue(), b); } - public static class Bpcc extends Fmt00c { - - public Bpcc(CC cc, int simm19) { - super(0, ConditionFlag.CarryClear, Op2s.Bp, cc, 1, simm19); - } - - public Bpcc(CC cc, Label label) { - super(0, ConditionFlag.CarryClear, Op2s.Bp, cc, 1, label); - } - - public Bpcc(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.CarryClear, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpcs extends Fmt00c { - - public Bpcs(CC cc, int simm19) { - super(0, ConditionFlag.CarrySet, Op2s.Bp, cc, 1, simm19); - } - - public Bpcs(CC cc, Label label) { - super(0, ConditionFlag.CarrySet, Op2s.Bp, cc, 1, label); - } - - public Bpcs(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.CarrySet, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } + // @formatter:off + /** + * Branch on Integer Register with Prediction. + * <pre> + * | 00 |an| 0|rcond | 011 |d16hi|p | rs1 | d16lo | + * |31 30|29|28|27 25 |24 22|21 20|19|18 14| 0| + * </pre> + */ + // @formatter:on + public void bpr(RCondition cond, Annul annul, Label l, BranchPredict predictTaken, Register rs1) { + int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; + final int disp = 16; + assert isSimm(pos, disp); + pos &= (1 << disp) - 1; + int a = (annul.flag << 4) | cond.getValue(); + int d16hi = (pos >> 13) << 13; + int d16lo = d16hi ^ pos; + int b = (d16hi << 20) | (predictTaken.flag << 19) | (rs1.encoding() << 14) | d16lo; + fmt00(a, Op2s.Bpr.getValue(), b); } - public static class Bpe extends Fmt00c { - - public Bpe(CC cc, int simm19) { - super(0, ConditionFlag.Equal, Op2s.Bp, cc, 1, simm19); - } + private int patchUnbound(Label label) { + label.addPatchAt(position()); + return 0; + } - public Bpe(CC cc, Label label, boolean predictTaken) { - super(0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - - public Bpe(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - - public Bpe(CC cc, Label label) { - super(0, ConditionFlag.Equal, Op2s.Bp, cc, 1, label); - } + public void cbcondw(ConditionFlag cf, Register rs1, Register rs2, Label lab) { + cbcond(0, 0, cf, rs1, rs2.encoding, lab); } - public static class Bpg extends Fmt00c { - - public Bpg(CC cc, int simm19) { - super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, simm19); - } + public void cbcondw(ConditionFlag cf, Register rs1, int rs2, Label lab) { + assert isSimm(rs2, 5); + cbcond(0, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab); + } - public Bpg(CC cc, Label label) { - super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, label); - } + public void cbcondx(ConditionFlag cf, Register rs1, Register rs2, Label lab) { + cbcond(1, 0, cf, rs1, rs2.encoding, lab); + } - public Bpg(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.Greater, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } + public void cbcondx(ConditionFlag cf, Register rs1, int rs2, Label lab) { + assert isSimm(rs2, 5); + cbcond(1, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab); } - public static class Bpge extends Fmt00c { - - public Bpge(CC cc, int simm19) { - super(0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, 1, simm19); - } - - public Bpge(CC cc, Label label) { - super(0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, 1, label); - } - - public Bpge(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpgu extends Fmt00c { - - public Bpgu(CC cc, int simm19) { - super(0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, 1, simm19); - } - - public Bpgu(CC cc, Label label) { - super(0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, 1, label); - } - - public Bpgu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } + private void cbcond(int cc2, int i, ConditionFlag cf, Register rs1, int rs2, Label l) { + int d10 = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; + assert isSimm(d10, 10) && isImm(rs2, 5); + d10 &= (1 << 10) - 1; + final int cLo = cf.value & 0b111; + final int cHi = cf.value >> 3; + final int d10Lo = d10 & ((1 << 8) - 1); + final int d10Hi = d10 >> 8; + int a = cHi << 4 | 0b1000 | cLo; + int b = cc2 << 21 | d10Hi << D10HI_SHIFT | rs1.encoding << 14 | i << 13 | d10Lo << D10LO_SHIFT | rs2; + fmt00(a, Op2s.Bpr.value, b); } - public static class Bpl extends Fmt00c { - - public Bpl(CC cc, int simm19) { - super(0, ConditionFlag.Less, Op2s.Bp, cc, 1, simm19); - } - - public Bpl(CC cc, Label label) { - super(0, ConditionFlag.Less, Op2s.Bp, cc, 1, label); - } - - public Bpl(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.Less, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } + // @formatter:off + /** + * NOP. + * <pre> + * | 00 |00000| 100 | 0 | + * |31 30|29 25|24 22|21 0| + * </pre> + */ + // @formatter:on + public void nop() { + emitInt(1 << 24); } - public static class Bple extends Fmt00c { - - public Bple(CC cc, int simm19) { - super(0, ConditionFlag.LessEqual, Op2s.Bp, cc, 1, simm19); - } - - public Bple(CC cc, Label label) { - super(0, ConditionFlag.LessEqual, Op2s.Bp, cc, 1, label); - } - - public Bple(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.LessEqual, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpleu extends Fmt00c { - - public Bpleu(CC cc, int simm19) { - super(0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, 1, simm19); - } - - public Bpleu(CC cc, Label label) { - super(0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, 1, label); - } - - public Bpleu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } - } - - public static class Bpn extends Fmt00c { - - public Bpn(CC cc, int simm19) { - super(0, ConditionFlag.Never, Op2s.Bp, cc, 1, simm19); - } - - public Bpn(CC cc, Label label) { - super(0, ConditionFlag.Never, Op2s.Bp, cc, 1, label); - } + public void sethi(int imm22, Register dst) { + fmt00(dst.encoding, Op2s.Sethi.value, imm22); } - public static class Bpne extends Fmt00c { - - public Bpne(CC cc, int simm19) { - super(0, ConditionFlag.NotZero, Op2s.Bp, cc, 1, simm19); - } - - public Bpne(CC cc, Label label) { - super(0, ConditionFlag.NotZero, Op2s.Bp, cc, 1, label); - } - - public Bpne(CC cc, boolean annul, boolean predictTaken, Label label) { - super(annul ? 1 : 0, ConditionFlag.NotZero, Op2s.Bp, cc, predictTaken ? 1 : 0, label); - } + // @formatter:off + /** + * Instruction format for calls. + * <pre> + * | 01 | disp30 | + * |31 30|29 0| + * </pre> + */ + // @formatter:on + public void call(int disp30) { + assert isImm(disp30, 30); + int instr = 1 << 30; + instr |= disp30; + emitInt(instr); } - public static class Bpneg extends Fmt00c { - - public Bpneg(CC cc, int simm19) { - super(0, ConditionFlag.Negative, Op2s.Bp, cc, 1, simm19); - } - - public Bpneg(CC cc, Label label) { - super(0, ConditionFlag.Negative, Op2s.Bp, cc, 1, label); - } + public void add(Register rs1, Register rs2, Register rd) { + op3(Add, rs1, rs2, rd); } - public static class Bppos extends Fmt00c { - - public Bppos(CC cc, int simm19) { - super(0, ConditionFlag.Positive, Op2s.Bp, cc, 1, simm19); - } - - public Bppos(CC cc, Label label) { - super(0, ConditionFlag.Positive, Op2s.Bp, cc, 1, label); - } + public void add(Register rs1, int simm13, Register rd) { + op3(Add, rs1, simm13, rd); } - public static class Bpvc extends Fmt00c { - - public Bpvc(CC cc, int simm19) { - super(0, ConditionFlag.OverflowClear, Op2s.Bp, cc, 1, simm19); - } - - public Bpvc(CC cc, Label label) { - super(0, ConditionFlag.OverflowClear, Op2s.Bp, cc, 1, label); - } + public void addc(Register rs1, Register rs2, Register rd) { + op3(Addc, rs1, rs2, rd); } - public static class Bpvs extends Fmt00c { + public void addc(Register rs1, int simm13, Register rd) { + op3(Addc, rs1, simm13, rd); + } - public Bpvs(CC cc, int simm19) { - super(0, ConditionFlag.OverflowSet, Op2s.Bp, cc, 1, simm19); - } - - public Bpvs(CC cc, Label label) { - super(0, ConditionFlag.OverflowSet, Op2s.Bp, cc, 1, label); - } + public void addcc(Register rs1, Register rs2, Register rd) { + op3(Addcc, rs1, rs2, rd); } - public static class Bshuffle extends Fmt3p { - - public Bshuffle(Register src1, Register src2, Register dst) { - /* VIS2 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Bshuffle, src1, src2, dst); - } + public void addcc(Register rs1, int simm13, Register rd) { + op3(Addcc, rs1, simm13, rd); } - public static class Call extends Fmt01 { - - public Call(int disp30) { - super(disp30); - } + public void and(Register rs1, Register rs2, Register rd) { + op3(And, rs1, rs2, rd); } - public static class CammelliaFl extends Fmt3p { - - public CammelliaFl(Register src1, Register src2, Register dst) { - /* CAMELLIA only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.CammelliaFl, src1, src2, dst); - } + public void and(Register rs1, int simm13, Register rd) { + op3(And, rs1, simm13, rd); } - public static class CammelliaFli extends Fmt3p { + public void andcc(Register rs1, Register rs2, Register rd) { + op3(Andcc, rs1, rs2, rd); + } - public CammelliaFli(Register src1, Register src2, Register dst) { - /* CAMELLIA only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.CammelliaFli, src1, src2, dst); - } + public void andcc(Register rs1, int simm13, Register rd) { + op3(Andcc, rs1, simm13, rd); } - public static class Casa extends Fmt11 { - - public Casa(Register src1, Register src2, Register dst, Asi asi) { - super(Op3s.Casa, src1, src2, dst, asi); - } + public void andn(Register rs1, Register rs2, Register rd) { + op3(Andn, rs1, rs2, rd); } - public static class Casxa extends Fmt11 { - - public Casxa(Register src1, Register src2, Register dst, Asi asi) { - super(Op3s.Casxa, src1, src2, dst, asi); - } - } - - public static class Cmask8 extends Fmt3n { - - public Cmask8(Register src2) { - super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask8.getValue(), src2.encoding(), 0); - } + public void andn(Register rs1, int simm13, Register rd) { + op3(Andn, rs1, simm13, rd); } - public static class Cmask16 extends Fmt3n { - - public Cmask16(Register src2) { - super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask16.getValue(), src2.encoding(), 0); - } + public void andncc(Register rs1, Register rs2, Register rd) { + op3(Andncc, rs1, rs2, rd); } - public static class Cmask32 extends Fmt3n { - - public Cmask32(Register src2) { - super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask32.getValue(), src2.encoding(), 0); - } + public void andncc(Register rs1, int simm13, Register rd) { + op3(Andncc, rs1, simm13, rd); } - public static class Crc32c extends Fmt3p { - - public Crc32c(Register src1, Register src2, Register dst) { - /* CRYPTO only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Crc32c, src1, src2, dst); - } + public void movwtos(Register rs2, Register rd) { + op3(Impdep1, Movwtos, null, rs2, rd); } - public static class CBcondw extends Fmt00e { - public CBcondw(ConditionFlag flag, Register src1, Register src2, Label label) { - super(flag.getValue(), 0, src1.encoding(), -1, 0, src2.encoding(), label); - } - - public CBcondw(ConditionFlag flag, Register src1, int simm5, Label label) { - super(flag.getValue(), 0, src1.encoding(), -1, 1, simm5, label); - } + public void umulxhi(Register rs1, Register rs2, Register rd) { + op3(Impdep1, UMulxhi, rs1, rs2, rd); } - public static class CBcondx extends Fmt00e { - public CBcondx(ConditionFlag flag, Register src1, Register src2, Label label) { - super(flag.getValue(), 1, src1.encoding(), -1, 0, src2.encoding(), label); - } - - public CBcondx(ConditionFlag flag, Register src1, int simm5, Label label) { - super(flag.getValue(), 1, src1.encoding(), -1, 1, simm5, label); - } + public void fdtos(Register rs2, Register rd) { + op3(Fpop1, Fdtos, null, rs2, rd); } - public static class Edge8cc extends Fmt3p { - - public Edge8cc(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8cc, src1, src2, dst); - } + public void movstouw(Register rs2, Register rd) { + op3(Impdep1, Movstosw, null, rs2, rd); } - public static class Edge8n extends Fmt3p { - - public Edge8n(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8n, src1, src2, dst); - } + public void movstosw(Register rs2, Register rd) { + op3(Impdep1, Movstosw, null, rs2, rd); } - public static class Edge8lcc extends Fmt3p { - - public Edge8lcc(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8lcc, src1, src2, dst); - } + public void movdtox(Register rs2, Register rd) { + op3(Impdep1, Movdtox, null, rs2, rd); } - public static class Edge8ln extends Fmt3p { - - public Edge8ln(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8ln, src1, src2, dst); - } + public void movxtod(Register rs2, Register rd) { + op3(Impdep1, Movxtod, null, rs2, rd); } - public static class Edge16cc extends Fmt3p { - - public Edge16cc(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16cc, src1, src2, dst); - } + public void fadds(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fadds, rs1, rs2, rd); } - public static class Edge16n extends Fmt3p { - - public Edge16n(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16n, src1, src2, dst); - } + public void faddd(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Faddd, rs1, rs2, rd); } - public static class Edge16lcc extends Fmt3p { - - public Edge16lcc(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16lcc, src1, src2, dst); - } + public void faddq(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Faddq, rs1, rs2, rd); } - public static class Edge16ln extends Fmt3p { - - public Edge16ln(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16ln, src1, src2, dst); - } + public void fdivs(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fdivs, rs1, rs2, rd); } - public static class Edge32cc extends Fmt3p { - - public Edge32cc(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32cc, src1, src2, dst); - } - } - - public static class Edge32n extends Fmt3p { - - public Edge32n(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32n, src1, src2, dst); - } + public void fdivd(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fdivd, rs1, rs2, rd); } - public static class Edge32lcc extends Fmt3p { - - public Edge32lcc(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32lcc, src1, src2, dst); - } + public void fmovs(Register rs2, Register rd) { + op3(Fpop1, Fmovs, null, rs2, rd); } - public static class Edge32ln extends Fmt3p { - - public Edge32ln(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32ln, src1, src2, dst); - } + public void fmovd(Register rs2, Register rd) { + op3(Fpop1, Fmovd, null, rs2, rd); } - public static class Fadds extends Fmt3p { - - public Fadds(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fadds, src1, src2, dst); - } + public void fmuls(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fmuls, rs1, rs2, rd); } - public static class Faddd extends Fmt3p { - - public Faddd(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Faddd, src1, src2, dst); - } - } - - public static class Faddq extends Fmt3p { - - public Faddq(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Faddq, src1, src2, dst); - } + public void fsmuld(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fsmuld, rs1, rs2, rd); } - public static class Faligndata extends Fmt3p { - - public Faligndata(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Faligndatag, src1, src2, dst); - } + public void fmuld(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fmuld, rs1, rs2, rd); } - public static class Fdivs extends Fmt3p { - - public Fdivs(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdivs, src1, src2, dst); - } + public void fnegs(Register rs2, Register rd) { + op3(Fpop1, Fnegs, null, rs2, rd); } - public static class Fdivd extends Fmt3p { - - public Fdivd(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdivd, src1, src2, dst); - } + public void fnegd(Register rs2, Register rd) { + op3(Fpop1, Fnegd, null, rs2, rd); } /** - * Floating-point multiply-add single (fused). - */ - public static class Fmadds extends Fmt5a { - - public Fmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmadds.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - } - } - - /** - * Floating-point multiply-add double (fused). - */ - public static class Fmaddd extends Fmt5a { - - public Fmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmaddd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - } - } - - /** - * 16-bit partitioned average. + * Helper method to determine if the instruction needs the X bit set. */ - public static class Fmean16 extends Fmt3p { - - public Fmean16(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmean16, src1, src2, dst); - } - } - - public static class Fmsubs extends Fmt5a { - - public Fmsubs(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubs.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(src3); - assert isSingleFloatRegister(dst); - } - } - - public static class Fmsubd extends Fmt5a { - - public Fmsubd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(src3); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fmovs extends Fmt3p { - - public Fmovs(Register src, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmovs, g0, src, dst); - assert isSingleFloatRegister(src); - assert isSingleFloatRegister(dst); - } - } - - public static class Fmovd extends Fmt3p { - - public Fmovd(Register src, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmovd, g0, src, dst); - } - } - - public static class Fmuls extends Fmt3p { - - public Fmuls(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmuls, src1, src2, dst); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } - } - - public static class Fmuld extends Fmt3p { - - public Fmuld(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmuld, src1, src2, dst); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fsmuld extends Fmt3p { - - public Fsmuld(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsmuld, src1, src2, dst); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fmul8x16 extends Fmt3p { - - public Fmul8x16(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8x16, src1, src2, dst); - } - } - - public static class Fmul8x16au extends Fmt3p { - - public Fmul8x16au(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8x16, src1, src2, dst); - } - } - - public static class Fmul8x16al extends Fmt3p { - - public Fmul8x16al(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8x16al, src1, src2, dst); - } - } - - public static class Fmul8sux16 extends Fmt3p { - - public Fmul8sux16(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8sux16, src1, src2, dst); - } - } - - public static class Fmul8ulx16 extends Fmt3p { - - public Fmul8ulx16(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8ulx16, src1, src2, dst); - } - } - - public static class Fmuld8sux16 extends Fmt3p { - - public Fmuld8sux16(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmuld8sux16, src1, src2, dst); - } - } - - public static class Fmuld8ulx16 extends Fmt3p { - - public Fmuld8ulx16(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmuld8ulx16, src1, src2, dst); - } - } - - public static class Fnadds extends Fmt3p { - - public Fnadds(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnadds, src1, src2, dst); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(dst); + private static int getXBit(Op3s op3) { + switch (op3) { + case Sllx: + case Srax: + case Srlx: + return 1 << 12; + default: + return 0; } } - public static class Fnaddd extends Fmt3p { - - public Fnaddd(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnaddd, src1, src2, dst); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fnegs extends Fmt3n { - - public Fnegs(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegs.getValue(), src2.encoding(), dst.encoding()); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } - } - - public static class Fnegd extends Fmt3n { - - public Fnegd(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegd.getValue(), src2.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fnhadds extends Fmt3p { - - public Fnhadds(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnhadds, src1, src2, dst); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } + public void fstoi(Register rs2, Register rd) { + op3(Fpop1, Fstoi, null, rs2, rd); } - public static class Fnhaddd extends Fmt3p { - - public Fnhaddd(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnhaddd, src1, src2, dst); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fnmadds extends Fmt5a { - - public Fnmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmadds.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(src3); - assert isSingleFloatRegister(dst); - } + public void fstox(Register rs2, Register rd) { + op3(Fpop1, Fstox, null, rs2, rd); } - public static class Fnmaddd extends Fmt5a { - - public Fnmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmaddd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(src3); - assert isDoubleFloatRegister(dst); - } + public void fdtox(Register rs2, Register rd) { + op3(Fpop1, Fdtox, null, rs2, rd); } - public static class Fnmsubs extends Fmt5a { - - public Fnmsubs(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) { - super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubs.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(src3); - assert isSingleFloatRegister(dst); - } - } - - public static class Fnmsubd extends Fmt5a { - - public Fnmsubd(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) { - super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(src3); - assert isDoubleFloatRegister(dst); - } + public void fstod(Register rs2, Register rd) { + op3(Fpop1, Fstod, null, rs2, rd); } - public static class Fnmuls extends Fmt3p { - - public Fnmuls(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnmuls, src1, src2, dst); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } - } - - public static class Fnmuld extends Fmt3p { - - public Fnmuld(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnmuld, src1, src2, dst); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } + public void fdtoi(Register rs2, Register rd) { + op3(Fpop1, Fdtoi, null, rs2, rd); } - public static class Fnsmuld extends Fmt3p { - - public Fnsmuld(Register src1, Register src2, Register dst) { - /* VIS3 only */ - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnsmuld, src1, src2, dst); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fstoi extends Fmt3n { - - public Fstoi(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstoi.getValue(), src2.encoding(), dst.encoding()); - assert isSingleFloatRegister(dst); - assert isSingleFloatRegister(src2); - } - } - - public static class Fstox extends Fmt3n { - - public Fstox(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstox.getValue(), src2.encoding(), dst.encoding()); - assert isDoubleFloatRegister(dst); - assert isSingleFloatRegister(src2); - } + public void fitos(Register rs2, Register rd) { + op3(Fpop1, Fitos, null, rs2, rd); } - public static class Fdtox extends Fmt3n { - - public Fdtox(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdtox.getValue(), src2.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fstod extends Fmt3n { - - public Fstod(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstod.getValue(), src2.encoding(), dst.encoding()); - assert isDoubleFloatRegister(dst); - assert isSingleFloatRegister(src2); - } - } - - /** - * Convert Double to 32-bit Integer. - */ - public static class Fdtoi extends Fmt3n { - - public Fdtoi(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdtoi.getValue(), src2.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } + public void fitod(Register rs2, Register rd) { + op3(Fpop1, Fitod, null, rs2, rd); } - public static class Fitos extends Fmt3n { - - public Fitos(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fitos.getValue(), src2.encoding(), dst.encoding()); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } + public void fxtos(Register rs2, Register rd) { + op3(Fpop1, Fxtos, null, rs2, rd); } - public static class Fitod extends Fmt3n { - - public Fitod(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fitod.getValue(), src2.encoding(), dst.encoding()); - assert isSingleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } + public void fxtod(Register rs2, Register rd) { + op3(Fpop1, Fxtod, null, rs2, rd); } - public static class Fxtos extends Fmt3n { - - public Fxtos(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fxtos.getValue(), src2.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } - } - - public static class Fxtod extends Fmt3n { - - public Fxtod(Register src2, Register dst) { - super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fxtod.getValue(), src2.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } + public void fzeros(Register rd) { + op3(Impdep1, Fzeros, null, null, rd); } - /** - * Flush register windows. - */ - public static class Flushw extends Fmt10 { - - public Flushw() { - super(Op3s.Flushw); - } - } - - public static class Fpack16 extends Fmt3p { - - public Fpack16(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpack16, src1, src2, dst); - } - } - - public static class Fpack32 extends Fmt3p { - - public Fpack32(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpack32, src1, src2, dst); - } + public void fzerod(Register rd) { + op3(Impdep1, Fzerod, null, null, rd); } - public static class Fpackfix extends Fmt3p { - - public Fpackfix(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpackfix, src1, src2, dst); - } - } - - public static class Fpmaddx extends Fmt5a { - - public Fpmaddx(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), 0, src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(src3); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fpmaddxhi extends Fmt5a { - - public Fpmaddxhi(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { - super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), 4, src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(src3); - assert isDoubleFloatRegister(dst); - } + public void flushw() { + op3(Flushw, g0, g0, g0); } - public static class Fpmerge extends Fmt3p { - - public Fpmerge(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpmerge, src1, src2, dst); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fpsub16 extends Fmt3p { - - public Fpsub16(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub16, src1, src2, dst); - } - } - - public static class Fpsub16s extends Fmt3p { - - public Fpsub16s(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub16s, src1, src2, dst); - } + public void fsqrtd(Register rs2, Register rd) { + op3(Fpop1, Fsqrtd, null, rs2, rd); } - public static class Fpsub32 extends Fmt3p { - - public Fpsub32(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub32, src1, src2, dst); - } + public void fsqrts(Register rs2, Register rd) { + op3(Fpop1, Fsqrts, null, rs2, rd); } - public static class Fpsub32s extends Fmt3p { - - public Fpsub32s(Register src1, Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub32s, src1, src2, dst); - } - } - - public static class Fpsub64 extends Fmt3p { - - public Fpsub64(Register src1, Register src2, Register dst) { - /* OSA 2011 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub64, src1, src2, dst); - } - } - - public static class Fpsubs16 extends Fmt3p { - - public Fpsubs16(Register src1, Register src2, Register dst) { - /* OSA 2011 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs16, src1, src2, dst); - } + public void fabss(Register rs2, Register rd) { + op3(Fpop1, Fabss, null, rs2, rd); } - public static class Fpsubs16s extends Fmt3p { - - public Fpsubs16s(Register src1, Register src2, Register dst) { - /* OSA 2011 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs16s, src1, src2, dst); - } - } - - public static class Fpsubs32 extends Fmt3p { - - public Fpsubs32(Register src1, Register src2, Register dst) { - /* OSA 2011 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs32, src1, src2, dst); - } - } - - public static class Fpsubs32s extends Fmt3p { - - public Fpsubs32s(Register src1, Register src2, Register dst) { - /* OSA 2011 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs32s, src1, src2, dst); - } + public void fabsd(Register rs2, Register rd) { + op3(Fpop1, Fabsd, null, rs2, rd); } - public static class Fsqrtd extends Fmt3p { - - public Fsqrtd(Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsqrtd, SPARC.r0, src2, dst); - } - } - - public static class Fsqrts extends Fmt3p { - - public Fsqrts(Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsqrts, SPARC.r0, src2, dst); - } + public void fsubs(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fsubs, rs1, rs2, rd); } - public static class Fabss extends Fmt3p { - public Fabss(Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fabss, SPARC.r0, src2, dst); - } - } - - public static class Fabsd extends Fmt3p { - public Fabsd(Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fabsd, SPARC.r0, src2, dst); - } - } - - public static class Fsrc1d extends Fmt3p { - - public Fsrc1d(Register src1, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc1d, src1, SPARC.r0, dst); - } + public void fsubd(Register rs1, Register rs2, Register rd) { + op3(Fpop1, Fsubd, rs1, rs2, rd); } - public static class Fsrc1s extends Fmt3p { - - public Fsrc1s(Register src1, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc1s, src1, SPARC.r0, dst); - } - } - - public static class Fsrc2d extends Fmt3p { - - public Fsrc2d(Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc2d, SPARC.r0, src2, dst); - } - } - - public static class Fsrc2s extends Fmt3p { - - public Fsrc2s(Register src2, Register dst) { - /* VIS1 only */ - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc2s, SPARC.r0, src2, dst); - } - } - - public static class Fsubs extends Fmt3p { - - public Fsubs(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsubs, src1, src2, dst); - assert isSingleFloatRegister(src1); - assert isSingleFloatRegister(src2); - assert isSingleFloatRegister(dst); - } - } - - public static class Fsubd extends Fmt3p { - - public Fsubd(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsubd, src1, src2, dst); - assert isDoubleFloatRegister(src1); - assert isDoubleFloatRegister(src2); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fsubq extends Fmt3p { - - public Fsubq(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsubq, src1, src2, dst); - } - } - - public static class Fzeros extends Fmt3n { - - public Fzeros(Register dst) { - /* VIS1 only */ - super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fzeros.getValue(), 0, dst.encoding()); - assert isSingleFloatRegister(dst); - } + // @formatter:off + /** + * Instruction format for fcmp. + * <pre> + * | 10 | --- |cc1|cc0|desc | rs1 | opf | rs2 | + * |31 30|29 27|26 |25 |24 19|18 14|13 5|4 0| + * </pre> + */ + // @formatter:on + public void fcmp(CC cc, Opfs opf, Register rs1, Register rs2) { + int a = cc.value; + int b = opf.value << 5 | rs2.encoding; + fmt10(a, Fcmp.value, rs1.encoding, b); } - public static class Fzerod extends Fmt3n { - - public Fzerod(Register dst) { - /* VIS1 only */ - super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fzerod.getValue(), 0, dst.encoding()); - assert isDoubleFloatRegister(dst); - } - } - - public static class Fcmp extends Fmt3c { - - public Fcmp(CC cc, Opfs opf, Register r1, Register r2) { - super(Ops.ArithOp, cc, 0b110101, opf, r1, r2); - assert opf != Opfs.Fcmpd || (isDoubleFloatRegister(r1) && isDoubleFloatRegister(r2)); - assert opf != Opfs.Fcmps || (isSingleFloatRegister(r1) && isSingleFloatRegister(r2)); - } - } - - public static class Fba extends Fmt00b { - public Fba(boolean annul, Label label) { - super(annul, FCond.Fba, Op2s.Fb, label); - } - - public Fba(boolean annul, int disp) { - super(annul, FCond.Fba, Op2s.Fb, disp); - } - } - - public static class Fbn extends Fmt00b { - public Fbn(boolean annul, Label label) { - super(annul, FCond.Fbn, Op2s.Fb, label); - } - - public Fbn(boolean annul, int disp) { - super(annul, FCond.Fbn, Op2s.Fb, disp); - } - } - - public static class Fbu extends Fmt00b { - public Fbu(boolean annul, Label label) { - super(annul, FCond.Fbu, Op2s.Fb, label); - } - - public Fbu(boolean annul, int disp) { - super(annul, FCond.Fbu, Op2s.Fb, disp); - } - } - - public static class Fbg extends Fmt00b { - public Fbg(boolean annul, Label label) { - super(annul, FCond.Fbg, Op2s.Fb, label); - } - - public Fbg(boolean annul, int disp) { - super(annul, FCond.Fbg, Op2s.Fb, disp); - } - } - - public static class Fbug extends Fmt00b { - public Fbug(boolean annul, Label label) { - super(annul, FCond.Fbug, Op2s.Fb, label); - } - - public Fbug(boolean annul, int disp) { - super(annul, FCond.Fbug, Op2s.Fb, disp); - } - } - - public static class Fbl extends Fmt00b { - public Fbl(boolean annul, Label label) { - super(annul, FCond.Fbl, Op2s.Fb, label); - } - - public Fbl(boolean annul, int disp) { - super(annul, FCond.Fbl, Op2s.Fb, disp); - } - } - - public static class Fbul extends Fmt00b { - public Fbul(boolean annul, Label label) { - super(annul, FCond.Fbul, Op2s.Fb, label); - } - - public Fbul(boolean annul, int disp) { - super(annul, FCond.Fbul, Op2s.Fb, disp); - } - } - - public static class Fblg extends Fmt00b { - public Fblg(boolean annul, Label label) { - super(annul, FCond.Fblg, Op2s.Fb, label); - } - - public Fblg(boolean annul, int disp) { - super(annul, FCond.Fblg, Op2s.Fb, disp); - } - } - - public static class Fbne extends Fmt00b { - public Fbne(boolean annul, Label label) { - super(annul, FCond.Fbne, Op2s.Fb, label); - } - - public Fbne(boolean annul, int disp) { - super(annul, FCond.Fbne, Op2s.Fb, disp); - } + // @formatter:off + /** + * Instruction format for most arithmetic stuff. + * <pre> + * | 10 | rd | op3 | rs1 | b | + * |31 30|29 25|24 19|18 14|13 0| + * </pre> + */ + // @formatter:on + protected void fmt10(int rd, int op3, int rs1, int b) { + fmt(0b10, rd, op3, rs1, b); } - public static class Fbe extends Fmt00b { - public Fbe(boolean annul, Label label) { - super(annul, FCond.Fbe, Op2s.Fb, label); - } - - public Fbe(boolean annul, int disp) { - super(annul, FCond.Fbe, Op2s.Fb, disp); - } - } - - public static class Fbue extends Fmt00b { - public Fbue(boolean annul, Label label) { - super(annul, FCond.Fbue, Op2s.Fb, label); - } - - public Fbue(boolean annul, int disp) { - super(annul, FCond.Fbue, Op2s.Fb, disp); - } - } - - public static class Fbge extends Fmt00b { - public Fbge(boolean annul, Label label) { - super(annul, FCond.Fbge, Op2s.Fb, label); - } - - public Fbge(boolean annul, int disp) { - super(annul, FCond.Fbge, Op2s.Fb, disp); - } - } - - public static class Fbuge extends Fmt00b { - public Fbuge(boolean annul, Label label) { - super(annul, FCond.Fbuge, Op2s.Fb, label); - } - - public Fbuge(boolean annul, int disp) { - super(annul, FCond.Fbuge, Op2s.Fb, disp); - } - } - - public static class Fble extends Fmt00b { - public Fble(boolean annul, Label label) { - super(annul, FCond.Fble, Op2s.Fb, label); - } - - public Fble(boolean annul, int disp) { - super(annul, FCond.Fble, Op2s.Fb, disp); - } + // @formatter:off + /** + * Instruction format for most arithmetic stuff. + * <pre> + * | op | rd | op3 | rs1 | b | + * |31 30|29 25|24 19|18 14|13 0| + * </pre> + */ + // @formatter:on + protected void fmt(int op, int rd, int op3, int rs1, int b) { + assert isImm(rd, 5) && isImm(op3, 6) && isImm(b, 14) : String.format("rd: 0x%x op3: 0x%x b: 0x%x", rd, op3, b); + int instr = op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | b; + emitInt(instr); } - public static class Fbule extends Fmt00b { - public Fbule(boolean annul, Label label) { - super(annul, FCond.Fbule, Op2s.Fb, label); - } - - public Fbule(boolean annul, int disp) { - super(annul, FCond.Fbule, Op2s.Fb, disp); - } + public void illtrap(int const22) { + fmt00(0, Op2s.Illtrap.value, const22); } - public static class Fbo extends Fmt00b { - public Fbo(boolean annul, Label label) { - super(annul, FCond.Fbo, Op2s.Fb, label); - } - - public Fbo(boolean annul, int disp) { - super(annul, FCond.Fbo, Op2s.Fb, disp); - } - } - - public static class Illtrap extends Fmt00a { - - public Illtrap(int const22) { - super(Op2s.Illtrap, const22, g0); - } + public void jmpl(Register rs1, Register rs2, Register rd) { + op3(Jmpl, rs1, rs2, rd); } - public static class Jmpl extends Fmt10 { - - public Jmpl(Register src, int simm13, Register dst) { - super(Op3s.Jmpl, src, simm13, dst); - } - - public Jmpl(Register src1, Register src2, Register dst) { - super(Op3s.Jmpl, src1, src2, dst); - } + public void jmpl(Register rs1, int simm13, Register rd) { + op3(Jmpl, rs1, simm13, rd); } - public static class Lddf extends Fmt11 { - - public Lddf(SPARCAddress src, Register dst) { - super(Op3s.Lddf, src, dst); - assert dst == f0 || dst == f2 || dst == f4 || dst == f6 || isDoubleFloatRegister(dst); - } - - public Lddf(Register src, Register dst) { - super(Op3s.Lddf, src, dst); - assert dst == f0 || dst == f2 || dst == f4 || dst == f6 || isDoubleFloatRegister(dst); - } + public void fmovdcc(ConditionFlag cond, CC cc, Register rs2, Register rd) { + fmovcc(cond, cc, rs2, rd, Fmovdcc.value); } - public static class Ldf extends Fmt11 { - - public Ldf(SPARCAddress src, Register dst) { - super(Op3s.Ldf, src, dst); - assert isSingleFloatRegister(dst); - } - - public Ldf(Register src, Register dst) { - super(Op3s.Ldf, src, dst); - assert isSingleFloatRegister(dst); - } + public void fmovscc(ConditionFlag cond, CC cc, Register rs2, Register rd) { + fmovcc(cond, cc, rs2, rd, Fmovscc.value); } - public static class Ldsb extends Fmt11 { - - public Ldsb(SPARCAddress src, Register dst) { - super(Op3s.Ldsb, src, dst); - } - } - - public static class Ldsh extends Fmt11 { - - public Ldsh(SPARCAddress src, Register dst) { - super(Op3s.Ldsh, src, dst); - } - } - - public static class Lduh extends Fmt11 { - - public Lduh(SPARCAddress src, Register dst) { - super(Op3s.Lduh, src, dst); - } + private void fmovcc(ConditionFlag cond, CC cc, Register rs2, Register rd, int opfLow) { + int opfCC = cc.value; + int a = opfCC << 11 | opfLow << 5 | rs2.encoding; + fmt10(rd.encoding, Fpop2.value, cond.value, a); } - public static class Ldub extends Fmt11 { - - public Ldub(SPARCAddress src, Register dst) { - super(Op3s.Ldub, src, dst); - } - } - - public static class Ldsw extends Fmt11 { - - public Ldsw(SPARCAddress src, Register dst) { - super(Op3s.Ldsw, src, dst); - } - } - - public static class Lduw extends Fmt11 { - - public Lduw(SPARCAddress src, Register dst) { - super(Op3s.Lduw, src, dst); - } - } - - public static class Ldx extends Fmt11 { - - public Ldx(SPARCAddress src, Register dst) { - super(Op3s.Ldx, src, dst); - } + public void movcc(ConditionFlag conditionFlag, CC cc, Register rs2, Register rd) { + movcc(conditionFlag, cc, 0, rs2.encoding, rd); } - public static class Ldxa extends Fmt11 { - - public Ldxa(Register src1, Register src2, Register dst, Asi asi) { - super(Op3s.Ldxa, src1, src2, dst, asi); - } - } - - public static class Lduwa extends Fmt11 { - - public Lduwa(Register src1, Register src2, Register dst, Asi asi) { - super(Op3s.Lduwa, src1, src2, dst, asi); - } - } - - public static class Membar extends Fmt10 { - - public Membar(int barriers) { - super(Op3s.Membar, r15, barriers, r0); - } - } - - public static class Fmovscc extends Fmt10d { - - public Fmovscc(ConditionFlag cond, CC cca, Register src2, Register dst) { - super(Op3s.Fpop2, Opfs.Fmovscc, cond, cca, src2, dst); - } + public void movcc(ConditionFlag conditionFlag, CC cc, int simm11, Register rd) { + assert isSimm11(simm11); + movcc(conditionFlag, cc, 1, simm11 & ((1 << 11) - 1), rd); } - public static class Fmovdcc extends Fmt10d { - - public Fmovdcc(ConditionFlag cond, CC cca, Register src2, Register dst) { - super(Op3s.Fpop2, Opfs.Fmovdcc, cond, cca, src2, dst); - } + private void movcc(ConditionFlag conditionFlag, CC cc, int i, int imm, Register rd) { + int cc01 = 0b11 & cc.value; + int cc2 = cc.isFloat ? 0 : 1; + int a = cc2 << 4 | conditionFlag.value; + int b = cc01 << 11 | i << 13 | imm; + fmt10(rd.encoding, Movcc.value, a, b); } - public static class Movcc extends Fmt10c { - - public Movcc(ConditionFlag cond, CC cca, Register src2, Register dst) { - super(Op3s.Movcc, cond, cca, src2, dst); - } - - public Movcc(ConditionFlag cond, CC cca, int simm11, Register dst) { - super(Op3s.Movcc, cond, cca, simm11, dst); - } - } - - public static class Movr extends Fmt3f { - - public Movr(SPARCAssembler masm, RCondition rc, Register src1, Register src2, Register dst) { - super(masm, Ops.ArithOp.getValue(), Op3s.Movr.getValue(), rc.getValue(), src1.encoding(), src2.encoding(), dst.encoding()); - } - - public Movr(SPARCAssembler masm, RCondition rc, Register src1, int simm10, Register dst) { - super(masm, Ops.ArithOp.getValue(), Op3s.Movr.getValue(), rc.getValue(), src1.encoding(), simm10, dst.encoding()); - } + public void mulx(Register rs1, Register rs2, Register rd) { + op3(Mulx, rs1, rs2, rd); } - @Deprecated - public static class Mulscc extends Fmt10 { - - @Deprecated - public Mulscc(Register src1, int simm13, Register dst) { - super(Op3s.Mulscc, src1, simm13, dst); - } - - @Deprecated - public Mulscc(Register src1, Register src2, Register dst) { - super(Op3s.Mulscc, src1, src2, dst); - } - } - - public static class Mulx extends Fmt10 { - - public Mulx(Register src1, int simm13, Register dst) { - super(Op3s.Mulx, src1, simm13, dst); - } - - public Mulx(Register src1, Register src2, Register dst) { - super(Op3s.Mulx, src1, src2, dst); - } + public void mulx(Register rs1, int simm13, Register rd) { + op3(Mulx, rs1, simm13, rd); } - public static class SMulcc extends Fmt10 { - - public SMulcc(Register src1, int simm13, Register dst) { - super(Op3s.Smulcc, src1, simm13, dst); - } - - public SMulcc(Register src1, Register src2, Register dst) { - super(Op3s.Smulcc, src1, src2, dst); - } + public void or(Register rs1, Register rs2, Register rd) { + op3(Or, rs1, rs2, rd); } - public static class Or extends Fmt10 { - - public Or(Register src1, int simm13, Register dst) { - super(Op3s.Or, src1, simm13, dst); - } - - public Or(Register src1, Register src2, Register dst) { - super(Op3s.Or, src1, src2, dst); - } - } - - public static class Orcc extends Fmt10 { - - public Orcc(Register src1, int simm13, Register dst) { - super(Op3s.Orcc, src1, simm13, dst); - } - - public Orcc(Register src1, Register src2, Register dst) { - super(Op3s.Orcc, src1, src2, dst); - } + public void or(Register rs1, int simm13, Register rd) { + op3(Or, rs1, simm13, rd); } - public static class Orn extends Fmt10 { - - public Orn(Register src1, int simm13, Register dst) { - super(Op3s.Orn, src1, simm13, dst); - } - - public Orn(Register src1, Register src2, Register dst) { - super(Op3s.Orn, src1, src2, dst); - } + public void popc(Register rs2, Register rd) { + op3(Popc, g0, rs2, rd); } - public static class Orncc extends Fmt10 { - - public Orncc(Register src1, int simm13, Register dst) { - super(Op3s.Orncc, src1, simm13, dst); - } - - public Orncc(Register src1, Register src2, Register dst) { - super(Op3s.Orncc, src1, src2, dst); - } + public void popc(int simm13, Register rd) { + op3(Popc, g0, simm13, rd); } - public static class Popc extends Fmt10 { - - public Popc(int simm13, Register dst) { - super(Op3s.Popc, r0, simm13, dst); - } - - public Popc(Register src2, Register dst) { - super(Op3s.Popc, r0, src2, dst); - } - } - - public static class Prefetch extends Fmt11 { - - public enum Fcn { - SeveralWritesAndPossiblyReads(2), - SeveralReadsWeak(0), - OneRead(1), - OneWrite(3), - Page(4), - NearestUnifiedCache(17), - SeveralReadsStrong(20), - OneReadStrong(21), - SeveralWritesAndPossiblyReadsStrong(22), - OneWriteStrong(23); - - private final int value; - - private Fcn(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - } - - public Prefetch(SPARCAddress addr, Prefetch.Fcn fcn) { - super(Op3s.Prefetch, addr, fcn); + public void prefetch(SPARCAddress addr, Fcn fcn) { + Register rs1 = addr.getBase(); + if (addr.getIndex().equals(Register.None)) { + int dis = addr.getDisplacement(); + assert isSimm13(dis); + fmt(Prefetch.op.op, fcn.value, Prefetch.value, rs1.encoding, 1 << 13 | dis & ((1 << 13) - 1)); + } else { + Register rs2 = addr.getIndex(); + fmt(Prefetch.op.op, fcn.value, Prefetch.value, rs1.encoding, rs2.encoding); } } // A.44 Read State Register - @Deprecated - public static class Rdy extends Fmt10 { + public void rdpc(Register rd) { + op3(Rd, r5, g0, rd); + } - public Rdy(Register dst) { - super(Op3s.Rdreg, r0, dst); - } + public void restore(Register rs1, Register rs2, Register rd) { + op3(Restore, rs1, rs2, rd); } - public static class Rdccr extends Fmt10 { + public static final int PC_RETURN_OFFSET = 8; - public Rdccr(Register dst) { - super(Op3s.Rdreg, r2, dst); - } + public void save(Register rs1, Register rs2, Register rd) { + op3(Save, rs1, rs2, rd); } - public static class Rdasi extends Fmt10 { - - public Rdasi(Register dst) { - super(Op3s.Rdreg, r3, dst); - } + public void save(Register rs1, int simm13, Register rd) { + op3(Save, rs1, simm13, rd); } - public static class Rdtick extends Fmt10 { + public void sdivx(Register rs1, Register rs2, Register rd) { + op3(Sdivx, rs1, rs2, rd); + } - public Rdtick(Register dst) { - super(Op3s.Rdreg, r4, dst); - } + public void sdivx(Register rs1, int simm13, Register rd) { + op3(Sdivx, rs1, simm13, rd); } - public static class Rdpc extends Fmt10 { - - public Rdpc(Register dst) { - super(Op3s.Rdreg, r5, dst); - } + public void udivx(Register rs1, Register rs2, Register rd) { + op3(Udivx, rs1, rs2, rd); } - public static class Rdfprs extends Fmt10 { - - public Rdfprs(Register dst) { - super(Op3s.Rdreg, r6, dst); - } + public void udivx(Register rs1, int simm13, Register rd) { + op3(Udivx, rs1, simm13, rd); } - public static class Restore extends Fmt10 { - - public Restore(Register src1, Register src2, Register dst) { - super(Op3s.Restore, src1, src2, dst); - } + public void sll(Register rs1, Register rs2, Register rd) { + op3(Sll, rs1, rs2, rd); } - public static class Restored extends Fmt10 { - - public Restored() { - super(Op3s.Saved, r0, r0, r1); - } + public void sll(Register rs1, int shcnt32, Register rd) { + assert isImm(shcnt32, 5); + op3(Sll, rs1, shcnt32, rd); } - public static class Return extends Fmt10 { - - public Return(Register src1, int simm13) { - super(Op3s.Rett, src1, simm13, r0); - } + public void sllx(Register rs1, Register rs2, Register rd) { + op3(Sllx, rs1, rs2, rd); + } - public Return(Register src1, Register src2) { - super(Op3s.Rett, src1, src2, r0); - } + public void sllx(Register rs1, int shcnt64, Register rd) { + assert isImm(shcnt64, 6); + op3(Sllx, rs1, shcnt64, rd); + } - public static final int PC_RETURN_OFFSET = 8; + public void sra(Register rs1, Register rs2, Register rd) { + op3(Sra, rs1, rs2, rd); } - public static class Save extends Fmt10 { + public void sra(Register rs1, int simm13, Register rd) { + op3(Sra, rs1, simm13, rd); + } - public Save(Register src1, Register src2, Register dst) { - super(Op3s.Save, src1, src2, dst); - } - - public Save(Register src1, int simm13, Register dst) { - super(Op3s.Save, src1, simm13, dst); - } + public void srax(Register rs1, Register rs2, Register rd) { + op3(Srax, rs1, rs2, rd); } - public static class Saved extends Fmt10 { - - public Saved() { - super(Op3s.Saved, r0, r0, r0); - } + public void srax(Register rs1, int shcnt64, Register rd) { + assert isImm(shcnt64, 6); + op3(Srax, rs1, shcnt64, rd); } - @Deprecated - public static class Sdiv extends Fmt10 { + public void srl(Register rs1, Register rs2, Register rd) { + op3(Srl, rs1, rs2, rd); + } - @Deprecated - public Sdiv(Register src1, int simm13, Register dst) { - super(Op3s.Sdiv, src1, simm13, dst); - } + public void srl(Register rs1, int simm13, Register rd) { + op3(Srl, rs1, simm13, rd); + } - @Deprecated - public Sdiv(Register src1, Register src2, Register dst) { - super(Op3s.Sdiv, src1, src2, dst); - } + public void srlx(Register rs1, Register rs2, Register rd) { + op3(Srlx, rs1, rs2, rd); } - @Deprecated - public static class Sdivcc extends Fmt10 { + public void srlx(Register rs1, int shcnt64, Register rd) { + assert isImm(shcnt64, 6); + op3(Srlx, rs1, shcnt64, rd); + } - @Deprecated - public Sdivcc(Register src1, int simm13, Register dst) { - super(Op3s.Sdivcc, src1, simm13, dst); - } + public void fandd(Register rs1, Register rs2, Register rd) { + op3(Impdep1, Fandd, rs1, rs2, rd); + } - @Deprecated - public Sdivcc(Register src1, Register src2, Register dst) { - super(Op3s.Sdivcc, src1, src2, dst); - } + public void sub(Register rs1, Register rs2, Register rd) { + op3(Sub, rs1, rs2, rd); + } + + public void sub(Register rs1, int simm13, Register rd) { + op3(Sub, rs1, simm13, rd); } - public static class Sdivx extends Fmt10 { + public void subcc(Register rs1, Register rs2, Register rd) { + op3(Subcc, rs1, rs2, rd); + } - public Sdivx(Register src1, int simm13, Register dst) { - super(Op3s.Sdivx, src1, simm13, dst); - } - - public Sdivx(Register src1, Register src2, Register dst) { - super(Op3s.Sdivx, src1, src2, dst); - } + public void subcc(Register rs1, int simm13, Register rd) { + op3(Subcc, rs1, simm13, rd); } - public static class Sethi extends Fmt00a { - - public Sethi(int imm22, Register dst) { - super(Op2s.Sethi, imm22, dst); - } + public void ta(int trap) { + tcc(Icc, Always, trap); } - public static class Sir extends Fmt10 { - - public Sir(int simm13) { - super(Op3s.Sir, r0, simm13, r15); - } + public void tcc(CC cc, ConditionFlag flag, int trap) { + assert isImm(trap, 8); + int b = cc.value << 11; + b |= trap; + fmt10(flag.value, trap, 0, b); } - public static class Sll extends Fmt10 { - - public Sll(Register src1, int shcnt32, Register dst) { - super(Op3s.Sll, src1, shcnt32, dst); - } - - public Sll(Register src1, Register src2, Register dst) { - super(Op3s.Sll, src1, src2, dst); - } + public void wrccr(Register rs1, Register rs2) { + op3(Wr, rs1, rs2, r2); } - public static class Sllx extends Fmt10 { + public void wrccr(Register rs1, int simm13) { + op3(Wr, rs1, simm13, r2); + } - public Sllx(Register src1, int shcnt64, Register dst) { - super(Op3s.Sllx, src1, shcnt64, dst); - } - - public Sllx(Register src1, Register src2, Register dst) { - super(Op3s.Sllx, src1, src2, dst); - } + public void xor(Register rs1, Register rs2, Register rd) { + op3(Xor, rs1, rs2, rd); } - public static class Sra extends Fmt10 { - - public Sra(Register src1, int shcnt32, Register dst) { - super(Op3s.Sra, src1, shcnt32, dst); - } - - public Sra(Register src1, Register src2, Register dst) { - super(Op3s.Sra, src1, src2, dst); - } + public void xor(Register rs1, int simm13, Register rd) { + op3(Xor, rs1, simm13, rd); } - public static class Srax extends Fmt10 { + public void xorcc(Register rs1, Register rs2, Register rd) { + op3(Xorcc, rs1, rs2, rd); + } - public Srax(Register src1, int shcnt64, Register dst) { - super(Op3s.Srax, src1, shcnt64, dst); - } - - public Srax(Register src1, Register src2, Register dst) { - super(Op3s.Srax, src1, src2, dst); - } + public void xorcc(Register rs1, int simm13, Register rd) { + op3(Xorcc, rs1, simm13, rd); } - public static class Srl extends Fmt10 { + public void xnor(Register rs1, Register rs2, Register rd) { + op3(Xnor, rs1, rs2, rd); + } - public Srl(Register src1, int shcnt32, Register dst) { - super(Op3s.Srl, src1, shcnt32, dst); - } - - public Srl(Register src1, Register src2, Register dst) { - super(Op3s.Srl, src1, src2, dst); - } + public void xnor(Register rs1, int simm13, Register rd) { + op3(Xnor, rs1, simm13, rd); } - public static class Srlx extends Fmt10 { - - public Srlx(Register src1, int shcnt64, Register dst) { - super(Op3s.Srlx, src1, shcnt64, dst); - } - - public Srlx(Register src1, Register src2, Register dst) { - super(Op3s.Srlx, src1, src2, dst); - } - } - - public static class Fandd extends Fmt3p { - public Fandd(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fandd, src1, src2, dst); - } - } - - public static class Fxord extends Fmt3p { - public Fxord(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fxord, src1, src2, dst); - } - } - - public static class Fxors extends Fmt3p { - public Fxors(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fxors, src1, src2, dst); + /* + * Load/Store + */ + protected void ld(Op3s op3, SPARCAddress addr, Register rd, Asi asi) { + Register rs1 = addr.getBase(); + if (!addr.getIndex().equals(Register.None)) { + Register rs2 = addr.getIndex(); + if (asi != null) { + int b = rs2.encoding; + b |= asi.value << 5; + fmt(op3.op.op, rd.encoding, op3.value, rs1.encoding, b); + } else { + op3(op3, rs1, rs2, rd); + } + } else { + int imm = addr.getDisplacement(); + op3(op3, rs1, imm, rd); } } - public static class Fands extends Fmt3p { - public Fands(Register src1, Register src2, Register dst) { - super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fands, src1, src2, dst); - } + protected void ld(Op3s op3, SPARCAddress addr, Register rd) { + ld(op3, addr, rd, null); } - public static class Stb extends Fmt11 { - - public Stb(Register dst, SPARCAddress addr) { - super(Op3s.Stb, addr, dst); - } - } - - public static class Stdf extends Fmt11 { - - public Stdf(Register dst, SPARCAddress src) { - super(Op3s.Stdf, src, dst); - } + public void lddf(SPARCAddress src, Register dst) { + ld(Lddf, src, dst); } - public static class Stf extends Fmt11 { - - public Stf(Register dst, SPARCAddress src) { - super(Op3s.Stf, src, dst); - } + public void ldf(SPARCAddress src, Register dst) { + ld(Ldf, src, dst); } - public static class Sth extends Fmt11 { - - public Sth(Register dst, SPARCAddress addr) { - super(Op3s.Sth, addr, dst); - } + public void lduh(SPARCAddress src, Register dst) { + ld(Lduh, src, dst); } - public static class Stw extends Fmt11 { - - public Stw(Register dst, SPARCAddress addr) { - super(Op3s.Stw, addr, dst); - } - } - - public static class Stx extends Fmt11 { - - public Stx(Register dst, SPARCAddress addr) { - super(Op3s.Stx, addr, dst); - } + public void ldsh(SPARCAddress src, Register dst) { + ld(Ldsh, src, dst); } - public static class Sub extends Fmt10 { - - public Sub(Register src1, int simm13, Register dst) { - super(Op3s.Sub, src1, simm13, dst); - } - - public Sub(Register src1, Register src2, Register dst) { - super(Op3s.Sub, src1, src2, dst); - } + public void ldub(SPARCAddress src, Register dst) { + ld(Ldub, src, dst); } - public static class Subc extends Fmt10 { - - public Subc(Register src1, int simm13, Register dst) { - super(Op3s.Subc, src1, simm13, dst); - } - - public Subc(Register src1, Register src2, Register dst) { - super(Op3s.Subc, src1, src2, dst); - } + public void ldsb(SPARCAddress src, Register dst) { + ld(Ldsb, src, dst); } - public static class Subcc extends Fmt10 { - - public Subcc(Register src1, int simm13, Register dst) { - super(Op3s.Subcc, src1, simm13, dst); - } - - public Subcc(Register src1, Register src2, Register dst) { - super(Op3s.Subcc, src1, src2, dst); - } + public void lduw(SPARCAddress src, Register dst) { + ld(Lduw, src, dst); } - public static class Subccc extends Fmt10 { - - public Subccc(Register src1, int simm13, Register dst) { - super(Op3s.Subccc, src1, simm13, dst); - } - - public Subccc(Register src1, Register src2, Register dst) { - super(Op3s.Subccc, src1, src2, dst); - } + public void ldsw(SPARCAddress src, Register dst) { + ld(Ldsw, src, dst); } - public static class Ta extends Fmt10 { - - public Ta(int trap) { - super(Op3s.Trap, g0, trap, ConditionFlag.Always); - } + public void ldx(SPARCAddress src, Register dst) { + ld(Ldx, src, dst); } - public static class Tcc extends Fmt10 { - - public Tcc(ConditionFlag flag, int trap) { - super(Op3s.Trap, g0, trap, flag); - } + public void ldxa(Register rs1, Register rs2, Register rd, Asi asi) { + ld(Ldxa, new SPARCAddress(rs1, rs2), rd, asi); } - public static class Taddcc extends Fmt10 { - - public Taddcc(Register src1, int simm13, Register dst) { - super(Op3s.Taddcc, src1, simm13, dst); - } - - public Taddcc(Register src1, Register src2, Register dst) { - super(Op3s.Taddcc, src1, src2, dst); - } + public void lduwa(Register rs1, Register rs2, Register rd, Asi asi) { + ld(Lduwa, new SPARCAddress(rs1, rs2), rd, asi); } - public static class Tsubcc extends Fmt10 { - - public Tsubcc(Register src1, int simm13, Register dst) { - super(Op3s.Tsubcc, src1, simm13, dst); - } - - public Tsubcc(Register src1, Register src2, Register dst) { - super(Op3s.Tsubcc, src1, src2, dst); - } + protected void st(Op3s op3, Register rs1, SPARCAddress dest) { + ld(op3, dest, rs1); } - public static class Udivx extends Fmt10 { - - public Udivx(Register src1, int simm13, Register dst) { - super(Op3s.Udivx, src1, simm13, dst); - } - - public Udivx(Register src1, Register src2, Register dst) { - super(Op3s.Udivx, src1, src2, dst); - } + public void stdf(Register rd, SPARCAddress addr) { + st(Stdf, rd, addr); } - @Deprecated - public static class Wry extends Fmt10 { - - @Deprecated - public Wry(Register src1, int simm13) { - super(Op3s.Wrreg, src1, simm13, r0); - } - - @Deprecated - public Wry(Register src1, Register src2) { - super(Op3s.Wrreg, src1, src2, r0); - } + public void stf(Register rd, SPARCAddress addr) { + st(Stf, rd, addr); } - public static class Wrccr extends Fmt10 { - - public Wrccr(Register src1, int simm13) { - super(Op3s.Wrreg, src1, simm13, r2); - } - - public Wrccr(Register src1, Register src2) { - super(Op3s.Wrreg, src1, src2, r2); - } + public void stb(Register rd, SPARCAddress addr) { + st(Stb, rd, addr); } - public static class Wrasi extends Fmt10 { - - public Wrasi(Register src1, int simm13) { - super(Op3s.Wrreg, src1, simm13, r3); - } - - public Wrasi(Register src1, Register src2) { - super(Op3s.Wrreg, src1, src2, r3); - } + public void sth(Register rd, SPARCAddress addr) { + st(Sth, rd, addr); } - public static class Wrfprs extends Fmt10 { - - public Wrfprs(Register src1, int simm13) { - super(Op3s.Wrreg, src1, simm13, r6); - } - - public Wrfprs(Register src1, Register src2) { - super(Op3s.Wrreg, src1, src2, r6); - } + public void stw(Register rd, SPARCAddress addr) { + st(Stw, rd, addr); } - public static class Xor extends Fmt10 { - - public Xor(Register src1, int simm13, Register dst) { - super(Op3s.Xor, src1, simm13, dst); - } - - public Xor(Register src1, Register src2, Register dst) { - super(Op3s.Xor, src1, src2, dst); - } + public void stx(Register rd, SPARCAddress addr) { + st(Stx, rd, addr); } - public static class Xorcc extends Fmt10 { - - public Xorcc(Register src1, int simm13, Register dst) { - super(Op3s.Xorcc, src1, simm13, dst); - } - - public Xorcc(Register src1, Register src2, Register dst) { - super(Op3s.Xorcc, src1, src2, dst); - } + public void membar(int barriers) { + op3(Membar, r15, barriers, g0); } - public static class Xnor extends Fmt10 { - - public Xnor(Register src1, int simm13, Register dst) { - super(Op3s.Xnor, src1, simm13, dst); - } - - public Xnor(Register src1, Register src2, Register dst) { - super(Op3s.Xnor, src1, src2, dst); - } + public void casa(Register rs1, Register rs2, Register rd, Asi asi) { + ld(Casa, new SPARCAddress(rs1, rs2), rd, asi); } - public static class Xnorcc extends Fmt10 { - - public Xnorcc(Register src1, int simm13, Register dst) { - super(Op3s.Xnorcc, src1, simm13, dst); - } - - public Xnorcc(Register src1, Register src2, Register dst) { - super(Op3s.Xnorcc, src1, src2, dst); - } + public void casxa(Register rs1, Register rs2, Register rd, Asi asi) { + ld(Casxa, new SPARCAddress(rs1, rs2), rd, asi); } }
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,10 +22,15 @@ */ package com.oracle.graal.asm.sparc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.sparc.SPARC.*; +import java.util.function.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; public class SPARCMacroAssembler extends SPARCAssembler { @@ -42,22 +47,64 @@ @Override public void align(int modulus) { while (position() % modulus != 0) { - new Nop().emit(this); + nop(); } } @Override public void jmp(Label l) { - new Bpa(l).emit(this); - new Nop().emit(this); // delay slot + bicc(Always, NOT_ANNUL, l); + nop(); // delay slot } @Override protected final void patchJumpTarget(int branch, int branchTarget) { - final int disp = branchTarget - branch; - Fmt00 fmt = Fmt00.read(this, branch); - fmt.setImm(disp); - fmt.write(this, branch); + final int disp = (branchTarget - branch) / 4; + final int inst = getInt(branch); + Op2s op2 = Op2s.byValue((inst & OP2_MASK) >> OP2_SHIFT); + int maskBits; + int setBits; + switch (op2) { + case Br: + case Fb: + case Sethi: + case Illtrap: + // Disp 22 in the lower 22 bits + assert isSimm(disp, 22); + setBits = disp << DISP22_SHIFT; + maskBits = DISP22_MASK; + break; + case Fbp: + case Bp: + // Disp 19 in the lower 19 bits + assert isSimm(disp, 19); + setBits = disp << DISP19_SHIFT; + maskBits = DISP19_MASK; + break; + case Bpr: + boolean isCBcond = (inst & CBCOND_MASK) != 0; + if (isCBcond) { + assert isSimm10(disp); + int d10Split = 0; + d10Split |= (disp & 0b11_0000_0000) << D10HI_SHIFT - 8; + d10Split |= (disp & 0b00_1111_1111) << D10LO_SHIFT; + setBits = d10Split; + maskBits = D10LO_MASK | D10HI_MASK; + } else { + assert isSimm(disp, 16); + int d16Split = 0; + d16Split |= (disp & 0b1100_0000_0000_0000) << D16HI_SHIFT - 14; + d16Split |= (disp & 0b0011_1111_1111_1111) << D16LO_SHIFT; + setBits = d16Split; + maskBits = D16HI_MASK | D16LO_MASK; + } + break; + default: + throw GraalInternalError.shouldNotReachHere("Unknown op2 " + op2); + } + int newInst = ~maskBits & inst; + newInst |= setBits; + emitInt(newInst, branch); } @Override @@ -72,278 +119,87 @@ @Override public final void ensureUniquePC() { - new Nop().emit(this); + nop(); } - public static class Bclr extends Andn { - - public Bclr(Register src, Register dst) { - super(dst, src, dst); - } - - public Bclr(int simm13, Register dst) { - super(dst, simm13, dst); - } + public void cas(Register rs1, Register rs2, Register rd) { + casa(rs1, rs2, rd, Asi.ASI_PRIMARY); } - public static class Bpgeu extends Bpcc { - - public Bpgeu(CC cc, int simm19) { - super(cc, simm19); - } - - public Bpgeu(CC cc, Label label) { - super(cc, label); - } - - public Bpgeu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(cc, annul, predictTaken, label); - } + public void casx(Register rs1, Register rs2, Register rd) { + casxa(rs1, rs2, rd, Asi.ASI_PRIMARY); } - public static class Bplu extends Bpcs { - - public Bplu(CC cc, int simm19) { - super(cc, simm19); - } - - public Bplu(CC cc, Label label) { - super(cc, label); - } - - public Bplu(CC cc, boolean annul, boolean predictTaken, Label label) { - super(cc, annul, predictTaken, label); - } + public void clr(Register dst) { + or(g0, g0, dst); } - public static class Bset extends Or { - - public Bset(Register src, Register dst) { - super(dst, src, dst); - } - - public Bset(int simm13, Register dst) { - super(dst, simm13, dst); - } + public void clrb(SPARCAddress addr) { + stb(g0, addr); } - public static class Btst extends Andcc { - - public Btst(Register src1, Register src2) { - super(src1, src2, g0); - } - - public Btst(Register src1, int simm13) { - super(src1, simm13, g0); - } + public void clrh(SPARCAddress addr) { + sth(g0, addr); } - public static class Cas extends Casa { - - public Cas(Register src1, Register src2, Register dst) { - super(src1, src2, dst, Asi.ASI_PRIMARY); - } - } - - public static class Casx extends Casxa { - - public Casx(Register src1, Register src2, Register dst) { - super(src1, src2, dst, Asi.ASI_PRIMARY); - } - } - - public static class Clr extends Or { - - public Clr(Register dst) { - super(g0, g0, dst); - } + public void clrx(SPARCAddress addr) { + stx(g0, addr); } - public static class Clrb extends Stb { - - public Clrb(SPARCAddress addr) { - super(g0, addr); - } - } - - public static class Clrh extends Sth { - - public Clrh(SPARCAddress addr) { - super(g0, addr); - } - } - - public static class Clrx extends Stx { - - public Clrx(SPARCAddress addr) { - super(g0, addr); - } + public void cmp(Register rs1, Register rs2) { + subcc(rs1, rs2, g0); } - public static class Clruw extends Srl { - - public Clruw(Register src1, Register dst) { - super(src1, g0, dst); - assert src1.encoding() != dst.encoding(); - } - - public Clruw(Register dst) { - super(dst, g0, dst); - } + public void cmp(Register rs1, int simm13) { + subcc(rs1, simm13, g0); } - public static class Cmp extends Subcc { - - public Cmp(Register a, Register b) { - super(a, b, g0); - } - - public Cmp(Register a, int simm13) { - super(a, simm13, g0); - } + public void dec(Register rd) { + sub(rd, 1, rd); } - public static class Dec extends Sub { - - public Dec(Register dst) { - super(dst, 1, dst); - } - - public Dec(int simm13, Register dst) { - super(dst, simm13, dst); - } + public void dec(int simm13, Register rd) { + sub(rd, simm13, rd); } - public static class Deccc extends Subcc { - - public Deccc(Register dst) { - super(dst, 1, dst); - } - - public Deccc(int simm13, Register dst) { - super(dst, simm13, dst); - } + public void jmp(SPARCAddress address) { + jmpl(address.getBase(), address.getDisplacement(), g0); } - @SuppressWarnings("unused") - public static class Inc { - - public Inc(Register dst) { - new Add(dst, 1, dst); - } - - public Inc(int simm13, Register dst) { - new Add(dst, simm13, dst); - } + public void jmp(Register rd) { + jmpl(rd, 0, g0); } - @SuppressWarnings("unused") - public static class Inccc { - - public Inccc(Register dst) { - new Addcc(dst, 1, dst); - } - - public Inccc(int simm13, Register dst) { - new Addcc(dst, simm13, dst); - } + public void neg(Register rs1, Register rd) { + sub(g0, rs1, rd); } - public static class Jmp extends Jmpl { - - public Jmp(SPARCAddress address) { - super(address.getBase(), address.getDisplacement(), g0); - } - - public Jmp(Register reg) { - super(reg, 0, g0); - } - } - - public static class Neg extends Sub { - - public Neg(Register src2, Register dst) { - super(g0, src2, dst); - } - - public Neg(Register dst) { - super(g0, dst, dst); - } + public void neg(Register rd) { + sub(g0, rd, rd); } - public static class Mov extends Or { - - public Mov(Register src1, Register dst) { - super(g0, src1, dst); - assert src1.encoding() != dst.encoding(); - } - - public Mov(int simm13, Register dst) { - super(g0, simm13, dst); - } + public void mov(Register rs, Register rd) { + or(g0, rs, rd); } - public static class Nop extends Sethi { - - public Nop() { - super(0, r0); - } - } - - public static class Not extends Xnor { - - public Not(Register src1, Register dst) { - super(src1, g0, dst); - } - - public Not(Register dst) { - super(dst, g0, dst); - } - } - - public static class RestoreWindow extends Restore { - - public RestoreWindow() { - super(g0, g0, g0); - } + public void mov(int simm13, Register rd) { + or(g0, simm13, rd); } - public static class Ret extends Jmpl { - - public Ret() { - super(i7, 8, g0); - } - } - - public static class SaveWindow extends Save { - - public SaveWindow() { - super(g0, g0, g0); - } + public void not(Register rs1, Register rd) { + xnor(rs1, g0, rd); } - public static class Setuw { - - private int value; - private Register dst; - - public Setuw(int value, Register dst) { - this.value = value; - this.dst = dst; - } + public void not(Register rd) { + xnor(rd, g0, rd); + } - public void emit(SPARCMacroAssembler masm) { - if (value == 0) { - new Clr(dst).emit(masm); - } else if (isSimm13(value)) { - new Or(g0, value, dst).emit(masm); - } else if (value >= 0 && ((value & 0x3FFF) == 0)) { - new Sethi(hi22(value), dst).emit(masm); - } else { - new Sethi(hi22(value), dst).emit(masm); - new Or(dst, lo10(value), dst).emit(masm); - } - } + public void restoreWindow() { + restore(g0, g0, g0); + } + + public void ret() { + jmpl(i7, 8, g0); } /** @@ -357,7 +213,7 @@ private Register dst; private boolean forceRelocatable; private boolean delayed = false; - private AssemblerEmittable delayedInstruction; + private Consumer<SPARCAssembler> delayedInstructionEmitter; public Sethix(long value, Register dst, boolean forceRelocatable, boolean delayed) { this(value, dst, forceRelocatable); @@ -375,72 +231,85 @@ this(value, dst, false); } - private void emitInstruction(AssemblerEmittable insn, SPARCMacroAssembler masm) { + private void emitInstruction(Consumer<SPARCAssembler> cb, SPARCMacroAssembler masm) { if (delayed) { - if (this.delayedInstruction != null) { - delayedInstruction.emit(masm); + if (this.delayedInstructionEmitter != null) { + delayedInstructionEmitter.accept(masm); } - delayedInstruction = insn; + delayedInstructionEmitter = cb; } else { - insn.emit(masm); + cb.accept(masm); } } public void emit(SPARCMacroAssembler masm) { - int hi = (int) (value >> 32); - int lo = (int) (value & ~0); + final int hi = (int) (value >> 32); + final int lo = (int) (value & ~0); // This is the same logic as MacroAssembler::internal_set. final int startPc = masm.position(); if (hi == 0 && lo >= 0) { - emitInstruction(new Sethi(hi22(lo), dst), masm); + Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(lo), dst); + emitInstruction(cb, masm); } else if (hi == -1) { - emitInstruction(new Sethi(hi22(~lo), dst), masm); - emitInstruction(new Xor(dst, ~lo10(~0), dst), masm); + Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(~lo), dst); + emitInstruction(cb, masm); + cb = eMasm -> eMasm.xor(dst, ~lo10(~0), dst); + emitInstruction(cb, masm); } else { - int shiftcnt = 0; - emitInstruction(new Sethi(hi22(hi), dst), masm); + final int shiftcnt; + final int shiftcnt2; + Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(hi), dst); + emitInstruction(cb, masm); if ((hi & 0x3ff) != 0) { // Any bits? // msb 32-bits are now in lsb 32 - emitInstruction(new Or(dst, hi & 0x3ff, dst), masm); + cb = eMasm -> eMasm.or(dst, hi & 0x3ff, dst); + emitInstruction(cb, masm); } if ((lo & 0xFFFFFC00) != 0) { // done? if (((lo >> 20) & 0xfff) != 0) { // Any bits set? // Make room for next 12 bits - emitInstruction(new Sllx(dst, 12, dst), masm); + cb = eMasm -> eMasm.sllx(dst, 12, dst); + emitInstruction(cb, masm); // Or in next 12 - emitInstruction(new Or(dst, (lo >> 20) & 0xfff, dst), masm); + cb = eMasm -> eMasm.or(dst, (lo >> 20) & 0xfff, dst); + emitInstruction(cb, masm); shiftcnt = 0; // We already shifted } else { shiftcnt = 12; } if (((lo >> 10) & 0x3ff) != 0) { // Make room for last 10 bits - emitInstruction(new Sllx(dst, shiftcnt + 10, dst), masm); + cb = eMasm -> eMasm.sllx(dst, shiftcnt + 10, dst); + emitInstruction(cb, masm); // Or in next 10 - emitInstruction(new Or(dst, (lo >> 10) & 0x3ff, dst), masm); - shiftcnt = 0; + cb = eMasm -> eMasm.or(dst, (lo >> 10) & 0x3ff, dst); + emitInstruction(cb, masm); + shiftcnt2 = 0; } else { - shiftcnt = 10; + shiftcnt2 = 10; } // Shift leaving disp field 0'd - emitInstruction(new Sllx(dst, shiftcnt + 10, dst), masm); + cb = eMasm -> eMasm.sllx(dst, shiftcnt2 + 10, dst); + emitInstruction(cb, masm); } else { - emitInstruction(new Sllx(dst, 32, dst), masm); + cb = eMasm -> eMasm.sllx(dst, 32, dst); + emitInstruction(cb, masm); } } // Pad out the instruction sequence so it can be patched later. if (forceRelocatable) { while (masm.position() < (startPc + (INSTRUCTION_SIZE * 4))) { - emitInstruction(new Nop(), masm); + Consumer<SPARCAssembler> cb = eMasm -> eMasm.nop(); + emitInstruction(cb, masm); } } } public void emitDelayed(SPARCMacroAssembler masm) { - assert delayedInstruction != null; - delayedInstruction.emit(masm); + assert delayedInstructionEmitter != null; + delayedInstructionEmitter.accept(masm); } } @@ -452,7 +321,7 @@ private boolean delayed = false; private boolean delayedFirstEmitted = false; private Sethix sethix; - private AssemblerEmittable delayedAdd; + private Consumer<SPARCMacroAssembler> delayedAdd; public Setx(long value, Register dst, boolean forceRelocatable, boolean delayed) { assert !(forceRelocatable && delayed) : "Cannot use relocatable setx as delayable"; @@ -480,14 +349,14 @@ sethix.emit(masm); int lo = (int) (value & ~0); if (lo10(lo) != 0 || forceRelocatable) { - Add add = new Add(dst, lo10(lo), dst); + Consumer<SPARCMacroAssembler> add = eMasm -> eMasm.add(dst, lo10(lo), dst); if (delayed) { sethix.emitDelayed(masm); sethix = null; delayedAdd = add; } else { sethix = null; - add.emit(masm); + add.accept(masm); } } } @@ -505,7 +374,7 @@ assert delayedFirstEmitted : "First part has not been emitted so far."; assert delayedAdd == null && sethix != null || delayedAdd != null && sethix == null : "Either add or sethix must be set"; if (delayedAdd != null) { - delayedAdd.emit(masm); + delayedAdd.accept(masm); } else { sethix.emitDelayed(masm); } @@ -513,14 +382,11 @@ } } - public static class Signx extends Sra { + public void signx(Register rs, Register rd) { + sra(rs, g0, rd); + } - public Signx(Register src1, Register dst) { - super(src1, g0, dst); - } - - public Signx(Register dst) { - super(dst, g0, dst); - } + public void signx(Register rd) { + sra(rd, g0, rd); } }
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeLookupSwitch.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeLookupSwitch.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ /** * Constructor for a {@link BytecodeStream}. - * + * * @param stream the {@code BytecodeStream} containing the switch instruction * @param bci the index in the stream of the switch instruction */
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ /** * Creates a new {@code BytecodeStream} for the specified bytecode. - * + * * @param code the array of bytes that contains the bytecode */ public BytecodeStream(byte[] code) { @@ -54,7 +54,7 @@ /** * Gets the next bytecode index (no side-effects). - * + * * @return the next bytecode index */ public int nextBCI() { @@ -63,7 +63,7 @@ /** * Gets the current bytecode index. - * + * * @return the current bytecode index */ public int currentBCI() { @@ -72,7 +72,7 @@ /** * Gets the bytecode index of the end of the code. - * + * * @return the index of the end of the code */ public int endBCI() { @@ -82,7 +82,7 @@ /** * Gets the current opcode. This method will never return the {@link Bytecodes#WIDE WIDE} * opcode, but will instead return the opcode that is modified by the {@code WIDE} opcode. - * + * * @return the current opcode; {@link Bytecodes#END} if at or beyond the end of the code */ public int currentBC() { @@ -96,7 +96,7 @@ /** * Reads the index of a local variable for one of the load or store instructions. The WIDE * modifier is handled internally. - * + * * @return the index of the local variable */ public int readLocalIndex() { @@ -109,7 +109,7 @@ /** * Read the delta for an {@link Bytecodes#IINC} bytecode. - * + * * @return the delta for the {@code IINC} */ public int readIncrement() { @@ -122,7 +122,7 @@ /** * Read the destination of a {@link Bytecodes#GOTO} or {@code IF} instructions. - * + * * @return the destination bytecode index */ public int readBranchDest() { @@ -136,7 +136,7 @@ /** * Read a signed 4-byte integer from the bytecode stream at the specified bytecode index. - * + * * @param bci the bytecode index * @return the integer value */ @@ -147,7 +147,7 @@ /** * Reads an unsigned, 1-byte value from the bytecode stream at the specified bytecode index. - * + * * @param bci the bytecode index * @return the byte */ @@ -157,7 +157,7 @@ /** * Reads a constant pool index for the current instruction. - * + * * @return the constant pool index */ public char readCPI() { @@ -169,7 +169,7 @@ /** * Reads a constant pool index for an invokedynamic instruction. - * + * * @return the constant pool index */ public int readCPI4() { @@ -179,7 +179,7 @@ /** * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH). - * + * * @return the byte */ public byte readByte() { @@ -188,7 +188,7 @@ /** * Reads a signed, 2-byte short for the current instruction (e.g. SIPUSH). - * + * * @return the short value */ public short readShort() { @@ -199,7 +199,7 @@ * Sets the bytecode index to the specified value. If {@code bci} is beyond the end of the * array, {@link #currentBC} will return {@link Bytecodes#END} and other methods may throw * {@link ArrayIndexOutOfBoundsException}. - * + * * @param bci the new bytecode index */ public void setBCI(int bci) {
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeSwitch.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeSwitch.java Tue Mar 10 21:26:02 2015 +0100 @@ -44,7 +44,7 @@ /** * Constructor for a {@link BytecodeStream}. - * + * * @param stream the {@code BytecodeStream} containing the switch instruction * @param bci the index in the stream of the switch instruction */ @@ -56,7 +56,7 @@ /** * Gets the current bytecode index. - * + * * @return the current bytecode index */ public int bci() { @@ -65,7 +65,7 @@ /** * Gets the index of the instruction denoted by the {@code i}'th switch target. - * + * * @param i index of the switch target * @return the index of the instruction denoted by the {@code i}'th switch target */ @@ -75,7 +75,7 @@ /** * Gets the index of the instruction for the default switch target. - * + * * @return the index of the instruction for the default switch target */ public int defaultTarget() { @@ -84,7 +84,7 @@ /** * Gets the offset from the start of the switch instruction to the default switch target. - * + * * @return the offset to the default switch target */ public int defaultOffset() { @@ -93,7 +93,7 @@ /** * Gets the key at {@code i}'th switch target index. - * + * * @param i the switch target index * @return the key at {@code i}'th switch target index */ @@ -101,7 +101,7 @@ /** * Gets the offset from the start of the switch instruction for the {@code i}'th switch target. - * + * * @param i the switch target index * @return the offset to the {@code i}'th switch target */ @@ -109,14 +109,14 @@ /** * Gets the number of switch targets. - * + * * @return the number of switch targets */ public abstract int numberOfCases(); /** * Gets the total size in bytes of the switch instruction. - * + * * @return the total size in bytes of the switch instruction */ public abstract int size();
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeTableSwitch.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeTableSwitch.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ /** * Constructor for a {@link BytecodeStream}. - * + * * @param stream the {@code BytecodeStream} containing the switch instruction * @param bci the index in the stream of the switch instruction */ @@ -44,7 +44,7 @@ /** * Gets the low key of the table switch. - * + * * @return the low key */ public int lowKey() { @@ -53,7 +53,7 @@ /** * Gets the high key of the table switch. - * + * * @return the high key */ public int highKey() {
--- a/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytes.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytes.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ /** * Gets a signed 1-byte value. - * + * * @param data the array containing the data * @param bci the start index of the value to retrieve * @return the signed 1-byte value at index {@code bci} in array {@code data} @@ -40,7 +40,7 @@ /** * Gets a signed 2-byte big-endian value. - * + * * @param data the array containing the data * @param bci the start index of the value to retrieve * @return the signed 2-byte, big-endian, value at index {@code bci} in array {@code data} @@ -51,7 +51,7 @@ /** * Gets an unsigned 1-byte value. - * + * * @param data the array containing the data * @param bci the start index of the value to retrieve * @return the unsigned 1-byte value at index {@code bci} in array {@code data} @@ -62,7 +62,7 @@ /** * Gets an unsigned 2-byte big-endian value. - * + * * @param data the array containing the data * @param bci the start index of the value to retrieve * @return the unsigned 2-byte, big-endian, value at index {@code bci} in array {@code data} @@ -73,7 +73,7 @@ /** * Gets a signed 4-byte big-endian value. - * + * * @param data the array containing the data * @param bci the start index of the value to retrieve * @return the signed 4-byte, big-endian, value at index {@code bci} in array {@code data} @@ -84,7 +84,7 @@ /** * Gets either a signed 2-byte or a signed 4-byte big-endian value. - * + * * @param data the array containing the data * @param bci the start index of the value to retrieve * @param fourByte if true, this method will return a 4-byte value
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Mar 10 21:26:02 2015 +0100 @@ -81,7 +81,7 @@ private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(Kind.Int)); - private class AMD64SpillMoveFactory implements LIR.SpillMoveFactory { + private class AMD64SpillMoveFactory implements LIRGeneratorTool.SpillMoveFactory { @Override public LIRInstruction createMove(AllocatableValue result, Value input) { @@ -91,7 +91,10 @@ public AMD64LIRGenerator(LIRKindTool lirKindTool, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) { super(lirKindTool, providers, cc, lirGenRes); - lirGenRes.getLIR().setSpillMoveFactory(new AMD64SpillMoveFactory()); + } + + public SpillMoveFactory getSpillMoveFactory() { + return new AMD64SpillMoveFactory(); } @Override
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Tue Mar 10 21:26:02 2015 +0100 @@ -61,7 +61,21 @@ if ((valueNode instanceof IntegerDivNode) || (valueNode instanceof IntegerRemNode)) { FixedBinaryNode divRem = (FixedBinaryNode) valueNode; FixedNode node = divRem.next(); - while (node instanceof FixedWithNextNode) { + while (true) { + if (node instanceof IfNode) { + IfNode ifNode = (IfNode) node; + double probability = ifNode.getTrueSuccessorProbability(); + if (probability == 1.0) { + node = ifNode.trueSuccessor(); + } else if (probability == 0.0) { + node = ifNode.falseSuccessor(); + } else { + break; + } + } else if (!(node instanceof FixedWithNextNode)) { + break; + } + FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node; if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) { FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,12 +22,8 @@ */ package com.oracle.graal.compiler.common; -import java.util.concurrent.*; - public abstract class FieldIntrospection<T> extends UnsafeAccess { - protected static final ConcurrentHashMap<Class<?>, FieldIntrospection<?>> allClasses = new ConcurrentHashMap<>(); - private final Class<T> clazz; /**
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Tue Mar 10 21:26:02 2015 +0100 @@ -143,6 +143,9 @@ @Option(help = "", type = OptionType.Debug) public static final OptionValue<String> PrintFilter = new OptionValue<>(null); + @Option(help = "", type = OptionType.Debug) + public static final StableOptionValue<Boolean> DumpDuringGraphBuilding = new StableOptionValue<>(false); + // Debug settings: @Option(help = "", type = OptionType.Debug) public static final OptionValue<Boolean> BootstrapReplacements = new OptionValue<>(false); @@ -201,7 +204,7 @@ public static final OptionValue<Boolean> PrintBailout = new OptionValue<>(false); @Option(help = "", type = OptionType.Debug) - public static final OptionValue<Boolean> TraceEscapeAnalysis = new OptionValue<>(false); + public static final StableOptionValue<Boolean> TraceEscapeAnalysis = new StableOptionValue<>(false); @Option(help = "", type = OptionType.Debug) public static final OptionValue<Boolean> ExitVMOnBailout = new OptionValue<>(false); @@ -334,6 +337,9 @@ @Option(help = "Max number of loop explosions per method.", type = OptionType.Debug) public static final OptionValue<Integer> MaximumLoopExplosionCount = new OptionValue<>(10000); + @Option(help = "Do not bail out but throw an exception on failed loop explosion.", type = OptionType.Debug) + public static final OptionValue<Boolean> FailedLoopExplosionIsFatal = new OptionValue<>(false); + /** * Counts the various paths taken through snippets. */
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/ComputeBlockOrder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/ComputeBlockOrder.java Tue Mar 10 21:26:02 2015 +0100 @@ -66,7 +66,7 @@ * * @return sorted list of blocks */ - public static <T extends AbstractBlock<T>> List<T> computeLinearScanOrder(int blockCount, T startBlock) { + public static <T extends AbstractBlockBase<T>> List<T> computeLinearScanOrder(int blockCount, T startBlock) { List<T> order = new ArrayList<>(); BitSet visitedBlocks = new BitSet(blockCount); PriorityQueue<T> worklist = initializeWorklist(startBlock, visitedBlocks); @@ -80,7 +80,7 @@ * * @return sorted list of blocks */ - public static <T extends AbstractBlock<T>> List<T> computeCodeEmittingOrder(int blockCount, T startBlock) { + public static <T extends AbstractBlockBase<T>> List<T> computeCodeEmittingOrder(int blockCount, T startBlock) { List<T> order = new ArrayList<>(); BitSet visitedBlocks = new BitSet(blockCount); PriorityQueue<T> worklist = initializeWorklist(startBlock, visitedBlocks); @@ -92,7 +92,7 @@ /** * Iteratively adds paths to the code emission block order. */ - private static <T extends AbstractBlock<T>> void computeCodeEmittingOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { + private static <T extends AbstractBlockBase<T>> void computeCodeEmittingOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { while (!worklist.isEmpty()) { T nextImportantPath = worklist.poll(); addPathToCodeEmittingOrder(nextImportantPath, order, worklist, visitedBlocks); @@ -102,7 +102,7 @@ /** * Iteratively adds paths to the linear scan block order. */ - private static <T extends AbstractBlock<T>> void computeLinearScanOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { + private static <T extends AbstractBlockBase<T>> void computeLinearScanOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { while (!worklist.isEmpty()) { T nextImportantPath = worklist.poll(); addPathToLinearScanOrder(nextImportantPath, order, worklist, visitedBlocks); @@ -112,7 +112,7 @@ /** * Initializes the priority queue used for the work list of blocks and adds the start block. */ - private static <T extends AbstractBlock<T>> PriorityQueue<T> initializeWorklist(T startBlock, BitSet visitedBlocks) { + private static <T extends AbstractBlockBase<T>> PriorityQueue<T> initializeWorklist(T startBlock, BitSet visitedBlocks) { PriorityQueue<T> result = new PriorityQueue<>(INITIAL_WORKLIST_CAPACITY, new BlockOrderComparator<>()); result.add(startBlock); visitedBlocks.set(startBlock.getId()); @@ -122,7 +122,7 @@ /** * Add a linear path to the linear scan order greedily following the most likely successor. */ - private static <T extends AbstractBlock<T>> void addPathToLinearScanOrder(T block, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { + private static <T extends AbstractBlockBase<T>> void addPathToLinearScanOrder(T block, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { block.setLinearScanNumber(order.size()); order.add(block); T mostLikelySuccessor = findAndMarkMostLikelySuccessor(block, visitedBlocks); @@ -151,7 +151,7 @@ /** * Add a linear path to the code emission order greedily following the most likely successor. */ - private static <T extends AbstractBlock<T>> void addPathToCodeEmittingOrder(T initialBlock, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { + private static <T extends AbstractBlockBase<T>> void addPathToCodeEmittingOrder(T initialBlock, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks) { T block = initialBlock; while (block != null) { // Skip loop headers if there is only a single loop end block to @@ -191,7 +191,7 @@ /** * Adds a block to the ordering. */ - private static <T extends AbstractBlock<T>> void addBlock(T header, List<T> order) { + private static <T extends AbstractBlockBase<T>> void addBlock(T header, List<T> order) { assert !order.contains(header) : "Cannot insert block twice"; order.add(header); } @@ -199,7 +199,7 @@ /** * Find the highest likely unvisited successor block of a given block. */ - private static <T extends AbstractBlock<T>> T findAndMarkMostLikelySuccessor(T block, BitSet visitedBlocks) { + private static <T extends AbstractBlockBase<T>> T findAndMarkMostLikelySuccessor(T block, BitSet visitedBlocks) { T result = null; for (T successor : block.getSuccessors()) { assert successor.probability() >= 0.0 : "Probabilities must be positive"; @@ -216,7 +216,7 @@ /** * Add successor blocks into the given work list if they are not already marked as visited. */ - private static <T extends AbstractBlock<T>> void enqueueSuccessors(T block, PriorityQueue<T> worklist, BitSet visitedBlocks) { + private static <T extends AbstractBlockBase<T>> void enqueueSuccessors(T block, PriorityQueue<T> worklist, BitSet visitedBlocks) { for (T successor : block.getSuccessors()) { if (!visitedBlocks.get(successor.getId())) { visitedBlocks.set(successor.getId()); @@ -229,14 +229,14 @@ * Skip the loop header block if the loop consists of more than one block and it has only a * single loop end block. */ - private static <T extends AbstractBlock<T>> boolean skipLoopHeader(AbstractBlock<T> block) { + private static <T extends AbstractBlockBase<T>> boolean skipLoopHeader(AbstractBlockBase<T> block) { return (block.isLoopHeader() && !block.isLoopEnd() && block.getLoop().numBackedges() == 1); } /** * Checks that the ordering contains the expected number of blocks. */ - private static boolean checkOrder(List<? extends AbstractBlock<?>> order, int expectedBlockCount) { + private static boolean checkOrder(List<? extends AbstractBlockBase<?>> order, int expectedBlockCount) { assert order.size() == expectedBlockCount : String.format("Number of blocks in ordering (%d) does not match expected block count (%d)", order.size(), expectedBlockCount); return true; } @@ -244,7 +244,7 @@ /** * Comparator for sorting blocks based on loop depth and probability. */ - private static class BlockOrderComparator<T extends AbstractBlock<T>> implements Comparator<T> { + private static class BlockOrderComparator<T extends AbstractBlockBase<T>> implements Comparator<T> { @Override public int compare(T a, T b) {
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2014, 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.compiler.common.cfg; - -import java.util.*; - -public interface AbstractBlock<T extends AbstractBlock<T>> { - - int getId(); - - Loop<T> getLoop(); - - void setLoop(Loop<T> loop); - - int getLoopDepth(); - - boolean isLoopHeader(); - - boolean isLoopEnd(); - - boolean isExceptionEntry(); - - List<T> getPredecessors(); - - int getPredecessorCount(); - - List<T> getSuccessors(); - - int getSuccessorCount(); - - int getLinearScanNumber(); - - void setLinearScanNumber(int linearScanNumber); - - boolean isAligned(); - - void setAlign(boolean align); - - T getDominator(); - - void setDominator(T block); - - List<T> getDominated(); - - void setDominated(List<T> blocks); - - T getPostdominator(); - - double probability(); - -}
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,15 +24,18 @@ import java.util.*; -public abstract class AbstractBlockBase<T extends AbstractBlock<T>> implements AbstractBlock<T> { +public abstract class AbstractBlockBase<T extends AbstractBlockBase<T>> { protected int id; + protected int domDepth; protected List<T> predecessors; protected List<T> successors; private T dominator; private List<T> dominated; + private int domNumber; + private int maxChildDomNumber; private boolean align; private int linearScanNumber; @@ -42,6 +45,19 @@ this.linearScanNumber = -1; } + public void setDominatorNumbers(int domNumber, int maxChildDomNumber) { + this.domNumber = domNumber; + this.maxChildDomNumber = maxChildDomNumber; + } + + public int getDominatorNumber() { + return domNumber; + } + + public int getMaxChildDominatorNumber() { + return this.maxChildDomNumber; + } + public int getId() { return id; } @@ -72,6 +88,11 @@ public void setDominator(T dominator) { this.dominator = dominator; + this.domDepth = dominator.domDepth + 1; + } + + public int getDominatorDepth() { + return domDepth; } public List<T> getDominated() { @@ -113,4 +134,20 @@ public void setAlign(boolean align) { this.align = align; } + + public abstract boolean isExceptionEntry(); + + public abstract Loop<T> getLoop(); + + public abstract int getLoopDepth(); + + public abstract boolean isLoopEnd(); + + public abstract boolean isLoopHeader(); + + public abstract T getPostdominator(); + + public abstract double probability(); + + public abstract T getDominator(int distance); }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,9 +24,7 @@ import java.util.*; -import com.oracle.graal.compiler.common.*; - -public interface AbstractControlFlowGraph<T extends AbstractBlock<T>> { +public interface AbstractControlFlowGraph<T extends AbstractBlockBase<T>> { int BLOCK_ID_INITIAL = -1; int BLOCK_ID_VISITED = -2; @@ -48,7 +46,8 @@ /** * Computes the dominators of control flow graph. */ - static <T extends AbstractBlock<T>> void computeDominators(AbstractControlFlowGraph<T> cfg) { + @SuppressWarnings("unchecked") + static <T extends AbstractBlockBase<T>> void computeDominators(AbstractControlFlowGraph<T> cfg) { List<T> reversePostOrder = cfg.getBlocks(); assert reversePostOrder.get(0).getPredecessorCount() == 0 : "start block has no predecessor and therefore no dominator"; for (int i = 1; i < reversePostOrder.size(); i++) { @@ -57,7 +56,7 @@ T dominator = null; for (T pred : block.getPredecessors()) { if (!pred.isLoopEnd()) { - dominator = commonDominatorTyped(dominator, pred); + dominator = (T) ((dominator == null) ? pred : commonDominatorRaw(dominator, pred)); } } // set dominator @@ -67,32 +66,33 @@ } dominator.getDominated().add(block); } + calcDominatorRanges(cfg.getStartBlock(), 0); + } + + static <T extends AbstractBlockBase<T>> int calcDominatorRanges(T block, int next) { + int myNumber = next; + int maxNumber = myNumber; + for (T dominated : block.getDominated()) { + maxNumber = calcDominatorRanges(dominated, maxNumber + 1); + } + block.setDominatorNumbers(myNumber, maxNumber); + return maxNumber; } /** * True if block {@code a} is dominated by block {@code b}. */ - static boolean isDominatedBy(AbstractBlock<?> a, AbstractBlock<?> b) { - assert a != null; - AbstractBlock<?> dominator = a; - int i = 0; - while (dominator != null) { - if (i++ == Integer.MAX_VALUE) { // For safety - throw GraalInternalError.shouldNotReachHere(); - } - if (dominator == b) { - return true; - } - dominator = dominator.getDominator(); - } - return false; + static boolean isDominatedBy(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { + int domNumberA = a.getDominatorNumber(); + int domNumberB = b.getDominatorNumber(); + return domNumberA >= domNumberB && domNumberA <= b.getMaxChildDominatorNumber(); } /** * True if block {@code a} dominates block {@code b}. */ - static boolean dominates(AbstractBlock<?> a, AbstractBlock<?> b) { - assert a != null; + static boolean dominates(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { + assert a != null && b != null; return isDominatedBy(b, a); } @@ -104,31 +104,64 @@ * @see #getBlocks() * @see CFGVerifier */ - static AbstractBlock<?> commonDominator(AbstractBlock<?> a, AbstractBlock<?> b) { + static AbstractBlockBase<?> commonDominator(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { if (a == null) { return b; - } - if (b == null) { + } else if (b == null) { return a; + } else { + int aDomDepth = a.getDominatorDepth(); + int bDomDepth = b.getDominatorDepth(); + AbstractBlockBase<?> aTemp; + AbstractBlockBase<?> bTemp; + if (aDomDepth > bDomDepth) { + aTemp = a; + bTemp = b; + } else { + aTemp = b; + bTemp = a; + } + return commonDominatorHelper(aTemp, bTemp); } - AbstractBlock<?> iterA = a; - AbstractBlock<?> iterB = b; + } + + static AbstractBlockBase<?> commonDominatorHelper(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { + int domNumberA = a.getDominatorNumber(); + AbstractBlockBase<?> result = b; + while (domNumberA < result.getDominatorNumber()) { + result = result.getDominator(); + } + while (domNumberA > result.getMaxChildDominatorNumber()) { + result = result.getDominator(); + } + return result; + } + + static AbstractBlockBase<?> commonDominatorRaw(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { + int aDomDepth = a.getDominatorDepth(); + int bDomDepth = b.getDominatorDepth(); + if (aDomDepth > bDomDepth) { + return commonDominatorRawSameDepth(a.getDominator(aDomDepth - bDomDepth), b); + } else { + return commonDominatorRawSameDepth(a, b.getDominator(bDomDepth - aDomDepth)); + } + } + + static AbstractBlockBase<?> commonDominatorRawSameDepth(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { + AbstractBlockBase<?> iterA = a; + AbstractBlockBase<?> iterB = b; while (iterA != iterB) { - if (iterA.getId() > iterB.getId()) { - iterA = iterA.getDominator(); - } else { - assert iterB.getId() > iterA.getId(); - iterB = iterB.getDominator(); - } + iterA = iterA.getDominator(); + iterB = iterB.getDominator(); } return iterA; } /** - * @see AbstractControlFlowGraph#commonDominator(AbstractBlock, AbstractBlock) + * @see AbstractControlFlowGraph#commonDominator(AbstractBlockBase, AbstractBlockBase) */ @SuppressWarnings("unchecked") - static <T extends AbstractBlock<T>> T commonDominatorTyped(T a, T b) { + static <T extends AbstractBlockBase<T>> T commonDominatorTyped(T a, T b) { return (T) commonDominator(a, b); } }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/BlockMap.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/BlockMap.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,11 +31,11 @@ data = (T[]) new Object[cfg.getBlocks().size()]; } - public T get(AbstractBlock<?> block) { + public T get(AbstractBlockBase<?> block) { return data[block.getId()]; } - public void put(AbstractBlock<?> block, T value) { + public void put(AbstractBlockBase<?> block, T value) { data[block.getId()] = value; } }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/CFGVerifier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/CFGVerifier.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,7 +26,7 @@ public class CFGVerifier { - public static <T extends AbstractBlock<T>, C extends AbstractControlFlowGraph<T>> boolean verify(C cfg) { + public static <T extends AbstractBlockBase<T>, C extends AbstractControlFlowGraph<T>> boolean verify(C cfg) { for (T block : cfg.getBlocks()) { assert block.getId() >= 0; assert cfg.getBlocks().get(block.getId()) == block;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/DominatorOptimizationProblem.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/DominatorOptimizationProblem.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ */ public abstract class DominatorOptimizationProblem<E extends Enum<E>, C> { - private List<? extends AbstractBlock<?>> blocks; + private List<? extends AbstractBlockBase<?>> blocks; private EnumMap<E, BitSet> flags; private BlockMap<C> costs; @@ -47,9 +47,9 @@ assert verify(blocks); } - private static boolean verify(List<? extends AbstractBlock<?>> blocks) { + private static boolean verify(List<? extends AbstractBlockBase<?>> blocks) { for (int i = 0; i < blocks.size(); i++) { - AbstractBlock<?> block = blocks.get(i); + AbstractBlockBase<?> block = blocks.get(i); if (i != block.getId()) { assert false : String.format("Id index mismatch @ %d vs. %s.getId()==%d", i, block, block.getId()); return false; @@ -58,12 +58,12 @@ return true; } - public final List<? extends AbstractBlock<?>> getBlocks() { + public final List<? extends AbstractBlockBase<?>> getBlocks() { return blocks; } - public final AbstractBlock<?> getBlockForId(int id) { - AbstractBlock<?> block = blocks.get(id); + public final AbstractBlockBase<?> getBlockForId(int id) { + AbstractBlockBase<?> block = blocks.get(id); assert block.getId() == id : "wrong block-to-id mapping"; return block; } @@ -71,7 +71,7 @@ /** * Sets a flag for a block. */ - public final void set(E flag, AbstractBlock<?> block) { + public final void set(E flag, AbstractBlockBase<?> block) { BitSet bitSet = flags.get(flag); if (bitSet == null) { bitSet = new BitSet(blocks.size()); @@ -83,7 +83,7 @@ /** * Checks whether a flag is set for a block. */ - public final boolean get(E flag, AbstractBlock<?> block) { + public final boolean get(E flag, AbstractBlockBase<?> block) { BitSet bitSet = flags.get(flag); return bitSet == null ? false : bitSet.get(block.getId()); } @@ -91,14 +91,14 @@ /** * Returns a {@linkplain Stream} of blocks for which {@code flag} is set. */ - public final Stream<? extends AbstractBlock<?>> stream(E flag) { + public final Stream<? extends AbstractBlockBase<?>> stream(E flag) { return getBlocks().stream().filter(block -> get(flag, block)); } /** * Returns the cost object associated with {@code block}. Might return {@code null} if not set. */ - public final C getCost(AbstractBlock<?> block) { + public final C getCost(AbstractBlockBase<?> block) { C cost = costs.get(block); return cost; } @@ -106,7 +106,7 @@ /** * Sets the cost for a {@code block}. */ - public final void setCost(AbstractBlock<?> block, C cost) { + public final void setCost(AbstractBlockBase<?> block, C cost) { costs.put(block, cost); } @@ -114,13 +114,13 @@ * Sets {@code flag} for all blocks along the dominator path from {@code block} to the root * until a block it finds a block where {@code flag} is already set. */ - public final void setDominatorPath(E flag, AbstractBlock<?> block) { + public final void setDominatorPath(E flag, AbstractBlockBase<?> block) { BitSet bitSet = flags.get(flag); if (bitSet == null) { bitSet = new BitSet(blocks.size()); flags.put(flag, bitSet); } - for (AbstractBlock<?> b = block; b != null && !bitSet.get(b.getId()); b = b.getDominator()) { + for (AbstractBlockBase<?> b = block; b != null && !bitSet.get(b.getId()); b = b.getDominator()) { // mark block bitSet.set(b.getId()); } @@ -129,7 +129,7 @@ /** * Returns a {@link Stream} of flags associated with {@code block}. */ - public final Stream<E> getFlagsForBlock(AbstractBlock<?> block) { + public final Stream<E> getFlagsForBlock(AbstractBlockBase<?> block) { return getFlags().stream().filter(flag -> get(flag, block)); }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/Loop.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/Loop.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,7 +25,7 @@ import java.util.*; -public abstract class Loop<T extends AbstractBlock<T>> { +public abstract class Loop<T extends AbstractBlockBase<T>> { private final Loop<T> parent; private final List<Loop<T>> children;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/PrintableCFG.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/PrintableCFG.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ */ public interface PrintableCFG { - List<? extends AbstractBlock<?>> getBlocks(); + List<? extends AbstractBlockBase<?>> getBlocks(); /** * Applies {@code action} to all extra property pairs (name, value) of {@code block}. @@ -39,7 +39,7 @@ * @param block a block from {@link #getBlocks()}. * @param action a {@link BiConsumer consumer}. */ - default void forEachPropertyPair(AbstractBlock<?> block, BiConsumer<String, String> action) { + default void forEachPropertyPair(AbstractBlockBase<?> block, BiConsumer<String, String> action) { // no extra properties per default } }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/PrintableDominatorOptimizationProblem.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/PrintableDominatorOptimizationProblem.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ super(keyType, cfg); } - public void forEachPropertyPair(AbstractBlock<?> block, BiConsumer<String, String> action) { + public void forEachPropertyPair(AbstractBlockBase<?> block, BiConsumer<String, String> action) { // for each flag getFlags().forEach(flag -> ((BiConsumer<String, Boolean>) (name, value) -> action.accept(name, value ? "true" : "false")).accept(getName(flag), get(flag, block))); // for each property
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Tue Mar 10 21:26:02 2015 +0100 @@ -135,4 +135,13 @@ } return newStamp; } + + public boolean neverDistinct(Stamp other) { + Constant constant = this.asConstant(); + if (constant != null) { + Constant otherConstant = other.asConstant(); + return otherConstant != null && constant.equals(otherConstant); + } + return false; + } }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,6 +37,8 @@ private static final Stamp objectAlwaysNullStamp = new ObjectStamp(null, false, false, true); private static final Stamp nodeIntrinsicStamp = new ObjectStamp(null, false, false, false); private static final Stamp positiveInt = forInteger(Kind.Int, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE); + private static final Stamp booleanTrue = forInteger(Kind.Boolean, -1, -1, 1, 1); + private static final Stamp booleanFalse = forInteger(Kind.Boolean, 0, 0, 0, 0); private static void setCache(Kind kind, Stamp stamp) { stampCache[kind.ordinal()] = stamp; @@ -80,6 +82,14 @@ } } + public static Stamp tautology() { + return booleanTrue; + } + + public static Stamp contradiction() { + return booleanFalse; + } + /** * Return a stamp for a Java kind, as it would be represented on the bytecode stack. */
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/ArrayMap.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/ArrayMap.java Tue Mar 10 21:26:02 2015 +0100 @@ -45,7 +45,7 @@ /** * Constructs a new {@code ArrayMap} that initially covers the specified interval. Note that * this map will automatically expand if necessary later. - * + * * @param low the low index, inclusive * @param high the high index, exclusive */ @@ -56,7 +56,7 @@ /** * Puts a new value in the map at the specified index. - * + * * @param i the index at which to store the value * @param value the value to store at the specified index */ @@ -81,7 +81,7 @@ /** * Gets the value at the specified index in the map. - * + * * @param i the index * @return the value at the specified index; {@code null} if there is no value at the specified * index, or if the index is out of the currently stored range
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/IntList.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/IntList.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,7 +26,7 @@ /** * An expandable and indexable list of {@code int}s. - * + * * This class avoids the boxing/unboxing incurred by {@code ArrayList<Integer>}. */ public final class IntList { @@ -36,7 +36,7 @@ /** * Creates an int list with a specified initial capacity. - * + * * @param initialCapacity */ public IntList(int initialCapacity) { @@ -45,7 +45,7 @@ /** * Creates an int list with a specified initial array. - * + * * @param array the initial array used for the list (no copy is made) * @param initialSize the initial {@linkplain #size() size} of the list (must be less than or * equal to {@code array.length} @@ -58,7 +58,7 @@ /** * Makes a new int list by copying a range from a given int list. - * + * * @param other the list from which a range of values is to be copied into the new list * @param startIndex the index in {@code other} at which to start copying * @param length the number of values to copy from {@code other} @@ -70,7 +70,7 @@ /** * Makes a new int list by copying a range from a given int list. - * + * * @param other the list from which a range of values is to be copied into the new list * @param startIndex the index in {@code other} at which to start copying * @param length the number of values to copy from {@code other} @@ -91,7 +91,7 @@ /** * Appends a value to the end of this list, increasing its {@linkplain #size() size} by 1. - * + * * @param value the value to append */ public void add(int value) { @@ -104,7 +104,7 @@ /** * Gets the value in this list at a given index. - * + * * @param index the index of the element to return * @throws IndexOutOfBoundsException if {@code index < 0 || index >= size()} */ @@ -124,7 +124,7 @@ /** * Sets a value at a given index in this list. - * + * * @param index the index of the element to update * @param value the new value of the element * @throws IndexOutOfBoundsException if {@code index < 0 || index >= size()} @@ -138,11 +138,11 @@ /** * Adjusts the {@linkplain #size() size} of this int list. - * + * * If {@code newSize < size()}, the size is changed to {@code newSize}. If * {@code newSize > size()}, sufficient 0 elements are {@linkplain #add(int) added} until * {@code size() == newSize}. - * + * * @param newSize the new size of this int list */ public void setSize(int newSize) {
--- a/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -47,7 +47,7 @@ @Test public void test2() { - testAllocation("test2snippet", 2, 1, 0); + testAllocation("test2snippet", 1, 0, 0); } public static long test2snippet(long x) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Mar 10 21:26:02 2015 +0100 @@ -70,7 +70,7 @@ private StackSlotValue tmpStackSlot; - private class SPARCSpillMoveFactory implements LIR.SpillMoveFactory { + private class SPARCSpillMoveFactory implements LIRGeneratorTool.SpillMoveFactory { @Override public LIRInstruction createMove(AllocatableValue result, Value input) { @@ -80,7 +80,10 @@ public SPARCLIRGenerator(LIRKindTool lirKindTool, Providers providers, CallingConvention cc, LIRGenerationResult lirGenRes) { super(lirKindTool, providers, cc, lirGenRes); - lirGenRes.getLIR().setSpillMoveFactory(new SPARCSpillMoveFactory()); + } + + public SpillMoveFactory getSpillMoveFactory() { + return new SPARCSpillMoveFactory(); } @Override @@ -215,7 +218,7 @@ double trueDestinationProbability) { Variable left; Value right; - Condition actualCondition = null; + Condition actualCondition; if (isConstant(x)) { left = load(y); right = loadNonConst(x); @@ -225,7 +228,7 @@ right = loadNonConst(y); actualCondition = cond; } - SPARCCompare opcode = null; + SPARCCompare opcode; Kind kind = left.getKind().getStackKind(); switch (kind) { case Object: @@ -247,7 +250,7 @@ opcode = DCMP; break; default: - GraalInternalError.shouldNotReachHere(kind.toString()); + throw GraalInternalError.shouldNotReachHere(kind.toString()); } append(new SPARCControlFlow.CompareBranchOp(opcode, left, right, actualCondition, trueDestination, falseDestination, kind, unorderedIsTrue, trueDestinationProbability)); } @@ -255,13 +258,13 @@ @Override public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) { Kind cmpKind = (Kind) cmpLIRKind.getPlatformKind(); - append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind)); + append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind, overflowProbability)); } @Override public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) { emitIntegerTest(left, right); - append(new BranchOp(Condition.EQ, trueDestination, falseDestination, left.getKind().getStackKind())); + append(new BranchOp(ConditionFlag.Equal, trueDestination, falseDestination, left.getKind().getStackKind(), trueDestinationProbability)); } private void emitIntegerTest(Value a, Value b) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -307,8 +307,8 @@ private void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); } private void compareGraphs(final String snippet, final String referenceSnippet) { @@ -318,9 +318,9 @@ private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) { graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); if (loopPeeling) { new LoopPeelingPhase().apply(graph); } @@ -332,9 +332,9 @@ canonicalizer.apply(graph, context); StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.YES); - new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context); + new InliningPhase(new CanonicalizerPhase()).apply(referenceGraph, context); new DeadCodeEliminationPhase().apply(referenceGraph); - new CanonicalizerPhase(true).apply(referenceGraph, context); + new CanonicalizerPhase().apply(referenceGraph, context); assertEquals(referenceGraph, graph, excludeVirtual, true); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 10 21:26:02 2015 +0100 @@ -47,7 +47,6 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.phases.*; import com.oracle.graal.phases.VerifyPhase.VerificationError; -import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.phases.verify.*; @@ -199,7 +198,6 @@ * Checks the invariants for a single graph. */ private static void checkGraph(HighTierContext context, StructuredGraph graph, boolean verifyEquals) { - InferStamps.inferStamps(graph); if (verifyEquals) { new VerifyUsageWithEquals(Value.class).apply(graph, context); new VerifyUsageWithEquals(Register.class).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ private StructuredGraph getCanonicalizedGraph(String name) { StructuredGraph graph = parseEager(name, AllowAssumptions.YES); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); return graph; } @@ -53,7 +53,7 @@ StructuredGraph graph = parseEager("canonicalCompare" + i, AllowAssumptions.NO); assertEquals(referenceGraph, graph); } - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); for (int i = 1; i < 4; i++) { StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i); assertEquals(referenceGraph, graph);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConcreteSubtypeTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.graal.api.code.Assumptions.*; +import com.oracle.graal.nodes.*; + +/** + * Ensure that abstract classes with a single implementor are properly optimized and that loading a + * subclass below the leaf type triggers invalidation. + */ +public class ConcreteSubtypeTest extends GraalCompilerAssumptionsTest { + abstract static class AbstractBase { + abstract void check(); + } + + static class Subclass extends AbstractBase { + @Override + public void check() { + throw new InternalError(); + } + } + + static class SubSubclass extends Subclass { + @Override + public void check() { + } + } + + public void callAbstractType(AbstractBase object) { + object.check(); + } + + @Override + protected void checkGraph(Assumption expectedAssumption, StructuredGraph graph) { + super.checkGraph(expectedAssumption, graph); + assertTrue(graph.isTrivial()); + } + + /** + * Test that {@link #callAbstractType} gets compiled into an empty method with a + * {@link ConcreteSubtype} assumption on {@link AbstractBase} and {@link Subclass}. Then ensures + * that loading and initialization of {@link SubSubclass} causes the compiled method to be + * invalidated. + */ + @Test + public void testLeafAbstractType() { + testAssumptionInvalidate("callAbstractType", new ConcreteSubtype(resolveAndInitialize(AbstractBase.class), resolveAndInitialize(Subclass.class)), "SubSubclass"); + } +}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2011, 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.compiler.test; - -import org.junit.*; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.tiers.*; - -/** - * Collection of tests for {@link com.oracle.graal.phases.common.ConditionalEliminationPhase} - * including those that triggered bugs in this phase. - */ -public class ConditionalEliminationTest extends GraalCompilerTest { - - public static Object field; - - static class Entry { - - final String name; - - public Entry(String name) { - this.name = name; - } - } - - static class EntryWithNext extends Entry { - - public EntryWithNext(String name, Entry next) { - super(name); - this.next = next; - } - - final Entry next; - } - - public static Entry search(Entry start, String name, Entry alternative) { - Entry current = start; - do { - while (current instanceof EntryWithNext) { - if (name != null && current.name == name) { - current = null; - } else { - Entry next = ((EntryWithNext) current).next; - current = next; - } - } - - if (current != null) { - if (current.name.equals(name)) { - return current; - } - } - if (current == alternative) { - return null; - } - current = alternative; - - } while (true); - } - - public static int testRedundantComparesSnippet(int[] array) { - if (array == null) { - return 0; - } - return array[0] + array[1] + array[2] + array[3]; - } - - @Test - public void testRedundantCompares() { - StructuredGraph graph = parseEager("testRedundantComparesSnippet", AllowAssumptions.YES); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - PhaseContext context = new PhaseContext(getProviders()); - - new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); - canonicalizer.apply(graph, context); - new FloatingReadPhase().apply(graph); - new ConditionalEliminationPhase().apply(graph, context); - canonicalizer.apply(graph, context); - - assertDeepEquals(1, graph.getNodes().filter(GuardNode.class).count()); - } - - public static String testInstanceOfCheckCastSnippet(Object e) { - if (e instanceof Entry) { - return ((Entry) e).name; - } - return null; - } - - @Test - @Ignore - public void testInstanceOfCheckCastLowered() { - StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet", AllowAssumptions.YES); - - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - PhaseContext context = new PhaseContext(getProviders()); - - new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); - canonicalizer.apply(graph, context); - new ConditionalEliminationPhase().apply(graph, context); - canonicalizer.apply(graph, context); - - assertDeepEquals(0, graph.getNodes().filter(GuardNode.class).count()); - } - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.directives.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest1 extends ConditionalEliminationTestBase { + + private static final String REFERENCE_SNIPPET = "referenceSnippet"; + + @SuppressWarnings("all") + public static int referenceSnippet(int a) { + if (a == 0) { + return 1; + } + return 0; + } + + @Test + public void test1() { + test("test1Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test1Snippet(int a) { + if (a == 0) { + if (a == 5) { + return 100; + } + if (a > 100) { + if (a == 0) { + return 200; + } + } + if (a != 2) { + return 1; + } + } + return 0; + } + + @Test + public void test2() { + test("test2Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test2Snippet(int a) { + if (a == 0) { + if (a > 100) { + if (a == 0) { + return 200; + } + } + if (a != 2) { + return 1; + } + } + return 0; + } + + @Test + public void test3() { + test("test3Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test3Snippet(int a) { + if (a == 0) { + if (a < 1) { + if (a < 2) { + if (a < 3) { + if (a > -1) { + if (a > -2) { + if (a > -3) { + if (a == 1) { + return 42; + } else { + return 1; + } + } + } + } + } + } + } + } + return 0; + } + + @SuppressWarnings("all") + public static int test4Snippet(int a, int b) { + if (b < 1) { + GraalDirectives.controlFlowAnchor(); + if (b < 0) { + return 1; + } + } + return 0; + } + + @Test + public void test4() { + test("test4Snippet", "test4Snippet"); + } + + @SuppressWarnings("all") + public static int test5Snippet(int a, int b) { + if ((b & 3) == 0) { + GraalDirectives.controlFlowAnchor(); + if ((b & 7) == 0) { + GraalDirectives.controlFlowAnchor(); + return 1; + } + } else { + GraalDirectives.controlFlowAnchor(); + if ((b & 1) == 0) { + GraalDirectives.controlFlowAnchor(); + return 2; + } + } + return 0; + } + + @Test + public void test5() { + test("test5Snippet", "test5Snippet"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest2.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2011, 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.compiler.test; + +import org.junit.*; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest2 extends ConditionalEliminationTestBase { + + public static Object field; + + static class Entry { + + final String name; + + public Entry(String name) { + this.name = name; + } + } + + static class EntryWithNext extends Entry { + + public EntryWithNext(String name, Entry next) { + super(name); + this.next = next; + } + + final Entry next; + } + + public static Entry search(Entry start, String name, Entry alternative) { + Entry current = start; + do { + while (current instanceof EntryWithNext) { + if (name != null && current.name == name) { + current = null; + } else { + Entry next = ((EntryWithNext) current).next; + current = next; + } + } + + if (current != null) { + if (current.name.equals(name)) { + return current; + } + } + if (current == alternative) { + return null; + } + current = alternative; + + } while (true); + } + + public static int testRedundantComparesSnippet(int[] array) { + if (array == null) { + return 0; + } + return array[0] + array[1] + array[2] + array[3]; + } + + @Test + public void testRedundantCompares() { + StructuredGraph graph = parseEager("testRedundantComparesSnippet", AllowAssumptions.YES); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + PhaseContext context = new PhaseContext(getProviders()); + + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + canonicalizer.apply(graph, context); + new FloatingReadPhase().apply(graph); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + + assertDeepEquals(1, graph.getNodes().filter(GuardNode.class).count()); + } + + public static String testInstanceOfCheckCastSnippet(Object e) { + if (e instanceof Entry) { + return ((Entry) e).name; + } + return null; + } + + @Test + public void testInstanceOfCheckCastLowered() { + StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet", AllowAssumptions.YES); + + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + PhaseContext context = new PhaseContext(getProviders()); + + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + canonicalizer.apply(graph, context); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + + assertDeepEquals(0, graph.getNodes().filter(GuardNode.class).count()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest3 extends ConditionalEliminationTestBase { + + private static final String REFERENCE_SNIPPET = "referenceSnippet"; + + @SuppressWarnings("all") + public static int referenceSnippet(int a, int b) { + int sum = 0; + outer: for (int i = 0;; ++i) { + if (b > 100) { + inner: for (int j = 0;; ++j) { + ++sum; + if (sum == 100) { + break inner; + } + if (sum == 1000 && b < 1000) { + break outer; + } + } + } + } + return sum; + } + + @Test + public void test1() { + test("test1Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test1Snippet(int a, int b) { + int sum = 0; + outer: for (int i = 0;; ++i) { + if (b > 100) { + inner: for (int j = 0;; ++j) { + ++sum; + if (sum == 100) { + break inner; + } + if (sum == 1000 && b < 1000) { + break outer; + } + } + } + } + if (b >= 1000) { + return 5; + } + return sum; + } + + @Test + public void test2() { + test("test2Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test2Snippet(int a, int b) { + int sum = 0; + outer: for (int i = 0;; ++i) { + if (b > 100) { + inner: for (int j = 0;; ++j) { + ++sum; + if (sum == 100) { + break inner; + } + if (sum == 1000 && b < 1000) { + break outer; + } + } + if (sum != 100) { + return 42; + } + } + } + return sum; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest4 extends ConditionalEliminationTestBase { + + @SuppressWarnings("all") + public static int reference1Snippet(int a, int b) { + if (a > b) { + return 1; + } + return 2; + } + + @SuppressWarnings("all") + public static int test1Snippet(int a, int b) { + if (a > b) { + if (a > b) { + return 1; + } + } + return 2; + } + + @Test + public void test1() { + test("test1Snippet", "reference1Snippet"); + } + + @SuppressWarnings("all") + public static int reference2Snippet(int a, int b) { + if (a < b) { + return 1; + } + return 2; + } + + @SuppressWarnings("all") + public static int test2Snippet(int a, int b) { + if (a < b) { + if (a < b) { + return 1; + } + } + return 2; + } + + @Test + public void test2() { + test("test2Snippet", "reference2Snippet"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest5 extends ConditionalEliminationTestBase { + + interface A { + } + + interface B extends A { + } + + static final class DistinctA { + } + + static final class DistinctB { + } + + @SuppressWarnings("all") + public static int reference1Snippet(A a, B b) { + if (a instanceof B) { + return 1; + } + return 2; + } + + @SuppressWarnings("all") + public static int test1Snippet(A a, B b) { + if (a instanceof B) { + if (a instanceof A) { + return 1; + } + } + return 2; + } + + @Test + public void test1() { + test("test1Snippet", "reference1Snippet"); + } + + public static int reference2Snippet(A a) { + if (a instanceof B) { + return 1; + } + return 2; + } + + public static int test2Snippet(A a) { + if (a instanceof B) { + B newVal = (B) a; + if (newVal != null) { + return 1; + } + } + return 2; + } + + @Test + public void test2() { + test("test2Snippet", "reference2Snippet"); + } + + @SuppressWarnings("unused") + public static int reference3Snippet(Object a, Object b) { + if (a instanceof DistinctA) { + DistinctA proxyA = (DistinctA) a; + if (b instanceof DistinctB) { + return 1; + } + } + return 2; + } + + @SuppressWarnings("all") + public static int test3Snippet(Object a, Object b) { + if (a instanceof DistinctA) { + DistinctA proxyA = (DistinctA) a; + if (b instanceof DistinctB) { + if (proxyA == b) { + return 42; + } + return 1; + } + } + return 2; + } + + @Test + public void test3() { + test("test3Snippet", "reference3Snippet", true); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest6 extends ConditionalEliminationTestBase { + + public static final A constA = new A(); + public static final B constB = new B(); + + static class A { + } + + static class B { + } + + @SuppressWarnings("all") + public static B reference1Snippet(Object a, B b) { + if (a == constA) { + return b; + } + return null; + } + + @SuppressWarnings("all") + public static B test1Snippet(Object a, B b) { + if (a == constA) { + if (a == null) { + return null; + } else { + return b; + } + } + return null; + } + + @Test + public void test1() { + test("test1Snippet", "reference1Snippet"); + } + + @SuppressWarnings("all") + public static B test2Snippet(Object a, B b) { + if (a == constA) { + if (a == constB) { + return null; + } else { + return b; + } + } + return null; + } + + @Test + public void test2() { + test("test2Snippet", "reference1Snippet"); + } + + @SuppressWarnings("all") + public static B test3Snippet(Object a, B b) { + if (a == constA) { + if (a == b) { + return null; + } else { + return b; + } + } + return null; + } + + @Test + public void test3() { + test("test3Snippet", "reference1Snippet"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest7.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest7 extends ConditionalEliminationTestBase { + + @SuppressWarnings("all") + public static int test1Snippet(int a, Object b) { + int sum = 0; + for (int j = 0;; ++j) { + ++sum; + if (b instanceof String) { + if (sum == 100) { + break; + } + } + } + String s = (String) b; + return s.length() + sum; + } + + @Test + public void test1() { + // One loop exit is skipped. + testProxies("test1Snippet", 1); + } + + @SuppressWarnings("all") + public static int test2Snippet(int a, Object b) { + int sum = 0; + for (int j = 0;; ++j) { + ++sum; + if (b instanceof String) { + break; + } + } + String s = (String) b; + return s.length() + sum; + } + + @Test + public void test2() { + // The loop exit is the anchor => no proxy necessary. + testProxies("test2Snippet", 0); + } + + @SuppressWarnings("all") + public static int test3Snippet(int a, Object b) { + int sum = a; + outer: while (true) { + sum++; + while (sum++ != 20) { + while (sum++ != 30) { + while (sum++ != 40) { + while (sum++ != 50) { + if (b instanceof String) { + break outer; + } + } + } + } + } + } + String s = (String) b; + return s.length() + sum; + } + + @Test + public void test3() { + // The break skips over 4 other loops. + testProxies("test3Snippet", 4); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest8.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest8 extends ConditionalEliminationTestBase { + + private static double value; + + @SuppressWarnings("all") + public static int test1Snippet(int a, Object b) { + double sum = 0; + if (!(b instanceof String)) { + return 42; + } + for (int j = 0; j < a; ++j) { + sum += value; + } + return ((String) b).length(); + } + + @Test + public void test1() { + // One loop exit is skipped, because the condition dominates also the loop begin. + testProxies("test1Snippet", 0); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.directives.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTest9 extends ConditionalEliminationTestBase { + + private static final String REFERENCE_SNIPPET = "referenceSnippet"; + + @SuppressWarnings("all") + public static int referenceSnippet(int a) { + if (a == 0) { + GraalDirectives.deoptimize(); + } + return 0; + } + + @Test + public void test1() { + test("test1Snippet", REFERENCE_SNIPPET); + } + + @SuppressWarnings("all") + public static int test1Snippet(int a) { + if (a == 0) { + if (a == 0) { + GraalDirectives.deoptimize(); + } + if (a == 0) { + GraalDirectives.deoptimize(); + } + } + return 0; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; + +/** + * Collection of tests for + * {@link com.oracle.graal.phases.common.DominatorConditionalEliminationPhase} including those that + * triggered bugs in this phase. + */ +public class ConditionalEliminationTestBase extends GraalCompilerTest { + + protected void test(String snippet, String referenceSnippet) { + test(snippet, referenceSnippet, false); + } + + protected void test(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference) { + StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); + Debug.dump(graph, "Graph"); + PhaseContext context = new PhaseContext(getProviders()); + CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase(); + canonicalizer1.disableSimplification(); + canonicalizer1.apply(graph, context); + new ConvertDeoptimizeToGuardPhase().apply(graph, context); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + canonicalizer.apply(graph, context); + StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.YES); + if (applyConditionalEliminationOnReference) { + new DominatorConditionalEliminationPhase(true).apply(referenceGraph, context); + canonicalizer.apply(referenceGraph, context); + canonicalizer.apply(referenceGraph, context); + } else { + canonicalizer.apply(referenceGraph, context); + } + assertEquals(referenceGraph, graph); + } + + public void testProxies(String snippet, int expectedProxiesCreated) { + StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); + PhaseContext context = new PhaseContext(getProviders()); + CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase(); + canonicalizer1.disableSimplification(); + canonicalizer1.apply(graph, context); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + canonicalizer.apply(graph, context); + + int baseProxyCount = graph.getNodes().filter(ProxyNode.class).count(); + new DominatorConditionalEliminationPhase(true).apply(graph, context); + canonicalizer.apply(graph, context); + new SchedulePhase().apply(graph, context); + int actualProxiesCreated = graph.getNodes().filter(ProxyNode.class).count() - baseProxyCount; + Assert.assertEquals(expectedProxiesCreated, actualProxiesCreated); + } +}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -83,8 +83,8 @@ try (Scope s = Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet))) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); Debug.dump(graph, "Graph"); StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES); Debug.dump(referenceGraph, "ReferenceGraph");
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -110,7 +110,7 @@ try (Scope s = Debug.scope("NestedCheckCastsTest", graph)) { Debug.dump(graph, "After parsing: " + snippet); Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count()); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count()); return graph; } catch (Throwable e) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -70,8 +70,8 @@ GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL, false).apply(graph); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); return graph; }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -60,7 +60,7 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new FloatingReadPhase().apply(graph); ReturnNode returnNode = null;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerAssumptionsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import static org.junit.Assert.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.Assumptions.Assumption; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; + +public abstract class GraalCompilerAssumptionsTest extends GraalCompilerTest { + + public GraalCompilerAssumptionsTest() { + super(); + } + + public GraalCompilerAssumptionsTest(Class<? extends Architecture> arch) { + super(arch); + } + + protected void testAssumptionInvalidate(String methodName, Assumption expected, String classToLoad) { + testAssumption(methodName, expected, classToLoad, true); + } + + /** + * Checks the behavior of class loading on {@link Assumption invalidation}. {@code methodName} + * is compiled and the resulting graph is checked for {@code expectedAssumption}. The code is + * installed and optionally {@code classToLoad} is loaded. The class is assumed to be an inner + * class of the test class and the name of the class to load is constructed relative to that. + * + * @param methodName the method to compile + * @param expectedAssumption expected {@link Assumption} instance to find in graph + * @param classToLoad an optional class to load to trigger an invalidation check + * @param willInvalidate true if loading {@code classToLoad} should invalidate the method + */ + protected void testAssumption(String methodName, Assumption expectedAssumption, String classToLoad, boolean willInvalidate) { + ResolvedJavaMethod javaMethod = getResolvedJavaMethod(methodName); + + StructuredGraph graph = parseEager(javaMethod, AllowAssumptions.YES); + assertTrue(!graph.getAssumptions().isEmpty()); + checkGraph(expectedAssumption, graph); + + CompilationResult compilationResult = compile(javaMethod, graph); + final InstalledCode installedCode = getProviders().getCodeCache().setDefaultMethod(javaMethod, compilationResult); + assertTrue(installedCode.isValid()); + if (classToLoad != null) { + String fullName = getClass().getName() + "$" + classToLoad; + try { + Class.forName(fullName); + } catch (ClassNotFoundException e) { + assertFalse(String.format("Can't find class %s", fullName), true); + } + assertTrue(!willInvalidate == installedCode.isValid()); + } + } + + protected void checkGraph(Assumption expectedAssumption, StructuredGraph graph) { + boolean found = false; + for (Assumption a : graph.getAssumptions()) { + if (expectedAssumption.equals(a)) { + found = true; + } + } + assertTrue(String.format("Can't find assumption %s", expectedAssumption), found); + } + + /** + * Converts a {@link Class} to an initialized {@link ResolvedJavaType}. + */ + protected ResolvedJavaType resolveAndInitialize(Class<?> clazz) { + ResolvedJavaType type = getMetaAccess().lookupJavaType(clazz); + type.initialize(); + return type; + } +}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -60,6 +60,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.schedule.SchedulePhase.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; @@ -302,7 +303,8 @@ } protected static String getCanonicalGraphString(StructuredGraph graph, boolean excludeVirtual, boolean checkConstants) { - SchedulePhase schedule = new SchedulePhase(); + SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST); + schedule.setScheduleConstants(true); schedule.apply(graph); NodeMap<Integer> canonicalId = graph.createNodeMap();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.directives.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; + +public class GuardEliminationCornerCasesTest extends GraalCompilerTest { + + static class A { + + } + + static class B extends A { + + } + + static class C extends B { + + } + + static class D extends C { + + } + + @SuppressWarnings({"static-method", "unused"}) + private int testMethod(Object a) { + if (a instanceof A) { + if (a instanceof C) { + if (a instanceof B) { + B b = (B) a; + if (b instanceof C) { + return 1; + } else { + GraalDirectives.deoptimize(); + } + } + } else { + GraalDirectives.deoptimize(); + } + } + return 0; + } + + @Test + public void testFloatingGuards() { + HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES); + new ConvertDeoptimizeToGuardPhase().apply(graph, context); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + Debug.dump(graph, "after parsing"); + + GuardNode myGuardNode = null; + for (Node n : graph.getNodes()) { + if (n instanceof GuardNode) { + GuardNode guardNode = (GuardNode) n; + LogicNode condition = guardNode.condition(); + if (condition instanceof InstanceOfNode) { + InstanceOfNode instanceOfNode = (InstanceOfNode) condition; + if (instanceOfNode.getValue() instanceof ValueProxy) { + myGuardNode = guardNode; + break; + } + } + } + } + + AbstractBeginNode myBegin = (AbstractBeginNode) myGuardNode.getAnchor(); + AbstractBeginNode prevBegin = BeginNode.prevBegin((FixedNode) myBegin.predecessor()); + myGuardNode.setAnchor(prevBegin); + + Debug.dump(graph, "after manual modification"); + graph.reverseUsageOrder(); + new ConditionalEliminationPhase().apply(graph); + new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST).apply(graph); + } +}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -182,13 +182,13 @@ private void testCombinedIf(String snippet, int count) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new FloatingReadPhase().apply(graph); MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); new ValueAnchorCleanupPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); assertDeepEquals(count, graph.getNodes().filter(IfNode.class).count()); } @@ -200,7 +200,7 @@ n.replaceFirstInput(param, constant); } Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) { fs.replaceFirstInput(param, null); param.safeDelete();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -114,7 +114,7 @@ private StructuredGraph getCanonicalizedGraph(String snippet) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); - new CanonicalizerPhase(false).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); for (FrameState state : graph.getNodes(FrameState.TYPE).snapshot()) { state.replaceAtUsages(null); state.safeDelete();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -67,8 +67,8 @@ hints.put(invoke, 1000d); } HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -78,8 +78,8 @@ } HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.NO); assertEquals(referenceGraph, graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -62,7 +62,7 @@ test("testSynchronizedSnippet", new A(), new A()); StructuredGraph graph = getGraph("testSynchronizedSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new LockEliminationPhase().apply(graph); assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -80,7 +80,7 @@ test("testSynchronizedMethodSnippet", new A()); StructuredGraph graph = getGraph("testSynchronizedMethodSnippet"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new LockEliminationPhase().apply(graph); assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count()); assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count()); @@ -90,11 +90,11 @@ ResolvedJavaMethod method = getResolvedJavaMethod(snippet); StructuredGraph graph = parseEager(method, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new CanonicalizerPhase(true).apply(graph, context); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new ValueAnchorCleanupPhase().apply(graph); new LockEliminationPhase().apply(graph); return graph;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.debug.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; +import com.oracle.graal.phases.tiers.*; + +public class LongNodeChainTest extends GraalCompilerTest { + + public static final int N = 10000; + + private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST}; + + @Test + public void testLongAddChain() { + longAddChain(true); + longAddChain(false); + } + + private void longAddChain(boolean reverse) { + HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + StructuredGraph graph = new StructuredGraph(AllowAssumptions.NO); + ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1)); + ValueNode value = null; + if (reverse) { + // Make sure the constant's stamp is not used to infer the add node's stamp. + OpaqueNode opaque = graph.unique(new OpaqueNode(constant)); + constant = opaque; + AddNode addNode = graph.unique(new AddNode(constant, constant)); + value = addNode; + for (int i = 1; i < N; ++i) { + AddNode newAddNode = graph.addWithoutUnique(new AddNode(constant, constant)); + addNode.setY(newAddNode); + addNode = newAddNode; + } + opaque.replaceAndDelete(opaque.getValue()); + } else { + value = constant; + for (int i = 0; i < N; ++i) { + value = graph.unique(new AddNode(constant, value)); + } + } + ReturnNode returnNode = graph.add(new ReturnNode(value)); + graph.start().setNext(returnNode); + + for (SchedulingStrategy s : Strategies) { + new SchedulePhase(s).apply(graph); + } + + new CanonicalizerPhase().apply(graph, context); + JavaConstant asConstant = (JavaConstant) returnNode.result().asConstant(); + Assert.assertEquals(N + 1, asConstant.asInt()); + } +}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -134,8 +134,8 @@ ((StateSplit) stateSplit).setStateAfter(null); } - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); try (Scope s = Debug.scope("Test", new DebugDumpScope("Test:" + snippet))) { assertEquals(referenceGraph, graph); } catch (Throwable e) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -600,7 +600,7 @@ try (Scope d = Debug.scope("FloatingReadTest", graph)) { try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) { HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { new InliningPhase(canonicalizer).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -58,8 +58,8 @@ private void testReturnCount(String snippet, int returnCount) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Debug.dump(graph, "Graph"); assertDeepEquals(returnCount, graph.getNodes(ReturnNode.TYPE).count()); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -97,8 +97,8 @@ hints.put(invoke, 1000d); } HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); return graph; }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NodePosIteratorTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NodePosIteratorTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo static final class TestNode extends Node { - public static final NodeClass<TestNode> TYPE = NodeClass.get(TestNode.class); + public static final NodeClass<TestNode> TYPE = NodeClass.create(TestNode.class); @Successor Node s1; @Successor Node s2; @Successor NodeSuccessorList<Node> stail;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,7 +27,6 @@ import org.junit.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; /** * Tests profiling information provided by the runtime.
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -93,7 +93,7 @@ private StructuredGraph compileTestSnippet(final String snippet) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); canonicalizer.apply(graph, context); new PushThroughPiPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -63,15 +63,15 @@ fs.replaceAtUsages(null); GraphUtil.killWithUnusedFloatingInputs(fs); } - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES); for (FrameState fs : referenceGraph.getNodes(FrameState.TYPE).snapshot()) { fs.replaceAtUsages(null); GraphUtil.killWithUnusedFloatingInputs(fs); } - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); assertEquals(referenceGraph, graph); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -83,7 +83,7 @@ // structure changes significantly StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); new FloatingReadPhase().apply(graph); new OptimizeGuardAnchorsPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -244,9 +244,9 @@ private <T extends Node & IterableNodeType> void test(String test, String ref) { StructuredGraph testGraph = parseEager(test, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(testGraph, new PhaseContext(getProviders())); StructuredGraph refGraph = parseEager(ref, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(refGraph, new PhaseContext(getProviders())); assertEquals(testGraph, refGraph); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -133,7 +133,7 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); Debug.dump(graph, "Graph"); PhaseContext context = new PhaseContext(getProviders()); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO); assertEquals(referenceGraph, graph); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -66,7 +66,7 @@ for (BinaryArithmeticNode<?> node : graph.getNodes().filter(BinaryArithmeticNode.class)) { if (!(node instanceof AddNode)) { assertTrue(nodeToBlock.get(node) == nodeToBlock.get(loopExit)); - assertTrue(list.indexOf(node) < list.indexOf(loopExit)); + assertTrue(list.indexOf(node) + " < " + list.indexOf(loopExit) + ", " + node + ", " + loopExit, list.indexOf(node) < list.indexOf(loopExit)); } } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,8 +43,8 @@ public void testImplies() { StructuredGraph graph = new StructuredGraph(AllowAssumptions.YES); - AbstractEndNode trueEnd = graph.add(new EndNode()); - AbstractEndNode falseEnd = graph.add(new EndNode()); + EndNode trueEnd = graph.add(new EndNode()); + EndNode falseEnd = graph.add(new EndNode()); AbstractBeginNode trueBegin = graph.add(new BeginNode()); trueBegin.setNext(trueEnd);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -110,7 +110,7 @@ private void testZeroReturn(String methodName) { StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new DeadCodeEliminationPhase().apply(graph); assertConstantReturn(graph, 0); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -89,7 +89,7 @@ // No debug scope to reduce console noise for @Test(expected = ...) tests StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES); assertEquals(referenceGraph, graph); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -178,11 +178,11 @@ * reference graph. */ new ConditionalEliminationPhase().apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); // a second canonicalizer is needed to process nested MaterializeNodes - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); assertEquals(referenceGraph, graph); } @@ -230,8 +230,8 @@ private <T extends Node> void testHelper(String snippet, Class<T> clazz) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Debug.dump(graph, "Graph " + snippet); Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext()); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -64,7 +64,7 @@ public RegisterStats(LIR lir) { this.lir = lir; - for (AbstractBlock<?> block : lir.codeEmittingOrder()) { + for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) { for (LIRInstruction instr : lir.getLIRforBlock(block)) { collectStats(instr); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -53,7 +53,7 @@ public void test1() { final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod"); final StructuredGraph graph = parseEager(javaMethod, AllowAssumptions.NO); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new DeadCodeEliminationPhase().apply(graph); for (ConstantNode node : ConstantNode.getConstantNodes(graph)) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Tue Mar 10 21:26:02 2015 +0100 @@ -154,10 +154,10 @@ new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL, false).apply(graph); context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); - new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true), null).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); + new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(), null).apply(graph, context); returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot(); } catch (Throwable e) { throw Debug.handle(e);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ protected void processMethod(final String snippet) { graph = parseEager(getResolvedJavaMethod(snippet), AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new EarlyReadEliminationPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new EarlyReadEliminationPhase(new CanonicalizerPhase()).apply(graph, context); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -308,8 +308,8 @@ @Test public void testFullyUnrolledLoop() { prepareGraph("testFullyUnrolledLoopSnippet", false); - new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(graph, context); - new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); + new LoopFullUnrollPhase(new CanonicalizerPhase()).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); Assert.assertEquals(1, returnNodes.size()); Assert.assertTrue(returnNodes.get(0).result() instanceof AllocatedObjectNode); CommitAllocationNode commit = ((AllocatedObjectNode) returnNodes.get(0).result()).getCommit();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -86,6 +86,6 @@ private void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new IterativeInliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new IterativeInliningPhase(new CanonicalizerPhase()).apply(graph, context); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -246,7 +246,7 @@ protected void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new PartialEscapePhase(false, true, new CanonicalizerPhase(true), null).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new PartialEscapePhase(false, true, new CanonicalizerPhase(), null).apply(graph, context); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -181,7 +181,7 @@ merge.setStateAfter(null); } new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); try { Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", graph.getNodes().filter(NewInstanceNode.class).isEmpty()); Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java Tue Mar 10 21:26:02 2015 +0100 @@ -61,9 +61,9 @@ try (Scope s = Debug.scope("PoorMansEATest", new DebugDumpScope(snippet))) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); + new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext); PhaseContext context = new PhaseContext(getProviders()); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); // remove framestates in order to trigger the simplification. cleanup: for (FrameState fs : graph.getNodes(FrameState.TYPE).snapshot()) { @@ -75,7 +75,7 @@ } } } - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); } catch (Throwable e) { throw Debug.handle(e); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -236,10 +236,10 @@ PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()) : getDefaultGraphBuilderSuite(); HighTierContext context = new HighTierContext(getProviders(), null, graphBuilderSuite, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); return graph; } catch (Throwable e) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -32,21 +32,20 @@ import com.oracle.graal.api.code.CompilationResult.ConstantReference; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.compiler.LIRGenerationPhase.LIRGenerationContext; import com.oracle.graal.compiler.common.alloc.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext; import com.oracle.graal.lir.phases.*; +import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext; -import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; -import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.spi.*; @@ -64,6 +63,8 @@ private static final DebugTimer FrontEnd = Debug.timer("FrontEnd"); private static final DebugTimer BackEnd = Debug.timer("BackEnd"); + private static final DebugTimer EmitLIR = Debug.timer("EmitLIR"); + private static final DebugTimer EmitCode = Debug.timer("EmitCode"); /** * The set of positive filters specified by the {@code -G:IntrinsificationsEnabled} option. To @@ -93,6 +94,9 @@ @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " + "See MethodFilter class for pattern syntax.", type = OptionType.Debug) public static final OptionValue<String> IntrinsificationsDisabled = new OptionValue<>(null); + + @Option(help = "Repeatedly run the LIR code generation pass to improve statistical profiling results.", type = OptionType.Debug) + public static final OptionValue<Integer> EmitLIRRepeatCount = new OptionValue<>(0); // @formatter:on } @@ -240,7 +244,7 @@ */ public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, Map<ResolvedJavaMethod, StructuredGraph> cache, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) { - try (Scope s = Debug.scope("FrontEnd"); TimerCloseable a = FrontEnd.start()) { + try (Scope s = Debug.scope("FrontEnd"); DebugCloseable a = FrontEnd.start()) { if (speculationLog != null) { speculationLog.collectFailedSpeculations(); } @@ -276,10 +280,18 @@ public static <T extends CompilationResult> void emitBackEnd(StructuredGraph graph, Object stub, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Backend backend, TargetDescription target, T compilationResult, CompilationResultBuilderFactory factory, SchedulePhase schedule, RegisterConfig registerConfig, LIRSuites lirSuites) { - try (TimerCloseable a = BackEnd.start()) { + try (Scope s = Debug.scope("BackEnd"); DebugCloseable a = BackEnd.start()) { + // Repeatedly run the LIR code generation pass to improve statistical profiling results. + for (int i = 0; i < EmitLIRRepeatCount.getValue(); i++) { + SchedulePhase dummySchedule = new SchedulePhase(); + dummySchedule.setScheduleConstants(true); + dummySchedule.apply(graph); + emitLIR(backend, target, dummySchedule, graph, stub, cc, registerConfig, lirSuites); + } + LIRGenerationResult lirGen = null; lirGen = emitLIR(backend, target, schedule, graph, stub, cc, registerConfig, lirSuites); - try (Scope s = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) { + try (Scope s2 = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) { emitCode(backend, graph.getAssumptions(), graph.method(), graph.getInlinedMethods(), lirGen, compilationResult, installedCodeOwner, factory); } catch (Throwable e) { throw Debug.handle(e); @@ -289,29 +301,18 @@ } } - private static void emitBlock(NodeLIRBuilderTool nodeLirGen, LIRGenerationResult lirGenRes, Block b, StructuredGraph graph, BlockMap<List<ValueNode>> blockMap) { - if (lirGenRes.getLIR().getLIRforBlock(b) == null) { - for (Block pred : b.getPredecessors()) { - if (!b.isLoopHeader() || !pred.isLoopEnd()) { - emitBlock(nodeLirGen, lirGenRes, pred, graph, blockMap); - } - } - nodeLirGen.doBlock(b, graph, blockMap); - } - } - public static LIRGenerationResult emitLIR(Backend backend, TargetDescription target, SchedulePhase schedule, StructuredGraph graph, Object stub, CallingConvention cc, RegisterConfig registerConfig, LIRSuites lirSuites) { - List<Block> blocks = schedule.getCFG().getBlocks(); - Block startBlock = schedule.getCFG().getStartBlock(); - assert startBlock != null; - assert startBlock.getPredecessorCount() == 0; + try (Scope ds = Debug.scope("EmitLIR"); DebugCloseable a = EmitLIR.start()) { + List<Block> blocks = schedule.getCFG().getBlocks(); + Block startBlock = schedule.getCFG().getStartBlock(); + assert startBlock != null; + assert startBlock.getPredecessorCount() == 0; - LIR lir = null; - List<Block> codeEmittingOrder = null; - List<Block> linearScanOrder = null; - try (Scope ds = Debug.scope("MidEnd")) { - try (Scope s = Debug.scope("ComputeLinearScanOrder")) { + LIR lir = null; + List<Block> codeEmittingOrder = null; + List<Block> linearScanOrder = null; + try (Scope s = Debug.scope("ComputeLinearScanOrder", lir)) { codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.size(), startBlock); linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.size(), startBlock); @@ -320,27 +321,16 @@ } catch (Throwable e) { throw Debug.handle(e); } - } catch (Throwable e) { - throw Debug.handle(e); - } - try (Scope ds = Debug.scope("BackEnd", lir)) { FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig); LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(lir, frameMapBuilder, graph.method(), stub); LIRGeneratorTool lirGen = backend.newLIRGenerator(cc, lirGenRes); NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen); - try (Scope s = Debug.scope("LIRGen", lirGen)) { - for (Block b : linearScanOrder) { - emitBlock(nodeLirGen, lirGenRes, b, graph, schedule.getBlockToNodesMap()); - } - lirGen.beforeRegisterAllocation(); + // LIR generation + LIRGenerationContext context = new LIRGenerationContext(lirGen, nodeLirGen, graph, schedule); + new LIRGenerationPhase().apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, context); - Debug.dump(lir, "After LIR generation"); - } catch (Throwable e) { - throw Debug.handle(e); - } - - try (Scope s = Debug.scope("LIRStages", nodeLirGen)) { + try (Scope s = Debug.scope("LIRStages", nodeLirGen, lir)) { return emitLowLevel(target, codeEmittingOrder, linearScanOrder, lirGenRes, lirGen, lirSuites); } catch (Throwable e) { throw Debug.handle(e); @@ -350,12 +340,12 @@ } } - public static <T extends AbstractBlock<T>> LIRGenerationResult emitLowLevel(TargetDescription target, List<T> codeEmittingOrder, List<T> linearScanOrder, LIRGenerationResult lirGenRes, + public static <T extends AbstractBlockBase<T>> LIRGenerationResult emitLowLevel(TargetDescription target, List<T> codeEmittingOrder, List<T> linearScanOrder, LIRGenerationResult lirGenRes, LIRGeneratorTool lirGen, LIRSuites lirSuites) { PreAllocationOptimizationContext preAllocOptContext = new PreAllocationOptimizationContext(lirGen); lirSuites.getPreAllocationOptimizationStage().apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, preAllocOptContext); - AllocationContext allocContext = new AllocationContext(); + AllocationContext allocContext = new AllocationContext(lirGen.getSpillMoveFactory()); lirSuites.getAllocationStage().apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, allocContext); PostAllocationOptimizationContext postAllocOptContext = new PostAllocationOptimizationContext(); @@ -366,45 +356,47 @@ public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Set<ResolvedJavaMethod> inlinedMethods, LIRGenerationResult lirGenRes, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) { - FrameMap frameMap = lirGenRes.getFrameMap(); - CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory); - backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner); - crb.finish(); - if (assumptions != null && !assumptions.isEmpty()) { - compilationResult.setAssumptions(assumptions.toArray()); - } - if (inlinedMethods != null) { - compilationResult.setMethods(rootMethod, inlinedMethods); - } - - if (Debug.isMeterEnabled()) { - List<DataPatch> ldp = compilationResult.getDataPatches(); - Kind[] kindValues = Kind.values(); - DebugMetric[] dms = new DebugMetric[kindValues.length]; - for (int i = 0; i < dms.length; i++) { - dms[i] = Debug.metric("DataPatches-%s", kindValues[i]); + try (DebugCloseable a = EmitCode.start()) { + FrameMap frameMap = lirGenRes.getFrameMap(); + CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory); + backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner); + crb.finish(); + if (assumptions != null && !assumptions.isEmpty()) { + compilationResult.setAssumptions(assumptions.toArray()); + } + if (inlinedMethods != null) { + compilationResult.setMethods(rootMethod, inlinedMethods); } - for (DataPatch dp : ldp) { - Kind kind = Kind.Illegal; - if (dp.reference instanceof ConstantReference) { - VMConstant constant = ((ConstantReference) dp.reference).getConstant(); - kind = ((JavaConstant) constant).getKind(); + if (Debug.isMeterEnabled()) { + List<DataPatch> ldp = compilationResult.getDataPatches(); + Kind[] kindValues = Kind.values(); + DebugMetric[] dms = new DebugMetric[kindValues.length]; + for (int i = 0; i < dms.length; i++) { + dms[i] = Debug.metric("DataPatches-%s", kindValues[i]); } - dms[kind.ordinal()].add(1); + + for (DataPatch dp : ldp) { + Kind kind = Kind.Illegal; + if (dp.reference instanceof ConstantReference) { + VMConstant constant = ((ConstantReference) dp.reference).getConstant(); + kind = ((JavaConstant) constant).getKind(); + } + dms[kind.ordinal()].add(1); + } + + Debug.metric("CompilationResults").increment(); + Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize()); + Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size()); + Debug.metric("DataPatches").add(ldp.size()); + Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size()); } - Debug.metric("CompilationResults").increment(); - Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize()); - Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size()); - Debug.metric("DataPatches").add(ldp.size()); - Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size()); + if (Debug.isLogEnabled()) { + Debug.log("%s", backend.getProviders().getCodeCache().disassemble(compilationResult, null)); + } + + Debug.dump(compilationResult, "After code generation"); } - - if (Debug.isLogEnabled()) { - Debug.log("%s", backend.getProviders().getCodeCache().disassemble(compilationResult, null)); - } - - Debug.dump(compilationResult, "After code generation"); } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Mar 10 21:26:02 2015 +0100 @@ -62,7 +62,7 @@ "Thread - aggregate by qualified name and thread", type = OptionType.Debug) public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name"); @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) - public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(false); + public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true); @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug) public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false); @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/LIRGenerationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler; + +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.phases.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.schedule.*; + +public class LIRGenerationPhase extends LIRPhase<LIRGenerationPhase.LIRGenerationContext> { + + public static final class LIRGenerationContext { + private final NodeLIRBuilderTool nodeLirBuilder; + private final LIRGeneratorTool lirGen; + private final StructuredGraph graph; + private final SchedulePhase schedule; + + public LIRGenerationContext(LIRGeneratorTool lirGen, NodeLIRBuilderTool nodeLirBuilder, StructuredGraph graph, SchedulePhase schedule) { + this.nodeLirBuilder = nodeLirBuilder; + this.lirGen = lirGen; + this.graph = graph; + this.schedule = schedule; + } + } + + @Override + protected final <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, + LIRGenerationPhase.LIRGenerationContext context) { + NodeLIRBuilderTool nodeLirBuilder = context.nodeLirBuilder; + StructuredGraph graph = context.graph; + SchedulePhase schedule = context.schedule; + for (B b : linearScanOrder) { + emitBlock(nodeLirBuilder, lirGenRes, (Block) b, graph, schedule.getBlockToNodesMap()); + } + context.lirGen.beforeRegisterAllocation(); + } + + private static void emitBlock(NodeLIRBuilderTool nodeLirGen, LIRGenerationResult lirGenRes, Block b, StructuredGraph graph, BlockMap<List<ValueNode>> blockMap) { + if (lirGenRes.getLIR().getLIRforBlock(b) == null) { + for (Block pred : b.getPredecessors()) { + if (!b.isLoopHeader() || !pred.isLoopEnd()) { + emitBlock(nodeLirGen, lirGenRes, pred, graph, blockMap); + } + } + nodeLirGen.doBlock(b, graph, blockMap); + } + } + +}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Mar 10 21:26:02 2015 +0100 @@ -83,7 +83,7 @@ for (Entry<VirtualObjectNode, VirtualObject> entry : virtualObjectsCopy.entrySet()) { if (entry.getValue().getValues() == null) { VirtualObjectNode vobj = entry.getKey(); - JavaValue[] values = new JavaValue[vobj.entryCount()]; + Value[] values = new Value[vobj.entryCount()]; if (values.length > 0) { changed = true; VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobj); @@ -98,7 +98,9 @@ } } if (pos != vobj.entryCount()) { - values = Arrays.copyOf(values, pos); + Value[] newValues = new Value[pos]; + System.arraycopy(values, 0, newValues, 0, pos); + values = newValues; } } entry.getValue().setValues(values); @@ -111,6 +113,7 @@ } objectStates.clear(); + assert frame.validateFormat(false); return newLIRFrameState(exceptionEdge, frame, virtualObjectsArray); } @@ -133,7 +136,7 @@ int numStack = state.stackSize(); int numLocks = state.locksSize(); - JavaValue[] values = new JavaValue[numLocals + numStack + numLocks]; + Value[] values = new Value[numLocals + numStack + numLocks]; computeLocals(state, numLocals, values); computeStack(state, numLocals, numStack, values); computeLocks(state, values); @@ -148,33 +151,33 @@ } } - protected void computeLocals(FrameState state, int numLocals, JavaValue[] values) { + protected void computeLocals(FrameState state, int numLocals, Value[] values) { for (int i = 0; i < numLocals; i++) { values[i] = computeLocalValue(state, i); } } - protected JavaValue computeLocalValue(FrameState state, int i) { + protected Value computeLocalValue(FrameState state, int i) { return toValue(state.localAt(i)); } - protected void computeStack(FrameState state, int numLocals, int numStack, JavaValue[] values) { + protected void computeStack(FrameState state, int numLocals, int numStack, Value[] values) { for (int i = 0; i < numStack; i++) { values[numLocals + i] = computeStackValue(state, i); } } - protected JavaValue computeStackValue(FrameState state, int i) { + protected Value computeStackValue(FrameState state, int i) { return toValue(state.stackAt(i)); } - protected void computeLocks(FrameState state, JavaValue[] values) { + protected void computeLocks(FrameState state, Value[] values) { for (int i = 0; i < state.locksSize(); i++) { values[state.localsSize() + state.stackSize() + i] = computeLockValue(state, i); } } - protected JavaValue computeLockValue(FrameState state, int i) { + protected Value computeLockValue(FrameState state, int i) { return toValue(state.lockAt(i)); } @@ -183,7 +186,7 @@ private static final DebugMetric STATE_VARIABLES = Debug.metric("StateVariables"); private static final DebugMetric STATE_CONSTANTS = Debug.metric("StateConstants"); - protected JavaValue toValue(ValueNode value) { + protected Value toValue(ValueNode value) { try { if (value instanceof VirtualObjectNode) { VirtualObjectNode obj = (VirtualObjectNode) value; @@ -215,7 +218,7 @@ STATE_VARIABLES.increment(); Value operand = nodeOperands.get(value); assert operand != null && (operand instanceof Variable || operand instanceof JavaConstant) : operand + " for " + value; - return (JavaValue) operand; + return operand; } else { // return a dummy value because real value not needed
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/InstructionPrinter.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/InstructionPrinter.java Tue Mar 10 21:26:02 2015 +0100 @@ -71,7 +71,7 @@ /** * Prints this column's label to a given stream after padding the stream with '_' characters * until its {@linkplain LogStream#position() position} is equal to this column's position. - * + * * @param out the print stream */ public void printLabel(LogStream out) { @@ -82,7 +82,7 @@ /** * Prints space characters to a given stream until its {@linkplain LogStream#position() * position} is equal to this column's position. - * + * * @param out the print stream */ public void advance(LogStream out) { @@ -116,7 +116,7 @@ /** * Prints an instruction listing on one line. The instruction listing is composed of the columns * specified by {@link InstructionLineColumn}. - * + * * @param instruction the instruction to print */ public void printInstructionListing(ValueNode instruction) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Tue Mar 10 21:26:02 2015 +0100 @@ -23,8 +23,6 @@ package com.oracle.graal.compiler.match; import static com.oracle.graal.compiler.GraalDebugConfig.*; -import static com.oracle.graal.graph.Edges.Type.*; - import java.util.*; import java.util.Map.Entry; @@ -50,7 +48,7 @@ public static Position[] findPositions(NodeClass<? extends ValueNode> nodeClass, String[] names) { Position[] result = new Position[names.length]; for (int i = 0; i < names.length; i++) { - Edges edges = nodeClass.getEdges(Inputs); + Edges edges = nodeClass.getInputEdges(); for (int e = 0; e < edges.getDirectCount(); e++) { if (names[i].equals(edges.getName(e))) { result[i] = new Position(edges, e, Node.NOT_ITERABLE);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/GraphChangeMonitoringPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/GraphChangeMonitoringPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,12 +22,14 @@ */ package com.oracle.graal.compiler.phases; +import java.util.*; import java.util.stream.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.Graph.NodeEvent; import com.oracle.graal.graph.Graph.NodeEventScope; +import com.oracle.graal.graph.Node; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.util.*; @@ -72,7 +74,11 @@ Debug.handle(t); } } - if (!listener.getNodes().isEmpty()) { + /* + * Ignore LogicConstantNode since those are sometimes created and deleted as part of running + * a phase. + */ + if (listener.getNodes().stream().filter(e -> !(e instanceof LogicConstantNode)).findFirst().get() != null) { /* rerun it on the real graph in a new Debug scope so Dump and Log can find it. */ listener = new HashSetNodeEventListener(); try (NodeEventScope s = graph.trackNodeEvents(listener)) { @@ -81,10 +87,11 @@ Debug.dump(BasePhase.PHASE_DUMP_LEVEL, graph, "*** Before phase %s", getName()); } super.run(graph, context); + Set<Node> collect = listener.getNodes().stream().filter(e -> !e.isAlive()).filter(e -> !(e instanceof LogicConstantNode)).collect(Collectors.toSet()); if (Debug.isDumpEnabled(BasePhase.PHASE_DUMP_LEVEL)) { - Debug.dump(BasePhase.PHASE_DUMP_LEVEL, graph, "*** After phase %s", getName()); + Debug.dump(BasePhase.PHASE_DUMP_LEVEL, graph, "*** After phase %s %s", getName(), collect); } - Debug.log("*** %s %s %s\n", message, graph, listener.getNodes().stream().filter(e -> !e.isAlive()).collect(Collectors.toSet())); + Debug.log("*** %s %s %s\n", message, graph, collect); } } } else {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Mar 10 21:26:02 2015 +0100 @@ -46,7 +46,10 @@ } public HighTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } if (OptCanonicalizer.getValue()) { appendPhase(canonicalizer); @@ -61,7 +64,7 @@ if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { appendPhase(canonicalizer); - appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); } } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,7 +43,10 @@ } public LowTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } if (Options.ProfileCompiledMethods.getValue()) { appendPhase(new ProfileCompiledMethodsPhase()); @@ -57,7 +60,7 @@ /* Cleanup IsNull checks resulting from MID_TIER/LOW_TIER lowering and ExpandLogic phase. */ if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); /* Canonicalizer may create some new ShortCircuitOrNodes so clean them up. */ appendPhase(new ExpandLogicPhase()); }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,10 @@ public class MidTier extends PhaseSuite<MidTierContext> { public MidTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } if (OptPushThroughPi.getValue()) { appendPhase(new PushThroughPiPhase()); @@ -64,7 +67,7 @@ } if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - appendPhase(new IterativeConditionalEliminationPhase(canonicalizer)); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, true)); } if (OptEliminatePartiallyRedundantGuards.getValue()) {
--- a/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugTimerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugTimerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,6 @@ import org.junit.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; public class DebugTimerTest { @@ -63,9 +62,9 @@ long spinA; long spinB; - try (TimerCloseable a1 = timerA.start()) { + try (DebugCloseable a1 = timerA.start()) { spinA = spin(50); - try (TimerCloseable b1 = timerB.start()) { + try (DebugCloseable b1 = timerB.start()) { spinB = spin(50); } } @@ -83,15 +82,15 @@ DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out); try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) { DebugTimer timerC = Debug.timer("TimerC"); - try (TimerCloseable c1 = timerC.start()) { + try (DebugCloseable c1 = timerC.start()) { spin(50); - try (TimerCloseable c2 = timerC.start()) { + try (DebugCloseable c2 = timerC.start()) { spin(50); - try (TimerCloseable c3 = timerC.start()) { + try (DebugCloseable c3 = timerC.start()) { spin(50); - try (TimerCloseable c4 = timerC.start()) { + try (DebugCloseable c4 = timerC.start()) { spin(50); - try (TimerCloseable c5 = timerC.start()) { + try (DebugCloseable c5 = timerC.start()) { spin(50); } } @@ -115,13 +114,13 @@ long spinD1; long spinE; - try (TimerCloseable d1 = timerD.start()) { + try (DebugCloseable d1 = timerD.start()) { spinD1 = spin(50); - try (TimerCloseable e1 = timerE.start()) { + try (DebugCloseable e1 = timerE.start()) { spinE = spin(50); - try (TimerCloseable d2 = timerD.start()) { + try (DebugCloseable d2 = timerD.start()) { spin(50); - try (TimerCloseable d3 = timerD.start()) { + try (DebugCloseable d3 = timerD.start()) { spin(50); } }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Tue Mar 10 21:26:02 2015 +0100 @@ -1131,8 +1131,8 @@ private static final DebugMemUseTracker VOID_MEM_USE_TRACKER = new DebugMemUseTracker() { - public Closeable start() { - return MemUseTrackerImpl.VOID_CLOSEABLE; + public DebugCloseable start() { + return DebugCloseable.VOID_CLOSEABLE; } public long getCurrentValue() { @@ -1319,8 +1319,8 @@ private static final DebugTimer VOID_TIMER = new DebugTimer() { - public TimerCloseable start() { - return TimerImpl.VOID_CLOSEABLE; + public DebugCloseable start() { + return DebugCloseable.VOID_CLOSEABLE; } public void setConditional(boolean flag) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugCloseable.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,39 @@ +/* + * 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.debug; + +/** + * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and + * adds the elapsed time since {@code start()} to the total for the timer. + */ +public interface DebugCloseable extends AutoCloseable { + + DebugCloseable VOID_CLOSEABLE = new DebugCloseable() { + + @Override + public void close() { + } + }; + + void close(); +}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigScope.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigScope.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,7 +27,7 @@ /** * A utility for scoping a change to the current debug * {@linkplain DebugScope#setConfig(DebugConfig) configuration}. For example: - * + * * <pre> * DebugConfig config = ...; * try (DebugConfigScope s = new DebugConfigScope(config)) {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMemUseTracker.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMemUseTracker.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,10 +36,6 @@ */ public interface DebugMemUseTracker { - public interface Closeable extends AutoCloseable { - void close(); - } - /** * Creates a point from which memory usage will be recorded if memory use tracking is * {@linkplain Debug#isMemUseTrackingEnabled() enabled}. @@ -47,7 +43,7 @@ * @return an object that must be closed once the activity has completed to add the memory used * since this call to the total for this tracker */ - Closeable start(); + DebugCloseable start(); /** * Gets the current value of this tracker.
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,8 +24,6 @@ import java.util.concurrent.*; -import com.oracle.graal.debug.internal.*; - /** * A timer for some activity of interest. A timer should be deployed using the try-with-resources * pattern: @@ -45,7 +43,7 @@ * @return an object that must be closed once the activity has completed to add the elapsed time * since this call to the total for this timer */ - TimerCloseable start(); + DebugCloseable start(); /** * Sets a flag determining if this timer is only enabled if timing is
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/LogStream.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/LogStream.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,20 +26,20 @@ /** * A utility for printing compiler debug and informational output to an output stream. - * + * * A {@link LogStream} instance maintains an internal buffer that is flushed to the underlying * output stream every time one of the {@code println} methods is invoked, or a newline character ( * {@code '\n'}) is written. - * + * * All of the {@code print} and {@code println} methods return the {code LogStream} instance on * which they were invoked. This allows chaining of these calls to mitigate use of String * concatenation by the caller. - * + * * A {@code LogStream} maintains a current {@linkplain #indentationLevel() indentation} level. Each * line of output written to this stream has {@code n} spaces prefixed to it where {@code n} is the * value that would be returned by {@link #indentationLevel()} when the first character of a new * line is written. - * + * * A {@code LogStream} maintains a current {@linkplain #position() position} for the current line * being written. This position can be advanced to a specified position by * {@linkplain #fillTo(int, char) filling} this stream with a given character. @@ -87,7 +87,7 @@ /** * Creates a new log stream. - * + * * @param os the underlying output stream to which prints are sent */ public LogStream(OutputStream os) { @@ -98,7 +98,7 @@ /** * Creates a new log stream that shares the same {@linkplain #ps output stream} as a given * {@link LogStream}. - * + * * @param log a LogStream whose output stream is shared with this one */ public LogStream(LogStream log) { @@ -147,7 +147,7 @@ /** * Gets the current column position of this log stream. - * + * * @return the current column position of this log stream */ public int position() { @@ -157,7 +157,7 @@ /** * Gets the current indentation level for this log stream. - * + * * @return the current indentation level for this log stream. */ public int indentationLevel() { @@ -166,7 +166,7 @@ /** * Adjusts the current indentation level of this log stream. - * + * * @param delta */ public void adjustIndentation(int delta) { @@ -202,7 +202,7 @@ /** * Advances this stream's {@linkplain #position() position} to a given position by repeatedly * appending a given character as necessary. - * + * * @param position the position to which this stream's position will be advanced * @param filler the character used to pad the stream */ @@ -218,7 +218,7 @@ /** * Writes a boolean value to this stream as {@code "true"} or {@code "false"}. - * + * * @param b the value to be printed * @return this {@link LogStream} instance */ @@ -233,7 +233,7 @@ /** * Writes a boolean value to this stream followed by a {@linkplain #LINE_SEPARATOR line * separator}. - * + * * @param b the value to be printed * @return this {@link LogStream} instance */ @@ -248,7 +248,7 @@ /** * Writes a character value to this stream. - * + * * @param c the value to be printed * @return this {@link LogStream} instance */ @@ -268,7 +268,7 @@ /** * Writes a character value to this stream followed by a {@linkplain #LINE_SEPARATOR line * separator}. - * + * * @param c the value to be printed * @return this {@link LogStream} instance */ @@ -283,7 +283,7 @@ /** * Prints an int value. - * + * * @param i the value to be printed * @return this {@link LogStream} instance */ @@ -297,7 +297,7 @@ /** * Writes an int value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * + * * @param i the value to be printed * @return this {@link LogStream} instance */ @@ -312,7 +312,7 @@ /** * Writes a float value to this stream. - * + * * @param f the value to be printed * @return this {@link LogStream} instance */ @@ -327,7 +327,7 @@ /** * Writes a float value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator} * . - * + * * @param f the value to be printed * @return this {@link LogStream} instance */ @@ -342,7 +342,7 @@ /** * Writes a long value to this stream. - * + * * @param l the value to be printed * @return this {@link LogStream} instance */ @@ -356,7 +356,7 @@ /** * Writes a long value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. - * + * * @param l the value to be printed * @return this {@link LogStream} instance */ @@ -371,7 +371,7 @@ /** * Writes a double value to this stream. - * + * * @param d the value to be printed * @return this {@link LogStream} instance */ @@ -386,7 +386,7 @@ /** * Writes a double value to this stream followed by a {@linkplain #LINE_SEPARATOR line * separator}. - * + * * @param d the value to be printed * @return this {@link LogStream} instance */ @@ -403,7 +403,7 @@ * Writes a {@code String} value to this stream. This method ensures that the * {@linkplain #position() position} of this stream is updated correctly with respect to any * {@linkplain #LINE_SEPARATOR line separators} present in {@code s}. - * + * * @param s the value to be printed * @return this {@link LogStream} instance */ @@ -436,7 +436,7 @@ /** * Writes a {@code String} value to this stream followed by a {@linkplain #LINE_SEPARATOR line * separator}. - * + * * @param s the value to be printed * @return this {@link LogStream} instance */ @@ -450,7 +450,7 @@ /** * Writes a formatted string to this stream. - * + * * @param format a format string as described in {@link String#format(String, Object...)} * @param args the arguments to be formatted * @return this {@link LogStream} instance @@ -464,7 +464,7 @@ /** * Writes a {@linkplain #LINE_SEPARATOR line separator} to this stream. - * + * * @return this {@code LogStream} instance */ public LogStream println() {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/TTY.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/TTY.java Tue Mar 10 21:26:02 2015 +0100 @@ -46,7 +46,7 @@ * Creates an object that will suppress {@link TTY} for the current thread if the given * filter does not match the given object. To revert the suppression state to how it was * before this call, the {@link #remove()} method must be called on the suppression object. - * + * * @param filter the pattern for matching. If {@code null}, then the match is successful. If * it starts with "~", then a regular expression * {@linkplain Pattern#matches(String, CharSequence) match} is performed where
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/AccumulatedDebugValue.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +public abstract class AccumulatedDebugValue extends DebugValue { + protected final DebugValue flat; + + public AccumulatedDebugValue(String name, boolean conditional, DebugValue flat) { + super(name + "_Accm", conditional); + this.flat = flat; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/CloseableCounterImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug.internal; + +import com.oracle.graal.debug.*; + +/** + * A helper class for DebugValues that can nest and need to split out accumulated and flat values + * for some kind of counter-like measurement. + */ +abstract class CloseableCounterImpl implements DebugCloseable { + + protected final CloseableCounterImpl parent; + protected final AccumulatedDebugValue counter; + protected final long start; + protected long nestedAmountToSubtract; + + CloseableCounterImpl(CloseableCounterImpl parent, AccumulatedDebugValue counter) { + this.parent = parent; + this.start = getCounterValue(); + this.counter = counter; + } + + @Override + public void close() { + long end = getCounterValue(); + long difference = end - start; + if (parent != null) { + if (!counter.getName().equals(parent.counter.getName())) { + parent.nestedAmountToSubtract += difference; + + // Look for our counter in an outer scope and fix up + // the adjustment to the flat count + CloseableCounterImpl ancestor = parent.parent; + while (ancestor != null) { + if (ancestor.counter.getName().equals(counter.getName())) { + ancestor.nestedAmountToSubtract -= difference; + break; + } + ancestor = ancestor.parent; + } + } + } + long flatAmount = difference - nestedAmountToSubtract; + counter.addToCurrentValue(difference); + counter.flat.addToCurrentValue(flatAmount); + } + + abstract long getCounterValue(); +}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.debug.internal; +import static com.oracle.graal.debug.DebugCloseable.*; import static java.lang.Thread.*; import java.lang.management.*; @@ -29,7 +30,7 @@ import com.oracle.graal.debug.*; import com.sun.management.ThreadMXBean; -public final class MemUseTrackerImpl extends DebugValue implements DebugMemUseTracker { +public final class MemUseTrackerImpl extends AccumulatedDebugValue implements DebugMemUseTracker { private static final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); @@ -42,35 +43,25 @@ return threadMXBean.getThreadAllocatedBytes(currentThread().getId()) - threadMXBeanOverhead; } - public static final Closeable VOID_CLOSEABLE = new Closeable() { - - @Override - public void close() { - } - }; - /** * Records the most recent active tracker. */ - private static final ThreadLocal<CloseableImpl> currentTracker = new ThreadLocal<>(); - - private final DebugValue flat; + private static final ThreadLocal<CloseableCounterImpl> currentTracker = new ThreadLocal<>(); public MemUseTrackerImpl(String name) { - super(name + "_Accm", true); - this.flat = new DebugValue(name + "_Flat", true) { + super(name, true, new DebugValue(name + "_Flat", true) { @Override public String toString(long value) { return valueToString(value); } - }; + }); } @Override - public Closeable start() { + public DebugCloseable start() { if (!isConditional() || Debug.isMemUseTrackingEnabled()) { - CloseableImpl result = new CloseableImpl(); + MemUseCloseableCounterImpl result = new MemUseCloseableCounterImpl(this); currentTracker.set(result); return result; } else { @@ -87,27 +78,21 @@ return valueToString(value); } - private final class CloseableImpl implements Closeable { + private static final class MemUseCloseableCounterImpl extends CloseableCounterImpl implements DebugCloseable { - private final CloseableImpl parent; - private final long start; - private long nestedAmountToSubtract; + private MemUseCloseableCounterImpl(AccumulatedDebugValue counter) { + super(currentTracker.get(), counter); + } - private CloseableImpl() { - this.parent = currentTracker.get(); - this.start = getCurrentThreadAllocatedBytes(); + @Override + long getCounterValue() { + return getCurrentThreadAllocatedBytes(); } @Override public void close() { - long end = getCurrentThreadAllocatedBytes(); - long allocated = end - start; - if (parent != null) { - parent.nestedAmountToSubtract += allocated; - } + super.close(); currentTracker.set(parent); - MemUseTrackerImpl.this.addToCurrentValue(allocated); - flat.addToCurrentValue(allocated - nestedAmountToSubtract); } } }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.debug.internal; - -import com.oracle.graal.debug.*; - -/** - * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and - * adds the elapsed time since {@code start()} to the total for the timer. - */ -public interface TimerCloseable extends AutoCloseable { - - void close(); -}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,35 +22,27 @@ */ package com.oracle.graal.debug.internal; +import static com.oracle.graal.debug.DebugCloseable.*; + import java.lang.management.*; import java.util.concurrent.*; import com.oracle.graal.debug.*; -public final class TimerImpl extends DebugValue implements DebugTimer { +public final class TimerImpl extends AccumulatedDebugValue implements DebugTimer { private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); - public static final TimerCloseable VOID_CLOSEABLE = new TimerCloseable() { - - @Override - public void close() { - } - }; - /** * Records the most recent active timer. */ - private static final ThreadLocal<AbstractTimer> currentTimer = new ThreadLocal<>(); - - private final FlatTimer flat; + private static final ThreadLocal<CloseableCounterImpl> currentTimer = new ThreadLocal<>(); static class FlatTimer extends DebugValue implements DebugTimer { - private final TimerImpl accm; + private TimerImpl accm; - public FlatTimer(TimerImpl accm, String name) { - super(name + "_Flat", accm.isConditional()); - this.accm = accm; + public FlatTimer(String name, boolean conditional) { + super(name + "_Flat", conditional); } @Override @@ -62,31 +54,24 @@ return accm.getTimeUnit(); } - public TimerCloseable start() { + public DebugCloseable start() { return accm.start(); } } public TimerImpl(String name, boolean conditional) { - super(name + "_Accm", conditional); - this.flat = new FlatTimer(this, name); + super(name, conditional, new FlatTimer(name, conditional)); + ((FlatTimer) flat).accm = this; } @Override - public TimerCloseable start() { + public DebugCloseable start() { if (!isConditional() || Debug.isTimeEnabled()) { - long startTime; - if (threadMXBean.isCurrentThreadCpuTimeSupported()) { - startTime = threadMXBean.getCurrentThreadCpuTime(); - } else { - startTime = System.nanoTime(); - } - AbstractTimer result; if (threadMXBean.isCurrentThreadCpuTimeSupported()) { - result = new CpuTimeTimer(this, startTime); + result = new CpuTimeTimer(this); } else { - result = new SystemNanosTimer(this, startTime); + result = new SystemNanosTimer(this); } currentTimer.set(result); return result; @@ -100,7 +85,7 @@ } public DebugTimer getFlat() { - return flat; + return (FlatTimer) flat; } @Override @@ -112,68 +97,39 @@ return TimeUnit.NANOSECONDS; } - private abstract static class AbstractTimer implements TimerCloseable { + private abstract static class AbstractTimer extends CloseableCounterImpl implements DebugCloseable { - private final AbstractTimer parent; - private final TimerImpl timer; - private final long startTime; - private long nestedTimeToSubtract; - - private AbstractTimer(TimerImpl timer, long startTime) { - this.parent = currentTimer.get(); - this.timer = timer; - this.startTime = startTime; + private AbstractTimer(AccumulatedDebugValue counter) { + super(currentTimer.get(), counter); } @Override public void close() { - long endTime = currentTime(); - long timeSpan = endTime - startTime; - if (parent != null) { - if (timer != parent.timer) { - parent.nestedTimeToSubtract += timeSpan; - - // Look for our timer in an outer timing scope and fix up - // the adjustment to the flat time - AbstractTimer ancestor = parent.parent; - while (ancestor != null) { - if (ancestor.timer == timer) { - ancestor.nestedTimeToSubtract -= timeSpan; - break; - } - ancestor = ancestor.parent; - } - } - } + super.close(); currentTimer.set(parent); - long flatTime = timeSpan - nestedTimeToSubtract; - timer.addToCurrentValue(timeSpan); - timer.flat.addToCurrentValue(flatTime); } - - protected abstract long currentTime(); } private final class SystemNanosTimer extends AbstractTimer { - public SystemNanosTimer(TimerImpl timer, long startTime) { - super(timer, startTime); + public SystemNanosTimer(TimerImpl timer) { + super(timer); } @Override - protected long currentTime() { + protected long getCounterValue() { return System.nanoTime(); } } private final class CpuTimeTimer extends AbstractTimer { - public CpuTimeTimer(TimerImpl timer, long startTime) { - super(timer, startTime); + public CpuTimeTimer(TimerImpl timer) { + super(timer); } @Override - protected long currentTime() { + protected long getCounterValue() { return threadMXBean.getCurrentThreadCpuTime(); } }
--- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeMapTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeMapTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo static final class TestNode extends Node { - public static final NodeClass<TestNode> TYPE = NodeClass.get(TestNode.class); + public static final NodeClass<TestNode> TYPE = NodeClass.create(TestNode.class); protected TestNode() { super(TYPE);
--- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo static final class Def extends Node { - public static final NodeClass<Def> TYPE = NodeClass.get(Def.class); + public static final NodeClass<Def> TYPE = NodeClass.create(Def.class); protected Def() { super(TYPE); @@ -44,7 +44,7 @@ @NodeInfo static final class Use extends Node { - public static final NodeClass<Use> TYPE = NodeClass.get(Use.class); + public static final NodeClass<Use> TYPE = NodeClass.create(Use.class); @Input Def in0; @Input Def in1; @Input Def in2;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeValidationChecksTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.test; + +import org.junit.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodeinfo.*; + +public class NodeValidationChecksTest { + + @NodeInfo + static final class TestNode extends Node { + public static final NodeClass<TestNode> TYPE = NodeClass.create(TestNode.class); + + @Input TestNode input; + @Successor TestNode successor; + + public TestNode(TestNode input, TestNode successor) { + super(TYPE); + this.input = input; + this.successor = successor; + } + } + + @Test + public void testInputNotAlive() { + Graph graph = new Graph(); + TestNode node = new TestNode(null, null); + try { + graph.add(new TestNode(node, null)); + Assert.fail("Exception expected."); + } catch (IllegalStateException e) { + Assert.assertTrue(e.getMessage().contains("Input")); + Assert.assertTrue(e.getMessage().contains("not alive")); + } + } + + @Test + public void testSuccessorNotAlive() { + Graph graph = new Graph(); + TestNode node = new TestNode(null, null); + try { + graph.add(new TestNode(null, node)); + Assert.fail("Exception expected."); + } catch (IllegalStateException e) { + Assert.assertTrue(e.getMessage().contains("Successor")); + Assert.assertTrue(e.getMessage().contains("not alive")); + } + } +}
--- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo static final class TestNode extends Node implements IterableNodeType, TestNodeInterface { - public static final NodeClass<TestNode> TYPE = NodeClass.get(TestNode.class); + public static final NodeClass<TestNode> TYPE = NodeClass.create(TestNode.class); protected final String name; public TestNode(String name) {
--- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo static class NodeA extends Node implements TestNodeInterface { - public static final NodeClass<NodeA> TYPE = NodeClass.get(NodeA.class); + public static final NodeClass<NodeA> TYPE = NodeClass.create(NodeA.class); protected final String name; public NodeA(String name) { @@ -53,7 +53,7 @@ @NodeInfo static class NodeB extends NodeA implements IterableNodeType { - public static final NodeClass<NodeB> TYPE = NodeClass.get(NodeB.class); + public static final NodeClass<NodeB> TYPE = NodeClass.create(NodeB.class); public NodeB(String name) { this(TYPE, name); @@ -67,7 +67,7 @@ @NodeInfo static class NodeC extends NodeB { - public static final NodeClass<NodeC> TYPE = NodeClass.get(NodeC.class); + public static final NodeClass<NodeC> TYPE = NodeClass.create(NodeC.class); public NodeC(String name) { this(TYPE, name); @@ -81,7 +81,7 @@ @NodeInfo static final class NodeD extends NodeC { - public static final NodeClass<NodeD> TYPE = NodeClass.get(NodeD.class); + public static final NodeClass<NodeD> TYPE = NodeClass.create(NodeD.class); public NodeD(String name) { super(TYPE, name);
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,6 +27,7 @@ import static com.oracle.graal.graph.Node.*; import java.util.*; +import java.util.function.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.NodeClass.EdgeInfo; @@ -60,20 +61,20 @@ } } - private static Node getNode(Node node, long offset) { + private static Node getNodeUnsafe(Node node, long offset) { return (Node) unsafe.getObject(node, offset); } @SuppressWarnings("unchecked") - private static NodeList<Node> getNodeList(Node node, long offset) { + private static NodeList<Node> getNodeListUnsafe(Node node, long offset) { return (NodeList<Node>) unsafe.getObject(node, offset); } - private static void putNode(Node node, long offset, Node value) { + private static void putNodeUnsafe(Node node, long offset, Node value) { unsafe.putObject(node, offset, value); } - private static void putNodeList(Node node, long offset, NodeList<?> value) { + private static void putNodeListUnsafe(Node node, long offset, NodeList<?> value) { unsafe.putObject(node, offset, value); } @@ -92,9 +93,8 @@ * @param index the index of a non-list the edge (must be less than {@link #getDirectCount()}) * @return the Node at the other edge of the requested edge */ - public Node getNode(Node node, int index) { - assert index >= 0 && index < directCount; - return getNode(node, offsets[index]); + public static Node getNode(Node node, long[] offsets, int index) { + return getNodeUnsafe(node, offsets[index]); } /** @@ -105,9 +105,8 @@ * {@link #getDirectCount()}) * @return the {@link NodeList} at the other edge of the requested edge */ - public NodeList<Node> getNodeList(Node node, int index) { - assert index >= directCount && index < getCount(); - return getNodeList(node, offsets[index]); + public static NodeList<Node> getNodeList(Node node, long[] offsets, int index) { + return getNodeListUnsafe(node, offsets[index]); } /** @@ -118,18 +117,22 @@ * @param node the node whose edges are to be cleared */ public void clear(Node node) { + final long[] curOffsets = this.offsets; + final Type curType = this.type; int index = 0; - while (index < getDirectCount()) { - initializeNode(node, index++, null); + int curDirectCount = getDirectCount(); + while (index < curDirectCount) { + initializeNode(node, curOffsets, index++, null); } - while (index < getCount()) { - NodeList<Node> list = getNodeList(node, index); + int curCount = getCount(); + while (index < curCount) { + NodeList<Node> list = getNodeList(node, curOffsets, index); if (list != null) { int size = list.initialSize; - NodeList<Node> newList = type == Edges.Type.Inputs ? new NodeInputList<>(node, size) : new NodeSuccessorList<>(node, size); + NodeList<Node> newList = curType == Edges.Type.Inputs ? new NodeInputList<>(node, size) : new NodeSuccessorList<>(node, size); // replacing with a new list object is the expected behavior! - initializeList(node, index, newList); + initializeList(node, curOffsets, index, newList); } index++; } @@ -144,12 +147,14 @@ */ public void initializeLists(Node node, Node prototype) { int index = getDirectCount(); + final long[] curOffsets = this.offsets; + final Edges.Type curType = this.type; while (index < getCount()) { - NodeList<Node> list = getNodeList(prototype, index); + NodeList<Node> list = getNodeList(prototype, curOffsets, index); if (list != null) { int size = list.initialSize; - NodeList<Node> newList = type == Edges.Type.Inputs ? new NodeInputList<>(node, size) : new NodeSuccessorList<>(node, size); - initializeList(node, index, newList); + NodeList<Node> newList = curType == Edges.Type.Inputs ? new NodeInputList<>(node, size) : new NodeSuccessorList<>(node, size); + initializeList(node, curOffsets, index, newList); } index++; } @@ -166,16 +171,20 @@ assert fromNode != toNode; assert fromNode.getNodeClass().getClazz() == toNode.getNodeClass().getClazz(); int index = 0; - while (index < getDirectCount()) { - initializeNode(toNode, index, getNode(fromNode, index)); + final long[] curOffsets = this.offsets; + final Type curType = this.type; + int curDirectCount = getDirectCount(); + while (index < curDirectCount) { + initializeNode(toNode, curOffsets, index, getNode(fromNode, curOffsets, index)); index++; } - while (index < getCount()) { - NodeList<Node> list = getNodeList(toNode, index); - NodeList<Node> fromList = getNodeList(fromNode, index); + int curCount = getCount(); + while (index < curCount) { + NodeList<Node> list = getNodeList(toNode, curOffsets, index); + NodeList<Node> fromList = getNodeList(fromNode, curOffsets, index); if (list == null || list == fromList) { - list = type == Edges.Type.Inputs ? new NodeInputList<>(toNode, fromList) : new NodeSuccessorList<>(toNode, fromList); - initializeList(toNode, index, list); + list = curType == Edges.Type.Inputs ? new NodeInputList<>(toNode, fromList) : new NodeSuccessorList<>(toNode, fromList); + initializeList(toNode, curOffsets, index, list); } else { list.copy(fromList); } @@ -194,17 +203,20 @@ */ public boolean replaceFirst(Node node, Node key, Node replacement) { int index = 0; - while (index < getDirectCount()) { - Node edge = getNode(node, index); + final long[] curOffsets = this.getOffsets(); + int curDirectCount = getDirectCount(); + while (index < curDirectCount) { + Node edge = getNode(node, curOffsets, index); if (edge == key) { assert replacement == null || getType(index).isAssignableFrom(replacement.getClass()) : "Can not assign " + replacement.getClass() + " to " + getType(index) + " in " + node; - initializeNode(node, index, replacement); + initializeNode(node, curOffsets, index, replacement); return true; } index++; } - while (index < getCount()) { - NodeList<Node> list = getNodeList(node, index); + int curCount = getCount(); + while (index < curCount) { + NodeList<Node> list = getNodeList(node, curOffsets, index); if (list != null) { if (list.replaceFirst(key, replacement)) { return true; @@ -228,13 +240,12 @@ * @param index the index of the edge (between 0 and {@link #getCount()}) * @param value the node to be written to the edge */ - public void initializeNode(Node node, int index, Node value) { - putNode(node, offsets[index], value); + public static void initializeNode(Node node, long[] offsets, int index, Node value) { + putNodeUnsafe(node, offsets[index], value); } - public void initializeList(Node node, int index, NodeList<Node> value) { - assert index >= directCount; - putNodeList(node, offsets[index], value); + public static void initializeList(Node node, long[] offsets, int index, NodeList<Node> value) { + putNodeListUnsafe(node, offsets[index], value); } /** @@ -247,21 +258,22 @@ */ public void setNode(Node node, int index, Node value) { assert index < directCount; - Node old = getNode(node, offsets[index]); - putNode(node, offsets[index], value); + Node old = getNodeUnsafe(node, offsets[index]); + putNodeUnsafe(node, offsets[index], value); update(node, old, value); } protected abstract void update(Node node, Node oldValue, Node newValue); public boolean contains(Node node, Node value) { + final long[] curOffsets = this.offsets; for (int i = 0; i < directCount; i++) { - if (getNode(node, i) == value) { + if (getNode(node, curOffsets, i) == value) { return true; } } for (int i = directCount; i < getCount(); i++) { - NodeList<?> curList = getNodeList(node, i); + NodeList<?> curList = getNodeList(node, curOffsets, i); if (curList != null && curList.contains(value)) { return true; } @@ -275,15 +287,16 @@ public boolean areEqualIn(Node node, Node other) { assert node.getNodeClass().getClazz() == other.getNodeClass().getClazz(); int index = 0; + final long[] curOffsets = this.offsets; while (index < directCount) { - if (getNode(other, index) != getNode(node, index)) { + if (getNode(other, curOffsets, index) != getNode(node, curOffsets, index)) { return false; } index++; } while (index < getCount()) { - NodeList<Node> list = getNodeList(other, index); - if (!Objects.equals(list, getNodeList(node, index))) { + NodeList<Node> list = getNodeList(other, curOffsets, index); + if (!Objects.equals(list, getNodeList(node, curOffsets, index))) { return false; } index++; @@ -305,6 +318,9 @@ NodeList<Node> list; protected boolean needsForward; protected Node nextElement; + protected final int directCount; + protected final int count; + protected final long[] offsets; /** * Creates an iterator that will iterate over some given edges in a given node. @@ -315,14 +331,17 @@ index = NOT_ITERABLE; subIndex = 0; needsForward = true; + this.directCount = edges.getDirectCount(); + this.offsets = edges.getOffsets(); + this.count = edges.getCount(); } void forward() { needsForward = false; - if (index < edges.getDirectCount()) { + if (index < directCount) { index++; - while (index < edges.getDirectCount()) { - nextElement = edges.getNode(node, index); + while (index < directCount) { + nextElement = Edges.getNode(node, offsets, index); if (nextElement != null) { return; } @@ -339,7 +358,7 @@ private void forwardNodeList() { do { if (subIndex == 0) { - list = edges.getNodeList(node, index); + list = Edges.getNodeList(node, offsets, index); } if (list != null) { while (subIndex < list.size()) { @@ -360,7 +379,7 @@ forward(); } needsForward = true; - if (index < edges.getCount()) { + if (index < count) { return nextElement; } throw new NoSuchElementException(); @@ -384,7 +403,7 @@ forward(); } needsForward = true; - if (index < edges.getDirectCount()) { + if (index < directCount) { return new Position(edges, index, NOT_ITERABLE); } else { return new Position(edges, index, subIndex); @@ -398,6 +417,7 @@ } private static class AllEdgesIterator extends EdgesIterator { + AllEdgesIterator(Node node, Edges edges) { super(node, edges); } @@ -405,10 +425,10 @@ @Override void forward() { needsForward = false; - if (index < edges.getDirectCount()) { + if (index < directCount) { index++; if (index < edges.getDirectCount()) { - nextElement = edges.getNode(node, index); + nextElement = Edges.getNode(node, edges.getOffsets(), index); return; } } else { @@ -416,7 +436,7 @@ } while (index < edges.getCount()) { if (subIndex == 0) { - list = edges.getNodeList(node, index); + list = Edges.getNodeList(node, edges.getOffsets(), index); } if (list != null) { if (subIndex < list.size()) { @@ -467,6 +487,9 @@ } } + static int cnt1; + static int cnt2; + public NodeClassIterable getIterable(final Node node) { return new NodeClassIterable() { @@ -493,4 +516,34 @@ public Type type() { return type; } + + public void accept(Node node, BiConsumer<Node, Node> consumer) { + int index = 0; + int curDirectCount = this.directCount; + final long[] curOffsets = this.offsets; + while (index < curDirectCount) { + Node curNode = getNode(node, curOffsets, index); + if (curNode != null) { + consumer.accept(node, curNode); + } + index++; + } + int count = getCount(); + while (index < count) { + NodeList<Node> list = getNodeList(node, curOffsets, index); + if (list != null) { + for (int i = 0; i < list.size(); ++i) { + Node curNode = list.get(i); + if (curNode != null) { + consumer.accept(node, curNode); + } + } + } + index++; + } + } + + public long[] getOffsets() { + return this.offsets; + } }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,6 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.options.*; @@ -452,18 +451,17 @@ return uniqueHelper(node, true); } - @SuppressWarnings("unchecked") <T extends Node> T uniqueHelper(T node, boolean addIfMissing) { assert node.getNodeClass().valueNumberable(); - Node other = this.findDuplicate(node); + T other = this.findDuplicate(node); if (other != null) { - return (T) other; + return other; } else { - Node result = addIfMissing ? addHelper(node) : node; + T result = addIfMissing ? addHelper(node) : node; if (node.getNodeClass().isLeafNode()) { putNodeIntoCache(result); } - return (T) result; + return result; } } @@ -484,41 +482,45 @@ return result; } - public Node findDuplicate(Node node) { + @SuppressWarnings("unchecked") + public <T extends Node> T findDuplicate(T node) { NodeClass<?> nodeClass = node.getNodeClass(); assert nodeClass.valueNumberable(); if (nodeClass.isLeafNode()) { // Leaf node: look up in cache Node cachedNode = findNodeInCache(node); if (cachedNode != null) { - return cachedNode; + return (T) cachedNode; } else { return null; } } else { - // Non-leaf node: look for another usage of the node's inputs that - // has the same data, inputs and successors as the node. To reduce - // the cost of this computation, only the input with estimated highest - // usage count is considered. - + /* + * Non-leaf node: look for another usage of the node's inputs that has the same data, + * inputs and successors as the node. To reduce the cost of this computation, only the + * input with lowest usage count is considered. If this node is the only user of any + * input then the search can terminate early. The usage count is only incremented once + * the Node is in the Graph, so account for that in the test. + */ + final int earlyExitUsageCount = node.graph() != null ? 1 : 0; int minCount = Integer.MAX_VALUE; Node minCountNode = null; for (Node input : node.inputs()) { if (input != null) { - int estimate = input.getUsageCount(); - if (estimate == 0) { + int usageCount = input.getUsageCount(); + if (usageCount == earlyExitUsageCount) { return null; - } else if (estimate < minCount) { - minCount = estimate; + } else if (usageCount < minCount) { + minCount = usageCount; minCountNode = input; } } } if (minCountNode != null) { for (Node usage : minCountNode.usages()) { - if (usage != node && nodeClass == usage.getNodeClass() && node.valueEquals(usage) && nodeClass.getEdges(Inputs).areEqualIn(node, usage) && + if (usage != node && nodeClass == usage.getNodeClass() && node.valueEquals(usage) && nodeClass.getInputEdges().areEqualIn(node, usage) && nodeClass.getEdges(Successors).areEqualIn(node, usage)) { - return usage; + return (T) usage; } } return null; @@ -626,7 +628,7 @@ @com.oracle.graal.nodeinfo.NodeInfo static final class PlaceHolderNode extends Node { - public static final NodeClass<PlaceHolderNode> TYPE = NodeClass.get(PlaceHolderNode.class); + public static final NodeClass<PlaceHolderNode> TYPE = NodeClass.create(PlaceHolderNode.class); public PlaceHolderNode() { super(TYPE); @@ -741,7 +743,9 @@ assert !isFrozen(); assert node.id() == Node.INITIAL_ID; if (nodes.length == nodesSize) { - nodes = Arrays.copyOf(nodes, (nodesSize * 2) + 1); + Node[] newNodes = new Node[(nodesSize * 2) + 1]; + System.arraycopy(nodes, 0, newNodes, 0, nodesSize); + nodes = newNodes; } int id = nodesSize; nodes[id] = node; @@ -823,8 +827,8 @@ return true; } - Node getNode(int i) { - return nodes[i]; + public Node getNode(int id) { + return nodes[id]; } /** @@ -882,11 +886,21 @@ @SuppressWarnings("all") public Map<Node, Node> addDuplicates(Iterable<? extends Node> newNodes, final Graph oldGraph, int estimatedNodeCount, DuplicationReplacement replacements) { - try (TimerCloseable s = DuplicateGraph.start()) { + try (DebugCloseable s = DuplicateGraph.start()) { return NodeClass.addGraphDuplicate(this, oldGraph, estimatedNodeCount, newNodes, replacements); } } + /** + * Reverses the usage orders of all nodes. This is used for debugging to make sure an unorthodox + * usage order does not trigger bugs in the compiler. + */ + public void reverseUsageOrder() { + for (Node n : getNodes()) { + n.reverseUsageOrder(); + } + } + public boolean isFrozen() { return isFrozen; }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,6 +27,7 @@ import java.lang.annotation.*; import java.util.*; +import java.util.function.*; import sun.misc.*; @@ -286,7 +287,16 @@ * @return an {@link NodeClassIterable iterable} for all non-null input edges. */ public NodeClassIterable inputs() { - return getNodeClass().getEdges(Inputs).getIterable(this); + return nodeClass.getInputEdges().getIterable(this); + } + + /** + * Applies the given consumer to all inputs of this node. + * + * @param consumer the consumer to be applied to the inputs + */ + public void acceptInputs(BiConsumer<Node, Node> consumer) { + nodeClass.getInputEdges().accept(this, consumer); } /** @@ -296,7 +306,16 @@ * @return an {@link NodeClassIterable iterable} for all non-null successor edges. */ public NodeClassIterable successors() { - return getNodeClass().getEdges(Successors).getIterable(this); + return nodeClass.getSuccessorEdges().getIterable(this); + } + + /** + * Applies the given consumer to all successors of this node. + * + * @param consumer the consumer to be applied to the inputs + */ + public void acceptSuccessors(BiConsumer<Node, Node> consumer) { + nodeClass.getSuccessorEdges().accept(this, consumer); } /** @@ -327,6 +346,24 @@ } /** + * Checks whether this node has usages. + */ + public final boolean hasUsages() { + return this.usage0 != null; + } + + void reverseUsageOrder() { + List<Node> snapshot = this.usages().snapshot(); + for (Node n : snapshot) { + this.removeUsage(n); + } + Collections.reverse(snapshot); + for (Node n : snapshot) { + this.addUsage(n); + } + } + + /** * Adds a given node to this node's {@linkplain #usages() usages}. * * @param node the node to add @@ -342,7 +379,9 @@ if (length == 0) { extraUsages = new Node[4]; } else if (extraUsagesCount == length) { - extraUsages = Arrays.copyOf(extraUsages, length * 2 + 1); + Node[] newExtraUsages = new Node[length * 2 + 1]; + System.arraycopy(extraUsages, 0, newExtraUsages, 0, length); + extraUsages = newExtraUsages; } extraUsages[extraUsagesCount++] = node; } @@ -381,7 +420,7 @@ * @param node the node to remove * @return whether or not {@code usage} was in the usage list */ - private boolean removeUsage(Node node) { + public boolean removeUsage(Node node) { assert node != null; // It is critical that this method maintains the invariant that // the usage list has no null element preceding a non-null element @@ -403,14 +442,6 @@ return false; } - private void clearUsages() { - incUsageModCount(); - usage0 = null; - usage1 = null; - extraUsages = NO_NODES; - extraUsagesCount = 0; - } - public final Node predecessor() { return predecessor; } @@ -499,12 +530,18 @@ assert assertTrue(id == INITIAL_ID, "unexpected id: %d", id); this.graph = newGraph; newGraph.register(this); - for (Node input : inputs()) { - updateUsages(null, input); - } - for (Node successor : successors()) { - updatePredecessor(null, successor); - } + this.acceptInputs((n, i) -> { + if (!i.isAlive()) { + throw new IllegalStateException(String.format("Input %s of newly created node %s is not alive.", i, n)); + } + n.updateUsages(null, i); + }); + this.acceptSuccessors((n, s) -> { + if (!s.isAlive()) { + throw new IllegalStateException(String.format("Successor %s of newly created node %s is not alive.", s, n)); + } + n.updatePredecessor(null, s); + }); } public final NodeClass<? extends Node> getNodeClass() { @@ -523,17 +560,27 @@ return true; } - public void replaceAtUsages(Node other) { + public final void replaceAtUsages(Node other) { + replaceAtUsages(other, null); + } + + public final void replaceAtUsages(Node other, Predicate<Node> filter) { assert checkReplaceWith(other); - for (Node usage : usages()) { - boolean result = usage.getNodeClass().getEdges(Inputs).replaceFirst(usage, this, other); - assert assertTrue(result, "not found in inputs, usage: %s", usage); - if (other != null) { - maybeNotifyInputChanged(usage); - other.addUsage(usage); + int i = 0; + while (i < this.getUsageCount()) { + Node usage = this.getUsageAt(i); + if (filter == null || filter.test(usage)) { + boolean result = usage.getNodeClass().getInputEdges().replaceFirst(usage, this, other); + assert assertTrue(result, "not found in inputs, usage: %s", usage); + if (other != null) { + maybeNotifyInputChanged(usage); + other.addUsage(usage); + } + this.movUsageFromEndTo(i); + } else { + ++i; } } - clearUsages(); } public Node getUsageAt(int index) { @@ -552,7 +599,7 @@ while (index < this.getUsageCount()) { Node usage = getUsageAt(index); if (usagePredicate.apply(usage)) { - boolean result = usage.getNodeClass().getEdges(Inputs).replaceFirst(usage, this, other); + boolean result = usage.getNodeClass().getInputEdges().replaceFirst(usage, this, other); assert assertTrue(result, "not found in inputs, usage: %s", usage); if (other != null) { maybeNotifyInputChanged(usage); @@ -595,7 +642,7 @@ if (graph != null) { assert !graph.isFrozen(); NodeEventListener listener = graph.nodeEventListener; - if (listener != null) { + if (listener != null && node.isAlive()) { listener.usagesDroppedToZero(node); } if (Fingerprint.ENABLED) { @@ -607,7 +654,7 @@ public void replaceAtPredecessor(Node other) { assert checkReplaceWith(other); if (predecessor != null) { - boolean result = predecessor.getNodeClass().getEdges(Successors).replaceFirst(predecessor, this, other); + boolean result = predecessor.getNodeClass().getSuccessorEdges().replaceFirst(predecessor, this, other); assert assertTrue(result, "not found in successors, predecessor: %s", predecessor); predecessor.updatePredecessor(this, other); } @@ -615,22 +662,22 @@ public void replaceAndDelete(Node other) { assert checkReplaceWith(other); - if (other != null) { - clearSuccessors(); - replaceAtUsages(other); - replaceAtPredecessor(other); - } + assert other != null; + clearInputs(); + clearSuccessors(); + replaceAtUsages(other); + replaceAtPredecessor(other); safeDelete(); } public void replaceFirstSuccessor(Node oldSuccessor, Node newSuccessor) { - if (getNodeClass().getEdges(Successors).replaceFirst(this, oldSuccessor, newSuccessor)) { + if (nodeClass.getSuccessorEdges().replaceFirst(this, oldSuccessor, newSuccessor)) { updatePredecessor(oldSuccessor, newSuccessor); } } public void replaceFirstInput(Node oldInput, Node newInput) { - if (getNodeClass().getEdges(Inputs).replaceFirst(this, oldInput, newInput)) { + if (nodeClass.getInputEdges().replaceFirst(this, oldInput, newInput)) { updateUsages(oldInput, newInput); } } @@ -648,7 +695,7 @@ assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); unregisterInputs(); - getNodeClass().getEdges(Inputs).clear(this); + getNodeClass().getInputEdges().clear(this); } private boolean removeThisFromUsages(Node n) { @@ -656,17 +703,14 @@ } private void unregisterSuccessors() { - for (Node successor : successors()) { - assert assertTrue(successor.predecessor == this, "wrong predecessor in old successor (%s): %s", successor, successor.predecessor); - successor.predecessor = null; - } + this.acceptSuccessors((n, successor) -> successor.predecessor = null); } public void clearSuccessors() { assert assertFalse(isDeleted(), "cannot clear successors of deleted node"); unregisterSuccessors(); - getNodeClass().getEdges(Successors).clear(this); + getNodeClass().getSuccessorEdges().clear(this); } private boolean checkDeletion() { @@ -683,6 +727,10 @@ assert checkDeletion(); unregisterInputs(); unregisterSuccessors(); + markDeleted(); + } + + public void markDeleted() { graph.unregister(this); id = DELETED_ID_START - id; assert isDeleted();
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,6 +32,7 @@ private long[] bits; private int nodeCount; private final NodeIdAccessor nodeIdAccessor; + private int counter; public NodeBitMap(Graph graph) { nodeCount = graph.nodeIdCount(); @@ -43,6 +44,10 @@ return (nodeCount + Long.SIZE - 1) >> SHIFT; } + public int getCounter() { + return counter; + } + private NodeBitMap(NodeBitMap other) { this.bits = other.bits.clone(); this.nodeCount = other.nodeCount; @@ -60,6 +65,20 @@ public boolean isMarked(Node node) { assert check(node, false); int id = nodeIdAccessor.getNodeId(node); + return isMarked(id); + } + + public boolean checkAndMarkInc(Node node) { + if (!isMarked(node)) { + this.counter++; + this.mark(node); + return true; + } else { + return false; + } + } + + public boolean isMarked(int id) { return (bits[id >> SHIFT] & (1L << id)) != 0; } @@ -67,7 +86,7 @@ assert check(node, true); int id = nodeIdAccessor.getNodeId(node); checkGrow(id); - return (bits[id >> SHIFT] & (1L << id)) != 0; + return isMarked(id); } public void mark(Node node) {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,13 +34,13 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.Edges.Type; import com.oracle.graal.graph.Graph.DuplicationReplacement; import com.oracle.graal.graph.Node.Input; import com.oracle.graal.graph.Node.OptionalInput; import com.oracle.graal.graph.Node.Successor; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.nodeinfo.*; /** @@ -63,7 +63,7 @@ private static final DebugTimer Init_IterableIds = Debug.timer("NodeClass.Init.IterableIds"); private static <T extends Annotation> T getAnnotationTimed(AnnotatedElement e, Class<T> annotationClass) { - try (TimerCloseable s = Init_AnnotationParsing.start()) { + try (DebugCloseable s = Init_AnnotationParsing.start()) { return e.getAnnotation(annotationClass); } } @@ -71,18 +71,18 @@ /** * Gets the {@link NodeClass} associated with a given {@link Class}. */ - public static <T> NodeClass<T> get(Class<T> c) { - assert getNodeClassViaReflection(c) == null; + public static <T> NodeClass<T> create(Class<T> c) { + assert get(c) == null; Class<? super T> superclass = c.getSuperclass(); NodeClass<? super T> nodeSuperclass = null; if (superclass != NODE_CLASS) { - nodeSuperclass = getNodeClassViaReflection(superclass); + nodeSuperclass = get(superclass); } return new NodeClass<>(c, nodeSuperclass); } @SuppressWarnings("unchecked") - public static <T> NodeClass<T> getNodeClassViaReflection(Class<T> superclass) { + public static <T> NodeClass<T> get(Class<T> superclass) { try { Field field = superclass.getDeclaredField("TYPE"); field.setAccessible(true); @@ -118,6 +118,11 @@ private final boolean isCanonicalizable; /** + * Determines if this node type implements {@link BinaryCommutative}. + */ + private final boolean isCommutative; + + /** * Determines if this node type implements {@link Simplifiable}. */ private final boolean isSimplifiable; @@ -133,6 +138,7 @@ assert NODE_CLASS.isAssignableFrom(clazz); this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); + this.isCommutative = BinaryCommutative.class.isAssignableFrom(clazz); if (Canonicalizable.Unary.class.isAssignableFrom(clazz) || Canonicalizable.Binary.class.isAssignableFrom(clazz)) { assert Canonicalizable.Unary.class.isAssignableFrom(clazz) ^ Canonicalizable.Binary.class.isAssignableFrom(clazz) : clazz + " should implement either Unary or Binary, not both"; } @@ -140,15 +146,15 @@ this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); NodeFieldsScanner fs = new NodeFieldsScanner(calcOffset, superNodeClass); - try (TimerCloseable t = Init_FieldScanning.start()) { + try (DebugCloseable t = Init_FieldScanning.start()) { fs.scan(clazz, clazz.getSuperclass(), false); } - try (TimerCloseable t1 = Init_Edges.start()) { + try (DebugCloseable t1 = Init_Edges.start()) { successors = new SuccessorEdges(fs.directSuccessors, fs.successors); inputs = new InputEdges(fs.directInputs, fs.inputs); } - try (TimerCloseable t1 = Init_Data.start()) { + try (DebugCloseable t1 = Init_Data.start()) { data = new Fields(fs.data); } @@ -161,7 +167,7 @@ assert info != null : "Missing NodeInfo annotation on " + clazz; this.nameTemplate = info.nameTemplate(); - try (TimerCloseable t1 = Init_AllowedUsages.start()) { + try (DebugCloseable t1 = Init_AllowedUsages.start()) { allowedUsageTypes = superNodeClass == null ? EnumSet.noneOf(InputType.class) : superNodeClass.allowedUsageTypes.clone(); allowedUsageTypes.addAll(Arrays.asList(info.allowedUsageTypes())); } @@ -171,7 +177,7 @@ this.iterableId = presetIterableId; } else if (IterableNodeType.class.isAssignableFrom(clazz)) { ITERABLE_NODE_TYPES.increment(); - try (TimerCloseable t1 = Init_IterableIds.start()) { + try (DebugCloseable t1 = Init_IterableIds.start()) { this.iterableId = nextIterableId.getAndIncrement(); NodeClass<?> snc = superNodeClass; @@ -238,6 +244,13 @@ } /** + * Determines if this node type implements {@link BinaryCommutative}. + */ + public boolean isCommutative() { + return isCommutative; + } + + /** * Determines if this node type implements {@link Simplifiable}. */ public boolean isSimplifiable() { @@ -321,7 +334,7 @@ Input inputAnnotation = getAnnotationTimed(field, Node.Input.class); OptionalInput optionalInputAnnotation = getAnnotationTimed(field, Node.OptionalInput.class); Successor successorAnnotation = getAnnotationTimed(field, Successor.class); - try (TimerCloseable s = Init_FieldScanningInner.start()) { + try (DebugCloseable s = Init_FieldScanningInner.start()) { Class<?> type = field.getType(); int modifiers = field.getModifiers(); @@ -569,30 +582,38 @@ static void updateEdgesInPlace(Node node, InplaceUpdateClosure duplicationReplacement, Edges edges) { int index = 0; - while (index < edges.getDirectCount()) { - Node edge = edges.getNode(node, index); + Type curType = edges.type(); + int directCount = edges.getDirectCount(); + final long[] curOffsets = edges.getOffsets(); + while (index < directCount) { + Node edge = Edges.getNode(node, curOffsets, index); if (edge != null) { - Node newEdge = duplicationReplacement.replacement(edge, edges.type()); - if (edges.type() == Edges.Type.Inputs) { + Node newEdge = duplicationReplacement.replacement(edge, curType); + if (curType == Edges.Type.Inputs) { node.updateUsages(null, newEdge); } else { node.updatePredecessor(null, newEdge); } - assert newEdge == null || edges.getType(index).isAssignableFrom(newEdge.getClass()) : "Can not assign " + newEdge.getClass() + " to " + edges.getType(index) + " in " + node; - edges.initializeNode(node, index, newEdge); + assert assertUpdateValid(node, edges, index, newEdge); + Edges.initializeNode(node, curOffsets, index, newEdge); } index++; } while (index < edges.getCount()) { - NodeList<Node> list = edges.getNodeList(node, index); + NodeList<Node> list = Edges.getNodeList(node, curOffsets, index); if (list != null) { - edges.initializeList(node, index, updateEdgeListCopy(node, list, duplicationReplacement, edges.type())); + Edges.initializeList(node, curOffsets, index, updateEdgeListCopy(node, list, duplicationReplacement, curType)); } index++; } } + private static boolean assertUpdateValid(Node node, Edges edges, int index, Node newEdge) { + assert newEdge == null || edges.getType(index).isAssignableFrom(newEdge.getClass()) : "Can not assign " + newEdge.getClass() + " to " + edges.getType(index) + " in " + node; + return true; + } + void updateInputSuccInPlace(Node node, InplaceUpdateClosure duplicationReplacement) { updateEdgesInPlace(node, duplicationReplacement, inputs); updateEdgesInPlace(node, duplicationReplacement, successors); @@ -618,6 +639,14 @@ return type == Edges.Type.Inputs ? inputs : successors; } + public Edges getInputEdges() { + return inputs; + } + + public Edges getSuccessorEdges() { + return successors; + } + /** * Initializes a fresh allocated node for which no constructor is called yet. Needed to * implement node factories in svm. @@ -630,9 +659,10 @@ private void initNullEdgeLists(Node node, Edges.Type type) { Edges edges = getEdges(type); + final long[] curOffsets = edges.getOffsets(); for (int inputPos = edges.getDirectCount(); inputPos < edges.getCount(); inputPos++) { - if (edges.getNodeList(node, inputPos) == null) { - edges.initializeList(node, inputPos, type == Edges.Type.Inputs ? new NodeInputList<>(node) : new NodeSuccessorList<>(node)); + if (Edges.getNodeList(node, curOffsets, inputPos) == null) { + Edges.initializeList(node, curOffsets, inputPos, type == Edges.Type.Inputs ? new NodeInputList<>(node) : new NodeSuccessorList<>(node)); } } }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeFlood.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeFlood.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,10 +24,11 @@ import java.util.*; -public class NodeFlood implements Iterable<Node> { +public final class NodeFlood implements Iterable<Node> { private final NodeBitMap visited; private final Queue<Node> worklist; + private int totalMarkedCount; public NodeFlood(Graph graph) { visited = graph.createNodeBitMap(); @@ -38,15 +39,24 @@ if (node != null && !visited.isMarked(node)) { visited.mark(node); worklist.add(node); + totalMarkedCount++; } } + public int getTotalMarkedCount() { + return totalMarkedCount; + } + public void addAll(Iterable<? extends Node> nodes) { for (Node node : nodes) { this.add(node); } } + public NodeBitMap getVisited() { + return visited; + } + public boolean isMarked(Node node) { return visited.isMarked(node); }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeIdAccessor.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeIdAccessor.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ /** * Verifies that node identifiers have not changed since this object was created. - * + * * @return true if the check succeeds * @throws VerificationError if the check fails */
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Tue Mar 10 21:26:02 2015 +0100 @@ -143,7 +143,9 @@ if (length == 0) { nodes = new Node[2]; } else if (size == length) { - nodes = Arrays.copyOf(nodes, nodes.length * 2 + 1); + Node[] newNodes = new Node[nodes.length * 2 + 1]; + System.arraycopy(nodes, 0, newNodes, 0, length); + nodes = newNodes; } nodes[size++] = node; update(null, (T) node); @@ -186,7 +188,9 @@ void copy(NodeList<? extends Node> other) { self.incModCount(); incModCount(); - nodes = Arrays.copyOf(other.nodes, other.size); + Node[] newNodes = new Node[other.size]; + System.arraycopy(other.nodes, 0, newNodes, 0, newNodes.length); + nodes = newNodes; size = other.size; }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java Tue Mar 10 21:26:02 2015 +0100 @@ -157,7 +157,7 @@ } private boolean checkInfiniteWork(Node node) { - if (lastPull == node) { + if (lastPull == node && !node.hasNoUsages()) { if (firstNoChange == null) { firstNoChange = node; lastChain = node;
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Position.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Position.java Tue Mar 10 21:26:02 2015 +0100 @@ -53,9 +53,9 @@ public Node get(Node node) { if (index < edges.getDirectCount()) { - return edges.getNode(node, index); + return Edges.getNode(node, edges.getOffsets(), index); } else { - return edges.getNodeList(node, index).get(subIndex); + return Edges.getNodeList(node, edges.getOffsets(), index).get(subIndex); } } @@ -75,15 +75,15 @@ if (index < edges.getDirectCount()) { edges.setNode(node, index, value); } else { - edges.getNodeList(node, index).set(subIndex, value); + Edges.getNodeList(node, edges.getOffsets(), index).set(subIndex, value); } } public void initialize(Node node, Node value) { if (index < edges.getDirectCount()) { - edges.initializeNode(node, index, value); + Edges.initializeNode(node, edges.getOffsets(), index, value); } else { - edges.getNodeList(node, index).initialize(subIndex, value); + Edges.getNodeList(node, edges.getOffsets(), index).initialize(subIndex, value); } }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/VerificationError.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/VerificationError.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ * This constructor creates a {@link VerificationError} with a message assembled via * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to * always generate the same output. - * + * * @param msg the message that will be associated with the error, in String.format syntax * @param args parameters to String.format - parameters that implement {@link Iterable} will be * expanded into a [x, x, ...] representation.
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Tue Mar 10 21:26:02 2015 +0100 @@ -128,4 +128,22 @@ return canonical(tool, getX(), getY()); } } + + /** + * This sub-interface of {@link Canonicalizable.Binary} is for nodes with two inputs where the + * operation is commutative. It is used to improve GVN by trying to merge nodes with the same + * inputs in different order. + */ + public interface BinaryCommutative<T extends Node> extends Binary<T> { + + /** + * Ensure a canonical ordering of inputs for commutative nodes to improve GVN results. Order + * the inputs by increasing {@link Node#id} and call {@link Graph#findDuplicate(Node)} on + * the node if it's currently in a graph. It's assumed that if there was a constant on the + * left it's been moved to the right by other code and that ordering is left alone. + * + * @return the original node or another node with the same input ordering + */ + Node maybeCommuteInputs(); + } }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Simplifiable.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Simplifiable.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,7 +25,7 @@ /** * This interface allows nodes to perform more complicated simplifications, in contrast to * {@link Canonicalizable}, which supports only replacing the current node. - * + * * Implementors of this interface need to be aware that they need to call * {@link SimplifierTool#addToWorkList(com.oracle.graal.graph.Node)} for each node that might be * influenced (in terms of simplification and canonicalization) by the actions performed in
--- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/DataPatchInConstantsTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/DataPatchInConstantsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -155,7 +155,7 @@ @NodeInfo private static final class LoadThroughPatchNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<LoadThroughPatchNode> TYPE = NodeClass.get(LoadThroughPatchNode.class); + public static final NodeClass<LoadThroughPatchNode> TYPE = NodeClass.create(LoadThroughPatchNode.class); @Input protected ValueNode input; @@ -178,13 +178,15 @@ public static native Object load(Object obj); } - private static class LoadThroughPatchOp extends LIRInstructionBase { + private static final class LoadThroughPatchOp extends LIRInstruction { + public static final LIRInstructionClass<LoadThroughPatchOp> TYPE = LIRInstructionClass.create(LoadThroughPatchOp.class); final Constant c; final boolean compressed; @Def({REG}) AllocatableValue result; LoadThroughPatchOp(Constant c, boolean compressed, AllocatableValue result) { + super(TYPE); this.c = c; this.compressed = compressed; this.result = result;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -32,10 +32,12 @@ @Opcode("DEOPT") final class AMD64DeoptimizeOp extends AMD64LIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<AMD64DeoptimizeOp> TYPE = LIRInstructionClass.create(AMD64DeoptimizeOp.class); @State private LIRFrameState info; AMD64DeoptimizeOp(LIRFrameState info) { + super(TYPE); this.info = info; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -30,12 +30,14 @@ @Opcode("CRUNTIME_CALL_EPILOGUE") final class AMD64HotSpotCRuntimeCallEpilogueOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotCRuntimeCallEpilogueOp> TYPE = LIRInstructionClass.create(AMD64HotSpotCRuntimeCallEpilogueOp.class); private final int threadLastJavaSpOffset; private final int threadLastJavaFpOffset; private final Register thread; public AMD64HotSpotCRuntimeCallEpilogueOp(int threadLastJavaSpOffset, int threadLastJavaFpOffset, Register thread) { + super(TYPE); this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaFpOffset = threadLastJavaFpOffset; this.thread = thread;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,11 +32,13 @@ @Opcode final class AMD64HotSpotCRuntimeCallPrologueOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotCRuntimeCallPrologueOp> TYPE = LIRInstructionClass.create(AMD64HotSpotCRuntimeCallPrologueOp.class); private final int threadLastJavaSpOffset; private final Register thread; public AMD64HotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread) { + super(TYPE); this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.thread = thread; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableAddressOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableAddressOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,15 +26,18 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.hotspot.HotSpotGraalRuntime; -public class AMD64HotSpotCardTableAddressOp extends AMD64LIRInstruction { +public final class AMD64HotSpotCardTableAddressOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotCardTableAddressOp> TYPE = LIRInstructionClass.create(AMD64HotSpotCardTableAddressOp.class); @Def({OperandFlag.REG}) private AllocatableValue result; public AMD64HotSpotCardTableAddressOp(AllocatableValue result) { + super(TYPE); this.result = result; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableShiftOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableShiftOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,15 +26,18 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.hotspot.HotSpotGraalRuntime; -public class AMD64HotSpotCardTableShiftOp extends AMD64LIRInstruction { +public final class AMD64HotSpotCardTableShiftOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotCardTableShiftOp> TYPE = LIRInstructionClass.create(AMD64HotSpotCardTableShiftOp.class); @Def({OperandFlag.REG, OperandFlag.ILLEGAL}) private AllocatableValue result; public AMD64HotSpotCardTableShiftOp(AllocatableValue result) { + super(TYPE); this.result = result; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -39,12 +39,14 @@ public class AMD64HotSpotCompare { @Opcode("CMP") - public static class HotSpotCompareConstantOp extends AMD64LIRInstruction { + public static final class HotSpotCompareConstantOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<HotSpotCompareConstantOp> TYPE = LIRInstructionClass.create(HotSpotCompareConstantOp.class); @Use({REG}) protected AllocatableValue x; protected JavaConstant y; public HotSpotCompareConstantOp(AllocatableValue x, JavaConstant y) { + super(TYPE); this.x = x; this.y = y; } @@ -100,12 +102,13 @@ } @Opcode("CMP") - public static class HotSpotCompareMemoryConstantOp extends MemOp { + public static final class HotSpotCompareMemoryConstantOp extends MemOp { + public static final LIRInstructionClass<HotSpotCompareMemoryConstantOp> TYPE = LIRInstructionClass.create(HotSpotCompareMemoryConstantOp.class); protected JavaConstant y; public HotSpotCompareMemoryConstantOp(Kind kind, AMD64AddressValue x, JavaConstant y, LIRFrameState state) { - super(kind, x, state); + super(TYPE, kind, x, state); this.y = y; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,6 +36,12 @@ @Opcode("DEOPT_CALLER") final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { + public static final LIRInstructionClass<AMD64HotSpotDeoptimizeCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotDeoptimizeCallerOp.class); + + protected AMD64HotSpotDeoptimizeCallerOp() { + super(TYPE); + } + @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { leaveFrameAndRestoreRbp(crb, masm);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -42,6 +42,7 @@ */ @Opcode("ENTER_UNPACK_FRAMES_STACK_FRAME") final class AMD64HotSpotEnterUnpackFramesStackFrameOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotEnterUnpackFramesStackFrameOp> TYPE = LIRInstructionClass.create(AMD64HotSpotEnterUnpackFramesStackFrameOp.class); private final Register threadRegister; private final int threadLastJavaSpOffset; @@ -55,6 +56,7 @@ AMD64HotSpotEnterUnpackFramesStackFrameOp(Register threadRegister, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue senderFp, SaveRegistersOp saveRegisterOp) { + super(TYPE); this.threadRegister = threadRegister; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,6 +38,10 @@ */ abstract class AMD64HotSpotEpilogueOp extends AMD64LIRInstruction { + protected AMD64HotSpotEpilogueOp(LIRInstructionClass<? extends AMD64HotSpotEpilogueOp> c) { + super(c); + } + /** * The type of location (i.e., stack or register) in which RBP is saved is not known until * initial LIR generation is finished. Until then, we use a placeholder variable so that LIR
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,6 +41,8 @@ @Opcode("JUMP_TO_EXCEPTION_HANDLER_IN_CALLER") final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { + public static final LIRInstructionClass<AMD64HotSpotJumpToExceptionHandlerInCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotJumpToExceptionHandlerInCallerOp.class); + @Use(REG) AllocatableValue handlerInCallerPc; @Use(REG) AllocatableValue exception; @Use(REG) AllocatableValue exceptionPc; @@ -48,6 +50,7 @@ private final int isMethodHandleReturnOffset; AMD64HotSpotJumpToExceptionHandlerInCallerOp(AllocatableValue handlerInCallerPc, AllocatableValue exception, AllocatableValue exceptionPc, int isMethodHandleReturnOffset, Register thread) { + super(TYPE); this.handlerInCallerPc = handlerInCallerPc; this.exception = exception; this.exceptionPc = exceptionPc;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,9 +39,12 @@ @Opcode("LEAVE_CURRENT_STACK_FRAME") final class AMD64HotSpotLeaveCurrentStackFrameOp extends AMD64HotSpotEpilogueOp { + public static final LIRInstructionClass<AMD64HotSpotLeaveCurrentStackFrameOp> TYPE = LIRInstructionClass.create(AMD64HotSpotLeaveCurrentStackFrameOp.class); + private final SaveRegistersOp saveRegisterOp; public AMD64HotSpotLeaveCurrentStackFrameOp(SaveRegistersOp saveRegisterOp) { + super(TYPE); this.saveRegisterOp = saveRegisterOp; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveDeoptimizedStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveDeoptimizedStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,10 +38,12 @@ @Opcode("LEAVE_DEOPTIMIZED_STACK_FRAME") final class AMD64HotSpotLeaveDeoptimizedStackFrameOp extends AMD64HotSpotEpilogueOp { + public static final LIRInstructionClass<AMD64HotSpotLeaveDeoptimizedStackFrameOp> TYPE = LIRInstructionClass.create(AMD64HotSpotLeaveDeoptimizedStackFrameOp.class); @Use(REG) AllocatableValue frameSize; @Use(REG) AllocatableValue framePointer; public AMD64HotSpotLeaveDeoptimizedStackFrameOp(AllocatableValue frameSize, AllocatableValue initialInfo) { + super(TYPE); this.frameSize = frameSize; this.framePointer = initialInfo; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -38,6 +38,7 @@ */ @Opcode("LEAVE_UNPACK_FRAMES_STACK_FRAME") final class AMD64HotSpotLeaveUnpackFramesStackFrameOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotLeaveUnpackFramesStackFrameOp> TYPE = LIRInstructionClass.create(AMD64HotSpotLeaveUnpackFramesStackFrameOp.class); private final Register threadRegister; private final int threadLastJavaSpOffset; @@ -47,6 +48,7 @@ private final SaveRegistersOp saveRegisterOp; AMD64HotSpotLeaveUnpackFramesStackFrameOp(Register threadRegister, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadLastJavaFpOffset, SaveRegistersOp saveRegisterOp) { + super(TYPE); this.threadRegister = threadRegister; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -43,12 +43,14 @@ public class AMD64HotSpotMove { - public static class HotSpotLoadConstantOp extends AMD64LIRInstruction implements MoveOp { + public static final class HotSpotLoadConstantOp extends AMD64LIRInstruction implements MoveOp { + public static final LIRInstructionClass<HotSpotLoadConstantOp> TYPE = LIRInstructionClass.create(HotSpotLoadConstantOp.class); @Def({REG, STACK}) private AllocatableValue result; private final JavaConstant input; public HotSpotLoadConstantOp(AllocatableValue result, JavaConstant input) { + super(TYPE); this.result = result; this.input = input; } @@ -145,9 +147,10 @@ } public static class HotSpotStoreConstantOp extends StoreConstantOp { + public static final LIRInstructionClass<HotSpotStoreConstantOp> TYPE = LIRInstructionClass.create(HotSpotStoreConstantOp.class); public HotSpotStoreConstantOp(Kind kind, AMD64AddressValue address, JavaConstant input, LIRFrameState state) { - super(kind, address, input, state); + super(TYPE, kind, address, input, state); } @Override @@ -181,7 +184,8 @@ } } - public static class CompressPointer extends AMD64LIRInstruction { + public static final class CompressPointer extends AMD64LIRInstruction { + public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class); private final CompressEncoding encoding; private final boolean nonNull; @@ -191,6 +195,7 @@ @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { + super(TYPE); this.result = result; this.input = input; this.baseRegister = baseRegister; @@ -218,7 +223,8 @@ } } - public static class UncompressPointer extends AMD64LIRInstruction { + public static final class UncompressPointer extends AMD64LIRInstruction { + public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class); private final CompressEncoding encoding; private final boolean nonNull; @@ -228,6 +234,7 @@ @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister; public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { + super(TYPE); this.result = result; this.input = input; this.baseRegister = baseRegister; @@ -274,12 +281,14 @@ } } - public static class CompressedNullCheckOp extends AMD64LIRInstruction { + public static final class CompressedNullCheckOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<CompressedNullCheckOp> TYPE = LIRInstructionClass.create(CompressedNullCheckOp.class); @Use({COMPOSITE}) protected AMD64AddressValue address; @State protected LIRFrameState state; public CompressedNullCheckOp(AMD64AddressValue address, LIRFrameState state) { + super(TYPE); this.address = address; this.state = state; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -37,10 +37,12 @@ */ @Opcode("PATCH_RETURN") final class AMD64HotSpotPatchReturnAddressOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotPatchReturnAddressOp> TYPE = LIRInstructionClass.create(AMD64HotSpotPatchReturnAddressOp.class); @Use(REG) AllocatableValue address; AMD64HotSpotPatchReturnAddressOp(AllocatableValue address) { + super(TYPE); this.address = address; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPushInterpreterFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPushInterpreterFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,6 +39,7 @@ */ @Opcode("PUSH_INTERPRETER_FRAME") final class AMD64HotSpotPushInterpreterFrameOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotPushInterpreterFrameOp> TYPE = LIRInstructionClass.create(AMD64HotSpotPushInterpreterFrameOp.class); @Alive(REG) AllocatableValue frameSize; @Alive(REG) AllocatableValue framePc; @@ -47,6 +48,7 @@ private final HotSpotVMConfig config; AMD64HotSpotPushInterpreterFrameOp(AllocatableValue frameSize, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue initialInfo, HotSpotVMConfig config) { + super(TYPE); this.frameSize = frameSize; this.framePc = framePc; this.senderSp = senderSp;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,12 +38,14 @@ @Opcode("RETURN") final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { + public static final LIRInstructionClass<AMD64HotSpotReturnOp> TYPE = LIRInstructionClass.create(AMD64HotSpotReturnOp.class); @Use({REG, ILLEGAL}) protected Value value; private final boolean isStub; private final Register scratchForSafepointOnReturn; private final HotSpotVMConfig config; AMD64HotSpotReturnOp(Value value, boolean isStub, Register scratchForSafepointOnReturn, HotSpotVMConfig config) { + super(TYPE); this.value = value; this.isStub = isStub; this.scratchForSafepointOnReturn = scratchForSafepointOnReturn;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -40,7 +40,8 @@ * Emits a safepoint poll. */ @Opcode("SAFEPOINT") -public class AMD64HotSpotSafepointOp extends AMD64LIRInstruction { +public final class AMD64HotSpotSafepointOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64HotSpotSafepointOp> TYPE = LIRInstructionClass.create(AMD64HotSpotSafepointOp.class); @State protected LIRFrameState state; @Temp({OperandFlag.REG, OperandFlag.ILLEGAL}) private AllocatableValue temp; @@ -48,6 +49,7 @@ private final HotSpotVMConfig config; public AMD64HotSpotSafepointOp(LIRFrameState state, HotSpotVMConfig config, NodeLIRBuilderTool tool) { + super(TYPE); this.state = state; this.config = config; if (isPollingPageFar(config) || ImmutableCode.getValue()) {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,10 +40,12 @@ */ @Opcode("UNWIND") final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueOp implements BlockEndOp { + public static final LIRInstructionClass<AMD64HotSpotUnwindOp> TYPE = LIRInstructionClass.create(AMD64HotSpotUnwindOp.class); @Use({REG}) protected RegisterValue exception; AMD64HotSpotUnwindOp(RegisterValue exception) { + super(TYPE); this.exception = exception; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -36,11 +36,12 @@ */ @Opcode("CALL_DIRECT") final class AMD64HotspotDirectStaticCallOp extends DirectCallOp { + public static final LIRInstructionClass<AMD64HotspotDirectStaticCallOp> TYPE = LIRInstructionClass.create(AMD64HotspotDirectStaticCallOp.class); private final InvokeKind invokeKind; AMD64HotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) { - super(target, result, parameters, temps, state); + super(TYPE, target, result, parameters, temps, state); assert invokeKind.isDirect(); this.invokeKind = invokeKind; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; +import com.oracle.graal.lir.amd64.AMD64Call.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; @@ -38,12 +38,13 @@ */ @Opcode("CALL_DIRECT") final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp { + public static final LIRInstructionClass<AMD64HotspotDirectVirtualCallOp> TYPE = LIRInstructionClass.create(AMD64HotspotDirectVirtualCallOp.class); private final InvokeKind invokeKind; private final HotSpotVMConfig config; AMD64HotspotDirectVirtualCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, HotSpotVMConfig config) { - super(target, result, parameters, temps, state); + super(TYPE, target, result, parameters, temps, state); this.invokeKind = invokeKind; this.config = config; assert invokeKind.isIndirect();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,6 +43,7 @@ */ @Opcode("CALL_INDIRECT") final class AMD64IndirectCallOp extends IndirectCallOp { + public static final LIRInstructionClass<AMD64IndirectCallOp> TYPE = LIRInstructionClass.create(AMD64IndirectCallOp.class); /** * Vtable stubs expect the metaspace Method in RBX. @@ -52,7 +53,7 @@ @Use({REG}) protected Value metaspaceMethod; AMD64IndirectCallOp(ResolvedJavaMethod targetMethod, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state) { - super(targetMethod, result, parameters, temps, targetAddress, state); + super(TYPE, targetMethod, result, parameters, temps, targetAddress, state); this.metaspaceMethod = metaspaceMethod; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -27,15 +27,18 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; -public class AMD64PrefetchOp extends AMD64LIRInstruction { +public final class AMD64PrefetchOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64PrefetchOp> TYPE = LIRInstructionClass.create(AMD64PrefetchOp.class); private final int instr; // AllocatePrefetchInstr @Alive({COMPOSITE}) protected AMD64AddressValue address; public AMD64PrefetchOp(AMD64AddressValue address, int instr) { + super(TYPE); this.address = address; this.instr = instr; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public final class AMD64RawNativeCallNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<AMD64RawNativeCallNode> TYPE = NodeClass.get(AMD64RawNativeCallNode.class); + public static final NodeClass<AMD64RawNativeCallNode> TYPE = NodeClass.create(AMD64RawNativeCallNode.class); protected final JavaConstant functionPointer; @Input NodeInputList<ValueNode> args;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -36,12 +36,14 @@ * {@link InstalledCode} instance. */ @Opcode("TAILCALL") -public class AMD64TailcallOp extends AMD64LIRInstruction { +public final class AMD64TailcallOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64TailcallOp> TYPE = LIRInstructionClass.create(AMD64TailcallOp.class); @Use protected Value target; @Alive protected Value[] parameters; public AMD64TailcallOp(Value[] parameters, Value target) { + super(TYPE); this.target = target; this.parameters = parameters; }
--- a/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/InvocationSocket.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/InvocationSocket.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ /** * A collection of java.lang.reflect proxies that communicate over a socket connection. - * + * * Calling a method sends the method name and the parameters through the socket. Afterwards this * class waits for a result. While waiting for a result three types of objects can arrive through * the socket: a method invocation, a method result or an exception. Method invocation can thus be @@ -83,7 +83,7 @@ /** * Represents one invocation of a method that is transferred via the socket connection. - * + * */ private static class Invocation implements Serializable { @@ -102,7 +102,7 @@ /** * Represents the result of an invocation that is transferred via the socket connection. - * + * */ private static class Result implements Serializable { @@ -130,7 +130,7 @@ * Each instance of this class handles remote invocations for one instance of a Remote class. It * will forward all interface methods to the other end of the socket and cache the results of * calls to certain methods. - * + * */ public class Handler implements InvocationHandler {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -32,10 +32,12 @@ @Opcode("DEOPT") final class SPARCDeoptimizeOp extends SPARCLIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<SPARCDeoptimizeOp> TYPE = LIRInstructionClass.create(SPARCDeoptimizeOp.class); @State private LIRFrameState info; SPARCDeoptimizeOp(LIRFrameState info) { + super(TYPE); this.info = info; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,6 +24,10 @@ import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.sparc.SPARC.*; @@ -34,14 +38,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Bpne; -import com.oracle.graal.asm.sparc.SPARCAssembler.CC; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; -import com.oracle.graal.asm.sparc.SPARCAssembler.Save; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.hotspot.*; @@ -115,12 +111,12 @@ // 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); + masm.stx(g0, address); } else { try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch = sc.getRegister(); new Setx(address.getDisplacement(), scratch).emit(masm); - new Stx(g0, new SPARCAddress(sp, scratch)).emit(masm); + masm.stx(g0, new SPARCAddress(sp, scratch)); } } } @@ -150,12 +146,12 @@ } if (SPARCAssembler.isSimm13(stackpoinerChange)) { - new Save(sp, stackpoinerChange, sp).emit(masm); + masm.save(sp, stackpoinerChange, sp); } else { try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch = sc.getRegister(); new Setx(stackpoinerChange, scratch).emit(masm); - new Save(sp, scratch, sp).emit(masm); + masm.save(sp, scratch, sp); } } @@ -163,7 +159,7 @@ final int slotSize = 8; for (int i = 0; i < frameSize / slotSize; ++i) { // 0xC1C1C1C1 - new Stx(g0, new SPARCAddress(sp, i * slotSize)).emit(masm); + masm.stx(g0, new SPARCAddress(sp, i * slotSize)); } } } @@ -171,7 +167,7 @@ @Override public void leave(CompilationResultBuilder crb) { SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; - new RestoreWindow().emit(masm); + masm.restoreWindow(); } } @@ -236,11 +232,11 @@ Register receiver = asRegister(cc.getArgument(0)); SPARCAddress src = new SPARCAddress(receiver, config.hubOffset); - new Ldx(src, scratch).emit(masm); - new Cmp(scratch, inlineCacheKlass).emit(masm); + masm.ldx(src, scratch); + masm.cmp(scratch, inlineCacheKlass); } - new Bpne(CC.Xcc, unverifiedStub).emit(masm); - new Nop().emit(masm); // delay slot + masm.bpcc(NotEqual, NOT_ANNUL, unverifiedStub, Xcc, PREDICT_NOT_TAKEN); + masm.nop(); // delay slot } masm.align(config.codeEntryAlignment); @@ -273,7 +269,7 @@ } private static void resetDelayedControlTransfers(LIR lir) { - for (AbstractBlock<?> block : lir.codeEmittingOrder()) { + for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) { for (LIRInstruction inst : lir.getLIRforBlock(block)) { if (inst instanceof SPARCDelayedControlTransfer) { ((SPARCDelayedControlTransfer) inst).resetState(); @@ -285,11 +281,11 @@ /** * Fix-up over whole LIR. * - * @see #stuffDelayedControlTransfers(LIR, AbstractBlock) + * @see #stuffDelayedControlTransfers(LIR, AbstractBlockBase) * @param l */ private static void stuffDelayedControlTransfers(LIR l) { - for (AbstractBlock<?> b : l.codeEmittingOrder()) { + for (AbstractBlockBase<?> b : l.codeEmittingOrder()) { stuffDelayedControlTransfers(l, b); } } @@ -299,7 +295,7 @@ * it tries to move the DelayedLIRInstruction to the DelayedControlTransfer instruction, if * possible. */ - private static void stuffDelayedControlTransfers(LIR l, AbstractBlock<?> block) { + private static void stuffDelayedControlTransfers(LIR l, AbstractBlockBase<?> block) { List<LIRInstruction> instructions = l.getLIRforBlock(block); if (instructions.size() >= 2) { LIRDependencyAccumulator acc = new LIRDependencyAccumulator();
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 10 21:26:02 2015 +0100 @@ -55,23 +55,40 @@ HotSpotRegistersProvider registers = createRegisters(); HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime); RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target, runtime.getConfig()); - HotSpotCodeCacheProvider codeCache = new HotSpotCodeCacheProvider(runtime, target, regConfig); + HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig); HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime); Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); - LoweringProvider lowerer = new SPARCHotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, target); + LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, new HotSpotStampProvider()); HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); - HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime, metaAccess, constantReflection, replacements); + HotSpotSuitesProvider suites = createSuites(runtime, metaAccess, constantReflection, replacements); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection); + return createBackend(runtime, providers); + } + + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Replacements replacements) { + return new HotSpotSuitesProvider(runtime, metaAccess, constantReflection, replacements); + } + + protected HotSpotCodeCacheProvider createCodeCache(HotSpotGraalRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) { + return new HotSpotCodeCacheProvider(runtime, target, regConfig); + } + + protected SPARCHotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { return new SPARCHotSpotBackend(runtime, providers); } - protected Set<CPUFeature> computeFeatures(HotSpotVMConfig config) { - Set<CPUFeature> features = EnumSet.noneOf(CPUFeature.class); + protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, + HotSpotRegistersProvider registers, TargetDescription target) { + return new SPARCHotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, target); + } + + protected EnumSet<CPUFeature> computeFeatures(HotSpotVMConfig config) { + EnumSet<CPUFeature> features = EnumSet.noneOf(CPUFeature.class); if ((config.sparcFeatures & config.vis1Instructions) != 0) { features.add(CPUFeature.VIS1); } @@ -93,10 +110,14 @@ @SuppressWarnings("unused") private static Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) { - CalleeSaveLayout csl = regConfig.getCalleeSaveLayout(); - Value[] nativeABICallerSaveRegisters = new Value[csl.registers.length]; - for (int i = 0; i < csl.registers.length; i++) { - nativeABICallerSaveRegisters[i] = csl.registers[i].asValue(); + Set<Register> callerSavedRegisters = new HashSet<>(); + Collections.addAll(callerSavedRegisters, regConfig.getCalleeSaveLayout().registers); + Collections.addAll(callerSavedRegisters, SPARC.fpuRegisters); + Value[] nativeABICallerSaveRegisters = new Value[callerSavedRegisters.size()]; + int i = 0; + for (Register reg : callerSavedRegisters) { + nativeABICallerSaveRegisters[i] = reg.asValue(); + i++; } return nativeABICallerSaveRegisters; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -28,14 +28,13 @@ 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.Stw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; @Opcode("CRUNTIME_CALL_EPILOGUE") final class SPARCHotSpotCRuntimeCallEpilogueOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotCRuntimeCallEpilogueOp> TYPE = LIRInstructionClass.create(SPARCHotSpotCRuntimeCallEpilogueOp.class); private final int threadLastJavaSpOffset; private final int threadLastJavaPcOffset; @@ -44,6 +43,7 @@ @Use({REG, STACK}) protected Value threadTemp; public SPARCHotSpotCRuntimeCallEpilogueOp(int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset, Register thread, Value threadTemp) { + super(TYPE); this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; this.threadJavaFrameAnchorFlagsOffset = threadJavaFrameAnchorFlagsOffset; @@ -58,8 +58,8 @@ SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(Kind.Long)), threadTemp, SPARCDelayedControlTransfer.DUMMY); // Reset last Java frame, last Java PC and flags. - new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); - new Stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)).emit(masm); - new Stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)).emit(masm); + masm.stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)); + masm.stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)); + masm.stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,14 +28,13 @@ 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.Add; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; @Opcode("CRUNTIME_CALL_PROLOGUE") final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotCRuntimeCallPrologueOp> TYPE = LIRInstructionClass.create(SPARCHotSpotCRuntimeCallPrologueOp.class); private final int threadLastJavaSpOffset; private final Register thread; @@ -43,6 +42,7 @@ @Def({REG, STACK}) protected Value threadTemp; public SPARCHotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread, Register stackPointer, Value threadTemp) { + super(TYPE); this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.thread = thread; this.stackPointer = stackPointer; @@ -52,8 +52,8 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Save last Java frame. - new Add(stackPointer, STACK_BIAS, g4).emit(masm); - new Stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); + masm.add(stackPointer, STACK_BIAS, g4); + masm.stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset)); // Save the thread register when calling out to the runtime. SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), delayedControlTransfer);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,6 +36,11 @@ */ @Opcode("DEOPT_CALLER") final class SPARCHotSpotDeoptimizeCallerOp extends SPARCHotSpotEpilogueOp { + public static final LIRInstructionClass<SPARCHotSpotDeoptimizeCallerOp> TYPE = LIRInstructionClass.create(SPARCHotSpotDeoptimizeCallerOp.class); + + protected SPARCHotSpotDeoptimizeCallerOp() { + super(TYPE); + } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,18 +22,17 @@ */ package com.oracle.graal.hotspot.sparc; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.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 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.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.asm.*; /** * Emits code that enters a stack frame which is tailored to call the C++ method @@ -41,6 +40,7 @@ */ @Opcode("ENTER_UNPACK_FRAMES_STACK_FRAME") final class SPARCHotSpotEnterUnpackFramesStackFrameOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotEnterUnpackFramesStackFrameOp> TYPE = LIRInstructionClass.create(SPARCHotSpotEnterUnpackFramesStackFrameOp.class); private final Register thread; private final int threadLastJavaSpOffset; @@ -50,6 +50,7 @@ @Temp(REG) AllocatableValue scratch; SPARCHotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue scratch) { + super(TYPE); this.thread = thread; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; @@ -66,32 +67,32 @@ Register scratchRegister = asRegister(scratch); // Save final sender SP to O5_savedSP. - new Mov(senderSpRegister, o5).emit(masm); + masm.mov(senderSpRegister, o5); // Load final frame PC. - new Mov(framePcRegister, o7).emit(masm); + masm.mov(framePcRegister, o7); // Allocate a full sized frame. - new Save(sp, -totalFrameSize, sp).emit(masm); + masm.save(sp, -totalFrameSize, sp); - new Mov(i0, o0).emit(masm); - new Mov(i1, o1).emit(masm); - new Mov(i2, o2).emit(masm); - new Mov(i3, o3).emit(masm); - new Mov(i4, o4).emit(masm); + masm.mov(i0, o0); + masm.mov(i1, o1); + masm.mov(i2, o2); + masm.mov(i3, o3); + masm.mov(i4, o4); // Set up last Java values. - new Add(sp, STACK_BIAS, scratchRegister).emit(masm); - new Stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); + masm.add(sp, STACK_BIAS, scratchRegister); + masm.stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset)); // Clear last Java PC. - new Stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)).emit(masm); + masm.stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)); /* * Safe thread register manually since we are not using LEAF_SP for {@link * DeoptimizationStub#UNPACK_FRAMES}. */ - new Mov(thread, l7).emit(masm); + masm.mov(thread, l7); } @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.sparc; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; @@ -30,6 +31,11 @@ * Superclass for operations that leave a method's frame. */ abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<SPARCHotSpotEpilogueOp> TYPE = LIRInstructionClass.create(SPARCHotSpotEpilogueOp.class); + + protected SPARCHotSpotEpilogueOp(LIRInstructionClass<? extends LIRInstruction> c) { + super(c); + } protected void leaveFrame(CompilationResultBuilder crb) { crb.frameContext.leave(crb);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -31,11 +31,6 @@ 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.SPARCAssembler.Jmpl; -import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Movcc; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.sparc.*; @@ -47,6 +42,8 @@ @Opcode("JUMP_TO_EXCEPTION_HANDLER_IN_CALLER") final class SPARCHotSpotJumpToExceptionHandlerInCallerOp extends SPARCHotSpotEpilogueOp { + public static final LIRInstructionClass<SPARCHotSpotJumpToExceptionHandlerInCallerOp> TYPE = LIRInstructionClass.create(SPARCHotSpotJumpToExceptionHandlerInCallerOp.class); + @Use(REG) AllocatableValue handlerInCallerPc; @Use(REG) AllocatableValue exception; @Use(REG) AllocatableValue exceptionPc; @@ -54,6 +51,7 @@ private final int isMethodHandleReturnOffset; SPARCHotSpotJumpToExceptionHandlerInCallerOp(AllocatableValue handlerInCallerPc, AllocatableValue exception, AllocatableValue exceptionPc, int isMethodHandleReturnOffset, Register thread) { + super(TYPE); this.handlerInCallerPc = handlerInCallerPc; this.exception = exception; this.exceptionPc = exceptionPc; @@ -64,21 +62,21 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Move the values up one level to be the input for the next call. - new SPARCMacroAssembler.Mov(asRegister(handlerInCallerPc), i2).emit(masm); - new SPARCMacroAssembler.Mov(asRegister(exception), i0).emit(masm); - new SPARCMacroAssembler.Mov(asRegister(exceptionPc), i1).emit(masm); + masm.mov(asRegister(handlerInCallerPc), i2); + masm.mov(asRegister(exception), i0); + masm.mov(asRegister(exceptionPc), i1); leaveFrame(crb); // 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()) { Register scratchReg = scratch.getRegister(); - new Lduw(dst, scratchReg).emit(masm); - new Cmp(scratchReg, scratchReg).emit(masm); - new Movcc(ConditionFlag.NotZero, CC.Icc, l7, sp).emit(masm); + masm.lduw(dst, scratchReg); + masm.cmp(scratchReg, scratchReg); + masm.movcc(ConditionFlag.NotZero, CC.Icc, l7, sp); } - new Jmpl(asRegister(handlerInCallerPc), 0, g0).emit(masm); - new Nop().emit(masm); + masm.jmpl(asRegister(handlerInCallerPc), 0, g0); + masm.nop(); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,6 +33,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; +import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.compiler.sparc.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; @@ -55,7 +56,12 @@ private LIRFrameState currentRuntimeCallInfo; public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { - super(new DefaultLIRKindTool(providers.getCodeCache().getTarget().wordKind), providers, cc, lirGenRes); + this(new DefaultLIRKindTool(providers.getCodeCache().getTarget().wordKind), providers, config, cc, lirGenRes); + } + + protected SPARCHotSpotLIRGenerator(LIRKindTool lirKindTool, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { + super(lirKindTool, providers, cc, lirGenRes); + assert config.basicLockSize == 8; this.config = config; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,7 +25,6 @@ import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; @@ -35,18 +34,20 @@ */ @Opcode("LEAVE_CURRENT_STACK_FRAME") final class SPARCHotSpotLeaveCurrentStackFrameOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotLeaveCurrentStackFrameOp> TYPE = LIRInstructionClass.create(SPARCHotSpotLeaveCurrentStackFrameOp.class); public SPARCHotSpotLeaveCurrentStackFrameOp() { + super(TYPE); } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Save O registers over restore. - new Mov(o0, i0).emit(masm); - new Mov(o1, i1).emit(masm); - new Mov(o2, i2).emit(masm); - new Mov(o3, i3).emit(masm); - new Mov(o4, i4).emit(masm); + masm.mov(o0, i0); + masm.mov(o1, i1); + masm.mov(o2, i2); + masm.mov(o3, i3); + masm.mov(o4, i4); crb.frameContext.leave(crb); }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.sparc; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.asm.sparc.*; @@ -36,16 +35,22 @@ @Opcode("LEAVE_DEOPTIMIZED_STACK_FRAME") final class SPARCHotSpotLeaveDeoptimizedStackFrameOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotLeaveDeoptimizedStackFrameOp> TYPE = LIRInstructionClass.create(SPARCHotSpotLeaveDeoptimizedStackFrameOp.class); + + protected SPARCHotSpotLeaveDeoptimizedStackFrameOp() { + super(TYPE); + } + @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Save O registers over restore. - new Mov(o0, i0).emit(masm); - new Mov(o1, i1).emit(masm); - new Mov(o2, i2).emit(masm); - new Mov(o3, i3).emit(masm); - new Mov(o4, i4).emit(masm); + masm.mov(o0, i0); + masm.mov(o1, i1); + masm.mov(o2, i2); + masm.mov(o3, i3); + masm.mov(o4, i4); - new RestoreWindow().emit(masm); + masm.restoreWindow(); } @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,15 +22,14 @@ */ package com.oracle.graal.hotspot.sparc; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.asm.*; /** * Emits code that leaves a stack frame which is tailored to call the C++ method @@ -38,6 +37,7 @@ */ @Opcode("LEAVE_UNPACK_FRAMES_STACK_FRAME") final class SPARCHotSpotLeaveUnpackFramesStackFrameOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotLeaveUnpackFramesStackFrameOp> TYPE = LIRInstructionClass.create(SPARCHotSpotLeaveUnpackFramesStackFrameOp.class); private final Register thread; private final int threadLastJavaSpOffset; @@ -45,6 +45,7 @@ private final int threadJavaFrameAnchorFlagsOffset; SPARCHotSpotLeaveUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset) { + super(TYPE); this.thread = thread; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; @@ -57,17 +58,17 @@ * Safe thread register manually since we are not using LEAF_SP for {@link * DeoptimizationStub#UNPACK_FRAMES}. */ - new Mov(l7, thread).emit(masm); + masm.mov(l7, thread); SPARCAddress lastJavaPc = new SPARCAddress(thread, threadLastJavaPcOffset); // We borrow the threads lastJavaPC to transfer the value from float to i0 - new Stdf(SPARCSaveRegistersOp.RETURN_REGISTER_STORAGE, lastJavaPc).emit(masm); - new Ldx(lastJavaPc, i0).emit(masm); + masm.stdf(SPARCSaveRegistersOp.RETURN_REGISTER_STORAGE, lastJavaPc); + masm.ldx(lastJavaPc, i0); // Clear last Java frame values. - new Stx(g0, lastJavaPc).emit(masm); - new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); - new Stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)).emit(masm); + masm.stx(g0, lastJavaPc); + masm.stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)); + masm.stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,14 +22,13 @@ */ package com.oracle.graal.hotspot.sparc; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.api.code.ValueUtil.*; 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.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; @@ -39,16 +38,18 @@ */ @Opcode("PATCH_RETURN") final class SPARCHotSpotPatchReturnAddressOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotPatchReturnAddressOp> TYPE = LIRInstructionClass.create(SPARCHotSpotPatchReturnAddressOp.class); @Use(REG) AllocatableValue address; SPARCHotSpotPatchReturnAddressOp(AllocatableValue address) { + super(TYPE); this.address = address; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { Register addrRegister = asLongReg(address); - new Sub(addrRegister, Return.PC_RETURN_OFFSET, i7).emit(masm); + masm.sub(addrRegister, SPARCAssembler.PC_RETURN_OFFSET, i7); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,23 +22,23 @@ */ 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.api.code.ValueUtil.*; 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.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.asm.*; /** * Pushes an interpreter frame to the stack. */ @Opcode("PUSH_INTERPRETER_FRAME") final class SPARCHotSpotPushInterpreterFrameOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotPushInterpreterFrameOp> TYPE = LIRInstructionClass.create(SPARCHotSpotPushInterpreterFrameOp.class); @Alive(REG) AllocatableValue frameSize; @Alive(REG) AllocatableValue framePc; @@ -46,6 +46,7 @@ @Alive(REG) AllocatableValue initialInfo; SPARCHotSpotPushInterpreterFrameOp(AllocatableValue frameSize, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue initialInfo) { + super(TYPE); this.frameSize = frameSize; this.framePc = framePc; this.senderSp = senderSp; @@ -59,21 +60,21 @@ final Register senderSpRegister = asRegister(senderSp); // Save sender SP to O5_savedSP. - new Mov(senderSpRegister, o5).emit(masm); + masm.mov(senderSpRegister, o5); - new Neg(frameSizeRegister).emit(masm); - new Save(sp, frameSizeRegister, sp).emit(masm); + masm.neg(frameSizeRegister); + masm.save(sp, frameSizeRegister, sp); - new Mov(i0, o0).emit(masm); - new Mov(i1, o1).emit(masm); - new Mov(i2, o2).emit(masm); - new Mov(i3, o3).emit(masm); - new Mov(i4, o4).emit(masm); + masm.mov(i0, o0); + masm.mov(i1, o1); + masm.mov(i2, o2); + masm.mov(i3, o3); + masm.mov(i4, o4); // NOTE: Don't touch I5 as it contains valuable saved SP! // Move frame's new PC into i7 - new Mov(framePcRegister, i7).emit(masm); + masm.mov(framePcRegister, i7); } @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Mar 10 21:26:02 2015 +0100 @@ -92,7 +92,8 @@ private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; // @formatter:off private final Register[] callerSaveRegisters = - {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7, + {g1, g2, g3, g4, g5, g6, g7, + o0, o1, o2, o3, o4, o5, o7, f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23,
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -37,12 +37,14 @@ */ @Opcode("RETURN") final class SPARCHotSpotReturnOp extends SPARCHotSpotEpilogueOp { + public static final LIRInstructionClass<SPARCHotSpotReturnOp> TYPE = LIRInstructionClass.create(SPARCHotSpotReturnOp.class); @Use({REG, ILLEGAL}) protected Value value; private final boolean isStub; private final HotSpotVMConfig config; SPARCHotSpotReturnOp(Value value, boolean isStub, HotSpotVMConfig config) { + super(TYPE); this.value = value; this.isStub = isStub; this.config = config;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -27,7 +27,6 @@ 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.Ldx; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; @@ -43,6 +42,7 @@ */ @Opcode("SAFEPOINT") public class SPARCHotSpotSafepointOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCHotSpotSafepointOp> TYPE = LIRInstructionClass.create(SPARCHotSpotSafepointOp.class); @State protected LIRFrameState state; @SuppressFBWarnings(value = "BC_IMPOSSIBLE_CAST", justification = "changed by the register allocator") @Temp({OperandFlag.REG}) private AllocatableValue temp; @@ -50,9 +50,10 @@ private final HotSpotVMConfig config; public SPARCHotSpotSafepointOp(LIRFrameState state, HotSpotVMConfig config, LIRGeneratorTool tool) { + super(TYPE); this.state = state; this.config = config; - temp = tool.newVariable(LIRKind.value(tool.target().wordKind)); + this.temp = tool.newVariable(LIRKind.value(tool.target().wordKind)); } @Override @@ -65,7 +66,7 @@ new Setx(config.safepointPollingAddress, scratch).emit(masm); MarkId.recordMark(crb, atReturn ? MarkId.POLL_RETURN_FAR : MarkId.POLL_FAR); final int pos = masm.position(); - new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm); + masm.ldx(new SPARCAddress(scratch, 0), g0); if (state != null) { crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -28,9 +28,7 @@ import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -41,10 +39,12 @@ */ @Opcode("UNWIND") final class SPARCHotSpotUnwindOp extends SPARCHotSpotEpilogueOp { + public static final LIRInstructionClass<SPARCHotSpotUnwindOp> TYPE = LIRInstructionClass.create(SPARCHotSpotUnwindOp.class); @Use({REG}) protected RegisterValue exception; SPARCHotSpotUnwindOp(RegisterValue exception) { + super(TYPE); this.exception = exception; } @@ -52,7 +52,7 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // This Frame is left but the called unwind (which is sibling) method needs the exception as // input in i0 - new Mov(o0, i0).emit(masm); + masm.mov(o0, i0); leaveFrame(crb); ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER); @@ -62,7 +62,7 @@ // Get return address (is in o7 after leave). Register returnAddress = asRegister(cc.getArgument(1)); - new Add(o7, Return.PC_RETURN_OFFSET, returnAddress).emit(masm); + masm.add(o7, SPARCAssembler.PC_RETURN_OFFSET, returnAddress); Register scratch = g5; SPARCCall.indirectJmp(crb, masm, scratch, linkage); }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -36,11 +36,12 @@ */ @Opcode("CALL_DIRECT") final class SPARCHotspotDirectStaticCallOp extends DirectCallOp { + public static final LIRInstructionClass<SPARCHotspotDirectStaticCallOp> TYPE = LIRInstructionClass.create(SPARCHotspotDirectStaticCallOp.class); private final InvokeKind invokeKind; SPARCHotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) { - super(target, result, parameters, temps, state); + super(TYPE, target, result, parameters, temps, state); assert invokeKind.isDirect(); this.invokeKind = invokeKind; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -41,12 +41,13 @@ */ @Opcode("CALL_DIRECT") final class SPARCHotspotDirectVirtualCallOp extends DirectCallOp { + public static final LIRInstructionClass<SPARCHotspotDirectVirtualCallOp> TYPE = LIRInstructionClass.create(SPARCHotspotDirectVirtualCallOp.class); private final InvokeKind invokeKind; private final HotSpotVMConfig config; SPARCHotspotDirectVirtualCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, HotSpotVMConfig config) { - super(target, result, parameters, temps, state); + super(TYPE, target, result, parameters, temps, state); this.invokeKind = invokeKind; this.config = config; assert invokeKind.isIndirect();
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,6 +43,7 @@ */ @Opcode("CALL_INDIRECT") final class SPARCIndirectCallOp extends IndirectCallOp { + public static final LIRInstructionClass<SPARCIndirectCallOp> TYPE = LIRInstructionClass.create(SPARCIndirectCallOp.class); /** * Vtable stubs expect the metaspace Method in g5. @@ -52,7 +53,7 @@ @Use({REG}) protected Value metaspaceMethod; SPARCIndirectCallOp(ResolvedJavaMethod targetMethod, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state) { - super(targetMethod, result, parameters, temps, targetAddress, state); + super(TYPE, targetMethod, result, parameters, temps, targetAddress, state); this.metaspaceMethod = metaspaceMethod; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,24 +25,26 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Prefetch; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -public class SPARCPrefetchOp extends SPARCLIRInstruction { +public final class SPARCPrefetchOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCPrefetchOp> TYPE = LIRInstructionClass.create(SPARCPrefetchOp.class); private final int instr; // AllocatePrefetchInstr @Alive({COMPOSITE}) protected SPARCAddressValue address; public SPARCPrefetchOp(SPARCAddressValue address, int instr) { + super(TYPE); this.address = address; this.instr = instr; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - assert instr >= 0 && instr < Prefetch.Fcn.values().length : instr; - new Prefetch(address.toAddress(), Prefetch.Fcn.values()[instr]).emit(masm); + assert instr >= 0 && instr < SPARCAssembler.Fcn.values().length : instr; + masm.prefetch(address.toAddress(), SPARCAssembler.Fcn.values()[instr]); } }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/DataPatchTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/DataPatchTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -95,7 +95,7 @@ @NodeInfo private static final class ConstantFoldBarrier extends FloatingNode implements LIRLowerable { - public static final NodeClass<ConstantFoldBarrier> TYPE = NodeClass.get(ConstantFoldBarrier.class); + public static final NodeClass<ConstantFoldBarrier> TYPE = NodeClass.create(ConstantFoldBarrier.class); @Input protected ValueNode input; public ConstantFoldBarrier(ValueNode input) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.hotspot.meta.*; public class HotSpotMonitorValueTest extends GraalCompilerTest { @@ -53,14 +52,14 @@ assertNull(caller.caller()); assertDeepEquals(2, frame.numLocks); assertDeepEquals(2, caller.numLocks); - HotSpotMonitorValue lock1 = (HotSpotMonitorValue) frame.getLockValue(0); - HotSpotMonitorValue lock2 = (HotSpotMonitorValue) frame.getLockValue(1); - HotSpotMonitorValue lock3 = (HotSpotMonitorValue) caller.getLockValue(0); - HotSpotMonitorValue lock4 = (HotSpotMonitorValue) caller.getLockValue(1); + StackLockValue lock1 = (StackLockValue) frame.getLockValue(0); + StackLockValue lock2 = (StackLockValue) frame.getLockValue(1); + StackLockValue lock3 = (StackLockValue) caller.getLockValue(0); + StackLockValue lock4 = (StackLockValue) caller.getLockValue(1); - List<HotSpotMonitorValue> locks = Arrays.asList(lock1, lock2, lock3, lock4); - for (HotSpotMonitorValue lock : locks) { - for (HotSpotMonitorValue other : locks) { + List<StackLockValue> locks = Arrays.asList(lock1, lock2, lock3, lock4); + for (StackLockValue lock : locks) { + for (StackLockValue other : locks) { if (other != lock) { // Every lock must have a different stack slot assertThat(lock.getSlot(), not(other.getSlot()));
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -248,10 +248,11 @@ HighTierContext highContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); new NodeIntrinsificationPhase(getProviders(), getSnippetReflection()).apply(graph); - new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext); + new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext); + new CanonicalizerPhase().apply(graph, highContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext); new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); new WriteBarrierAdditionPhase(config).apply(graph); Debug.dump(graph, "After Write Barrier Addition");
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -628,14 +628,14 @@ try (Scope d = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) { final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); + new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext); MidTierContext midTierContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext); new GuardLoweringPhase().apply(graph, midTierContext); new LoopSafepointInsertionPhase().apply(graph); - new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext); + new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext); new WriteBarrierAdditionPhase(config).apply(graph);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Mar 10 21:26:02 2015 +0100 @@ -172,7 +172,7 @@ EventProvider eventProvider = Graal.getRequiredCapability(EventProvider.class); CompilationEvent compilationEvent = eventProvider.newCompilationEvent(); - try (TimerCloseable a = CompilationTime.start()) { + try (DebugCloseable a = CompilationTime.start()) { // If there is already compiled code for this method on our level we simply return. // Graal compiles are always at the highest compile level, even in non-tiered mode so we // only need to check for that value. @@ -259,7 +259,7 @@ } } - try (TimerCloseable b = CodeInstallationTime.start()) { + try (DebugCloseable b = CodeInstallationTime.start()) { installedCode = (HotSpotInstalledCode) installMethod(result); if (!isOSR) { ProfilingInfo profile = method.getProfilingInfo();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,6 @@ import java.util.jar.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Tue Mar 10 21:26:02 2015 +0100 @@ -172,7 +172,7 @@ } } }; - for (AbstractBlock<?> block : lir.codeEmittingOrder()) { + for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) { for (LIRInstruction op : lir.getLIRforBlock(block)) { if (op instanceof LabelOp) { // Don't consider this as a definition
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Tue Mar 10 21:26:02 2015 +0100 @@ -115,7 +115,7 @@ Infopoint info = (Infopoint) site; if (info.debugInfo != null) { BytecodeFrame frame = info.debugInfo.frame(); - assert frame == null || frame.validateFormat(); + assert frame == null || frame.validateFormat(false); } } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,8 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; /** @@ -47,22 +45,17 @@ } @Override - protected JavaValue computeLockValue(FrameState state, int lockIndex) { + protected Value computeLockValue(FrameState state, int lockIndex) { int lockDepth = lockIndex; if (state.outerFrameState() != null) { lockDepth += state.outerFrameState().nestedLockDepth(); } StackSlotValue slot = lockStack.makeLockSlot(lockDepth); ValueNode lock = state.lockAt(lockIndex); - JavaValue object = toValue(lock); + Value object = toValue(lock); boolean eliminated = object instanceof VirtualObject && state.monitorIdAt(lockIndex) != null; assert state.monitorIdAt(lockIndex) == null || state.monitorIdAt(lockIndex).getLockDepth() == lockDepth; - return new HotSpotMonitorValue(object, slot, eliminated); - } - - @Override - protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) { - return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge); + return new StackLockValue(object, slot, eliminated); } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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.hotspot; - -import static com.oracle.graal.api.code.ValueUtil.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandMode; - -/** - * Extends {@link LIRFrameState} to handle {@link HotSpotMonitorValue}s correctly. - */ -class HotSpotLIRFrameState extends LIRFrameState { - - public HotSpotLIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) { - super(topFrame, virtualObjects, exceptionEdge); - } - - @Override - protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { - if (value instanceof HotSpotMonitorValue) { - HotSpotMonitorValue monitor = (HotSpotMonitorValue) value; - if (monitor.getOwner() instanceof Value) { - Value owner = (Value) monitor.getOwner(); - if (processed(owner)) { - monitor.setOwner((JavaValue) proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS)); - } - } - Value slot = monitor.getSlot(); - if (isVirtualStackSlot(slot) && processed(slot)) { - monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS))); - } - return value; - } else { - return super.processValue(inst, proc, value); - } - } -}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Mar 10 21:26:02 2015 +0100 @@ -739,7 +739,6 @@ @HotSpotVMFlag(name = "VerifyOops") @Stable public boolean verifyOops; @HotSpotVMFlag(name = "CITime") @Stable public boolean ciTime; @HotSpotVMFlag(name = "CITimeEach") @Stable public boolean ciTimeEach; - @HotSpotVMFlag(name = "CompileThreshold") @Stable public long compileThreshold; @HotSpotVMFlag(name = "CompileTheWorldStartAt", optional = true) @Stable public int compileTheWorldStartAt; @HotSpotVMFlag(name = "CompileTheWorldStopAt", optional = true) @Stable public int compileTheWorldStopAt; @HotSpotVMFlag(name = "DontCompileHugeMethods") @Stable public boolean dontCompileHugeMethods;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Mar 10 21:26:02 2015 +0100 @@ -390,7 +390,7 @@ @NodeInfo(nameTemplate = "CounterIndex") private static final class CounterIndexNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<CounterIndexNode> TYPE = NodeClass.get(CounterIndexNode.class); + public static final NodeClass<CounterIndexNode> TYPE = NodeClass.create(CounterIndexNode.class); protected final Object counter; protected final int countersSize;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Mar 10 21:26:02 2015 +0100 @@ -83,7 +83,7 @@ assert target == providers.getCodeCache().getTarget(); checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(providers, target); - instanceofSnippets = new InstanceOfSnippets.Templates(providers, target, config.compileThreshold); + instanceofSnippets = new InstanceOfSnippets.Templates(providers, target); newObjectSnippets = new NewObjectSnippets.Templates(providers, target); monitorSnippets = new MonitorSnippets.Templates(providers, target, config.useFastLocking); writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, target, config.useCompressedOops ? config.getOopEncoding() : null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.JavaMethodProfile.ProfiledMethod; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.HotSpotMethodDataAccessor.Tag;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,7 +25,6 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.*; /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.meta; - -import static com.oracle.graal.api.code.ValueUtil.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; - -/** - * Represents lock information in the debug information. - */ -public final class HotSpotMonitorValue extends AbstractValue implements JavaValue { - - private static final long serialVersionUID = 8241681800464483691L; - - private JavaValue owner; - private StackSlotValue slot; - private final boolean eliminated; - - public HotSpotMonitorValue(JavaValue owner, StackSlotValue slot, boolean eliminated) { - super(LIRKind.Illegal); - this.owner = owner; - this.slot = slot; - this.eliminated = eliminated; - } - - public JavaValue getOwner() { - return owner; - } - - public void setOwner(JavaValue newOwner) { - this.owner = newOwner; - } - - public Value getSlot() { - return slot; - } - - public boolean isEliminated() { - return eliminated; - } - - @Override - public String toString() { - return "monitor[" + owner + (slot != null ? ", " + slot : "") + (eliminated ? ", eliminated" : "") + "]"; - } - - @Override - public int hashCode() { - final int prime = 43; - int result = super.hashCode(); - result = prime * result + (eliminated ? 1231 : 1237); - result = prime * result + owner.hashCode(); - result = prime * result + slot.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof HotSpotMonitorValue) { - HotSpotMonitorValue other = (HotSpotMonitorValue) obj; - return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot); - } - return false; - } - - public void setSlot(StackSlotValue stackSlot) { - assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot); - slot = stackSlot; - } -}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Tue Mar 10 21:26:02 2015 +0100 @@ -87,7 +87,7 @@ JavaConstant getCallSiteTarget(Assumptions assumptions); /** - * Gets the result of {@link CompositeValueClass#get(Class)} for the {@link Class} object + * Gets the result of {@link CompositeValueClass#create(Class)} for the {@link Class} object * represented by this constant. * * @return {@code null} if this constant does not represent a {@link Class} object
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -190,7 +190,7 @@ if (object instanceof Class) { Class<? extends CompositeValue> c = (Class<? extends CompositeValue>) object; assert CompositeValue.class.isAssignableFrom(c) : c; - return HotSpotObjectConstantImpl.forObject(CompositeValueClass.get(c)); + return HotSpotObjectConstantImpl.forObject(CompositeValueClass.create(c)); } return null; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -868,10 +868,8 @@ return "HotSpotType<" + getName() + ", resolved>"; } - private static final HotSpotResolvedObjectTypeImpl trustedInterfaceType = fromObjectClass(TrustedInterface.class); - @Override public boolean isTrustedInterfaceType() { - return trustedInterfaceType.isAssignableFrom(this); + return TrustedInterface.class.isAssignableFrom(mirror()); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class AllocaNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<AllocaNode> TYPE = NodeClass.get(AllocaNode.class); + public static final NodeClass<AllocaNode> TYPE = NodeClass.create(AllocaNode.class); /** * The number of slots in block. */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayRangeWriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayRangeWriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public abstract class ArrayRangeWriteBarrier extends WriteBarrier { - public static final NodeClass<ArrayRangeWriteBarrier> TYPE = NodeClass.get(ArrayRangeWriteBarrier.class); + public static final NodeClass<ArrayRangeWriteBarrier> TYPE = NodeClass.create(ArrayRangeWriteBarrier.class); @Input ValueNode startIndex; @Input ValueNode length;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class BeginLockScopeNode extends AbstractMemoryCheckpoint implements LIRLowerable, MonitorEnter, MemoryCheckpoint.Single { - public static final NodeClass<BeginLockScopeNode> TYPE = NodeClass.get(BeginLockScopeNode.class); + public static final NodeClass<BeginLockScopeNode> TYPE = NodeClass.create(BeginLockScopeNode.class); protected int lockDepth; public BeginLockScopeNode(int lockDepth) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class CStringNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<CStringNode> TYPE = NodeClass.get(CStringNode.class); + public static final NodeClass<CStringNode> TYPE = NodeClass.create(CStringNode.class); protected final String string; public CStringNode(String string) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class ClassCastNode extends MacroStateSplitNode implements Canonicalizable.Binary<ValueNode> { - public static final NodeClass<ClassCastNode> TYPE = NodeClass.get(ClassCastNode.class); + public static final NodeClass<ClassCastNode> TYPE = NodeClass.create(ClassCastNode.class); public ClassCastNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo public final class ClassGetClassLoader0Node extends MacroStateSplitNode implements Canonicalizable { - public static final NodeClass<ClassGetClassLoader0Node> TYPE = NodeClass.get(ClassGetClassLoader0Node.class); + public static final NodeClass<ClassGetClassLoader0Node> TYPE = NodeClass.create(ClassGetClassLoader0Node.class); public ClassGetClassLoader0Node(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class ClassGetComponentTypeNode extends MacroNode implements Canonicalizable { - public static final NodeClass<ClassGetComponentTypeNode> TYPE = NodeClass.get(ClassGetComponentTypeNode.class); + public static final NodeClass<ClassGetComponentTypeNode> TYPE = NodeClass.create(ClassGetComponentTypeNode.class); public ClassGetComponentTypeNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ */ @NodeInfo public final class ClassGetModifiersNode extends MacroNode implements Canonicalizable { - public static final NodeClass<ClassGetModifiersNode> TYPE = NodeClass.get(ClassGetModifiersNode.class); + public static final NodeClass<ClassGetModifiersNode> TYPE = NodeClass.create(ClassGetModifiersNode.class); public ClassGetModifiersNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class ClassGetSuperclassNode extends MacroNode implements Canonicalizable { - public static final NodeClass<ClassGetSuperclassNode> TYPE = NodeClass.get(ClassGetSuperclassNode.class); + public static final NodeClass<ClassGetSuperclassNode> TYPE = NodeClass.create(ClassGetSuperclassNode.class); public ClassGetSuperclassNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class ClassIsArrayNode extends MacroNode implements Canonicalizable { - public static final NodeClass<ClassIsArrayNode> TYPE = NodeClass.get(ClassIsArrayNode.class); + public static final NodeClass<ClassIsArrayNode> TYPE = NodeClass.create(ClassIsArrayNode.class); public ClassIsArrayNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class ClassIsInterfaceNode extends MacroNode implements Canonicalizable { - public static final NodeClass<ClassIsInterfaceNode> TYPE = NodeClass.get(ClassIsInterfaceNode.class); + public static final NodeClass<ClassIsInterfaceNode> TYPE = NodeClass.create(ClassIsInterfaceNode.class); public ClassIsInterfaceNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class ClassIsPrimitiveNode extends MacroNode implements Canonicalizable { - public static final NodeClass<ClassIsPrimitiveNode> TYPE = NodeClass.get(ClassIsPrimitiveNode.class); + public static final NodeClass<ClassIsPrimitiveNode> TYPE = NodeClass.create(ClassIsPrimitiveNode.class); public ClassIsPrimitiveNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,7 +43,7 @@ @NodeInfo(nameTemplate = "{p#op/s}") public final class CompressionNode extends UnaryNode implements ConvertNode, LIRLowerable { - public static final NodeClass<CompressionNode> TYPE = NodeClass.get(CompressionNode.class); + public static final NodeClass<CompressionNode> TYPE = NodeClass.create(CompressionNode.class); public enum CompressionOp { Compress,
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ */ @NodeInfo public final class CurrentJavaThreadNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<CurrentJavaThreadNode> TYPE = NodeClass.get(CurrentJavaThreadNode.class); + public static final NodeClass<CurrentJavaThreadNode> TYPE = NodeClass.create(CurrentJavaThreadNode.class); protected LIRKind wordKind;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ */ @NodeInfo public final class CurrentLockNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<CurrentLockNode> TYPE = NodeClass.get(CurrentLockNode.class); + public static final NodeClass<CurrentLockNode> TYPE = NodeClass.create(CurrentLockNode.class); protected int lockDepth;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class DeoptimizationFetchUnrollInfoCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi { - public static final NodeClass<DeoptimizationFetchUnrollInfoCallNode> TYPE = NodeClass.get(DeoptimizationFetchUnrollInfoCallNode.class); + public static final NodeClass<DeoptimizationFetchUnrollInfoCallNode> TYPE = NodeClass.create(DeoptimizationFetchUnrollInfoCallNode.class); @Input SaveAllRegistersNode registerSaver; protected final ForeignCallsProvider foreignCalls;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo(shortName = "DeoptCaller", nameTemplate = "DeoptCaller {p#reason/s}") public final class DeoptimizeCallerNode extends ControlSinkNode implements LIRLowerable { - public static final NodeClass<DeoptimizeCallerNode> TYPE = NodeClass.get(DeoptimizeCallerNode.class); + public static final NodeClass<DeoptimizeCallerNode> TYPE = NodeClass.create(DeoptimizeCallerNode.class); protected final DeoptimizationAction action; protected final DeoptimizationReason reason;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public abstract class DeoptimizingStubCall extends DeoptimizingFixedWithNextNode { - public static final NodeClass<DeoptimizingStubCall> TYPE = NodeClass.get(DeoptimizingStubCall.class); + public static final NodeClass<DeoptimizingStubCall> TYPE = NodeClass.create(DeoptimizingStubCall.class); public DeoptimizingStubCall(NodeClass<? extends DeoptimizingStubCall> c, Stamp stamp) { super(c, stamp);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ @NodeInfo public final class DimensionsNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<DimensionsNode> TYPE = NodeClass.get(DimensionsNode.class); + public static final NodeClass<DimensionsNode> TYPE = NodeClass.create(DimensionsNode.class); protected final int rank; public DimensionsNode(int rank) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class DirectCompareAndSwapNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { - public static final NodeClass<DirectCompareAndSwapNode> TYPE = NodeClass.get(DirectCompareAndSwapNode.class); + public static final NodeClass<DirectCompareAndSwapNode> TYPE = NodeClass.create(DirectCompareAndSwapNode.class); @Input ValueNode object; @Input ValueNode offset; @Input ValueNode expectedValue;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ */ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class EndLockScopeNode extends AbstractMemoryCheckpoint implements LIRLowerable, MonitorExit, MemoryCheckpoint.Single { - public static final NodeClass<EndLockScopeNode> TYPE = NodeClass.get(EndLockScopeNode.class); + public static final NodeClass<EndLockScopeNode> TYPE = NodeClass.create(EndLockScopeNode.class); public EndLockScopeNode() { super(TYPE, StampFactory.forVoid());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ */ @NodeInfo public final class EnterUnpackFramesStackFrameNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<EnterUnpackFramesStackFrameNode> TYPE = NodeClass.get(EnterUnpackFramesStackFrameNode.class); + public static final NodeClass<EnterUnpackFramesStackFrameNode> TYPE = NodeClass.create(EnterUnpackFramesStackFrameNode.class); @Input ValueNode framePc; @Input ValueNode senderSp;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ArrayRangePostWriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ArrayRangePostWriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ @NodeInfo public class G1ArrayRangePostWriteBarrier extends ArrayRangeWriteBarrier { - public static final NodeClass<G1ArrayRangePostWriteBarrier> TYPE = NodeClass.get(G1ArrayRangePostWriteBarrier.class); + public static final NodeClass<G1ArrayRangePostWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePostWriteBarrier.class); public G1ArrayRangePostWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) { super(TYPE, object, startIndex, length);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ArrayRangePreWriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ArrayRangePreWriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ @NodeInfo public final class G1ArrayRangePreWriteBarrier extends ArrayRangeWriteBarrier { - public static final NodeClass<G1ArrayRangePreWriteBarrier> TYPE = NodeClass.get(G1ArrayRangePreWriteBarrier.class); + public static final NodeClass<G1ArrayRangePreWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePreWriteBarrier.class); public G1ArrayRangePreWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) { super(TYPE, object, startIndex, length);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public class G1PostWriteBarrier extends WriteBarrier { - public static final NodeClass<G1PostWriteBarrier> TYPE = NodeClass.get(G1PostWriteBarrier.class); + public static final NodeClass<G1PostWriteBarrier> TYPE = NodeClass.create(G1PostWriteBarrier.class); protected final boolean alwaysNull; public G1PostWriteBarrier(ValueNode object, ValueNode value, LocationNode location, boolean precise, boolean alwaysNull) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class G1PreWriteBarrier extends WriteBarrier implements DeoptimizingNode.DeoptBefore { - public static final NodeClass<G1PreWriteBarrier> TYPE = NodeClass.get(G1PreWriteBarrier.class); + public static final NodeClass<G1PreWriteBarrier> TYPE = NodeClass.create(G1PreWriteBarrier.class); @OptionalInput(InputType.State) FrameState stateBefore; protected final boolean nullCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ */ @NodeInfo public final class G1ReferentFieldReadBarrier extends WriteBarrier { - public static final NodeClass<G1ReferentFieldReadBarrier> TYPE = NodeClass.get(G1ReferentFieldReadBarrier.class); + public static final NodeClass<G1ReferentFieldReadBarrier> TYPE = NodeClass.create(G1ReferentFieldReadBarrier.class); protected final boolean doLoad;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ */ @NodeInfo public final class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<GetObjectAddressNode> TYPE = NodeClass.get(GetObjectAddressNode.class); + public static final NodeClass<GetObjectAddressNode> TYPE = NodeClass.create(GetObjectAddressNode.class); @Input ValueNode object;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public final class HotSpotDirectCallTargetNode extends DirectCallTargetNode { - public static final NodeClass<HotSpotDirectCallTargetNode> TYPE = NodeClass.get(HotSpotDirectCallTargetNode.class); + public static final NodeClass<HotSpotDirectCallTargetNode> TYPE = NodeClass.create(HotSpotDirectCallTargetNode.class); public HotSpotDirectCallTargetNode(List<ValueNode> arguments, Stamp returnStamp, JavaType[] signature, ResolvedJavaMethod target, Type callType, InvokeKind invokeKind) { super(TYPE, arguments, returnStamp, signature, target, callType, invokeKind);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public final class HotSpotIndirectCallTargetNode extends IndirectCallTargetNode { - public static final NodeClass<HotSpotIndirectCallTargetNode> TYPE = NodeClass.get(HotSpotIndirectCallTargetNode.class); + public static final NodeClass<HotSpotIndirectCallTargetNode> TYPE = NodeClass.create(HotSpotIndirectCallTargetNode.class); @Input ValueNode metaspaceMethod;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class JumpToExceptionHandlerInCallerNode extends ControlSinkNode implements LIRLowerable { - public static final NodeClass<JumpToExceptionHandlerInCallerNode> TYPE = NodeClass.get(JumpToExceptionHandlerInCallerNode.class); + public static final NodeClass<JumpToExceptionHandlerInCallerNode> TYPE = NodeClass.create(JumpToExceptionHandlerInCallerNode.class); @Input ValueNode handlerInCallerPc; @Input ValueNode exception; @Input ValueNode exceptionPc;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveCurrentStackFrameNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveCurrentStackFrameNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class LeaveCurrentStackFrameNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<LeaveCurrentStackFrameNode> TYPE = NodeClass.get(LeaveCurrentStackFrameNode.class); + public static final NodeClass<LeaveCurrentStackFrameNode> TYPE = NodeClass.create(LeaveCurrentStackFrameNode.class); @Input SaveAllRegistersNode registerSaver; public LeaveCurrentStackFrameNode(ValueNode registerSaver) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveDeoptimizedStackFrameNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveDeoptimizedStackFrameNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class LeaveDeoptimizedStackFrameNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<LeaveDeoptimizedStackFrameNode> TYPE = NodeClass.get(LeaveDeoptimizedStackFrameNode.class); + public static final NodeClass<LeaveDeoptimizedStackFrameNode> TYPE = NodeClass.create(LeaveDeoptimizedStackFrameNode.class); @Input ValueNode frameSize; @Input ValueNode initialInfo;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class LeaveUnpackFramesStackFrameNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<LeaveUnpackFramesStackFrameNode> TYPE = NodeClass.get(LeaveUnpackFramesStackFrameNode.class); + public static final NodeClass<LeaveUnpackFramesStackFrameNode> TYPE = NodeClass.create(LeaveUnpackFramesStackFrameNode.class); @Input SaveAllRegistersNode registerSaver; public LeaveUnpackFramesStackFrameNode(ValueNode registerSaver) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LoadIndexedPointerNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LoadIndexedPointerNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public final class LoadIndexedPointerNode extends LoadIndexedNode { - public static final NodeClass<LoadIndexedPointerNode> TYPE = NodeClass.get(LoadIndexedPointerNode.class); + public static final NodeClass<LoadIndexedPointerNode> TYPE = NodeClass.create(LoadIndexedPointerNode.class); public LoadIndexedPointerNode(Stamp stamp, ValueNode array, ValueNode index) { super(TYPE, stamp, array, index, Kind.Illegal);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ */ @NodeInfo public final class MonitorCounterNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<MonitorCounterNode> TYPE = NodeClass.get(MonitorCounterNode.class); + public static final NodeClass<MonitorCounterNode> TYPE = NodeClass.create(MonitorCounterNode.class); public MonitorCounterNode() { super(TYPE, null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class NewArrayStubCall extends DeoptimizingStubCall implements LIRLowerable { - public static final NodeClass<NewArrayStubCall> TYPE = NodeClass.get(NewArrayStubCall.class); + public static final NodeClass<NewArrayStubCall> TYPE = NodeClass.create(NewArrayStubCall.class); private static final Stamp defaultStamp = StampFactory.objectNonNull(); @Input ValueNode hub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class NewInstanceStubCall extends DeoptimizingStubCall implements LIRLowerable { - public static final NodeClass<NewInstanceStubCall> TYPE = NodeClass.get(NewInstanceStubCall.class); + public static final NodeClass<NewInstanceStubCall> TYPE = NodeClass.create(NewInstanceStubCall.class); private static final Stamp defaultStamp = StampFactory.objectNonNull(); @Input ValueNode hub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class NewMultiArrayStubCall extends ForeignCallNode { - public static final NodeClass<NewMultiArrayStubCall> TYPE = NodeClass.get(NewMultiArrayStubCall.class); + public static final NodeClass<NewMultiArrayStubCall> TYPE = NodeClass.create(NewMultiArrayStubCall.class); private static final Stamp defaultStamp = StampFactory.objectNonNull(); @Input ValueNode hub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PatchReturnAddressNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PatchReturnAddressNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public final class PatchReturnAddressNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<PatchReturnAddressNode> TYPE = NodeClass.get(PatchReturnAddressNode.class); + public static final NodeClass<PatchReturnAddressNode> TYPE = NodeClass.create(PatchReturnAddressNode.class); @Input ValueNode address; public PatchReturnAddressNode(ValueNode address) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public final class PrefetchAllocateNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<PrefetchAllocateNode> TYPE = NodeClass.get(PrefetchAllocateNode.class); + public static final NodeClass<PrefetchAllocateNode> TYPE = NodeClass.create(PrefetchAllocateNode.class); @Input ValueNode distance; @Input ValueNode address;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PushInterpreterFrameNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PushInterpreterFrameNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class PushInterpreterFrameNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<PushInterpreterFrameNode> TYPE = NodeClass.get(PushInterpreterFrameNode.class); + public static final NodeClass<PushInterpreterFrameNode> TYPE = NodeClass.create(PushInterpreterFrameNode.class); @Input ValueNode framePc; @Input ValueNode frameSize; @Input ValueNode senderSp;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class SaveAllRegistersNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { - public static final NodeClass<SaveAllRegistersNode> TYPE = NodeClass.get(SaveAllRegistersNode.class); + public static final NodeClass<SaveAllRegistersNode> TYPE = NodeClass.create(SaveAllRegistersNode.class); protected SaveRegistersOp saveRegistersOp; public SaveAllRegistersNode() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialArrayRangeWriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialArrayRangeWriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public final class SerialArrayRangeWriteBarrier extends ArrayRangeWriteBarrier { - public static final NodeClass<SerialArrayRangeWriteBarrier> TYPE = NodeClass.get(SerialArrayRangeWriteBarrier.class); + public static final NodeClass<SerialArrayRangeWriteBarrier> TYPE = NodeClass.create(SerialArrayRangeWriteBarrier.class); public SerialArrayRangeWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) { super(TYPE, object, startIndex, length);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public class SerialWriteBarrier extends WriteBarrier { - public static final NodeClass<SerialWriteBarrier> TYPE = NodeClass.get(SerialWriteBarrier.class); + public static final NodeClass<SerialWriteBarrier> TYPE = NodeClass.create(SerialWriteBarrier.class); protected final boolean alwaysNull; public SerialWriteBarrier(ValueNode object, LocationNode location, boolean precise, boolean alwaysNull) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Value, InputType.Anchor, InputType.Guard}) public final class SnippetAnchorNode extends FixedWithNextNode implements Simplifiable, GuardingNode { - public static final NodeClass<SnippetAnchorNode> TYPE = NodeClass.get(SnippetAnchorNode.class); + public static final NodeClass<SnippetAnchorNode> TYPE = NodeClass.create(SnippetAnchorNode.class); public SnippetAnchorNode() { super(TYPE, StampFactory.object());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetLocationProxyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetLocationProxyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Association, InputType.Value}) public final class SnippetLocationProxyNode extends FloatingNode implements Canonicalizable { - public static final NodeClass<SnippetLocationProxyNode> TYPE = NodeClass.get(SnippetLocationProxyNode.class); + public static final NodeClass<SnippetLocationProxyNode> TYPE = NodeClass.create(SnippetLocationProxyNode.class); @Input(InputType.Unchecked) ValueNode location; public SnippetLocationProxyNode(ValueNode location) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo(nameTemplate = "StubForeignCall#{p#descriptor/s}", allowedUsageTypes = {InputType.Memory}) public final class StubForeignCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi { - public static final NodeClass<StubForeignCallNode> TYPE = NodeClass.get(StubForeignCallNode.class); + public static final NodeClass<StubForeignCallNode> TYPE = NodeClass.create(StubForeignCallNode.class); @Input NodeInputList<ValueNode> arguments; protected final ForeignCallsProvider foreignCalls;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubStartNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubStartNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public final class StubStartNode extends StartNode { - public static final NodeClass<StubStartNode> TYPE = NodeClass.get(StubStartNode.class); + public static final NodeClass<StubStartNode> TYPE = NodeClass.create(StubStartNode.class); protected final Stub stub; public StubStartNode(Stub stub) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class UncommonTrapCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi { - public static final NodeClass<UncommonTrapCallNode> TYPE = NodeClass.get(UncommonTrapCallNode.class); + public static final NodeClass<UncommonTrapCallNode> TYPE = NodeClass.create(UncommonTrapCallNode.class); @Input ValueNode trapRequest; @Input SaveAllRegistersNode registerSaver; protected final ForeignCallsProvider foreignCalls;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class VMErrorNode extends DeoptimizingStubCall implements LIRLowerable { - public static final NodeClass<VMErrorNode> TYPE = NodeClass.get(VMErrorNode.class); + public static final NodeClass<VMErrorNode> TYPE = NodeClass.create(VMErrorNode.class); protected final String format; @Input ValueNode value;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable { - public static final NodeClass<WriteBarrier> TYPE = NodeClass.get(WriteBarrier.class); + public static final NodeClass<WriteBarrier> TYPE = NodeClass.create(WriteBarrier.class); @Input protected ValueNode object; @OptionalInput protected ValueNode value; @OptionalInput(InputType.Association) protected LocationNode location;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java Tue Mar 10 21:26:02 2015 +0100 @@ -44,14 +44,17 @@ public static class Guard implements SubstitutionGuard { - private HotSpotVMConfig config; + @SuppressWarnings("unused") private HotSpotVMConfig config; public Guard(HotSpotVMConfig config) { this.config = config; } public boolean execute() { - return config.useCRC32Intrinsics; + /* + * Disabled until MethodSubstitutions are compiled like snipppets. + */ + return false; // return config.useCRC32Intrinsics; } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public final class CallSiteTargetNode extends MacroStateSplitNode implements Canonicalizable, Lowerable { - public static final NodeClass<CallSiteTargetNode> TYPE = NodeClass.get(CallSiteTargetNode.class); + public static final NodeClass<CallSiteTargetNode> TYPE = NodeClass.create(CallSiteTargetNode.class); public CallSiteTargetNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableAddressNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableAddressNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public final class CardTableAddressNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<CardTableAddressNode> TYPE = NodeClass.get(CardTableAddressNode.class); + public static final NodeClass<CardTableAddressNode> TYPE = NodeClass.create(CardTableAddressNode.class); public CardTableAddressNode() { super(TYPE, StampFactory.forKind(Kind.Long));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableShiftNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableShiftNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public final class CardTableShiftNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<CardTableShiftNode> TYPE = NodeClass.get(CardTableShiftNode.class); + public static final NodeClass<CardTableShiftNode> TYPE = NodeClass.create(CardTableShiftNode.class); public CardTableShiftNode() { super(TYPE, StampFactory.intValue());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,7 +43,7 @@ */ @NodeInfo public final class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode { - public static final NodeClass<ClassGetHubNode> TYPE = NodeClass.get(ClassGetHubNode.class); + public static final NodeClass<ClassGetHubNode> TYPE = NodeClass.create(ClassGetHubNode.class); @Input protected ValueNode clazz; public ClassGetHubNode(ValueNode clazz) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.replacements; - -import static com.oracle.graal.compiler.common.GraalOptions.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.nodes.*; - -/** - * Substitutions for improving the performance of {@link CompositeValueClass#getClass()}. - */ -@ClassSubstitution(CompositeValueClass.class) -public class CompositeValueClassSubstitutions { - - /** - * A macro node for calls to {@link CompositeValueClass#get(Class)}. It can use the compiler's - * knowledge about node classes to replace itself with a constant value for a constant - * {@link Class} parameter. - */ - @NodeInfo - public static final class CompositeValueClassGetNode extends PureFunctionMacroNode { - - public static final NodeClass<CompositeValueClassGetNode> TYPE = NodeClass.get(CompositeValueClassGetNode.class); - - public CompositeValueClassGetNode(Invoke invoke) { - super(TYPE, invoke); - } - - @Override - protected JavaConstant evaluate(JavaConstant param, MetaAccessProvider metaAccess) { - if (param.isNull() || ImmutableCode.getValue()) { - return null; - } - HotSpotObjectConstant c = (HotSpotObjectConstant) param; - return c.getCompositeValueClass(); - } - } - - @MacroSubstitution(isStatic = true, forced = true, macro = CompositeValueClassGetNode.class) - private static native CompositeValueClass<?> get(Class<?> c); -}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.bridge.*; -import com.oracle.graal.lir.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; @@ -62,7 +61,6 @@ replacements.registerSubstitutions(Class.class, HotSpotClassSubstitutions.class); replacements.registerSubstitutions(CRC32.class, CRC32Substitutions.class); replacements.registerSubstitutions(Reflection.class, ReflectionSubstitutions.class); - replacements.registerSubstitutions(CompositeValueClass.class, CompositeValueClassSubstitutions.class); replacements.registerSubstitutions(CompilerToVMImpl.class, CompilerToVMImplSubstitutions.class); replacements.registerSubstitutions(new NamedType("com.sun.crypto.provider.AESCrypt"), AESCryptSubstitutions.class); replacements.registerSubstitutions(new NamedType("com.sun.crypto.provider.CipherBlockChaining"), CipherBlockChainingSubstitutions.class);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo public final class HubGetClassNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode { - public static final NodeClass<HubGetClassNode> TYPE = NodeClass.get(HubGetClassNode.class); + public static final NodeClass<HubGetClassNode> TYPE = NodeClass.create(HubGetClassNode.class); @Input protected ValueNode hub; public HubGetClassNode(@InjectedNodeParameter MetaAccessProvider metaAccess, ValueNode hub) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; @@ -61,33 +60,9 @@ */ public class InstanceOfSnippets implements Snippets { - private static final double COMPILED_VS_INTERPRETER_SPEEDUP = 50; - private static final double INSTANCEOF_DEOPT_SPEEDUP = 1.01; // generous 1% speedup - - private static final int DEOPT_THRESHOLD_FACTOR = (int) (COMPILED_VS_INTERPRETER_SPEEDUP / (INSTANCEOF_DEOPT_SPEEDUP - 1.0)); - /** - * Gets the minimum required probability of a profiled instanceof hitting one the profiled types - * for use of the {@linkplain #instanceofWithProfile deoptimizing} snippet. The value is - * computed to be an order of greater than the configured compilation threshold by a - * {@linkplain #DEOPT_THRESHOLD_FACTOR factor}. - * - * <p> - * This factor is such that the additional executions we get from using the deoptimizing snippet - * (({@linkplain #INSTANCEOF_DEOPT_SPEEDUP speedup} - 1) / probability threshold) is greater - * than the time lost during re-interpretation ({@linkplain #COMPILED_VS_INTERPRETER_SPEEDUP - * compiled code speedup} × compilation threshold). - * </p> - */ - public static double hintHitProbabilityThresholdForDeoptimizingSnippet(long compilationThreshold) { - return 1.0D - (1.0D / (compilationThreshold * DEOPT_THRESHOLD_FACTOR)); - } - - /** - * A test against a set of hints derived from a profile with very close to 100% precise coverage - * of seen types. This snippet deoptimizes on hint miss paths. - * - * @see #hintHitProbabilityThresholdForDeoptimizingSnippet(long) + * A test against a set of hints derived from a profile with 100% precise coverage of seen + * types. This snippet deoptimizes on hint miss paths. */ @Snippet public static Object instanceofWithProfile(Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue, @@ -244,11 +219,9 @@ private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic"); private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom"); - private final long compilationThreshold; - public Templates(HotSpotProviders providers, TargetDescription target, long compilationThreshold) { + public Templates(HotSpotProviders providers, TargetDescription target) { super(providers, providers.getSnippetReflection(), target); - this.compilationThreshold = compilationThreshold; } @Override @@ -264,7 +237,7 @@ Arguments args; StructuredGraph graph = instanceOf.graph(); - if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet(compilationThreshold) && hintInfo.exact == null) { + if (hintInfo.hintHitProbability >= 1.0 && hintInfo.exact == null) { Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph); args = new Arguments(instanceofWithProfile, graph.getGuardsStage(), tool.getLoweringStage()); args.add("object", object); @@ -289,7 +262,7 @@ } args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); - if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet(compilationThreshold) && hintInfo.exact == null) { + if (hintInfo.hintHitProbability >= 1.0 && hintInfo.exact == null) { args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE); } return args;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo public final class KlassLayoutHelperNode extends FloatingGuardedNode implements Canonicalizable, Lowerable { - public static final NodeClass<KlassLayoutHelperNode> TYPE = NodeClass.get(KlassLayoutHelperNode.class); + public static final NodeClass<KlassLayoutHelperNode> TYPE = NodeClass.create(KlassLayoutHelperNode.class); @Input protected ValueNode klass; protected final HotSpotVMConfig config;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -44,7 +44,7 @@ */ @NodeInfo public final class MethodHandleNode extends MacroStateSplitNode implements Simplifiable { - public static final NodeClass<MethodHandleNode> TYPE = NodeClass.get(MethodHandleNode.class); + public static final NodeClass<MethodHandleNode> TYPE = NodeClass.create(MethodHandleNode.class); // Replacement method data protected ResolvedJavaMethod replacementTargetMethod;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Mar 10 21:26:02 2015 +0100 @@ -251,7 +251,7 @@ /** * Computes the size of the memory chunk allocated for an array. This size accounts for the - * array header size, boy size and any padding after the last element to satisfy object + * array header size, body size and any padding after the last element to satisfy object * alignment requirements. * * @param length the number of elements in the array
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ @NodeInfo public final class ObjectCloneNode extends BasicObjectCloneNode implements VirtualizableAllocation, ArrayLengthProvider { - public static final NodeClass<ObjectCloneNode> TYPE = NodeClass.get(ObjectCloneNode.class); + public static final NodeClass<ObjectCloneNode> TYPE = NodeClass.create(ObjectCloneNode.class); public ObjectCloneNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class ReflectionGetCallerClassNode extends MacroStateSplitNode implements Canonicalizable, Lowerable { - public static final NodeClass<ReflectionGetCallerClassNode> TYPE = NodeClass.get(ReflectionGetCallerClassNode.class); + public static final NodeClass<ReflectionGetCallerClassNode> TYPE = NodeClass.create(ReflectionGetCallerClassNode.class); public ReflectionGetCallerClassNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemIdentityHashCodeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public final class SystemIdentityHashCodeNode extends PureFunctionMacroNode { - public static final NodeClass<SystemIdentityHashCodeNode> TYPE = NodeClass.get(SystemIdentityHashCodeNode.class); + public static final NodeClass<SystemIdentityHashCodeNode> TYPE = NodeClass.create(SystemIdentityHashCodeNode.class); public SystemIdentityHashCodeNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class ArrayCopyCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { - public static final NodeClass<ArrayCopyCallNode> TYPE = NodeClass.get(ArrayCopyCallNode.class); + public static final NodeClass<ArrayCopyCallNode> TYPE = NodeClass.create(ArrayCopyCallNode.class); @Input ValueNode src; @Input ValueNode srcPos; @Input ValueNode dest;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class ArrayCopyNode extends BasicArrayCopyNode implements Virtualizable, Lowerable { - public static final NodeClass<ArrayCopyNode> TYPE = NodeClass.get(ArrayCopyNode.class); + public static final NodeClass<ArrayCopyNode> TYPE = NodeClass.create(ArrayCopyNode.class); public ArrayCopyNode(Invoke invoke) { super(TYPE, invoke); @@ -77,9 +77,9 @@ // the canonicalization before loop unrolling is needed to propagate the length into // additions, etc. PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.getStampProvider()); - new CanonicalizerPhase(true).apply(snippetGraph, context); - new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context); - new CanonicalizerPhase(true).apply(snippetGraph, context); + new CanonicalizerPhase().apply(snippetGraph, context); + new LoopFullUnrollPhase(new CanonicalizerPhase()).apply(snippetGraph, context); + new CanonicalizerPhase().apply(snippetGraph, context); } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Value}) public final class CheckcastArrayCopyCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { - public static final NodeClass<CheckcastArrayCopyCallNode> TYPE = NodeClass.get(CheckcastArrayCopyCallNode.class); + public static final NodeClass<CheckcastArrayCopyCallNode> TYPE = NodeClass.create(CheckcastArrayCopyCallNode.class); @Input ValueNode src; @Input ValueNode srcPos; @Input ValueNode dest;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single { - public static final NodeClass<UnsafeArrayCopyNode> TYPE = NodeClass.get(UnsafeArrayCopyNode.class); + public static final NodeClass<UnsafeArrayCopyNode> TYPE = NodeClass.create(UnsafeArrayCopyNode.class); @Input ValueNode src; @Input ValueNode srcPos; @Input ValueNode dest;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Tue Mar 10 21:26:02 2015 +0100 @@ -138,7 +138,7 @@ * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for * total size of the interpreter frames plus shadow page size. Bang one page at a time * because large sizes can bang beyond yellow and red zones. - * + * * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository. */ final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Tue Mar 10 21:26:02 2015 +0100 @@ -149,7 +149,7 @@ * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for * total size of the interpreter frames plus shadow page size. Bang one page at a time * because large sizes can bang beyond yellow and red zones. - * + * * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository. */ final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/PointerCastNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/PointerCastNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class PointerCastNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<PointerCastNode> TYPE = NodeClass.get(PointerCastNode.class); + public static final NodeClass<PointerCastNode> TYPE = NodeClass.create(PointerCastNode.class); @Input ValueNode input; public PointerCastNode(Stamp stamp, ValueNode input) {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; @@ -42,7 +41,7 @@ import com.oracle.graal.options.*; import com.oracle.graal.phases.*; -public abstract class AbstractBytecodeParser<T extends KindProvider, F extends AbstractFrameStateBuilder<T, F>> { +public abstract class AbstractBytecodeParser { static class Options { // @formatter:off @@ -63,7 +62,7 @@ */ public static final int TRACELEVEL_STATE = 2; - protected F frameState; + protected HIRFrameStateBuilder frameState; protected BciBlock currentBlock; protected final BytecodeStream stream; @@ -97,7 +96,7 @@ assert metaAccess != null; } - public void setCurrentFrameState(F frameState) { + public void setCurrentFrameState(HIRFrameStateBuilder frameState) { this.frameState = frameState; } @@ -114,7 +113,7 @@ } public void storeLocal(Kind kind, int index) { - T value; + ValueNode value; if (kind == Kind.Object) { value = frameState.xpop(); // astore and astore_<n> may be used to store a returnAddress (jsr) @@ -134,13 +133,13 @@ * @param type the unresolved type of the type check * @param object the object value whose type is being checked against {@code type} */ - protected abstract void handleUnresolvedCheckCast(JavaType type, T object); + protected abstract void handleUnresolvedCheckCast(JavaType type, ValueNode object); /** * @param type the unresolved type of the type check * @param object the object value whose type is being checked against {@code type} */ - protected abstract void handleUnresolvedInstanceOf(JavaType type, T object); + protected abstract void handleUnresolvedInstanceOf(JavaType type, ValueNode object); /** * @param type the type being instantiated @@ -151,26 +150,26 @@ * @param type the type of the array being instantiated * @param length the length of the array */ - protected abstract void handleUnresolvedNewObjectArray(JavaType type, T length); + protected abstract void handleUnresolvedNewObjectArray(JavaType type, ValueNode length); /** * @param type the type being instantiated * @param dims the dimensions for the multi-array */ - protected abstract void handleUnresolvedNewMultiArray(JavaType type, List<T> dims); + protected abstract void handleUnresolvedNewMultiArray(JavaType type, List<ValueNode> dims); /** * @param field the unresolved field * @param receiver the object containing the field or {@code null} if {@code field} is static */ - protected abstract void handleUnresolvedLoadField(JavaField field, T receiver); + protected abstract void handleUnresolvedLoadField(JavaField field, ValueNode receiver); /** * @param field the unresolved field * @param value the value being stored to the field * @param receiver the object containing the field or {@code null} if {@code field} is static */ - protected abstract void handleUnresolvedStoreField(JavaField field, T value, T receiver); + protected abstract void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver); /** * @param type @@ -179,7 +178,7 @@ // protected abstract void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind); - // protected abstract DispatchBeginNode handleException(T exceptionObject, int bci); + // protected abstract DispatchBeginNode handleException(ValueNode exceptionObject, int bci); private void genLoadConstant(int cpi, int opcode) { Object con = lookupConstant(cpi, opcode); @@ -200,56 +199,41 @@ } } - protected abstract T genLoadIndexed(T index, T array, Kind kind); + protected abstract ValueNode genLoadIndexed(ValueNode index, ValueNode array, Kind kind); private void genLoadIndexed(Kind kind) { emitExplicitExceptions(frameState.peek(1), frameState.peek(0)); - T index = frameState.ipop(); - T array = frameState.apop(); + ValueNode index = frameState.ipop(); + ValueNode array = frameState.apop(); frameState.push(kind.getStackKind(), append(genLoadIndexed(array, index, kind))); } - protected abstract T genStoreIndexed(T array, T index, Kind kind, T value); + protected abstract ValueNode genStoreIndexed(ValueNode array, ValueNode index, Kind kind, ValueNode value); private void genStoreIndexed(Kind kind) { emitExplicitExceptions(frameState.peek(2), frameState.peek(1)); - T value = frameState.pop(kind.getStackKind()); - T index = frameState.ipop(); - T array = frameState.apop(); + ValueNode value = frameState.pop(kind.getStackKind()); + ValueNode index = frameState.ipop(); + ValueNode array = frameState.apop(); append(genStoreIndexed(array, index, kind, value)); } private void stackOp(int opcode) { switch (opcode) { - case POP: { - frameState.xpop(); - break; - } - case POP2: { - frameState.xpop(); - frameState.xpop(); - break; - } - case DUP: { - T w = frameState.xpop(); - frameState.xpush(w); - frameState.xpush(w); - break; - } case DUP_X1: { - T w1 = frameState.xpop(); - T w2 = frameState.xpop(); + ValueNode w1 = frameState.xpop(); + ValueNode w2 = frameState.xpop(); frameState.xpush(w1); frameState.xpush(w2); frameState.xpush(w1); break; } case DUP_X2: { - T w1 = frameState.xpop(); - T w2 = frameState.xpop(); - T w3 = frameState.xpop(); + ValueNode w1 = frameState.xpop(); + ValueNode w2 = frameState.xpop(); + ValueNode w3 = frameState.xpop(); frameState.xpush(w1); frameState.xpush(w3); frameState.xpush(w2); @@ -257,8 +241,8 @@ break; } case DUP2: { - T w1 = frameState.xpop(); - T w2 = frameState.xpop(); + ValueNode w1 = frameState.xpop(); + ValueNode w2 = frameState.xpop(); frameState.xpush(w2); frameState.xpush(w1); frameState.xpush(w2); @@ -266,9 +250,9 @@ break; } case DUP2_X1: { - T w1 = frameState.xpop(); - T w2 = frameState.xpop(); - T w3 = frameState.xpop(); + ValueNode w1 = frameState.xpop(); + ValueNode w2 = frameState.xpop(); + ValueNode w3 = frameState.xpop(); frameState.xpush(w2); frameState.xpush(w1); frameState.xpush(w3); @@ -277,10 +261,10 @@ break; } case DUP2_X2: { - T w1 = frameState.xpop(); - T w2 = frameState.xpop(); - T w3 = frameState.xpop(); - T w4 = frameState.xpop(); + ValueNode w1 = frameState.xpop(); + ValueNode w2 = frameState.xpop(); + ValueNode w3 = frameState.xpop(); + ValueNode w4 = frameState.xpop(); frameState.xpush(w2); frameState.xpush(w1); frameState.xpush(w4); @@ -290,8 +274,8 @@ break; } case SWAP: { - T w1 = frameState.xpop(); - T w2 = frameState.xpop(); + ValueNode w1 = frameState.xpop(); + ValueNode w2 = frameState.xpop(); frameState.xpush(w1); frameState.xpush(w2); break; @@ -301,27 +285,27 @@ } } - protected abstract T genIntegerAdd(Kind kind, T x, T y); + protected abstract ValueNode genIntegerAdd(Kind kind, ValueNode x, ValueNode y); - protected abstract T genIntegerSub(Kind kind, T x, T y); + protected abstract ValueNode genIntegerSub(Kind kind, ValueNode x, ValueNode y); - protected abstract T genIntegerMul(Kind kind, T x, T y); + protected abstract ValueNode genIntegerMul(Kind kind, ValueNode x, ValueNode y); - protected abstract T genFloatAdd(Kind kind, T x, T y, boolean isStrictFP); + protected abstract ValueNode genFloatAdd(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP); - protected abstract T genFloatSub(Kind kind, T x, T y, boolean isStrictFP); + protected abstract ValueNode genFloatSub(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP); - protected abstract T genFloatMul(Kind kind, T x, T y, boolean isStrictFP); + protected abstract ValueNode genFloatMul(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP); - protected abstract T genFloatDiv(Kind kind, T x, T y, boolean isStrictFP); + protected abstract ValueNode genFloatDiv(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP); - protected abstract T genFloatRem(Kind kind, T x, T y, boolean isStrictFP); + protected abstract ValueNode genFloatRem(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP); private void genArithmeticOp(Kind result, int opcode) { - T y = frameState.pop(result); - T x = frameState.pop(result); + ValueNode y = frameState.pop(result); + ValueNode x = frameState.pop(result); boolean isStrictFP = method.isStrict(); - T v; + ValueNode v; switch (opcode) { case IADD: case LADD: @@ -361,14 +345,14 @@ frameState.push(result, append(v)); } - protected abstract T genIntegerDiv(Kind kind, T x, T y); + protected abstract ValueNode genIntegerDiv(Kind kind, ValueNode x, ValueNode y); - protected abstract T genIntegerRem(Kind kind, T x, T y); + protected abstract ValueNode genIntegerRem(Kind kind, ValueNode x, ValueNode y); private void genIntegerDivOp(Kind result, int opcode) { - T y = frameState.pop(result); - T x = frameState.pop(result); - T v; + ValueNode y = frameState.pop(result); + ValueNode x = frameState.pop(result); + ValueNode v; switch (opcode) { case IDIV: case LDIV: @@ -384,22 +368,22 @@ frameState.push(result, append(v)); } - protected abstract T genNegateOp(T x); + protected abstract ValueNode genNegateOp(ValueNode x); private void genNegateOp(Kind kind) { frameState.push(kind, append(genNegateOp(frameState.pop(kind)))); } - protected abstract T genLeftShift(Kind kind, T x, T y); + protected abstract ValueNode genLeftShift(Kind kind, ValueNode x, ValueNode y); - protected abstract T genRightShift(Kind kind, T x, T y); + protected abstract ValueNode genRightShift(Kind kind, ValueNode x, ValueNode y); - protected abstract T genUnsignedRightShift(Kind kind, T x, T y); + protected abstract ValueNode genUnsignedRightShift(Kind kind, ValueNode x, ValueNode y); private void genShiftOp(Kind kind, int opcode) { - T s = frameState.ipop(); - T x = frameState.pop(kind); - T v; + ValueNode s = frameState.ipop(); + ValueNode x = frameState.pop(kind); + ValueNode v; switch (opcode) { case ISHL: case LSHL: @@ -419,16 +403,16 @@ frameState.push(kind, append(v)); } - protected abstract T genAnd(Kind kind, T x, T y); + protected abstract ValueNode genAnd(Kind kind, ValueNode x, ValueNode y); - protected abstract T genOr(Kind kind, T x, T y); + protected abstract ValueNode genOr(Kind kind, ValueNode x, ValueNode y); - protected abstract T genXor(Kind kind, T x, T y); + protected abstract ValueNode genXor(Kind kind, ValueNode x, ValueNode y); private void genLogicOp(Kind kind, int opcode) { - T y = frameState.pop(kind); - T x = frameState.pop(kind); - T v; + ValueNode y = frameState.pop(kind); + ValueNode x = frameState.pop(kind); + ValueNode v; switch (opcode) { case IAND: case LAND: @@ -448,29 +432,29 @@ frameState.push(kind, append(v)); } - protected abstract T genNormalizeCompare(T x, T y, boolean isUnorderedLess); + protected abstract ValueNode genNormalizeCompare(ValueNode x, ValueNode y, boolean isUnorderedLess); private void genCompareOp(Kind kind, boolean isUnorderedLess) { - T y = frameState.pop(kind); - T x = frameState.pop(kind); + ValueNode y = frameState.pop(kind); + ValueNode x = frameState.pop(kind); frameState.ipush(append(genNormalizeCompare(x, y, isUnorderedLess))); } - protected abstract T genFloatConvert(FloatConvert op, T input); + protected abstract ValueNode genFloatConvert(FloatConvert op, ValueNode input); private void genFloatConvert(FloatConvert op, Kind from, Kind to) { - T input = frameState.pop(from.getStackKind()); + ValueNode input = frameState.pop(from.getStackKind()); frameState.push(to.getStackKind(), append(genFloatConvert(op, input))); } - protected abstract T genNarrow(T input, int bitCount); + protected abstract ValueNode genNarrow(ValueNode input, int bitCount); - protected abstract T genSignExtend(T input, int bitCount); + protected abstract ValueNode genSignExtend(ValueNode input, int bitCount); - protected abstract T genZeroExtend(T input, int bitCount); + protected abstract ValueNode genZeroExtend(ValueNode input, int bitCount); private void genSignExtend(Kind from, Kind to) { - T input = frameState.pop(from.getStackKind()); + ValueNode input = frameState.pop(from.getStackKind()); if (from != from.getStackKind()) { input = append(genNarrow(input, from.getBitCount())); } @@ -478,7 +462,7 @@ } private void genZeroExtend(Kind from, Kind to) { - T input = frameState.pop(from.getStackKind()); + ValueNode input = frameState.pop(from.getStackKind()); if (from != from.getStackKind()) { input = append(genNarrow(input, from.getBitCount())); } @@ -486,46 +470,45 @@ } private void genNarrow(Kind from, Kind to) { - T input = frameState.pop(from.getStackKind()); + ValueNode input = frameState.pop(from.getStackKind()); frameState.push(to.getStackKind(), append(genNarrow(input, to.getBitCount()))); } private void genIncrement() { int index = getStream().readLocalIndex(); int delta = getStream().readIncrement(); - T x = frameState.loadLocal(index); - T y = appendConstant(JavaConstant.forInt(delta)); + ValueNode x = frameState.loadLocal(index); + ValueNode y = appendConstant(JavaConstant.forInt(delta)); frameState.storeLocal(index, append(genIntegerAdd(Kind.Int, x, y))); } protected abstract void genGoto(); - protected abstract T genObjectEquals(T x, T y); + protected abstract ValueNode genObjectEquals(ValueNode x, ValueNode y); - protected abstract T genIntegerEquals(T x, T y); + protected abstract ValueNode genIntegerEquals(ValueNode x, ValueNode y); - protected abstract T genIntegerLessThan(T x, T y); + protected abstract ValueNode genIntegerLessThan(ValueNode x, ValueNode y); - protected abstract T genUnique(T x); + protected abstract ValueNode genUnique(ValueNode x); - protected abstract void genIf(T x, Condition cond, T y); + protected abstract void genIf(ValueNode x, Condition cond, ValueNode y); private void genIfZero(Condition cond) { - T y = appendConstant(JavaConstant.INT_0); - T x = frameState.ipop(); + ValueNode y = appendConstant(JavaConstant.INT_0); + ValueNode x = frameState.ipop(); genIf(x, cond, y); } private void genIfNull(Condition cond) { - T y = appendConstant(JavaConstant.NULL_POINTER); - T x = frameState.apop(); + ValueNode y = appendConstant(JavaConstant.NULL_POINTER); + ValueNode x = frameState.apop(); genIf(x, cond, y); } private void genIfSame(Kind kind, Condition cond) { - T y = frameState.pop(kind); - T x = frameState.pop(kind); - // assert !x.isDeleted() && !y.isDeleted(); + ValueNode y = frameState.pop(kind); + ValueNode x = frameState.pop(kind); genIf(x, cond, y); } @@ -579,41 +562,40 @@ } } - protected abstract T createCheckCast(ResolvedJavaType type, T object, JavaTypeProfile profileForTypeCheck, boolean forStoreCheck); + protected abstract ValueNode createCheckCast(ResolvedJavaType type, ValueNode object, JavaTypeProfile profileForTypeCheck, boolean forStoreCheck); private void genCheckCast() { int cpi = getStream().readCPI(); JavaType type = lookupType(cpi, CHECKCAST); - T object = frameState.apop(); + ValueNode object = frameState.apop(); if (type instanceof ResolvedJavaType) { JavaTypeProfile profileForTypeCheck = getProfileForTypeCheck((ResolvedJavaType) type); - T checkCastNode = append(createCheckCast((ResolvedJavaType) type, object, profileForTypeCheck, false)); + ValueNode checkCastNode = append(createCheckCast((ResolvedJavaType) type, object, profileForTypeCheck, false)); frameState.apush(checkCastNode); } else { handleUnresolvedCheckCast(type, object); } } - protected abstract T createInstanceOf(ResolvedJavaType type, T object, JavaTypeProfile profileForTypeCheck); + protected abstract ValueNode createInstanceOf(ResolvedJavaType type, ValueNode object, JavaTypeProfile profileForTypeCheck); - protected abstract T genConditional(T x); + protected abstract ValueNode genConditional(ValueNode x); private void genInstanceOf() { int cpi = getStream().readCPI(); JavaType type = lookupType(cpi, INSTANCEOF); - T object = frameState.apop(); + ValueNode object = frameState.apop(); if (type instanceof ResolvedJavaType) { ResolvedJavaType resolvedType = (ResolvedJavaType) type; - T instanceOfNode = createInstanceOf((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType)); + ValueNode instanceOfNode = createInstanceOf((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType)); frameState.ipush(append(genConditional(genUnique(instanceOfNode)))); } else { handleUnresolvedInstanceOf(type, object); } } - protected abstract T createNewInstance(ResolvedJavaType type, boolean fillContents); + protected abstract ValueNode createNewInstance(ResolvedJavaType type, boolean fillContents); - @SuppressWarnings("unchecked") void genNewInstance(int cpi) { JavaType type = lookupType(cpi, NEW); if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) { @@ -621,7 +603,7 @@ if (skippedExceptionTypes != null) { for (ResolvedJavaType exceptionType : skippedExceptionTypes) { if (exceptionType.isAssignableFrom((ResolvedJavaType) type)) { - append((T) new DeoptimizeNode(DeoptimizationAction.None, TransferToInterpreter)); + append(new DeoptimizeNode(DeoptimizationAction.None, TransferToInterpreter)); return; } } @@ -672,7 +654,7 @@ private void genNewObjectArray(int cpi) { JavaType type = lookupType(cpi, ANEWARRAY); - T length = frameState.ipop(); + ValueNode length = frameState.ipop(); if (type instanceof ResolvedJavaType) { frameState.apush(append(createNewArray((ResolvedJavaType) type, length, true))); } else { @@ -681,12 +663,12 @@ } - protected abstract T createNewArray(ResolvedJavaType elementType, T length, boolean fillContents); + protected abstract ValueNode createNewArray(ResolvedJavaType elementType, ValueNode length, boolean fillContents); private void genNewMultiArray(int cpi) { JavaType type = lookupType(cpi, MULTIANEWARRAY); int rank = getStream().readUByte(bci() + 3); - List<T> dims = new ArrayList<>(Collections.nCopies(rank, null)); + List<ValueNode> dims = new ArrayList<>(Collections.nCopies(rank, null)); for (int i = rank - 1; i >= 0; i--) { dims.set(i, frameState.ipop()); } @@ -697,18 +679,18 @@ } } - protected abstract T createNewMultiArray(ResolvedJavaType type, List<T> dims); + protected abstract ValueNode createNewMultiArray(ResolvedJavaType type, List<ValueNode> dims); - protected abstract T genLoadField(T receiver, ResolvedJavaField field); + protected abstract ValueNode genLoadField(ValueNode receiver, ResolvedJavaField field); private void genGetField(JavaField field) { emitExplicitExceptions(frameState.peek(0), null); Kind kind = field.getKind(); - T receiver = frameState.apop(); + ValueNode receiver = frameState.apop(); if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getLoadFieldPlugin(); - if (loadFieldPlugin == null || !loadFieldPlugin.apply((GraphBuilderContext) this, (ValueNode) receiver, (ResolvedJavaField) field)) { + if (loadFieldPlugin == null || !loadFieldPlugin.apply((GraphBuilderContext) this, receiver, (ResolvedJavaField) field)) { appendOptimizedLoadField(kind, genLoadField(receiver, (ResolvedJavaField) field)); } } else { @@ -716,15 +698,15 @@ } } - protected abstract void emitNullCheck(T receiver); + protected abstract void emitNullCheck(ValueNode receiver); - protected abstract void emitBoundsCheck(T index, T length); + protected abstract void emitBoundsCheck(ValueNode index, ValueNode length); private static final DebugMetric EXPLICIT_EXCEPTIONS = Debug.metric("ExplicitExceptions"); - protected abstract T genArrayLength(T x); + protected abstract ValueNode genArrayLength(ValueNode x); - protected void emitExplicitExceptions(T receiver, T outOfBoundsIndex) { + protected void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) { assert receiver != null; if (graphBuilderConfig.omitAllExceptionEdges() || profilingInfo == null || (optimisticOpts.useExceptionProbabilityForOperations() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE && !GraalOptions.StressExplicitExceptionCode.getValue())) { @@ -733,19 +715,19 @@ emitNullCheck(receiver); if (outOfBoundsIndex != null) { - T length = append(genArrayLength(receiver)); + ValueNode length = append(genArrayLength(receiver)); emitBoundsCheck(outOfBoundsIndex, length); } EXPLICIT_EXCEPTIONS.increment(); } - protected abstract T genStoreField(T receiver, ResolvedJavaField field, T value); + protected abstract ValueNode genStoreField(ValueNode receiver, ResolvedJavaField field, ValueNode value); private void genPutField(JavaField field) { emitExplicitExceptions(frameState.peek(1), null); - T value = frameState.pop(field.getKind().getStackKind()); - T receiver = frameState.apop(); + ValueNode value = frameState.pop(field.getKind().getStackKind()); + ValueNode receiver = frameState.apop(); if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { appendOptimizedStoreField(genStoreField(receiver, (ResolvedJavaField) field, value)); } else { @@ -766,7 +748,7 @@ } private void genPutStatic(JavaField field) { - T value = frameState.pop(field.getKind().getStackKind()); + ValueNode value = frameState.pop(field.getKind().getStackKind()); if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) { appendOptimizedStoreField(genStoreField(null, (ResolvedJavaField) field, value)); } else { @@ -774,13 +756,13 @@ } } - protected void appendOptimizedStoreField(T store) { + protected void appendOptimizedStoreField(ValueNode store) { append(store); } - protected void appendOptimizedLoadField(Kind kind, T load) { + protected void appendOptimizedLoadField(Kind kind, ValueNode load) { // append the load to the instruction - T optimized = append(load); + ValueNode optimized = append(load); frameState.push(kind.getStackKind(), optimized); } @@ -794,11 +776,11 @@ protected abstract void genInvokeSpecial(JavaMethod target); - protected abstract void genReturn(T x); + protected abstract void genReturn(ValueNode x); - protected abstract T genMonitorEnter(T x); + protected abstract ValueNode genMonitorEnter(ValueNode x); - protected abstract T genMonitorExit(T x, T returnValue); + protected abstract ValueNode genMonitorExit(ValueNode x, ValueNode returnValue); protected abstract void genJsr(int dest); @@ -843,7 +825,7 @@ private void genSwitch(BytecodeSwitch bs) { int bci = bci(); - T value = frameState.ipop(); + ValueNode value = frameState.ipop(); int nofCases = bs.numberOfCases(); double[] keyProbabilities = switchProbability(nofCases + 1, bci); @@ -861,12 +843,13 @@ int[] keySuccessors = new int[nofCases + 1]; int deoptSuccessorIndex = -1; int nextSuccessorIndex = 0; + boolean constantValue = value.isConstant(); for (int i = 0; i < nofCases + 1; i++) { if (i < nofCases) { keys[i] = bs.keyAt(i); } - if (isNeverExecutedCode(keyProbabilities[i])) { + if (!constantValue && isNeverExecutedCode(keyProbabilities[i])) { if (deoptSuccessorIndex < 0) { deoptSuccessorIndex = nextSuccessorIndex++; actualSuccessors.add(null); @@ -887,7 +870,7 @@ } - protected abstract void genIntegerSwitch(T value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors); + protected abstract void genIntegerSwitch(ValueNode value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors); private static class SuccessorInfo { @@ -900,9 +883,9 @@ } } - protected abstract T appendConstant(JavaConstant constant); + protected abstract ValueNode appendConstant(JavaConstant constant); - protected abstract T append(T v); + protected abstract ValueNode append(ValueNode v); protected boolean isNeverExecutedCode(double probability) { return probability == 0 && optimisticOpts.removeNeverExecutedCode(); @@ -1050,9 +1033,9 @@ case BASTORE : genStoreIndexed(Kind.Byte ); break; case CASTORE : genStoreIndexed(Kind.Char ); break; case SASTORE : genStoreIndexed(Kind.Short ); break; - case POP : // fall through - case POP2 : // fall through - case DUP : // fall through + case POP : frameState.xpop(); break; + case POP2 : frameState.xpop(); frameState.xpop(); break; + case DUP : frameState.xpush(frameState.xpeek()); break; case DUP_X1 : // fall through case DUP_X2 : // fall through case DUP2 : // fall through @@ -1181,7 +1164,7 @@ return method; } - public F getFrameState() { + public HIRFrameStateBuilder getFrameState() { return frameState; }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Tue Mar 10 21:26:02 2015 +0100 @@ -86,4 +86,6 @@ } GuardingNode getCurrentBlockGuard(); + + BailoutException bailout(String string); }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.api.replacements.*; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.common.*; @@ -138,13 +137,24 @@ parser.connectLoopEndToBegin(); - // remove dead parameters + // Remove dead parameters. for (ParameterNode param : currentGraph.getNodes(ParameterNode.TYPE)) { if (param.hasNoUsages()) { assert param.inputs().isEmpty(); param.safeDelete(); } } + + // Remove redundant begin nodes. + for (BeginNode beginNode : currentGraph.getNodes(BeginNode.TYPE)) { + Node predecessor = beginNode.predecessor(); + if (predecessor instanceof ControlSplitNode) { + // The begin node is necessary. + } else { + GraphUtil.unlinkFixedNode(beginNode); + beginNode.safeDelete(); + } + } } finally { filter.remove(); } @@ -170,11 +180,11 @@ private static class ExplodedLoopContext { private BciBlock header; - private int targetPeelIteration; + private int[] targetPeelIteration; private int peelIteration; } - public class BytecodeParser extends AbstractBytecodeParser<ValueNode, HIRFrameStateBuilder> implements GraphBuilderContext { + public class BytecodeParser extends AbstractBytecodeParser implements GraphBuilderContext { private BciBlockMapping blockMap; private LocalLiveness liveness; @@ -194,14 +204,16 @@ private FixedWithNextNode lastInstr; // the last instruction added private final boolean explodeLoops; + private final boolean mergeExplosions; + private final Map<HIRFrameStateBuilder, Integer> mergeExplosionsMap; private Stack<ExplodedLoopContext> explodeLoopsContext; private int nextPeelIteration = 1; private boolean controlFlowSplit; private FixedWithNextNode[] firstInstructionArray; - private AbstractFrameStateBuilder<?, ?>[] entryStateArray; + private HIRFrameStateBuilder[] entryStateArray; private FixedWithNextNode[][] firstInstructionMatrix; - private AbstractFrameStateBuilder<?, ?>[][] entryStateMatrix; + private HIRFrameStateBuilder[][] entryStateMatrix; /** * @param isReplacement specifies if this object is being used to parse a method that @@ -222,8 +234,17 @@ LoopExplosionPlugin loopExplosionPlugin = graphBuilderConfig.getLoopExplosionPlugin(); if (loopExplosionPlugin != null) { explodeLoops = loopExplosionPlugin.shouldExplodeLoops(method); + if (explodeLoops) { + mergeExplosions = loopExplosionPlugin.shouldMergeExplosions(method); + mergeExplosionsMap = new HashMap<>(); + } else { + mergeExplosions = false; + mergeExplosionsMap = null; + } } else { explodeLoops = false; + mergeExplosions = false; + mergeExplosionsMap = null; } } @@ -255,7 +276,7 @@ BciBlockMapping newMapping = BciBlockMapping.create(stream, method); this.blockMap = newMapping; this.firstInstructionArray = new FixedWithNextNode[blockMap.getBlockCount()]; - this.entryStateArray = new AbstractFrameStateBuilder<?, ?>[blockMap.getBlockCount()]; + this.entryStateArray = new HIRFrameStateBuilder[blockMap.getBlockCount()]; if (graphBuilderConfig.doLivenessAnalysis()) { try (Scope s = Debug.scope("LivenessAnalysis")) { @@ -274,11 +295,11 @@ if (startInstruction == currentGraph.start()) { StartNode startNode = currentGraph.start(); if (method.isSynchronized()) { - startNode.setStateAfter(frameState.create(BytecodeFrame.BEFORE_BCI)); + startNode.setStateAfter(createFrameState(BytecodeFrame.BEFORE_BCI)); } else { frameState.clearNonLiveLocals(startBlock, liveness, true); assert bci() == 0; - startNode.setStateAfter(frameState.create(bci())); + startNode.setStateAfter(createFrameState(bci())); } } @@ -288,7 +309,7 @@ MonitorEnterNode monitorEnter = genMonitorEnter(methodSynchronizedObject); frameState.clearNonLiveLocals(startBlock, liveness, true); assert bci() == 0; - monitorEnter.setStateAfter(frameState.create(bci())); + monitorEnter.setStateAfter(createFrameState(bci())); } if (graphBuilderConfig.insertNonSafepointDebugInfo()) { @@ -310,12 +331,179 @@ index = iterateBlock(blocks, block); } - if (Debug.isDumpEnabled() && this.beforeReturnNode != startInstruction) { + if (this.mergeExplosions) { + Debug.dump(currentGraph, "Before loop detection"); + detectLoops(startInstruction); + } + + if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue() && this.beforeReturnNode != startInstruction) { Debug.dump(currentGraph, "Bytecodes parsed: " + method.getDeclaringClass().getUnqualifiedName() + "." + method.getName()); } } } + private void detectLoops(FixedNode startInstruction) { + NodeBitMap visited = currentGraph.createNodeBitMap(); + NodeBitMap active = currentGraph.createNodeBitMap(); + Stack<Node> stack = new Stack<>(); + stack.add(startInstruction); + visited.mark(startInstruction); + while (!stack.isEmpty()) { + Node next = stack.peek(); + assert next.isDeleted() || visited.isMarked(next); + if (next.isDeleted() || active.isMarked(next)) { + stack.pop(); + if (!next.isDeleted()) { + active.clear(next); + } + } else { + active.mark(next); + for (Node n : next.cfgSuccessors()) { + if (active.contains(n)) { + // Detected cycle. + assert n instanceof MergeNode; + assert next instanceof EndNode; + MergeNode merge = (MergeNode) n; + EndNode endNode = (EndNode) next; + merge.removeEnd(endNode); + FixedNode afterMerge = merge.next(); + if (!(afterMerge instanceof EndNode) || !(((EndNode) afterMerge).merge() instanceof LoopBeginNode)) { + merge.setNext(null); + LoopBeginNode newLoopBegin = this.appendLoopBegin(merge); + newLoopBegin.setNext(afterMerge); + } + LoopBeginNode loopBegin = (LoopBeginNode) ((EndNode) merge.next()).merge(); + LoopEndNode loopEnd = currentGraph.add(new LoopEndNode(loopBegin)); + endNode.replaceAndDelete(loopEnd); + } else if (visited.contains(n)) { + // Normal merge into a branch we are already exploring. + } else { + visited.mark(n); + stack.push(n); + } + } + } + } + + Debug.dump(currentGraph, "After loops detected"); + insertLoopEnds(startInstruction); + } + + private void insertLoopEnds(FixedNode startInstruction) { + NodeBitMap visited = currentGraph.createNodeBitMap(); + Stack<Node> stack = new Stack<>(); + stack.add(startInstruction); + visited.mark(startInstruction); + List<LoopBeginNode> loopBegins = new ArrayList<>(); + while (!stack.isEmpty()) { + Node next = stack.pop(); + assert visited.isMarked(next); + if (next instanceof LoopBeginNode) { + loopBegins.add((LoopBeginNode) next); + } + for (Node n : next.cfgSuccessors()) { + if (visited.contains(n)) { + // Nothing to do. + } else { + visited.mark(n); + stack.push(n); + } + } + } + + IdentityHashMap<LoopBeginNode, List<LoopBeginNode>> innerLoopsMap = new IdentityHashMap<>(); + for (int i = loopBegins.size() - 1; i >= 0; --i) { + LoopBeginNode loopBegin = loopBegins.get(i); + insertLoopExits(loopBegin, innerLoopsMap); + if (GraalOptions.DumpDuringGraphBuilding.getValue()) { + Debug.dump(currentGraph, "After building loop exits for %s.", loopBegin); + } + } + + // Remove degenerated merges with only one predecessor. + for (LoopBeginNode loopBegin : loopBegins) { + Node pred = loopBegin.forwardEnd().predecessor(); + if (pred instanceof MergeNode) { + MergeNode.removeMergeIfDegenerated((MergeNode) pred); + } + } + } + + private void insertLoopExits(LoopBeginNode loopBegin, IdentityHashMap<LoopBeginNode, List<LoopBeginNode>> innerLoopsMap) { + NodeBitMap visited = currentGraph.createNodeBitMap(); + Stack<Node> stack = new Stack<>(); + for (LoopEndNode loopEnd : loopBegin.loopEnds()) { + stack.push(loopEnd); + visited.mark(loopEnd); + } + + List<ControlSplitNode> controlSplits = new ArrayList<>(); + List<LoopBeginNode> innerLoopBegins = new ArrayList<>(); + + while (!stack.isEmpty()) { + Node current = stack.pop(); + if (current == loopBegin) { + continue; + } + for (Node pred : current.cfgPredecessors()) { + if (!visited.isMarked(pred)) { + visited.mark(pred); + if (pred instanceof LoopExitNode) { + // Inner loop + LoopExitNode loopExitNode = (LoopExitNode) pred; + LoopBeginNode innerLoopBegin = loopExitNode.loopBegin(); + if (!visited.isMarked(innerLoopBegin)) { + stack.push(innerLoopBegin); + visited.mark(innerLoopBegin); + innerLoopBegins.add(innerLoopBegin); + } + } else { + if (pred instanceof ControlSplitNode) { + ControlSplitNode controlSplitNode = (ControlSplitNode) pred; + controlSplits.add(controlSplitNode); + } + stack.push(pred); + } + } + } + } + + for (ControlSplitNode controlSplit : controlSplits) { + for (Node succ : controlSplit.cfgSuccessors()) { + if (!visited.isMarked(succ)) { + LoopExitNode loopExit = currentGraph.add(new LoopExitNode(loopBegin)); + FixedNode next = ((FixedWithNextNode) succ).next(); + next.replaceAtPredecessor(loopExit); + loopExit.setNext(next); + } + } + } + + for (LoopBeginNode inner : innerLoopBegins) { + addLoopExits(loopBegin, inner, innerLoopsMap, visited); + if (GraalOptions.DumpDuringGraphBuilding.getValue()) { + Debug.dump(currentGraph, "After adding loop exits for %s.", inner); + } + } + + innerLoopsMap.put(loopBegin, innerLoopBegins); + } + + private void addLoopExits(LoopBeginNode loopBegin, LoopBeginNode inner, IdentityHashMap<LoopBeginNode, List<LoopBeginNode>> innerLoopsMap, NodeBitMap visited) { + for (LoopExitNode exit : inner.loopExits()) { + if (!visited.isMarked(exit)) { + LoopExitNode newLoopExit = currentGraph.add(new LoopExitNode(loopBegin)); + FixedNode next = exit.next(); + next.replaceAtPredecessor(newLoopExit); + newLoopExit.setNext(next); + } + } + + for (LoopBeginNode innerInner : innerLoopsMap.get(inner)) { + addLoopExits(loopBegin, innerInner, innerLoopsMap, visited); + } + } + private int iterateBlock(BciBlock[] blocks, BciBlock block) { if (block.isLoopHeader && this.explodeLoops) { return iterateExplodedLoopHeader(blocks, block); @@ -333,29 +521,50 @@ ExplodedLoopContext context = new ExplodedLoopContext(); context.header = header; context.peelIteration = this.getCurrentDimension(); - context.targetPeelIteration = -1; + if (this.mergeExplosions) { + this.addToMergeCache(getEntryState(context.header, context.peelIteration), context.peelIteration); + } explodeLoopsContext.push(context); - Debug.dump(currentGraph, "before loop explosion " + context.peelIteration); + if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) { + Debug.dump(currentGraph, "before loop explosion dimension " + context.peelIteration); + } + peelIteration(blocks, header, context); + explodeLoopsContext.pop(); + return header.loopEnd + 1; + } + + private void addToMergeCache(HIRFrameStateBuilder key, int dimension) { + mergeExplosionsMap.put(key, dimension); + } + + private void peelIteration(BciBlock[] blocks, BciBlock header, ExplodedLoopContext context) { while (true) { - processBlock(this, header); - for (int j = header.getId() + 1; j <= header.loopEnd; ++j) { + int j = header.getId() + 1; + while (j <= header.loopEnd) { BciBlock block = blocks[j]; - iterateBlock(blocks, block); + j = iterateBlock(blocks, block); } - if (context.targetPeelIteration != -1) { + int[] targets = context.targetPeelIteration; + if (targets != null) { // We were reaching the backedge during explosion. Explode further. - context.peelIteration = context.targetPeelIteration; - context.targetPeelIteration = -1; + for (int i = 0; i < targets.length; ++i) { + context.peelIteration = targets[i]; + context.targetPeelIteration = null; + if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) { + Debug.dump(currentGraph, "next loop explosion iteration " + context.peelIteration); + } + if (i < targets.length - 1) { + peelIteration(blocks, header, context); + } + } } else { // We did not reach the backedge. Exit. break; } } - explodeLoopsContext.pop(); - return header.loopEnd + 1; } /** @@ -644,8 +853,8 @@ return (ValueNode) currentGraph.unique((Node & ValueNumberable) x); } - protected ValueNode genIfNode(ValueNode condition, ValueNode falseSuccessor, ValueNode trueSuccessor, double d) { - return new IfNode((LogicNode) condition, (FixedNode) falseSuccessor, (FixedNode) trueSuccessor, d); + protected ValueNode genIfNode(LogicNode condition, FixedNode falseSuccessor, FixedNode trueSuccessor, double d) { + return new IfNode(condition, falseSuccessor, trueSuccessor, d); } @Override @@ -700,7 +909,7 @@ append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), exception, falseSucc, 0.01)); lastInstr = falseSucc; - exception.setStateAfter(frameState.create(bci())); + exception.setStateAfter(createFrameState(bci())); exception.setNext(handleException(exception, bci())); } @@ -711,7 +920,7 @@ append(new IfNode(currentGraph.unique(IntegerBelowNode.create(index, length, constantReflection)), trueSucc, exception, 0.99)); lastInstr = trueSucc; - exception.setStateAfter(frameState.create(bci())); + exception.setStateAfter(createFrameState(bci())); exception.setNext(handleException(exception, bci())); } @@ -950,7 +1159,7 @@ HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, checkTypes, () -> { if (lazyFrameState[0] == null) { - lazyFrameState[0] = frameState.create(bci()); + lazyFrameState[0] = createFrameState(bci()); } return lazyFrameState[0]; }); @@ -970,15 +1179,6 @@ if (calleeBeforeUnwindNode != null) { ValueNode calleeUnwindValue = parser.getUnwindValue(); assert calleeUnwindValue != null; - if (calleeBeforeUnwindNode instanceof AbstractMergeNode) { - AbstractMergeNode mergeNode = (AbstractMergeNode) calleeBeforeUnwindNode; - HIRFrameStateBuilder dispatchState = frameState.copy(); - dispatchState.clearStack(); - dispatchState.apush(calleeUnwindValue); - dispatchState.setRethrowException(true); - mergeNode.setStateAfter(dispatchState.create(bci())); - - } calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci())); } @@ -1002,7 +1202,7 @@ DispatchBeginNode exceptionEdge = handleException(null, bci()); InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci())); frameState.pushReturn(resultType, invoke); - invoke.setStateAfter(frameState.create(stream.nextBCI())); + invoke.setStateAfter(createFrameState(stream.nextBCI())); return invoke; } @@ -1040,7 +1240,7 @@ synchronizedEpilogue(BytecodeFrame.AFTER_BCI, x); if (frameState.lockDepth() != 0) { - throw new BailoutException("unbalanced monitors"); + throw bailout("unbalanced monitors"); } } @@ -1057,7 +1257,7 @@ MonitorIdNode monitorId = frameState.peekMonitorId(); ValueNode lockedObject = frameState.popLock(); if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) { - throw new BailoutException("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject)); + throw bailout(String.format("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject))); } MonitorExitNode monitorExit = append(new MonitorExitNode(x, monitorId, escapedReturnValue)); return monitorExit; @@ -1105,11 +1305,23 @@ @Override protected void genIntegerSwitch(ValueNode value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) { - this.controlFlowSplit = true; - double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); - IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); - for (int i = 0; i < actualSuccessors.size(); i++) { - switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState)); + if (value.isConstant()) { + JavaConstant constant = (JavaConstant) value.asConstant(); + int constantValue = constant.asInt(); + for (int i = 0; i < keys.length; ++i) { + if (keys[i] == constantValue) { + appendGoto(actualSuccessors.get(keySuccessors[i])); + return; + } + } + appendGoto(actualSuccessors.get(keySuccessors[keys.length])); + } else { + this.controlFlowSplit = true; + double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); + IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); + for (int i = 0; i < actualSuccessors.size(); i++) { + switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState)); + } } } @@ -1218,7 +1430,7 @@ } lastLoopExit = loopExit; Debug.log("Target %s Exits %s, scanning framestates...", targetBlock, loop); - newState.insertLoopProxies(loopExit, (HIRFrameStateBuilder) getEntryState(loop, this.getCurrentDimension())); + newState.insertLoopProxies(loopExit, getEntryState(loop, this.getCurrentDimension())); loopExit.setStateAfter(newState.create(bci)); } @@ -1229,7 +1441,7 @@ return new Target(target, state); } - private AbstractFrameStateBuilder<?, ?> getEntryState(BciBlock block, int dimension) { + private HIRFrameStateBuilder getEntryState(BciBlock block, int dimension) { int id = block.id; if (dimension == 0) { return entryStateArray[id]; @@ -1238,9 +1450,9 @@ } } - private AbstractFrameStateBuilder<?, ?> getEntryStateMultiDimension(int dimension, int id) { + private HIRFrameStateBuilder getEntryStateMultiDimension(int dimension, int id) { if (entryStateMatrix != null && dimension - 1 < entryStateMatrix.length) { - AbstractFrameStateBuilder<?, ?>[] entryStateArrayEntry = entryStateMatrix[dimension - 1]; + HIRFrameStateBuilder[] entryStateArrayEntry = entryStateMatrix[dimension - 1]; if (entryStateArrayEntry == null) { return null; } @@ -1250,7 +1462,7 @@ } } - private void setEntryState(BciBlock block, int dimension, AbstractFrameStateBuilder<?, ?> entryState) { + private void setEntryState(BciBlock block, int dimension, HIRFrameStateBuilder entryState) { int id = block.id; if (dimension == 0) { this.entryStateArray[id] = entryState; @@ -1259,9 +1471,9 @@ } } - private void setEntryStateMultiDimension(int dimension, AbstractFrameStateBuilder<?, ?> entryState, int id) { + private void setEntryStateMultiDimension(int dimension, HIRFrameStateBuilder entryState, int id) { if (entryStateMatrix == null) { - entryStateMatrix = new AbstractFrameStateBuilder<?, ?>[4][]; + entryStateMatrix = new HIRFrameStateBuilder[4][]; } if (dimension - 1 < entryStateMatrix.length) { // We are within bounds. @@ -1270,7 +1482,7 @@ entryStateMatrix = Arrays.copyOf(entryStateMatrix, Math.max(entryStateMatrix.length * 2, dimension)); } if (entryStateMatrix[dimension - 1] == null) { - entryStateMatrix[dimension - 1] = new AbstractFrameStateBuilder<?, ?>[blockMap.getBlockCount()]; + entryStateMatrix[dimension - 1] = new HIRFrameStateBuilder[blockMap.getBlockCount()]; } entryStateMatrix[dimension - 1][id] = entryState; } @@ -1332,14 +1544,14 @@ } private FixedNode createTarget(BciBlock block, HIRFrameStateBuilder state) { - return createTarget(block, state, false); + return createTarget(block, state, false, false); } - private FixedNode createTarget(BciBlock block, HIRFrameStateBuilder state, boolean isGoto) { + private FixedNode createTarget(BciBlock block, HIRFrameStateBuilder state, boolean canReuseInstruction, boolean canReuseState) { assert block != null && state != null; assert !block.isExceptionEntry || state.stackSize() == 1; - int operatingDimension = findOperatingDimension(block); + int operatingDimension = findOperatingDimension(block, state); if (getFirstInstruction(block, operatingDimension) == null) { /* @@ -1348,7 +1560,7 @@ * this block again. */ FixedNode targetNode; - if (isGoto && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader && (currentBlock.loops & ~block.loops) == 0) { + if (canReuseInstruction && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader && (currentBlock.loops & ~block.loops) == 0) { setFirstInstruction(block, operatingDimension, lastInstr); lastInstr = null; } else { @@ -1357,7 +1569,7 @@ targetNode = getFirstInstruction(block, operatingDimension); Target target = checkLoopExit(targetNode, block, state); FixedNode result = target.fixed; - AbstractFrameStateBuilder<?, ?> currentEntryState = target.state == state ? state.copy() : target.state; + HIRFrameStateBuilder currentEntryState = target.state == state ? (canReuseState ? state : state.copy()) : target.state; setEntryState(block, operatingDimension, currentEntryState); currentEntryState.clearNonLiveLocals(block, liveness, true); @@ -1366,8 +1578,8 @@ } // We already saw this block before, so we have to merge states. - if (!((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).isCompatibleWith(state)) { - throw new BailoutException("stacks do not match; bytecodes would not verify"); + if (!getEntryState(block, operatingDimension).isCompatibleWith(state)) { + throw bailout("stacks do not match; bytecodes would not verify"); } if (getFirstInstruction(block, operatingDimension) instanceof LoopBeginNode) { @@ -1379,33 +1591,32 @@ LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block, operatingDimension); Target target = checkLoopExit(currentGraph.add(new LoopEndNode(loopBegin)), block, state); FixedNode result = target.fixed; - ((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).merge(loopBegin, target.state); + getEntryState(block, operatingDimension).merge(loopBegin, target.state); Debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result); return result; } - assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch"; - assert getFirstInstruction(block, operatingDimension).next() == null : "bytecodes already parsed for block"; + assert currentBlock == null || currentBlock.getId() < block.getId() || this.mergeExplosions : "must not be backward branch"; + assert getFirstInstruction(block, operatingDimension).next() == null || this.mergeExplosions : "bytecodes already parsed for block"; if (getFirstInstruction(block, operatingDimension) instanceof AbstractBeginNode && !(getFirstInstruction(block, operatingDimension) instanceof AbstractMergeNode)) { /* * This is the second time we see this block. Create the actual MergeNode and - * the End Node for the already existing edge. For simplicity, we leave the - * placeholder in the graph and just append the new nodes after the placeholder. + * the End Node for the already existing edge. */ - AbstractBeginNode placeholder = (AbstractBeginNode) getFirstInstruction(block, operatingDimension); + AbstractBeginNode beginNode = (AbstractBeginNode) getFirstInstruction(block, operatingDimension); // The EndNode for the already existing edge. - AbstractEndNode end = currentGraph.add(new EndNode()); + EndNode end = currentGraph.add(new EndNode()); // The MergeNode that replaces the placeholder. AbstractMergeNode mergeNode = currentGraph.add(new MergeNode()); - FixedNode next = placeholder.next(); + FixedNode next = beginNode.next(); - if (placeholder.predecessor() instanceof ControlSplitNode) { - placeholder.setNext(end); + if (beginNode.predecessor() instanceof ControlSplitNode) { + beginNode.setNext(end); } else { - placeholder.replaceAtPredecessor(end); - placeholder.safeDelete(); + beginNode.replaceAtPredecessor(end); + beginNode.safeDelete(); } mergeNode.addForwardEnd(end); @@ -1417,42 +1628,62 @@ AbstractMergeNode mergeNode = (AbstractMergeNode) getFirstInstruction(block, operatingDimension); // The EndNode for the newly merged edge. - AbstractEndNode newEnd = currentGraph.add(new EndNode()); + EndNode newEnd = currentGraph.add(new EndNode()); Target target = checkLoopExit(newEnd, block, state); FixedNode result = target.fixed; - ((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).merge(mergeNode, target.state); + getEntryState(block, operatingDimension).merge(mergeNode, target.state); mergeNode.addForwardEnd(newEnd); Debug.log("createTarget %s: merging state, result: %s", block, result); return result; } - private int findOperatingDimension(BciBlock block) { + private int findOperatingDimension(BciBlock block, HIRFrameStateBuilder state) { if (this.explodeLoops && this.explodeLoopsContext != null && !this.explodeLoopsContext.isEmpty()) { - return findOperatingDimensionWithLoopExplosion(block); + return findOperatingDimensionWithLoopExplosion(block, state); } return this.getCurrentDimension(); } - private int findOperatingDimensionWithLoopExplosion(BciBlock block) { + private int findOperatingDimensionWithLoopExplosion(BciBlock block, HIRFrameStateBuilder state) { int i; for (i = explodeLoopsContext.size() - 1; i >= 0; --i) { ExplodedLoopContext context = explodeLoopsContext.elementAt(i); if (context.header == block) { + if (this.mergeExplosions) { + state.clearNonLiveLocals(block, liveness, true); + Integer cachedDimension = mergeExplosionsMap.get(state); + if (cachedDimension != null) { + return cachedDimension; + } + } + // We have a hit on our current explosion context loop begin. - if (context.targetPeelIteration == -1) { - // This is the first hit => allocate a new dimension and at the same - // time mark the context loop begin as hit during the current - // iteration. - context.targetPeelIteration = nextPeelIteration++; - if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) { - throw new BailoutException("too many loop explosion interations - does the explosion not terminate?"); + if (context.targetPeelIteration == null) { + context.targetPeelIteration = new int[1]; + } else { + context.targetPeelIteration = Arrays.copyOf(context.targetPeelIteration, context.targetPeelIteration.length + 1); + } + + // This is the first hit => allocate a new dimension and at the same + // time mark the context loop begin as hit during the current + // iteration. + if (this.mergeExplosions) { + this.addToMergeCache(state, nextPeelIteration); + } + context.targetPeelIteration[context.targetPeelIteration.length - 1] = nextPeelIteration++; + if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) { + String message = "too many loop explosion interations - does the explosion not terminate for method " + method + "?"; + if (FailedLoopExplosionIsFatal.getValue()) { + throw new RuntimeException(message); + } else { + throw bailout(message); } } // Operate on the target dimension. - return context.targetPeelIteration; + return context.targetPeelIteration[context.targetPeelIteration.length - 1]; } else if (block.getId() > context.header.getId() && block.getId() <= context.header.loopEnd) { // We hit the range of this context. return context.peelIteration; @@ -1486,45 +1717,27 @@ protected void processBlock(BytecodeParser parser, BciBlock block) { // Ignore blocks that have no predecessors by the time their bytecodes are parsed - if (block == null || getFirstInstruction(block, this.getCurrentDimension()) == null) { + int currentDimension = this.getCurrentDimension(); + FixedWithNextNode firstInstruction = getFirstInstruction(block, currentDimension); + if (firstInstruction == null) { Debug.log("Ignoring block %s", block); return; } - try (Indent indent = Debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, getFirstInstruction(block, this.getCurrentDimension()), block.isLoopHeader)) { + try (Indent indent = Debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, firstInstruction, block.isLoopHeader)) { - lastInstr = getFirstInstruction(block, this.getCurrentDimension()); - frameState = (HIRFrameStateBuilder) getEntryState(block, this.getCurrentDimension()); + lastInstr = firstInstruction; + frameState = getEntryState(block, currentDimension); parser.setCurrentFrameState(frameState); currentBlock = block; - if (lastInstr instanceof AbstractMergeNode) { - - AbstractMergeNode abstractMergeNode = (AbstractMergeNode) lastInstr; - if (abstractMergeNode.stateAfter() == null) { - int bci = block.startBci; - if (block instanceof ExceptionDispatchBlock) { - bci = ((ExceptionDispatchBlock) block).deoptBci; - } - abstractMergeNode.setStateAfter(frameState.create(bci)); - } + if (firstInstruction instanceof AbstractMergeNode) { + setMergeStateAfter(block, firstInstruction); } if (block == blockMap.getReturnBlock()) { - Kind returnKind = method.getSignature().getReturnKind().getStackKind(); - ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind); - assert frameState.stackSize() == 0; - beforeReturn(x); - this.returnValue = x; - this.beforeReturnNode = this.lastInstr; + handleReturnBlock(); } else if (block == blockMap.getUnwindBlock()) { - if (parent == null) { - frameState.setRethrowException(false); - createUnwind(); - } else { - ValueNode exception = frameState.apop(); - this.unwindValue = exception; - this.beforeUnwindNode = this.lastInstr; - } + handleUnwindBlock(); } else if (block instanceof ExceptionDispatchBlock) { createExceptionDispatch((ExceptionDispatchBlock) block); } else { @@ -1534,6 +1747,37 @@ } } + private void handleUnwindBlock() { + if (parent == null) { + frameState.setRethrowException(false); + createUnwind(); + } else { + ValueNode exception = frameState.apop(); + this.unwindValue = exception; + this.beforeUnwindNode = this.lastInstr; + } + } + + private void handleReturnBlock() { + Kind returnKind = method.getSignature().getReturnKind().getStackKind(); + ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind); + assert frameState.stackSize() == 0; + beforeReturn(x); + this.returnValue = x; + this.beforeReturnNode = this.lastInstr; + } + + private void setMergeStateAfter(BciBlock block, FixedWithNextNode firstInstruction) { + AbstractMergeNode abstractMergeNode = (AbstractMergeNode) firstInstruction; + if (abstractMergeNode.stateAfter() == null) { + int bci = block.startBci; + if (block instanceof ExceptionDispatchBlock) { + bci = ((ExceptionDispatchBlock) block).deoptBci; + } + abstractMergeNode.setStateAfter(createFrameState(bci)); + } + } + /** * Remove loop header without loop ends. This can happen with degenerated loops like * this one: @@ -1571,7 +1815,7 @@ if (currentReturnValue != null) { frameState.push(currentReturnValue.getKind(), currentReturnValue); } - monitorExit.setStateAfter(frameState.create(bci)); + monitorExit.setStateAfter(createFrameState(bci)); assert !frameState.rethrowException(); } } @@ -1621,7 +1865,7 @@ } private void appendGoto(BciBlock successor) { - FixedNode targetInstr = createTarget(successor, frameState, true); + FixedNode targetInstr = createTarget(successor, frameState, true, true); if (lastInstr != null && lastInstr != targetInstr) { lastInstr.setNext(targetInstr); } @@ -1637,16 +1881,12 @@ // Create the loop header block, which later will merge the backward branches of // the loop. controlFlowSplit = true; - AbstractEndNode preLoopEnd = currentGraph.add(new EndNode()); - LoopBeginNode loopBegin = currentGraph.add(new LoopBeginNode()); - lastInstr.setNext(preLoopEnd); - // Add the single non-loop predecessor of the loop header. - loopBegin.addForwardEnd(preLoopEnd); + LoopBeginNode loopBegin = appendLoopBegin(this.lastInstr); lastInstr = loopBegin; // Create phi functions for all local variables and operand stack slots. frameState.insertLoopPhis(liveness, block.loopId, loopBegin); - loopBegin.setStateAfter(frameState.create(block.startBci)); + loopBegin.setStateAfter(createFrameState(block.startBci)); /* * We have seen all forward branches. All subsequent backward branches will @@ -1661,6 +1901,8 @@ setEntryState(block, this.getCurrentDimension(), frameState.copy()); Debug.log(" created loop header %s", loopBegin); + } else if (block.isLoopHeader && explodeLoops && this.mergeExplosions) { + frameState = frameState.copy(); } assert lastInstr.next() == null : "instructions already appended at block " + block; Debug.log(" frameState: %s", frameState); @@ -1692,7 +1934,7 @@ } EntryMarkerNode x = append(new EntryMarkerNode()); frameState.insertProxies(x); - x.setStateAfter(frameState.create(bci)); + x.setStateAfter(createFrameState(bci)); } processBytecode(bci, opcode); @@ -1712,7 +1954,7 @@ } else { StateSplit stateSplit = (StateSplit) lastInstr; if (stateSplit.stateAfter() == null) { - stateSplit.setStateAfter(frameState.create(bci)); + stateSplit.setStateAfter(createFrameState(bci)); } } } @@ -1729,6 +1971,15 @@ } } + private LoopBeginNode appendLoopBegin(FixedWithNextNode fixedWithNext) { + EndNode preLoopEnd = currentGraph.add(new EndNode()); + LoopBeginNode loopBegin = currentGraph.add(new LoopBeginNode()); + fixedWithNext.setNext(preLoopEnd); + // Add the single non-loop predecessor of the loop header. + loopBegin.addForwardEnd(preLoopEnd); + return loopBegin; + } + /** * A hook for derived classes to modify the last instruction or add other instructions. * @@ -1742,7 +1993,7 @@ private InfopointNode createInfoPointNode(InfopointReason reason) { if (graphBuilderConfig.insertFullDebugInfo()) { - return new FullInfopointNode(reason, frameState.create(bci())); + return new FullInfopointNode(reason, createFrameState(bci())); } else { return new SimpleInfopointNode(reason, new BytecodePosition(null, method, bci())); } @@ -1773,17 +2024,107 @@ BciBlock trueBlock = currentBlock.getSuccessor(0); BciBlock falseBlock = currentBlock.getSuccessor(1); if (trueBlock == falseBlock) { + // The target block is the same independent of the condition. appendGoto(trueBlock); return; } - // the mirroring and negation operations get the condition into canonical form - boolean mirror = cond.canonicalMirror(); + ValueNode a = x; + ValueNode b = y; + + // Check whether the condition needs to mirror the operands. + if (cond.canonicalMirror()) { + a = y; + b = x; + } + + // Create the logic node for the condition. + LogicNode condition = createLogicNode(cond, a, b); + + // Check whether the condition needs to negate the result. boolean negate = cond.canonicalNegate(); - ValueNode a = mirror ? y : x; - ValueNode b = mirror ? x : y; + // Remove a logic negation node and fold it into the negate boolean. + if (condition instanceof LogicNegationNode) { + LogicNegationNode logicNegationNode = (LogicNegationNode) condition; + negate = !negate; + condition = logicNegationNode.getValue(); + } + + if (condition instanceof LogicConstantNode) { + genConstantTargetIf(trueBlock, falseBlock, negate, condition); + } else { + if (condition.graph() == null) { + condition = currentGraph.unique(condition); + } + + // Need to get probability based on current bci. + double probability = branchProbability(); + + if (negate) { + BciBlock tmpBlock = trueBlock; + trueBlock = falseBlock; + falseBlock = tmpBlock; + probability = 1 - probability; + } + + if (isNeverExecutedCode(probability)) { + append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true)); + appendGoto(falseBlock); + return; + } else if (isNeverExecutedCode(1 - probability)) { + append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false)); + appendGoto(trueBlock); + return; + } + int oldBci = stream.currentBCI(); + int trueBlockInt = checkPositiveIntConstantPushed(trueBlock); + if (trueBlockInt != -1) { + int falseBlockInt = checkPositiveIntConstantPushed(falseBlock); + if (falseBlockInt != -1) { + if (tryGenConditionalForIf(trueBlock, falseBlock, condition, oldBci, trueBlockInt, falseBlockInt)) { + return; + } + } + } + + this.controlFlowSplit = true; + FixedNode trueSuccessor = createTarget(trueBlock, frameState, false, false); + FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, true); + ValueNode ifNode = genIfNode(condition, trueSuccessor, falseSuccessor, probability); + append(ifNode); + } + } + + private boolean tryGenConditionalForIf(BciBlock trueBlock, BciBlock falseBlock, LogicNode condition, int oldBci, int trueBlockInt, int falseBlockInt) { + if (gotoOrFallThroughAfterConstant(trueBlock) && gotoOrFallThroughAfterConstant(falseBlock) && trueBlock.getSuccessor(0) == falseBlock.getSuccessor(0)) { + genConditionalForIf(trueBlock, condition, oldBci, trueBlockInt, falseBlockInt, false); + return true; + } else if (this.parent != null && returnAfterConstant(trueBlock) && returnAfterConstant(falseBlock)) { + genConditionalForIf(trueBlock, condition, oldBci, trueBlockInt, falseBlockInt, true); + return true; + } + return false; + } + + private void genConditionalForIf(BciBlock trueBlock, LogicNode condition, int oldBci, int trueBlockInt, int falseBlockInt, boolean genReturn) { + ConstantNode trueValue = currentGraph.unique(ConstantNode.forInt(trueBlockInt)); + ConstantNode falseValue = currentGraph.unique(ConstantNode.forInt(falseBlockInt)); + ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue); + if (conditionalNode.graph() == null) { + conditionalNode = currentGraph.addOrUnique(conditionalNode); + } + if (genReturn) { + this.genReturn(conditionalNode); + } else { + frameState.push(Kind.Int, conditionalNode); + appendGoto(trueBlock.getSuccessor(0)); + stream.setBCI(oldBci); + } + } + + private LogicNode createLogicNode(Condition cond, ValueNode a, ValueNode b) { LogicNode condition; assert !a.getKind().isNumericFloat(); if (cond == Condition.EQ || cond == Condition.NE) { @@ -1796,80 +2137,20 @@ assert a.getKind() != Kind.Object && !cond.isUnsigned(); condition = genIntegerLessThan(a, b); } - - if (condition instanceof LogicNegationNode) { - LogicNegationNode logicNegationNode = (LogicNegationNode) condition; - negate = !negate; - condition = logicNegationNode.getValue(); - } - - if (condition instanceof LogicConstantNode) { - LogicConstantNode constantLogicNode = (LogicConstantNode) condition; - boolean value = constantLogicNode.getValue(); - if (negate) { - value = !value; - } - BciBlock nextBlock = falseBlock; - if (value) { - nextBlock = trueBlock; - } - appendGoto(nextBlock); - } else { - - if (condition.graph() == null) { - condition = currentGraph.unique(condition); - } - - // Need to get probability based on current bci. - double probability = branchProbability(); - - int oldBci = stream.currentBCI(); - int trueBlockInt = checkPositiveIntConstantPushed(trueBlock); - if (trueBlockInt != -1) { - int falseBlockInt = checkPositiveIntConstantPushed(falseBlock); - if (falseBlockInt != -1) { + return condition; + } - boolean genReturn = false; - boolean genConditional = false; - if (gotoOrFallThroughAfterConstant(trueBlock) && gotoOrFallThroughAfterConstant(falseBlock) && trueBlock.getSuccessor(0) == falseBlock.getSuccessor(0)) { - genConditional = true; - } else if (parent != null && returnAfterConstant(trueBlock) && returnAfterConstant(falseBlock)) { - genReturn = true; - genConditional = true; - } - - if (genConditional) { - ConstantNode trueValue = currentGraph.unique(ConstantNode.forInt(trueBlockInt)); - ConstantNode falseValue = currentGraph.unique(ConstantNode.forInt(falseBlockInt)); - if (negate) { - ConstantNode tmp = falseValue; - falseValue = trueValue; - trueValue = tmp; - } - ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue); - if (conditionalNode.graph() == null) { - conditionalNode = currentGraph.addOrUnique(conditionalNode); - } - if (genReturn) { - this.genReturn(conditionalNode); - } else { - frameState.push(Kind.Int, conditionalNode); - appendGoto(trueBlock.getSuccessor(0)); - stream.setBCI(oldBci); - } - return; - } - } - } - - this.controlFlowSplit = true; - - ValueNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState); - ValueNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState); - - ValueNode ifNode = negate ? genIfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : genIfNode(condition, trueSuccessor, falseSuccessor, probability); - append(ifNode); + private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, boolean negate, LogicNode condition) { + LogicConstantNode constantLogicNode = (LogicConstantNode) condition; + boolean value = constantLogicNode.getValue(); + if (negate) { + value = !value; } + BciBlock nextBlock = falseBlock; + if (value) { + nextBlock = trueBlock; + } + appendGoto(nextBlock); } private int checkPositiveIntConstantPushed(BciBlock block) { @@ -1967,6 +2248,17 @@ } return fmt.toString(); } + + public BailoutException bailout(String string) { + FrameState currentFrameState = createFrameState(bci()); + StackTraceElement[] elements = GraphUtil.approxSourceStackTraceElement(currentFrameState); + BailoutException bailout = new BailoutException(string); + throw GraphUtil.createBailoutException(string, bailout, elements); + } + + private FrameState createFrameState(int bci) { + return frameState.create(bci); + } } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Tue Mar 10 21:26:02 2015 +0100 @@ -80,6 +80,8 @@ public interface LoopExplosionPlugin extends GraphBuilderPlugin { boolean shouldExplodeLoops(ResolvedJavaMethod method); + + boolean shouldMergeExplosions(ResolvedJavaMethod method); } public interface ParameterPlugin extends GraphBuilderPlugin {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -31,6 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; +import com.oracle.graal.java.BciBlockMapping.*; import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -38,11 +39,27 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.util.*; -public class HIRFrameStateBuilder extends AbstractFrameStateBuilder<ValueNode, HIRFrameStateBuilder> { +public final class HIRFrameStateBuilder { private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0]; private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0]; + protected final ResolvedJavaMethod method; + protected int stackSize; + protected final ValueNode[] locals; + protected final ValueNode[] stack; + protected ValueNode[] lockedObjects; + + /** + * Specifies if asserting type checks are enabled. + */ + protected final boolean checkTypes; + + /** + * @see BytecodeFrame#rethrowException + */ + protected boolean rethrowException; + private MonitorIdNode[] monitorIds; private final StructuredGraph graph; private final Supplier<FrameState> outerFrameStateSupplier; @@ -54,7 +71,11 @@ * @param graph the target graph of Graal nodes created by the builder */ public HIRFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, boolean checkTypes, Supplier<FrameState> outerFrameStateSupplier) { - super(method, checkTypes); + this.method = method; + this.locals = allocateArray(method.getMaxLocals()); + this.stack = allocateArray(Math.max(1, method.getMaxStackSize())); + this.lockedObjects = allocateArray(0); + this.checkTypes = checkTypes; assert graph != null; @@ -63,7 +84,7 @@ this.outerFrameStateSupplier = outerFrameStateSupplier; } - public final void initializeFromArgumentsArray(ValueNode[] arguments) { + public void initializeFromArgumentsArray(ValueNode[] arguments) { int javaIndex = 0; int index = 0; @@ -82,7 +103,7 @@ } } - public final void initializeForMethodStart(boolean eagerResolve, ParameterPlugin parameterPlugin) { + public void initializeForMethodStart(boolean eagerResolve, ParameterPlugin parameterPlugin) { int javaIndex = 0; int index = 0; @@ -128,7 +149,17 @@ } private HIRFrameStateBuilder(HIRFrameStateBuilder other) { - super(other); + this.method = other.method; + this.stackSize = other.stackSize; + this.locals = other.locals.clone(); + this.stack = other.stack.clone(); + this.lockedObjects = other.lockedObjects.length == 0 ? other.lockedObjects : other.lockedObjects.clone(); + this.rethrowException = other.rethrowException; + this.checkTypes = other.checkTypes; + + assert locals.length == method.getMaxLocals(); + assert stack.length == Math.max(1, method.getMaxStackSize()); + assert other.graph != null; graph = other.graph; monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone(); @@ -139,8 +170,7 @@ assert lockedObjects.length == monitorIds.length; } - @Override - protected ValueNode[] allocateArray(int length) { + private static ValueNode[] allocateArray(int length) { return length == 0 ? EMPTY_ARRAY : new ValueNode[length]; } @@ -171,16 +201,18 @@ FrameState outerFrameState = null; if (outerFrameStateSupplier != null) { outerFrameState = outerFrameStateSupplier.get(); + if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) { + FrameState newFrameState = outerFrameState.duplicateModified(outerFrameState.bci, true, Kind.Void, this.peek(0)); + return newFrameState; + } } return graph.add(new FrameState(outerFrameState, method, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, false)); } - @Override public HIRFrameStateBuilder copy() { return new HIRFrameStateBuilder(this); } - @Override public boolean isCompatibleWith(HIRFrameStateBuilder other) { assert method.equals(other.method) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method"; assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds"; @@ -210,10 +242,18 @@ assert isCompatibleWith(other); for (int i = 0; i < localsSize(); i++) { - storeLocal(i, merge(localAt(i), other.localAt(i), block)); + ValueNode curLocal = localAt(i); + ValueNode mergedLocal = merge(curLocal, other.localAt(i), block); + if (curLocal != mergedLocal) { + storeLocal(i, mergedLocal); + } } for (int i = 0; i < stackSize(); i++) { - storeStack(i, merge(stackAt(i), other.stackAt(i), block)); + ValueNode curStack = stackAt(i); + ValueNode mergedStack = merge(curStack, other.stackAt(i), block); + if (curStack != mergedStack) { + storeStack(i, mergedStack); + } } for (int i = 0; i < lockedObjects.length; i++) { lockedObjects[i] = merge(lockedObjects[i], other.lockedObjects[i], block); @@ -224,7 +264,6 @@ private ValueNode merge(ValueNode currentValue, ValueNode otherValue, AbstractMergeNode block) { if (currentValue == null || currentValue.isDeleted()) { return null; - } else if (block.isPhiAtMerge(currentValue)) { if (otherValue == null || otherValue.isDeleted() || currentValue.getKind() != otherValue.getKind()) { propagateDelete((ValuePhiNode) currentValue); @@ -232,26 +271,27 @@ } ((PhiNode) currentValue).addInput(otherValue); return currentValue; - } else if (currentValue != otherValue) { assert !(block instanceof LoopBeginNode) : "Phi functions for loop headers are create eagerly for changed locals and all stack slots"; if (otherValue == null || otherValue.isDeleted() || currentValue.getKind() != otherValue.getKind()) { return null; } - - ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp().unrestricted(), block)); - for (int i = 0; i < block.phiPredecessorCount(); i++) { - phi.addInput(currentValue); - } - phi.addInput(otherValue); - assert phi.valueCount() == block.phiPredecessorCount() + 1 : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPredecessorCount(); - return phi; - + return createValuePhi(currentValue, otherValue, block); } else { return currentValue; } } + private ValuePhiNode createValuePhi(ValueNode currentValue, ValueNode otherValue, AbstractMergeNode block) { + ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp().unrestricted(), block)); + for (int i = 0; i < block.phiPredecessorCount(); i++) { + phi.addInput(currentValue); + } + phi.addInput(otherValue); + assert phi.valueCount() == block.phiPredecessorCount() + 1; + return phi; + } + private void propagateDelete(FloatingNode node) { assert node instanceof ValuePhiNode || node instanceof ProxyNode; if (node.isDeleted()) { @@ -380,7 +420,6 @@ /** * @return the current lock depth */ - @Override public int lockDepth() { assert lockedObjects.length == monitorIds.length; return lockedObjects.length; @@ -405,4 +444,490 @@ } return false; } + + public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) { + /* + * (lstadler) if somebody is tempted to remove/disable this clearing code: it's possible to + * remove it for normal compilations, but not for OSR compilations - otherwise dead object + * slots at the OSR entry aren't cleared. it is also not enough to rely on PiNodes with + * Kind.Illegal, because the conflicting branch might not have been parsed. + */ + if (liveness == null) { + return; + } + if (liveIn) { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveIn(block, i)) { + locals[i] = null; + } + } + } else { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveOut(block, i)) { + locals[i] = null; + } + } + } + } + + /** + * @see BytecodeFrame#rethrowException + */ + public boolean rethrowException() { + return rethrowException; + } + + /** + * @see BytecodeFrame#rethrowException + */ + public void setRethrowException(boolean b) { + rethrowException = b; + } + + /** + * Returns the size of the local variables. + * + * @return the size of the local variables + */ + public int localsSize() { + return locals.length; + } + + /** + * Gets the current size (height) of the stack. + */ + public int stackSize() { + return stackSize; + } + + /** + * Gets the value in the local variables at the specified index, without any sanity checking. + * + * @param i the index into the locals + * @return the instruction that produced the value for the specified local + */ + public ValueNode localAt(int i) { + return locals[i]; + } + + /** + * Get the value on the stack at the specified stack index. + * + * @param i the index into the stack, with {@code 0} being the bottom of the stack + * @return the instruction at the specified position in the stack + */ + public ValueNode stackAt(int i) { + return stack[i]; + } + + /** + * Gets the value in the lock at the specified index, without any sanity checking. + * + * @param i the index into the lock + * @return the instruction that produced the value for the specified lock + */ + public ValueNode lockAt(int i) { + return lockedObjects[i]; + } + + public void storeLock(int i, ValueNode lock) { + lockedObjects[i] = lock; + } + + /** + * Loads the local variable at the specified index, checking that the returned value is non-null + * and that two-stack values are properly handled. + * + * @param i the index of the local variable to load + * @return the instruction that produced the specified local + */ + public ValueNode loadLocal(int i) { + ValueNode x = locals[i]; + assert assertLoadLocal(i, x); + return x; + } + + private boolean assertLoadLocal(int i, ValueNode x) { + assert x != null : i; + assert !checkTypes || (x.getKind().getSlotCount() == 1 || locals[i + 1] == null); + assert !checkTypes || (i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1); + return true; + } + + /** + * Stores a given local variable at the specified index. If the value occupies two slots, then + * the next local variable index is also overwritten. + * + * @param i the index at which to store + * @param x the instruction which produces the value for the local + */ + public void storeLocal(int i, ValueNode x) { + assert assertStoreLocal(x); + locals[i] = x; + if (x != null && x.getKind().needsTwoSlots()) { + // if this is a double word, then kill i+1 + locals[i + 1] = null; + } + if (x != null && i > 0) { + ValueNode p = locals[i - 1]; + if (p != null && p.getKind().needsTwoSlots()) { + // if there was a double word at i - 1, then kill it + locals[i - 1] = null; + } + } + } + + private boolean assertStoreLocal(ValueNode x) { + assert x == null || !checkTypes || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal) : "unexpected value: " + x; + return true; + } + + public void storeStack(int i, ValueNode x) { + assert assertStoreStack(i, x); + stack[i] = x; + } + + private boolean assertStoreStack(int i, ValueNode x) { + assert x == null || (stack[i] == null || x.getKind() == stack[i].getKind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; + return true; + } + + /** + * Pushes an instruction onto the stack with the expected type. + * + * @param kind the type expected for this instruction + * @param x the instruction to push onto the stack + */ + public void push(Kind kind, ValueNode x) { + assert assertPush(kind, x); + xpush(x); + if (kind.needsTwoSlots()) { + xpush(null); + } + } + + private boolean assertPush(Kind kind, ValueNode x) { + assert !checkTypes || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal); + assert x != null && (!checkTypes || x.getKind() == kind); + return true; + } + + /** + * Pushes a value onto the stack without checking the type. + * + * @param x the instruction to push onto the stack + */ + public void xpush(ValueNode x) { + assert assertXpush(x); + stack[stackSize++] = x; + } + + private boolean assertXpush(ValueNode x) { + assert !checkTypes || (x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal)); + return true; + } + + /** + * Pushes a value onto the stack and checks that it is an int. + * + * @param x the instruction to push onto the stack + */ + public void ipush(ValueNode x) { + assert assertInt(x); + xpush(x); + } + + /** + * Pushes a value onto the stack and checks that it is a float. + * + * @param x the instruction to push onto the stack + */ + public void fpush(ValueNode x) { + assert assertFloat(x); + xpush(x); + } + + /** + * Pushes a value onto the stack and checks that it is an object. + * + * @param x the instruction to push onto the stack + */ + public void apush(ValueNode x) { + assert assertObject(x); + xpush(x); + } + + /** + * Pushes a value onto the stack and checks that it is a long. + * + * @param x the instruction to push onto the stack + */ + public void lpush(ValueNode x) { + assert assertLong(x); + xpush(x); + xpush(null); + } + + /** + * Pushes a value onto the stack and checks that it is a double. + * + * @param x the instruction to push onto the stack + */ + public void dpush(ValueNode x) { + assert assertDouble(x); + xpush(x); + xpush(null); + } + + public void pushReturn(Kind kind, ValueNode x) { + if (kind != Kind.Void) { + push(kind.getStackKind(), x); + } + } + + /** + * Pops an instruction off the stack with the expected type. + * + * @param kind the expected type + * @return the instruction on the top of the stack + */ + public ValueNode pop(Kind kind) { + if (kind.needsTwoSlots()) { + xpop(); + } + assert assertPop(kind); + return xpop(); + } + + private boolean assertPop(Kind kind) { + assert kind != Kind.Void; + ValueNode x = xpeek(); + assert x != null && (!checkTypes || x.getKind() == kind); + return true; + } + + /** + * Pops a value off of the stack without checking the type. + * + * @return x the instruction popped off the stack + */ + public ValueNode xpop() { + return stack[--stackSize]; + } + + public ValueNode xpeek() { + return stack[stackSize - 1]; + } + + /** + * Pops a value off of the stack and checks that it is an int. + * + * @return x the instruction popped off the stack + */ + public ValueNode ipop() { + assert assertIntPeek(); + return xpop(); + } + + /** + * Pops a value off of the stack and checks that it is a float. + * + * @return x the instruction popped off the stack + */ + public ValueNode fpop() { + assert assertFloatPeek(); + return xpop(); + } + + /** + * Pops a value off of the stack and checks that it is an object. + * + * @return x the instruction popped off the stack + */ + public ValueNode apop() { + assert assertObjectPeek(); + return xpop(); + } + + /** + * Pops a value off of the stack and checks that it is a long. + * + * @return x the instruction popped off the stack + */ + public ValueNode lpop() { + assert assertHighPeek(); + xpop(); + assert assertLongPeek(); + return xpop(); + } + + /** + * Pops a value off of the stack and checks that it is a double. + * + * @return x the instruction popped off the stack + */ + public ValueNode dpop() { + assert assertHighPeek(); + xpop(); + assert assertDoublePeek(); + return xpop(); + } + + /** + * Pop the specified number of slots off of this stack and return them as an array of + * instructions. + * + * @return an array containing the arguments off of the stack + */ + public ValueNode[] popArguments(int argSize) { + ValueNode[] result = allocateArray(argSize); + int newStackSize = stackSize; + for (int i = argSize - 1; i >= 0; i--) { + newStackSize--; + if (stack[newStackSize] == null) { + /* Two-slot value. */ + newStackSize--; + assert stack[newStackSize].getKind().needsTwoSlots(); + } else { + assert !checkTypes || (stack[newStackSize].getKind().getSlotCount() == 1); + } + result[i] = stack[newStackSize]; + } + stackSize = newStackSize; + return result; + } + + /** + * Peeks an element from the operand stack. + * + * @param argumentNumber The number of the argument, relative from the top of the stack (0 = + * top). Long and double arguments only count as one argument, i.e., null-slots are + * ignored. + * @return The peeked argument. + */ + public ValueNode peek(int argumentNumber) { + int idx = stackSize() - 1; + for (int i = 0; i < argumentNumber; i++) { + if (stackAt(idx) == null) { + idx--; + assert stackAt(idx).getKind().needsTwoSlots(); + } + idx--; + } + return stackAt(idx); + } + + /** + * Clears all values on this stack. + */ + public void clearStack() { + stackSize = 0; + } + + private boolean assertLongPeek() { + return assertLong(xpeek()); + } + + private static boolean assertLong(ValueNode x) { + assert x != null && (x.getKind() == Kind.Long); + return true; + } + + private boolean assertIntPeek() { + return assertInt(xpeek()); + } + + private static boolean assertInt(ValueNode x) { + assert x != null && (x.getKind() == Kind.Int); + return true; + } + + private boolean assertFloatPeek() { + return assertFloat(xpeek()); + } + + private static boolean assertFloat(ValueNode x) { + assert x != null && (x.getKind() == Kind.Float); + return true; + } + + private boolean assertObjectPeek() { + return assertObject(xpeek()); + } + + private boolean assertObject(ValueNode x) { + assert x != null && (!checkTypes || (x.getKind() == Kind.Object)); + return true; + } + + private boolean assertDoublePeek() { + return assertDouble(xpeek()); + } + + private static boolean assertDouble(ValueNode x) { + assert x != null && (x.getKind() == Kind.Double); + return true; + } + + private boolean assertHighPeek() { + assert xpeek() == null; + return true; + } + + @Override + public int hashCode() { + int result = hashCode(locals, locals.length); + result *= 13; + result += hashCode(stack, this.stackSize); + return result; + } + + private static int hashCode(Object[] a, int length) { + int result = 1; + for (int i = 0; i < length; ++i) { + Object element = a[i]; + result = 31 * result + (element == null ? 0 : System.identityHashCode(element)); + } + return result; + } + + private static boolean equals(ValueNode[] a, ValueNode[] b, int length) { + for (int i = 0; i < length; ++i) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + @Override + public boolean equals(Object otherObject) { + if (otherObject instanceof HIRFrameStateBuilder) { + HIRFrameStateBuilder other = (HIRFrameStateBuilder) otherObject; + if (!other.method.equals(method)) { + return false; + } + if (other.stackSize != stackSize) { + return false; + } + if (other.checkTypes != checkTypes) { + return false; + } + if (other.rethrowException != rethrowException) { + return false; + } + if (other.graph != graph) { + return false; + } + if (other.outerFrameStateSupplier != outerFrameStateSupplier) { + return false; + } + if (other.locals.length != locals.length) { + return false; + } + return equals(other.locals, locals, locals.length) && equals(other.stack, stack, stackSize) && equals(other.lockedObjects, lockedObjects, lockedObjects.length) && + equals(other.monitorIds, monitorIds, monitorIds.length); + } + return false; + } }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/UntrustedInterfaces.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/UntrustedInterfaces.java Tue Mar 10 21:26:02 2015 +0100 @@ -45,20 +45,20 @@ * public void setField() { * field = new TestConstant(); * } - * + * * public void setStaticField() { * staticField = new TestConstant(); * } - * + * * public int callMe(CallBack callback) { * return callback.callBack(new TestConstant()); * } - * + * * public TestInterface get() { * return new TestConstant(); * } * } - * + * * private static final class TestConstant implements TestInterface { * public int method() { * return 42;
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6753639.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6753639.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ * @test * @bug 6753639 * @summary Strange optimisation in for loop with cyclic integer condition - * + * * @run main/othervm -Xbatch Test6753639 */ // @formatter:off
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/LongToSomethingArray01.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/LongToSomethingArray01.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ /** * inspired by java.security.SecureRandom.longToByteArray(long). - * + * */ public class LongToSomethingArray01 extends JTTTest {
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/NestedLoop_EA.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,7 +26,6 @@ import org.junit.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.jtt.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.virtual.*; @@ -41,7 +40,7 @@ protected Suites createSuites() { Suites suites = super.createSuites(); ListIterator<BasePhase<? super HighTierContext>> position = suites.getHighTier().findPhase(PartialEscapePhase.class); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!GraalOptions.ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); // incremental canonicalizer of PEA is missing some important canonicalization (TODO?) position.add(canonicalizer); position.add(new PartialEscapePhase(true, canonicalizer));
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,6 +33,7 @@ import com.oracle.graal.lir.LIRInstruction.OperandFlag; public final class AMD64AddressValue extends CompositeValue { + public static final CompositeValueClass<AMD64AddressValue> TYPE = CompositeValueClass.create(AMD64AddressValue.class); private static final long serialVersionUID = -4444600052487578694L; @@ -46,7 +47,7 @@ } public AMD64AddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index, Scale scale, int displacement) { - super(kind); + super(TYPE, kind); this.base = base; this.index = index; this.scale = scale;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Tue Mar 10 21:26:02 2015 +0100 @@ -63,13 +63,15 @@ /** * Unary operation with separate source and destination operand. */ - public static class Unary2Op extends AMD64LIRInstruction { + public static final class Unary2Op extends AMD64LIRInstruction { + public static final LIRInstructionClass<Unary2Op> TYPE = LIRInstructionClass.create(Unary2Op.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG}) protected AllocatableValue result; @Use({REG, STACK}) protected AllocatableValue x; public Unary2Op(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -84,13 +86,15 @@ /** * Unary operation with separate source and destination operand but register only. */ - public static class Unary2RegOp extends AMD64LIRInstruction { + public static final class Unary2RegOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<Unary2RegOp> TYPE = LIRInstructionClass.create(Unary2RegOp.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue x; public Unary2RegOp(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -106,12 +110,14 @@ * Unary operation with single operand for source and destination. */ public static class Unary1Op extends AMD64LIRInstruction { + public static final LIRInstructionClass<Unary1Op> TYPE = LIRInstructionClass.create(Unary1Op.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG, STACK}) protected AllocatableValue x; public Unary1Op(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -127,13 +133,14 @@ /** * Unary operation with separate memory source and destination operand. */ - public static class Unary2MemoryOp extends MemOp { + public static final class Unary2MemoryOp extends MemOp { + public static final LIRInstructionClass<Unary2MemoryOp> TYPE = LIRInstructionClass.create(Unary2MemoryOp.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG}) protected AllocatableValue result; public Unary2MemoryOp(AMD64Arithmetic opcode, AllocatableValue result, Kind kind, AMD64AddressValue address, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.opcode = opcode; this.result = result; } @@ -149,6 +156,7 @@ * destination. The second source operand may be a stack slot. */ public static class BinaryRegStack extends AMD64LIRInstruction { + public static final LIRInstructionClass<BinaryRegStack> TYPE = LIRInstructionClass.create(BinaryRegStack.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @@ -156,6 +164,7 @@ @Alive({REG, STACK}) protected AllocatableValue y; public BinaryRegStack(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -180,7 +189,8 @@ * Binary operation with two operands. The first source operand is combined with the * destination. The second source operand may be a stack slot. */ - public static class BinaryMemory extends AMD64LIRInstruction { + public static final class BinaryMemory extends AMD64LIRInstruction { + public static final LIRInstructionClass<BinaryMemory> TYPE = LIRInstructionClass.create(BinaryMemory.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @@ -190,6 +200,7 @@ @State protected LIRFrameState state; public BinaryMemory(AMD64Arithmetic opcode, Kind kind, AllocatableValue result, AllocatableValue x, AMD64AddressValue location, LIRFrameState state) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -219,7 +230,8 @@ * Binary operation with two operands. The first source operand is combined with the * destination. The second source operand must be a register. */ - public static class BinaryRegReg extends AMD64LIRInstruction { + public static final class BinaryRegReg extends AMD64LIRInstruction { + public static final LIRInstructionClass<BinaryRegReg> TYPE = LIRInstructionClass.create(BinaryRegReg.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @@ -227,6 +239,7 @@ @Alive({REG}) protected AllocatableValue y; public BinaryRegReg(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -250,7 +263,8 @@ /** * Binary operation with single source/destination operand and one constant. */ - public static class BinaryRegConst extends AMD64LIRInstruction { + public static final class BinaryRegConst extends AMD64LIRInstruction { + public static final LIRInstructionClass<BinaryRegConst> TYPE = LIRInstructionClass.create(BinaryRegConst.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @@ -258,6 +272,7 @@ protected JavaConstant y; public BinaryRegConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, JavaConstant y) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -281,7 +296,8 @@ * Commutative binary operation with two operands. One of the operands is combined with the * result. */ - public static class BinaryCommutative extends AMD64LIRInstruction { + public static final class BinaryCommutative extends AMD64LIRInstruction { + public static final LIRInstructionClass<BinaryCommutative> TYPE = LIRInstructionClass.create(BinaryCommutative.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @@ -289,6 +305,7 @@ @Use({REG, STACK}) protected AllocatableValue y; public BinaryCommutative(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -315,7 +332,8 @@ /** * Binary operation with separate source and destination and one constant operand. */ - public static class BinaryRegStackConst extends AMD64LIRInstruction { + public static final class BinaryRegStackConst extends AMD64LIRInstruction { + public static final LIRInstructionClass<BinaryRegStackConst> TYPE = LIRInstructionClass.create(BinaryRegStackConst.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG}) protected AllocatableValue result; @@ -323,6 +341,7 @@ protected JavaConstant y; public BinaryRegStackConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, JavaConstant y) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -364,7 +383,8 @@ } } - public static class MulHighOp extends AMD64LIRInstruction { + public static final class MulHighOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<MulHighOp> TYPE = LIRInstructionClass.create(MulHighOp.class); @Opcode private final AMD64Arithmetic opcode; @Def({REG}) public AllocatableValue lowResult; @@ -373,6 +393,7 @@ @Use({REG, STACK}) public AllocatableValue y; public MulHighOp(AMD64Arithmetic opcode, LIRKind kind, AllocatableValue y) { + super(TYPE); this.opcode = opcode; this.x = AMD64.rax.asValue(kind); this.y = y; @@ -420,7 +441,8 @@ } } - public static class DivRemOp extends AMD64LIRInstruction { + public static final class DivRemOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<DivRemOp> TYPE = LIRInstructionClass.create(DivRemOp.class); @Opcode private final AMD64Arithmetic opcode; @Def public AllocatableValue divResult; @@ -430,6 +452,7 @@ @State protected LIRFrameState state; public DivRemOp(AMD64Arithmetic opcode, AllocatableValue x, AllocatableValue y, LIRFrameState state) { + super(TYPE); this.opcode = opcode; this.divResult = AMD64.rax.asValue(LIRKind.derive(x, y)); this.remResult = AMD64.rdx.asValue(LIRKind.derive(x, y)); @@ -456,6 +479,7 @@ } public static class FPDivRemOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<FPDivRemOp> TYPE = LIRInstructionClass.create(FPDivRemOp.class); @Opcode private final AMD64Arithmetic opcode; @Def protected AllocatableValue result; @@ -464,6 +488,7 @@ @Temp protected AllocatableValue raxTemp; public FPDivRemOp(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y) { + super(TYPE); this.opcode = opcode; this.result = result; this.raxTemp = AMD64.rax.asValue(LIRKind.value(Kind.Int));
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArrayEqualsOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ArrayEqualsOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -45,7 +45,8 @@ * instructions specialized code is emitted to leverage these instructions. */ @Opcode("ARRAY_EQUALS") -public class AMD64ArrayEqualsOp extends AMD64LIRInstruction { +public final class AMD64ArrayEqualsOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64ArrayEqualsOp> TYPE = LIRInstructionClass.create(AMD64ArrayEqualsOp.class); private final Kind kind; private final int arrayBaseOffset; @@ -63,6 +64,7 @@ @Temp({REG, ILLEGAL}) protected Value vectorTemp2; public AMD64ArrayEqualsOp(LIRGeneratorTool tool, Kind kind, Value result, Value array1, Value array2, Value length) { + super(TYPE); this.kind = kind; Class<?> arrayClass = Array.newInstance(kind.toJavaClass(), 0).getClass();
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,8 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -public class AMD64BitManipulationOp extends AMD64LIRInstruction { +public final class AMD64BitManipulationOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64BitManipulationOp> TYPE = LIRInstructionClass.create(AMD64BitManipulationOp.class); public enum IntrinsicOpcode { IPOPCNT, @@ -47,6 +48,7 @@ @Use({OperandFlag.REG, OperandFlag.STACK}) protected AllocatableValue input; public AMD64BitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input) { + super(TYPE); this.opcode = opcode; this.result = result; this.input = input;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -33,7 +33,8 @@ * Emits a breakpoint. */ @Opcode("BREAKPOINT") -public class AMD64BreakpointOp extends AMD64LIRInstruction { +public final class AMD64BreakpointOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64BreakpointOp> TYPE = LIRInstructionClass.create(AMD64BreakpointOp.class); /** * A set of values loaded into the Java ABI parameter locations (for inspection by a debugger). @@ -41,6 +42,7 @@ @Use({REG, STACK}) protected Value[] parameters; public AMD64BreakpointOp(Value[] parameters) { + super(TYPE); this.parameters = parameters; }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -29,12 +29,14 @@ import com.oracle.graal.lir.asm.*; @Opcode("BSWAP") -public class AMD64ByteSwapOp extends AMD64LIRInstruction { +public final class AMD64ByteSwapOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64ByteSwapOp> TYPE = LIRInstructionClass.create(AMD64ByteSwapOp.class); @Def({OperandFlag.REG, OperandFlag.HINT}) protected Value result; @Use protected Value input; public AMD64ByteSwapOp(Value result, Value input) { + super(TYPE); this.result = result; this.input = input; }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CCall.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CCall.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -27,9 +27,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -public class AMD64CCall extends AMD64LIRInstruction { +public final class AMD64CCall extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64CCall> TYPE = LIRInstructionClass.create(AMD64CCall.class); @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @@ -37,6 +39,7 @@ @Use({REG}) protected Value numberOfFloatingPointArguments; public AMD64CCall(Value result, Value functionPtr, Value numberOfFloatingPointArguments, Value[] parameters) { + super(TYPE); this.result = result; this.functionPtr = functionPtr; this.parameters = parameters;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,13 +36,15 @@ public class AMD64Call { public abstract static class CallOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<CallOp> TYPE = LIRInstructionClass.create(CallOp.class); @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @Temp protected Value[] temps; @State protected LIRFrameState state; - public CallOp(Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + protected CallOp(LIRInstructionClass<? extends CallOp> c, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c); this.result = result; this.parameters = parameters; this.state = state; @@ -57,21 +59,23 @@ } public abstract static class MethodCallOp extends CallOp { + public static final LIRInstructionClass<MethodCallOp> TYPE = LIRInstructionClass.create(MethodCallOp.class); protected final ResolvedJavaMethod callTarget; - public MethodCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(result, parameters, temps, state); + protected MethodCallOp(LIRInstructionClass<? extends MethodCallOp> c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, result, parameters, temps, state); this.callTarget = callTarget; } } @Opcode("CALL_DIRECT") - public static class DirectCallOp extends MethodCallOp { + public abstract static class DirectCallOp extends MethodCallOp { + public static final LIRInstructionClass<DirectCallOp> TYPE = LIRInstructionClass.create(DirectCallOp.class); - public DirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(callTarget, result, parameters, temps, state); + protected DirectCallOp(LIRInstructionClass<? extends DirectCallOp> c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, callTarget, result, parameters, temps, state); } @Override @@ -82,11 +86,17 @@ @Opcode("CALL_INDIRECT") public static class IndirectCallOp extends MethodCallOp { + public static final LIRInstructionClass<IndirectCallOp> TYPE = LIRInstructionClass.create(IndirectCallOp.class); @Use({REG}) protected Value targetAddress; public IndirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value targetAddress, LIRFrameState state) { - super(callTarget, result, parameters, temps, state); + this(TYPE, callTarget, result, parameters, temps, targetAddress, state); + } + + protected IndirectCallOp(LIRInstructionClass<? extends IndirectCallOp> c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value targetAddress, + LIRFrameState state) { + super(c, callTarget, result, parameters, temps, state); this.targetAddress = targetAddress; } @@ -103,11 +113,12 @@ } public abstract static class ForeignCallOp extends CallOp { + public static final LIRInstructionClass<ForeignCallOp> TYPE = LIRInstructionClass.create(ForeignCallOp.class); protected final ForeignCallLinkage callTarget; - public ForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(result, parameters, temps, state); + public ForeignCallOp(LIRInstructionClass<? extends ForeignCallOp> c, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, result, parameters, temps, state); this.callTarget = callTarget; } @@ -118,10 +129,11 @@ } @Opcode("NEAR_FOREIGN_CALL") - public static class DirectNearForeignCallOp extends ForeignCallOp { + public static final class DirectNearForeignCallOp extends ForeignCallOp { + public static final LIRInstructionClass<DirectNearForeignCallOp> TYPE = LIRInstructionClass.create(DirectNearForeignCallOp.class); public DirectNearForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(linkage, result, parameters, temps, state); + super(TYPE, linkage, result, parameters, temps, state); } @Override @@ -131,12 +143,13 @@ } @Opcode("FAR_FOREIGN_CALL") - public static class DirectFarForeignCallOp extends ForeignCallOp { + public static final class DirectFarForeignCallOp extends ForeignCallOp { + public static final LIRInstructionClass<DirectFarForeignCallOp> TYPE = LIRInstructionClass.create(DirectFarForeignCallOp.class); @Temp({REG}) protected AllocatableValue callTemp; public DirectFarForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(callTarget, result, parameters, temps, state); + super(TYPE, callTarget, result, parameters, temps, state); /* * The register allocator does not support virtual registers that are used at the call * site, so use a fixed register.
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,12 +42,14 @@ FCMP, DCMP; - public static class CompareOp extends AMD64LIRInstruction { + public static final class CompareOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<CompareOp> TYPE = LIRInstructionClass.create(CompareOp.class); @Opcode private final AMD64Compare opcode; @Use({REG}) protected Value x; @Use({REG, STACK, CONST}) protected Value y; public CompareOp(AMD64Compare opcode, Value x, Value y) { + super(TYPE); this.opcode = opcode; this.x = x; this.y = y; @@ -70,7 +72,8 @@ } } - public static class CompareMemoryOp extends MemOp { + public static final class CompareMemoryOp extends MemOp { + public static final LIRInstructionClass<CompareMemoryOp> TYPE = LIRInstructionClass.create(CompareMemoryOp.class); @Opcode private final AMD64Compare opcode; @Use({REG, CONST}) protected Value y; @@ -78,7 +81,7 @@ * Compare memory, constant or register, memory. */ public CompareMemoryOp(AMD64Compare opcode, Kind kind, AMD64AddressValue address, Value y, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.opcode = opcode; this.y = y; }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,14 +38,17 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure; +import com.oracle.graal.lir.amd64.AMD64Call.CallOp; import com.oracle.graal.lir.asm.*; public class AMD64ControlFlow { - public static class ReturnOp extends AMD64LIRInstruction implements BlockEndOp { + public static final class ReturnOp extends AMD64LIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<CallOp> TYPE = LIRInstructionClass.create(CallOp.class); @Use({REG, ILLEGAL}) protected Value x; public ReturnOp(Value x) { + super(TYPE); this.x = x; } @@ -57,6 +60,7 @@ } public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp { + public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class); protected final ConditionFlag condition; protected final LabelRef trueDestination; protected final LabelRef falseDestination; @@ -68,6 +72,11 @@ } public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) { + this(TYPE, condition, trueDestination, falseDestination, trueDestinationProbability); + } + + protected BranchOp(LIRInstructionClass<? extends BranchOp> c, ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) { + super(c); this.condition = condition; this.trueDestination = trueDestination; this.falseDestination = falseDestination; @@ -102,11 +111,12 @@ } } - public static class FloatBranchOp extends BranchOp { + public static final class FloatBranchOp extends BranchOp { + public static final LIRInstructionClass<FloatBranchOp> TYPE = LIRInstructionClass.create(FloatBranchOp.class); protected boolean unorderedIsTrue; public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) { - super(floatCond(condition), trueDestination, falseDestination, trueDestinationProbability); + super(TYPE, floatCond(condition), trueDestination, falseDestination, trueDestinationProbability); this.unorderedIsTrue = unorderedIsTrue; } @@ -116,7 +126,8 @@ } } - public static class StrategySwitchOp extends AMD64LIRInstruction implements BlockEndOp { + public static final class StrategySwitchOp extends AMD64LIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class); @Use({CONST}) protected JavaConstant[] keyConstants; private final LabelRef[] keyTargets; private LabelRef defaultTarget; @@ -125,6 +136,7 @@ private final SwitchStrategy strategy; public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { + super(TYPE); this.strategy = strategy; this.keyConstants = strategy.keyConstants; this.keyTargets = keyTargets; @@ -170,7 +182,8 @@ } } - public static class TableSwitchOp extends AMD64LIRInstruction implements BlockEndOp { + public static final class TableSwitchOp extends AMD64LIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class); private final int lowKey; private final LabelRef defaultTarget; private final LabelRef[] targets; @@ -179,6 +192,7 @@ @Temp protected Value scratch; public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Value index, Variable scratch, Variable idxScratch) { + super(TYPE); this.lowKey = lowKey; this.defaultTarget = defaultTarget; this.targets = targets; @@ -254,13 +268,15 @@ } @Opcode("CMOVE") - public static class CondMoveOp extends AMD64LIRInstruction { + public static final class CondMoveOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<CondMoveOp> TYPE = LIRInstructionClass.create(CondMoveOp.class); @Def({REG, HINT}) protected Value result; @Alive({REG}) protected Value trueValue; @Use({REG, STACK, CONST}) protected Value falseValue; private final ConditionFlag condition; public CondMoveOp(Variable result, Condition condition, AllocatableValue trueValue, Value falseValue) { + super(TYPE); this.result = result; this.condition = intCond(condition); this.trueValue = trueValue; @@ -274,7 +290,8 @@ } @Opcode("CMOVE") - public static class FloatCondMoveOp extends AMD64LIRInstruction { + public static final class FloatCondMoveOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<FloatCondMoveOp> TYPE = LIRInstructionClass.create(FloatCondMoveOp.class); @Def({REG}) protected Value result; @Alive({REG}) protected Value trueValue; @Alive({REG}) protected Value falseValue; @@ -282,6 +299,7 @@ private final boolean unorderedIsTrue; public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) { + super(TYPE); this.result = result; this.condition = floatCond(condition); this.unorderedIsTrue = unorderedIsTrue;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ * * <pre> * Base Contents - * + * * : : ----- * caller | incoming overflow argument n | ^ * frame : ... : | positive
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64LIRInstruction.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64LIRInstruction.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,12 @@ /** * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method. */ -public abstract class AMD64LIRInstruction extends LIRInstructionBase { +public abstract class AMD64LIRInstruction extends LIRInstruction { + public static final LIRInstructionClass<AMD64LIRInstruction> TYPE = LIRInstructionClass.create(AMD64LIRInstruction.class); + + protected AMD64LIRInstruction(LIRInstructionClass<? extends AMD64LIRInstruction> c) { + super(c); + } @Override public final void emitCode(CompilationResultBuilder crb) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -31,7 +31,8 @@ import com.oracle.graal.lir.asm.*; // @formatter:off -public class AMD64MathIntrinsicOp extends AMD64LIRInstruction { +public final class AMD64MathIntrinsicOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64MathIntrinsicOp> TYPE = LIRInstructionClass.create(AMD64MathIntrinsicOp.class); public enum IntrinsicOpcode { SIN, COS, TAN, LOG, LOG10 @@ -42,6 +43,7 @@ @Use protected Value input; public AMD64MathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) { + super(TYPE); this.opcode = opcode; this.result = result; this.input = input;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -42,10 +42,12 @@ public class AMD64Move { private abstract static class AbstractMoveOp extends AMD64LIRInstruction implements MoveOp { + public static final LIRInstructionClass<AbstractMoveOp> TYPE = LIRInstructionClass.create(AbstractMoveOp.class); private Kind moveKind; - public AbstractMoveOp(Kind moveKind) { + protected AbstractMoveOp(LIRInstructionClass<? extends AbstractMoveOp> c, Kind moveKind) { + super(c); if (moveKind == Kind.Illegal) { // unknown operand size, conservatively move the whole register this.moveKind = Kind.Long; @@ -61,13 +63,14 @@ } @Opcode("MOVE") - public static class MoveToRegOp extends AbstractMoveOp { + public static final class MoveToRegOp extends AbstractMoveOp { + public static final LIRInstructionClass<MoveToRegOp> TYPE = LIRInstructionClass.create(MoveToRegOp.class); @Def({REG, HINT}) protected AllocatableValue result; @Use({REG, STACK, CONST}) protected Value input; public MoveToRegOp(Kind moveKind, AllocatableValue result, Value input) { - super(moveKind); + super(TYPE, moveKind); this.result = result; this.input = input; } @@ -84,13 +87,14 @@ } @Opcode("MOVE") - public static class MoveFromRegOp extends AbstractMoveOp { + public static final class MoveFromRegOp extends AbstractMoveOp { + public static final LIRInstructionClass<MoveFromRegOp> TYPE = LIRInstructionClass.create(MoveFromRegOp.class); @Def({REG, STACK}) protected AllocatableValue result; @Use({REG, CONST, HINT}) protected Value input; public MoveFromRegOp(Kind moveKind, AllocatableValue result, Value input) { - super(moveKind); + super(TYPE, moveKind); this.result = result; this.input = input; } @@ -107,12 +111,14 @@ } public abstract static class MemOp extends AMD64LIRInstruction implements ImplicitNullCheck { + public static final LIRInstructionClass<MemOp> TYPE = LIRInstructionClass.create(MemOp.class); protected final Kind kind; @Use({COMPOSITE}) protected AMD64AddressValue address; @State protected LIRFrameState state; - public MemOp(Kind kind, AMD64AddressValue address, LIRFrameState state) { + public MemOp(LIRInstructionClass<? extends MemOp> c, Kind kind, AMD64AddressValue address, LIRFrameState state) { + super(c); this.kind = kind; this.address = address; this.state = state; @@ -137,12 +143,13 @@ } } - public static class LoadOp extends MemOp { + public static final class LoadOp extends MemOp { + public static final LIRInstructionClass<LoadOp> TYPE = LIRInstructionClass.create(LoadOp.class); @Def({REG}) protected AllocatableValue result; public LoadOp(Kind kind, AllocatableValue result, AMD64AddressValue address, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.result = result; } @@ -182,12 +189,13 @@ } } - public static class ZeroExtendLoadOp extends MemOp { + public static final class ZeroExtendLoadOp extends MemOp { + public static final LIRInstructionClass<ZeroExtendLoadOp> TYPE = LIRInstructionClass.create(ZeroExtendLoadOp.class); @Def({REG}) protected AllocatableValue result; public ZeroExtendLoadOp(Kind kind, AllocatableValue result, AMD64AddressValue address, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.result = result; } @@ -214,12 +222,13 @@ } } - public static class StoreOp extends MemOp { + public static final class StoreOp extends MemOp { + public static final LIRInstructionClass<StoreOp> TYPE = LIRInstructionClass.create(StoreOp.class); @Use({REG}) protected AllocatableValue input; public StoreOp(Kind kind, AMD64AddressValue address, AllocatableValue input, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.input = input; } @@ -256,12 +265,13 @@ } } - public static class StoreConstantOp extends MemOp { + public abstract static class StoreConstantOp extends MemOp { + public static final LIRInstructionClass<StoreConstantOp> TYPE = LIRInstructionClass.create(StoreConstantOp.class); protected final JavaConstant input; - public StoreConstantOp(Kind kind, AMD64AddressValue address, JavaConstant input, LIRFrameState state) { - super(kind, address, state); + protected StoreConstantOp(LIRInstructionClass<? extends StoreConstantOp> c, Kind kind, AMD64AddressValue address, JavaConstant input, LIRFrameState state) { + super(c, kind, address, state); this.input = input; } @@ -304,12 +314,14 @@ } } - public static class LeaOp extends AMD64LIRInstruction { + public static final class LeaOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<LeaOp> TYPE = LIRInstructionClass.create(LeaOp.class); @Def({REG}) protected AllocatableValue result; @Use({COMPOSITE, UNINITIALIZED}) protected AMD64AddressValue address; public LeaOp(AllocatableValue result, AMD64AddressValue address) { + super(TYPE); this.result = result; this.address = address; } @@ -320,12 +332,14 @@ } } - public static class LeaDataOp extends AMD64LIRInstruction { + public static final class LeaDataOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<LeaDataOp> TYPE = LIRInstructionClass.create(LeaDataOp.class); @Def({REG}) protected AllocatableValue result; private final byte[] data; public LeaDataOp(AllocatableValue result, byte[] data) { + super(TYPE); this.result = result; this.data = data; } @@ -336,12 +350,14 @@ } } - public static class StackLeaOp extends AMD64LIRInstruction { + public static final class StackLeaOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<StackLeaOp> TYPE = LIRInstructionClass.create(StackLeaOp.class); @Def({REG}) protected AllocatableValue result; @Use({STACK, UNINITIALIZED}) protected StackSlotValue slot; public StackLeaOp(AllocatableValue result, StackSlotValue slot) { + super(TYPE); assert isStackSlotValue(slot) : "Not a stack slot: " + slot; this.result = result; this.slot = slot; @@ -353,11 +369,13 @@ } } - public static class MembarOp extends AMD64LIRInstruction { + public static final class MembarOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<MembarOp> TYPE = LIRInstructionClass.create(MembarOp.class); private final int barriers; public MembarOp(final int barriers) { + super(TYPE); this.barriers = barriers; } @@ -367,12 +385,14 @@ } } - public static class NullCheckOp extends AMD64LIRInstruction implements NullCheck { + public static final class NullCheckOp extends AMD64LIRInstruction implements NullCheck { + public static final LIRInstructionClass<NullCheckOp> TYPE = LIRInstructionClass.create(NullCheckOp.class); @Use({REG}) protected AllocatableValue input; @State protected LIRFrameState state; public NullCheckOp(Variable input, LIRFrameState state) { + super(TYPE); this.input = input; this.state = state; } @@ -393,7 +413,8 @@ } @Opcode("CAS") - public static class CompareAndSwapOp extends AMD64LIRInstruction { + public static final class CompareAndSwapOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<CompareAndSwapOp> TYPE = LIRInstructionClass.create(CompareAndSwapOp.class); private final Kind accessKind; @@ -403,6 +424,7 @@ @Use protected AllocatableValue newValue; public CompareAndSwapOp(Kind accessKind, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + super(TYPE); this.accessKind = accessKind; this.result = result; this.address = address; @@ -432,7 +454,8 @@ } @Opcode("ATOMIC_READ_AND_ADD") - public static class AtomicReadAndAddOp extends AMD64LIRInstruction { + public static final class AtomicReadAndAddOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AtomicReadAndAddOp> TYPE = LIRInstructionClass.create(AtomicReadAndAddOp.class); private final Kind accessKind; @@ -441,6 +464,7 @@ @Use protected AllocatableValue delta; public AtomicReadAndAddOp(Kind accessKind, AllocatableValue result, AMD64AddressValue address, AllocatableValue delta) { + super(TYPE); this.accessKind = accessKind; this.result = result; this.address = address; @@ -467,7 +491,8 @@ } @Opcode("ATOMIC_READ_AND_WRITE") - public static class AtomicReadAndWriteOp extends AMD64LIRInstruction { + public static final class AtomicReadAndWriteOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AtomicReadAndWriteOp> TYPE = LIRInstructionClass.create(AtomicReadAndWriteOp.class); private final Kind accessKind; @@ -476,6 +501,7 @@ @Use protected AllocatableValue newValue; public AtomicReadAndWriteOp(Kind accessKind, AllocatableValue result, AMD64AddressValue address, AllocatableValue newValue) { + super(TYPE); this.accessKind = accessKind; this.result = result; this.address = address;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -37,6 +37,7 @@ */ @Opcode("RESTORE_REGISTER") public class AMD64RestoreRegistersOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64RestoreRegistersOp> TYPE = LIRInstructionClass.create(AMD64RestoreRegistersOp.class); /** * The slots from which the registers are restored. @@ -49,6 +50,11 @@ private final AMD64SaveRegistersOp save; public AMD64RestoreRegistersOp(StackSlotValue[] values, AMD64SaveRegistersOp save) { + this(TYPE, values, save); + } + + protected AMD64RestoreRegistersOp(LIRInstructionClass<? extends AMD64RestoreRegistersOp> c, StackSlotValue[] values, AMD64SaveRegistersOp save) { + super(c); assert Arrays.asList(values).stream().allMatch(ValueUtil::isVirtualStackSlot); this.slots = values; this.save = save;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -39,6 +39,7 @@ */ @Opcode("SAVE_REGISTER") public class AMD64SaveRegistersOp extends AMD64LIRInstruction implements SaveRegistersOp { + public static final LIRInstructionClass<AMD64SaveRegistersOp> TYPE = LIRInstructionClass.create(AMD64SaveRegistersOp.class); /** * The registers (potentially) saved by this operation. @@ -63,6 +64,11 @@ * @param supportsRemove determines if registers can be {@linkplain #remove(Set) pruned} */ public AMD64SaveRegistersOp(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) { + this(TYPE, savedRegisters, savedRegisterLocations, supportsRemove); + } + + public AMD64SaveRegistersOp(LIRInstructionClass<? extends AMD64SaveRegistersOp> c, Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) { + super(c); assert Arrays.asList(savedRegisterLocations).stream().allMatch(ValueUtil::isVirtualStackSlot); this.savedRegisters = savedRegisters; this.slots = savedRegisterLocations;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestMemoryOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestMemoryOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -32,12 +32,13 @@ import com.oracle.graal.lir.amd64.AMD64Move.MemOp; import com.oracle.graal.lir.asm.*; -public class AMD64TestMemoryOp extends MemOp { +public final class AMD64TestMemoryOp extends MemOp { + public static final LIRInstructionClass<AMD64TestMemoryOp> TYPE = LIRInstructionClass.create(AMD64TestMemoryOp.class); @Use({REG, CONST}) protected Value y; public AMD64TestMemoryOp(Kind kind, AMD64AddressValue x, Value y, LIRFrameState state) { - super(kind, x, state); + super(TYPE, kind, x, state); this.y = y; this.state = state; }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -28,14 +28,17 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -public class AMD64TestOp extends AMD64LIRInstruction { +public final class AMD64TestOp extends AMD64LIRInstruction { + public static final LIRInstructionClass<AMD64TestOp> TYPE = LIRInstructionClass.create(AMD64TestOp.class); @Use({REG}) protected Value x; @Use({REG, STACK, CONST}) protected Value y; public AMD64TestOp(Value x, Value y) { + super(TYPE); this.x = x; this.y = y; }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -40,6 +40,7 @@ */ @Opcode("ZAP_REGISTER") public final class AMD64ZapRegistersOp extends AMD64LIRInstruction implements SaveRegistersOp { + public static final LIRInstructionClass<AMD64ZapRegistersOp> TYPE = LIRInstructionClass.create(AMD64ZapRegistersOp.class); /** * The registers that are zapped. @@ -52,6 +53,7 @@ @Use({CONST}) protected JavaConstant[] zapValues; public AMD64ZapRegistersOp(Register[] zappedRegisters, JavaConstant[] zapValues) { + super(TYPE); this.zappedRegisters = zappedRegisters; this.zapValues = zapValues; }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -31,7 +31,8 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; -public class SPARCAddressValue extends CompositeValue { +public final class SPARCAddressValue extends CompositeValue { + public static final CompositeValueClass<SPARCAddressValue> TYPE = CompositeValueClass.create(SPARCAddressValue.class); private static final long serialVersionUID = -3583286416638228207L; @@ -44,7 +45,7 @@ } public SPARCAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index, int displacement) { - super(kind); + super(TYPE, kind); assert isIllegal(index) || displacement == 0; this.base = base; this.index = index;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,18 +24,24 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.sparc.SPARC.*; +import static com.oracle.graal.sparc.SPARC.CPUFeature.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; -import com.oracle.graal.sparc.SPARC.CPUFeature; import com.oracle.graal.sparc.*; public enum SPARCArithmetic { @@ -56,13 +62,15 @@ /** * Unary operation with separate source and destination operand. */ - public static class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<Unary2Op> TYPE = LIRInstructionClass.create(Unary2Op.class); @Opcode private final SPARCArithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue x; public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -78,7 +86,8 @@ * Binary operation with two operands. The first source operand is combined with the * destination. The second source operand must be a register. */ - public static class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<BinaryRegReg> TYPE = LIRInstructionClass.create(BinaryRegReg.class); @Opcode private final SPARCArithmetic opcode; @Def({REG, HINT}) protected Value result; @@ -91,6 +100,7 @@ } public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -113,7 +123,8 @@ /** * Binary operation with single source/destination operand and one constant. */ - public static class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<BinaryRegConst> TYPE = LIRInstructionClass.create(BinaryRegConst.class); @Opcode private final SPARCArithmetic opcode; @Def({REG, HINT}) protected AllocatableValue result; @@ -126,6 +137,7 @@ } public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, JavaConstant y, LIRFrameState state) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -148,7 +160,8 @@ /** * Special LIR instruction as it requires a bunch of scratch registers. */ - public static class RemOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final class RemOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<RemOp> TYPE = LIRInstructionClass.create(RemOp.class); @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected Value result; @@ -159,6 +172,7 @@ @State protected LIRFrameState state; public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) { + super(TYPE); this.opcode = opcode; this.result = result; this.x = x; @@ -183,7 +197,8 @@ /** * Calculates the product and condition code for long multiplication of long values. */ - public static class SPARCLMulccOp extends SPARCLIRInstruction { + public static final class SPARCLMulccOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCLMulccOp> TYPE = LIRInstructionClass.create(SPARCLMulccOp.class); @Def({REG}) protected Value result; @Alive({REG}) protected Value x; @Alive({REG}) protected Value y; @@ -191,6 +206,7 @@ @Temp({REG}) protected Value scratch2; public SPARCLMulccOp(Value result, Value x, Value y, LIRGeneratorTool gen) { + super(TYPE); this.result = result; this.x = x; this.y = y; @@ -201,24 +217,24 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { Label noOverflow = new Label(); - new Mulx(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm); + masm.mulx(asLongReg(x), asLongReg(y), asLongReg(result)); // Calculate the upper 64 bit signed := (umulxhi product - (x{63}&y + y{63}&x)) - new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(scratch1)).emit(masm); - new Srax(asLongReg(x), 63, asLongReg(scratch2)).emit(masm); - new And(asLongReg(scratch2), asLongReg(y), asLongReg(scratch2)).emit(masm); - new Sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)).emit(masm); + masm.umulxhi(asLongReg(x), asLongReg(y), asLongReg(scratch1)); + masm.srax(asLongReg(x), 63, asLongReg(scratch2)); + masm.and(asLongReg(scratch2), asLongReg(y), asLongReg(scratch2)); + masm.sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)); - new Srax(asLongReg(y), 63, asLongReg(scratch2)).emit(masm); - new And(asLongReg(scratch2), asLongReg(x), asLongReg(scratch2)).emit(masm); - new Sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)).emit(masm); + masm.srax(asLongReg(y), 63, asLongReg(scratch2)); + masm.and(asLongReg(scratch2), asLongReg(x), asLongReg(scratch2)); + masm.sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)); // Now construct the lower half and compare - new Srax(asLongReg(result), 63, asLongReg(scratch2)).emit(masm); - new Cmp(asLongReg(scratch1), asLongReg(scratch2)).emit(masm); - new Bpe(CC.Xcc, false, true, noOverflow).emit(masm); - new Nop().emit(masm); - new Wrccr(SPARC.g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)).emit(masm); + masm.srax(asLongReg(result), 63, asLongReg(scratch2)); + masm.cmp(asLongReg(scratch1), asLongReg(scratch2)); + masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN); + masm.nop(); + masm.wrccr(g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)); masm.bind(noOverflow); } } @@ -231,86 +247,86 @@ delaySlotLir.emitControlTransfer(crb, masm); switch (opcode) { case IADD: - new Add(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.add(asIntReg(src1), constant, asIntReg(dst)); break; case IADDCC: - new Addcc(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.addcc(asIntReg(src1), constant, asIntReg(dst)); break; case ISUB: - new Sub(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.sub(asIntReg(src1), constant, asIntReg(dst)); break; case ISUBCC: - new Subcc(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.subcc(asIntReg(src1), constant, asIntReg(dst)); break; case IMUL: - new Mulx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.mulx(asIntReg(src1), constant, asIntReg(dst)); break; case IMULCC: throw GraalInternalError.unimplemented(); case IDIV: - new Sdivx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.sdivx(asIntReg(src1), constant, asIntReg(dst)); break; case IUDIV: - new Udivx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.udivx(asIntReg(src1), constant, asIntReg(dst)); break; case IAND: - new And(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.and(asIntReg(src1), constant, asIntReg(dst)); break; case ISHL: - new Sll(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.sll(asIntReg(src1), constant, asIntReg(dst)); break; case ISHR: - new Sra(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.sra(asIntReg(src1), constant, asIntReg(dst)); break; case IUSHR: - new Srl(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.srl(asIntReg(src1), constant, asIntReg(dst)); break; case IOR: - new Or(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.or(asIntReg(src1), constant, asIntReg(dst)); break; case IXOR: - new Xor(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + masm.xor(asIntReg(src1), constant, asIntReg(dst)); break; case LADD: - new Add(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.add(asLongReg(src1), constant, asLongReg(dst)); break; case LADDCC: - new Addcc(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.addcc(asLongReg(src1), constant, asLongReg(dst)); break; case LSUB: - new Sub(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.sub(asLongReg(src1), constant, asLongReg(dst)); break; case LSUBCC: - new Subcc(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.subcc(asLongReg(src1), constant, asLongReg(dst)); break; case LMUL: - new Mulx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.mulx(asLongReg(src1), constant, asLongReg(dst)); break; case LDIV: exceptionOffset = masm.position(); - new Sdivx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.sdivx(asLongReg(src1), constant, asLongReg(dst)); break; case LUDIV: exceptionOffset = masm.position(); - new Udivx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.udivx(asLongReg(src1), constant, asLongReg(dst)); break; case LAND: - new And(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.and(asLongReg(src1), constant, asLongReg(dst)); break; case LOR: - new Or(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.or(asLongReg(src1), constant, asLongReg(dst)); break; case LXOR: - new Xor(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.xor(asLongReg(src1), constant, asLongReg(dst)); break; case LSHL: - new Sllx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.sllx(asLongReg(src1), constant, asLongReg(dst)); break; case LSHR: - new Srax(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.srax(asLongReg(src1), constant, asLongReg(dst)); break; case LUSHR: - new Srlx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + masm.srlx(asLongReg(src1), constant, asLongReg(dst)); break; case DAND: // Has no constant implementation in SPARC case FADD: @@ -336,185 +352,185 @@ switch (opcode) { case IADD: delaySlotLir.emitControlTransfer(crb, masm); - new Add(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.add(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IADDCC: delaySlotLir.emitControlTransfer(crb, masm); - new Addcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.addcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case ISUB: delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.sub(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case ISUBCC: delaySlotLir.emitControlTransfer(crb, masm); - new Subcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.subcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IMUL: delaySlotLir.emitControlTransfer(crb, masm); - new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IMULCC: try (SPARCScratchRegister tmpScratch = SPARCScratchRegister.get()) { Register tmp = tmpScratch.getRegister(); - new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)); Label noOverflow = new Label(); - new Sra(asIntReg(dst), 0, tmp).emit(masm); - new Xorcc(SPARC.g0, SPARC.g0, SPARC.g0).emit(masm); - if (masm.hasFeature(CPUFeature.CBCOND)) { - new CBcondx(ConditionFlag.Equal, tmp, asIntReg(dst), noOverflow).emit(masm); + masm.sra(asIntReg(dst), 0, tmp); + masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0); + if (masm.hasFeature(CBCOND)) { + masm.cbcondx(Equal, tmp, asIntReg(dst), noOverflow); // Is necessary, otherwise we will have a penalty of 5 cycles in S3 - new Nop().emit(masm); + masm.nop(); } else { - new Cmp(tmp, asIntReg(dst)).emit(masm); - new Bpe(CC.Xcc, noOverflow).emit(masm); - new Nop().emit(masm); + masm.cmp(tmp, asIntReg(dst)); + masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN); + masm.nop(); } - new Wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)).emit(masm); + masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)); masm.bind(noOverflow); } break; case IDIV: - new Signx(asIntReg(src1), asIntReg(src1)).emit(masm); - new Signx(asIntReg(src2), asIntReg(src2)).emit(masm); + masm.signx(asIntReg(src1), asIntReg(src1)); + masm.signx(asIntReg(src2), asIntReg(src2)); delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); - new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IUDIV: - new Signx(asIntReg(src1), asIntReg(src1)).emit(masm); - new Signx(asIntReg(src2), asIntReg(src2)).emit(masm); + masm.signx(asIntReg(src1), asIntReg(src1)); + masm.signx(asIntReg(src2), asIntReg(src2)); delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); - new Udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IAND: delaySlotLir.emitControlTransfer(crb, masm); - new And(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.and(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IOR: delaySlotLir.emitControlTransfer(crb, masm); - new Or(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.or(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IXOR: delaySlotLir.emitControlTransfer(crb, masm); - new Xor(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.xor(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case ISHL: delaySlotLir.emitControlTransfer(crb, masm); - new Sll(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.sll(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case ISHR: delaySlotLir.emitControlTransfer(crb, masm); - new Sra(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.sra(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IUSHR: delaySlotLir.emitControlTransfer(crb, masm); - new Srl(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + masm.srl(asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; case IREM: throw GraalInternalError.unimplemented(); case LADD: delaySlotLir.emitControlTransfer(crb, masm); - new Add(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.add(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LADDCC: delaySlotLir.emitControlTransfer(crb, masm); - new Addcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.addcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LSUB: delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.sub(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LSUBCC: delaySlotLir.emitControlTransfer(crb, masm); - new Subcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.subcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LMUL: delaySlotLir.emitControlTransfer(crb, masm); - new Mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LMULCC: throw GraalInternalError.unimplemented(); case LDIV: delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); - new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LUDIV: delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); - new Udivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.udivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LAND: delaySlotLir.emitControlTransfer(crb, masm); - new And(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.and(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LOR: delaySlotLir.emitControlTransfer(crb, masm); - new Or(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.or(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LXOR: delaySlotLir.emitControlTransfer(crb, masm); - new Xor(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + masm.xor(asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LSHL: delaySlotLir.emitControlTransfer(crb, masm); - new Sllx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); + masm.sllx(asLongReg(src1), asIntReg(src2), asLongReg(dst)); break; case LSHR: delaySlotLir.emitControlTransfer(crb, masm); - new Srax(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); + masm.srax(asLongReg(src1), asIntReg(src2), asLongReg(dst)); break; case LUSHR: delaySlotLir.emitControlTransfer(crb, masm); - new Srlx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); + masm.srlx(asLongReg(src1), asIntReg(src2), asLongReg(dst)); break; case FADD: delaySlotLir.emitControlTransfer(crb, masm); - new Fadds(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); + masm.fadds(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); break; case FSUB: delaySlotLir.emitControlTransfer(crb, masm); - new Fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); + masm.fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); break; case FMUL: delaySlotLir.emitControlTransfer(crb, masm); if (dst.getPlatformKind() == Kind.Double) { - new Fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst)).emit(masm); + masm.fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst)); } else if (dst.getPlatformKind() == Kind.Float) { - new Fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); + masm.fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); } break; case FDIV: delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); - new Fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); + masm.fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); break; case FREM: throw GraalInternalError.unimplemented(); case DADD: delaySlotLir.emitControlTransfer(crb, masm); - new Faddd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); + masm.faddd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); break; case DSUB: delaySlotLir.emitControlTransfer(crb, masm); - new Fsubd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); + masm.fsubd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); break; case DMUL: delaySlotLir.emitControlTransfer(crb, masm); - new Fmuld(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); + masm.fmuld(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); break; case DDIV: delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); - new Fdivd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); + masm.fdivd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); break; case DREM: throw GraalInternalError.unimplemented(); case DAND: delaySlotLir.emitControlTransfer(crb, masm); - new Fandd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); + masm.fandd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -535,26 +551,26 @@ assert !src2.equals(scratch1); switch (opcode) { case IREM: - new Sra(asIntReg(src1), 0, asIntReg(dst)).emit(masm); + masm.sra(asIntReg(src1), 0, asIntReg(dst)); exceptionOffset = masm.position(); - new Sdivx(asIntReg(dst), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm); - new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm); + masm.sdivx(asIntReg(dst), crb.asIntConst(src2), asIntReg(scratch1)); + masm.mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)); delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm); + masm.sub(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)); break; case LREM: exceptionOffset = masm.position(); - new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm); - new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm); + masm.sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)); + masm.mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)); delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm); + masm.sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)); break; case LUREM: exceptionOffset = masm.position(); - new Udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm); - new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm); + masm.udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)); + masm.mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)); delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm); + masm.sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)); break; case IUREM: GraalInternalError.unimplemented(); @@ -574,10 +590,10 @@ assert !asLongReg(src2).equals(asLongReg(scratch1)); // But src2 can be scratch2 exceptionOffset = masm.position(); - new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); - new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); + masm.sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)); + masm.mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)); delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm); + masm.sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)); break; case LUREM: if (isConstant(src1)) { @@ -587,10 +603,10 @@ assert !asLongReg(srcLeft).equals(asLongReg(scratch1)); assert !asLongReg(src2).equals(asLongReg(scratch1)); exceptionOffset = masm.position(); - new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); - new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); + masm.udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)); + masm.mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)); delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm); + masm.sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)); break; case IREM: if (isConstant(src1)) { @@ -599,24 +615,24 @@ } assert !asIntReg(srcLeft).equals(asIntReg(scratch1)); assert !asIntReg(src2).equals(asIntReg(scratch1)); - new Sra(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm); - new Sra(asIntReg(src2), 0, asIntReg(scratch2)).emit(masm); + masm.sra(asIntReg(src1), 0, asIntReg(scratch1)); + masm.sra(asIntReg(src2), 0, asIntReg(scratch2)); exceptionOffset = masm.position(); - new Sdivx(asIntReg(scratch1), asIntReg(scratch2), asIntReg(dst)).emit(masm); - new Mulx(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm); + masm.sdivx(asIntReg(scratch1), asIntReg(scratch2), asIntReg(dst)); + masm.mulx(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)); delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm); + masm.sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)); break; case IUREM: assert !asIntReg(dst).equals(asIntReg(scratch1)); assert !asIntReg(dst).equals(asIntReg(scratch2)); - new Srl(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm); - new Srl(asIntReg(src2), 0, asIntReg(dst)).emit(masm); + masm.srl(asIntReg(src1), 0, asIntReg(scratch1)); + masm.srl(asIntReg(src2), 0, asIntReg(dst)); exceptionOffset = masm.position(); - new Udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)).emit(masm); - new Mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)).emit(masm); + masm.udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)); + masm.mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)); delaySlotLir.emitControlTransfer(crb, masm); - new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm); + masm.sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -636,110 +652,110 @@ switch (opcode) { case INEG: delaySlotLir.emitControlTransfer(crb, masm); - new Neg(asIntReg(src), asIntReg(dst)).emit(masm); + masm.neg(asIntReg(src), asIntReg(dst)); break; case LNEG: delaySlotLir.emitControlTransfer(crb, masm); - new Neg(asLongReg(src), asLongReg(dst)).emit(masm); + masm.neg(asLongReg(src), asLongReg(dst)); break; case INOT: delaySlotLir.emitControlTransfer(crb, masm); - new Not(asIntReg(src), asIntReg(dst)).emit(masm); + masm.not(asIntReg(src), asIntReg(dst)); break; case LNOT: delaySlotLir.emitControlTransfer(crb, masm); - new Not(asLongReg(src), asLongReg(dst)).emit(masm); + masm.not(asLongReg(src), asLongReg(dst)); break; case D2F: delaySlotLir.emitControlTransfer(crb, masm); - new Fdtos(asDoubleReg(src), asFloatReg(dst)).emit(masm); + masm.fdtos(asDoubleReg(src), asFloatReg(dst)); break; case L2D: delaySlotLir.emitControlTransfer(crb, masm); - new Fxtod(asDoubleReg(src), asDoubleReg(dst)).emit(masm); + masm.fxtod(asDoubleReg(src), asDoubleReg(dst)); break; case L2F: delaySlotLir.emitControlTransfer(crb, masm); - new Fxtos(asDoubleReg(src), asFloatReg(dst)).emit(masm); + masm.fxtos(asDoubleReg(src), asFloatReg(dst)); break; case I2D: delaySlotLir.emitControlTransfer(crb, masm); - new Fitod(asFloatReg(src), asDoubleReg(dst)).emit(masm); + masm.fitod(asFloatReg(src), asDoubleReg(dst)); break; case I2L: delaySlotLir.emitControlTransfer(crb, masm); - new Signx(asIntReg(src), asLongReg(dst)).emit(masm); + masm.signx(asIntReg(src), asLongReg(dst)); break; case L2I: delaySlotLir.emitControlTransfer(crb, masm); - new Signx(asLongReg(src), asIntReg(dst)).emit(masm); + masm.signx(asLongReg(src), asIntReg(dst)); break; case B2L: - new Sll(asIntReg(src), 24, asLongReg(dst)).emit(masm); + masm.sll(asIntReg(src), 24, asLongReg(dst)); delaySlotLir.emitControlTransfer(crb, masm); - new Sra(asLongReg(dst), 24, asLongReg(dst)).emit(masm); + masm.sra(asLongReg(dst), 24, asLongReg(dst)); break; case B2I: - new Sll(asIntReg(src), 24, asIntReg(dst)).emit(masm); + masm.sll(asIntReg(src), 24, asIntReg(dst)); delaySlotLir.emitControlTransfer(crb, masm); - new Sra(asIntReg(dst), 24, asIntReg(dst)).emit(masm); + masm.sra(asIntReg(dst), 24, asIntReg(dst)); break; case S2L: - new Sll(asIntReg(src), 16, asLongReg(dst)).emit(masm); + masm.sll(asIntReg(src), 16, asLongReg(dst)); delaySlotLir.emitControlTransfer(crb, masm); - new Sra(asLongReg(dst), 16, asLongReg(dst)).emit(masm); + masm.sra(asLongReg(dst), 16, asLongReg(dst)); break; case S2I: - new Sll(asIntReg(src), 16, asIntReg(dst)).emit(masm); + masm.sll(asIntReg(src), 16, asIntReg(dst)); delaySlotLir.emitControlTransfer(crb, masm); - new Sra(asIntReg(dst), 16, asIntReg(dst)).emit(masm); + masm.sra(asIntReg(dst), 16, asIntReg(dst)); break; case I2F: delaySlotLir.emitControlTransfer(crb, masm); - new Fitos(asFloatReg(src), asFloatReg(dst)).emit(masm); + masm.fitos(asFloatReg(src), asFloatReg(dst)); break; case F2D: delaySlotLir.emitControlTransfer(crb, masm); - new Fstod(asFloatReg(src), asDoubleReg(dst)).emit(masm); + masm.fstod(asFloatReg(src), asDoubleReg(dst)); break; case F2L: - new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm); - new Fbo(true, notOrdered).emit(masm); - new Fstox(asFloatReg(src), asDoubleReg(dst)).emit(masm); - new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm); + masm.fcmp(Fcc0, Fcmps, asFloatReg(src), asFloatReg(src)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fstox(asFloatReg(src), asDoubleReg(dst)); + masm.fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)); masm.bind(notOrdered); break; case F2I: - new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm); - new Fbo(true, notOrdered).emit(masm); - new Fstoi(asFloatReg(src), asFloatReg(dst)).emit(masm); - new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm); - new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm); + masm.fcmp(Fcc0, Fcmps, asFloatReg(src), asFloatReg(src)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fstoi(asFloatReg(src), asFloatReg(dst)); + masm.fitos(asFloatReg(dst), asFloatReg(dst)); + masm.fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)); masm.bind(notOrdered); break; case D2L: - new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm); - new Fbo(false, notOrdered).emit(masm); - new Fdtox(asDoubleReg(src), asDoubleReg(dst)).emit(masm); - new Fxtod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm); - new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm); + masm.fcmp(Fcc0, Fcmpd, asDoubleReg(src), asDoubleReg(src)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fdtox(asDoubleReg(src), asDoubleReg(dst)); + masm.fxtod(asDoubleReg(dst), asDoubleReg(dst)); + masm.fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)); masm.bind(notOrdered); break; case D2I: - new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm); - new Fbo(true, notOrdered).emit(masm); - new Fdtoi(asDoubleReg(src), asFloatReg(dst)).emit(masm); - new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm); - new Fstoi(asFloatReg(dst), asFloatReg(dst)).emit(masm); + masm.fcmp(Fcc0, Fcmpd, asDoubleReg(src), asDoubleReg(src)); + masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN); + masm.fdtoi(asDoubleReg(src), asFloatReg(dst)); + masm.fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)); + masm.fstoi(asFloatReg(dst), asFloatReg(dst)); masm.bind(notOrdered); break; case FNEG: delaySlotLir.emitControlTransfer(crb, masm); - new Fnegs(asFloatReg(src), asFloatReg(dst)).emit(masm); + masm.fnegs(asFloatReg(src), asFloatReg(dst)); break; case DNEG: delaySlotLir.emitControlTransfer(crb, masm); - new Fnegd(asDoubleReg(src), asDoubleReg(dst)).emit(masm); + masm.fnegd(asDoubleReg(src), asDoubleReg(dst)); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + opcode); @@ -835,7 +851,8 @@ } } - public static class MulHighOp extends SPARCLIRInstruction { + public static final class MulHighOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<MulHighOp> TYPE = LIRInstructionClass.create(MulHighOp.class); @Opcode private final SPARCArithmetic opcode; @Def({REG}) public AllocatableValue result; @@ -844,6 +861,7 @@ @Temp({REG}) public AllocatableValue scratch; public MulHighOp(SPARCArithmetic opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) { + super(TYPE); this.opcode = opcode; this.x = x; this.y = y; @@ -856,30 +874,30 @@ assert isRegister(x) && isRegister(y) && isRegister(result) && isRegister(scratch); switch (opcode) { case IMUL: - new Mulx(asIntReg(x), asIntReg(y), asIntReg(result)).emit(masm); - new Srax(asIntReg(result), 32, asIntReg(result)).emit(masm); + masm.mulx(asIntReg(x), asIntReg(y), asIntReg(result)); + masm.srax(asIntReg(result), 32, asIntReg(result)); break; case IUMUL: assert !asIntReg(scratch).equals(asIntReg(result)); - new Srl(asIntReg(x), 0, asIntReg(scratch)).emit(masm); - new Srl(asIntReg(y), 0, asIntReg(result)).emit(masm); - new Mulx(asIntReg(result), asIntReg(scratch), asIntReg(result)).emit(masm); - new Srlx(asIntReg(result), 32, asIntReg(result)).emit(masm); + masm.srl(asIntReg(x), 0, asIntReg(scratch)); + masm.srl(asIntReg(y), 0, asIntReg(result)); + masm.mulx(asIntReg(result), asIntReg(scratch), asIntReg(result)); + masm.srlx(asIntReg(result), 32, asIntReg(result)); break; case LMUL: assert !asLongReg(scratch).equals(asLongReg(result)); - new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm); + masm.umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)); - new Srlx(asLongReg(x), 63, asLongReg(scratch)).emit(masm); - new Mulx(asLongReg(scratch), asLongReg(y), asLongReg(scratch)).emit(masm); - new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm); + masm.srlx(asLongReg(x), 63, asLongReg(scratch)); + masm.mulx(asLongReg(scratch), asLongReg(y), asLongReg(scratch)); + masm.sub(asLongReg(result), asLongReg(scratch), asLongReg(result)); - new Srlx(asLongReg(y), 63, asLongReg(scratch)).emit(masm); - new Mulx(asLongReg(scratch), asLongReg(x), asLongReg(scratch)).emit(masm); - new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm); + masm.srlx(asLongReg(y), 63, asLongReg(scratch)); + masm.mulx(asLongReg(scratch), asLongReg(x), asLongReg(scratch)); + masm.sub(asLongReg(result), asLongReg(scratch), asLongReg(result)); break; case LUMUL: - new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm); + masm.umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)); break; default: throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -23,11 +23,15 @@ package com.oracle.graal.lir.sparc; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.*; import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.asm.sparc.SPARCAssembler.*; -import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.sparc.SPARC.CPUFeature.*; import java.lang.reflect.*; @@ -35,18 +39,19 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; +import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.sparc.SPARC.CPUFeature; /** * Emits code which compares two arrays of the same length. */ @Opcode("ARRAY_EQUALS") -public class SPARCArrayEqualsOp extends SPARCLIRInstruction { +public final class SPARCArrayEqualsOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCArrayEqualsOp> TYPE = LIRInstructionClass.create(SPARCArrayEqualsOp.class); private final Kind kind; private final int arrayBaseOffset; @@ -63,6 +68,7 @@ @Temp({REG}) protected Value temp5; public SPARCArrayEqualsOp(LIRGeneratorTool tool, Kind kind, Value result, Value array1, Value array2, Value length) { + super(TYPE); this.kind = kind; Class<?> arrayClass = Array.newInstance(kind.toJavaClass(), 0).getClass(); @@ -94,25 +100,25 @@ Label done = new Label(); // Load array base addresses. - new Add(asObjectReg(array1Value), arrayBaseOffset, array1).emit(masm); - new Add(asObjectReg(array2Value), arrayBaseOffset, array2).emit(masm); + masm.add(asObjectReg(array1Value), arrayBaseOffset, array1); + masm.add(asObjectReg(array2Value), arrayBaseOffset, array2); // Get array length in bytes. - new Mulx(asIntReg(lengthValue), arrayIndexScale, length).emit(masm); - new Mov(length, result).emit(masm); // copy + masm.mulx(asIntReg(lengthValue), arrayIndexScale, length); + masm.mov(length, result); // copy emit8ByteCompare(masm, result, array1, array2, length, trueLabel, falseLabel); emitTailCompares(masm, result, array1, array2, trueLabel, falseLabel); // Return true masm.bind(trueLabel); - new Mov(1, result).emit(masm); - new Bpa(done).emit(masm); - new Nop().emit(masm); + masm.mov(1, result); + masm.bicc(Always, ANNUL, done); + masm.nop(); // Return false masm.bind(falseLabel); - new Mov(g0, result).emit(masm); + masm.mov(g0, result); // That's it masm.bind(done); @@ -136,54 +142,55 @@ boolean hasCBcond = masm.hasFeature(CPUFeature.CBCOND); - new And(result, VECTOR_SIZE - 1, result).emit(masm); // tail count (in bytes) - new Andcc(length, ~(VECTOR_SIZE - 1), length).emit(masm); // vector count (in bytes) - new Bpe(CC.Xcc, compareTail).emit(masm); + masm.and(result, VECTOR_SIZE - 1, result); // tail count (in bytes) + masm.andcc(length, ~(VECTOR_SIZE - 1), length); // vector count (in bytes) + masm.bpcc(ConditionFlag.Equal, NOT_ANNUL, compareTail, CC.Xcc, PREDICT_NOT_TAKEN); - new Sub(length, VECTOR_SIZE, length).emit(masm); // Delay slot - new Add(array1, length, array1).emit(masm); - new Add(array2, length, array2).emit(masm); - new Sub(g0, length, length).emit(masm); + masm.sub(length, VECTOR_SIZE, length); // Delay slot + masm.add(array1, length, array1); + masm.add(array2, length, array2); + masm.sub(g0, length, length); // Compare the last element first - new Ldx(new SPARCAddress(array1, 0), tempReg1).emit(masm); - new Ldx(new SPARCAddress(array2, 0), tempReg2).emit(masm); + masm.ldx(new SPARCAddress(array1, 0), tempReg1); + masm.ldx(new SPARCAddress(array2, 0), tempReg2); if (hasCBcond) { - new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm); - new Nop().emit(masm); // for optimal performance (see manual) - new CBcondx(ConditionFlag.Equal, length, 0, compareTailCorrectVectorEnd).emit(masm); - new Nop().emit(masm); // for optimal performance (see manual) + masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); + masm.nop(); // for optimal performance (see manual) + masm.cbcondx(Equal, length, 0, compareTailCorrectVectorEnd); + masm.nop(); // for optimal performance (see manual) } else { - new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, true, false, falseLabel).emit(masm); - new Nop().emit(masm); - new Bpr(RCondition.Rc_z, false, false, length, compareTailCorrectVectorEnd).emit(masm); - new Nop().emit(masm); + masm.cmp(tempReg1, tempReg2); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); + masm.nop(); + masm.bpr(Rc_z, NOT_ANNUL, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, length); + masm.nop(); } // Load the first value from array 1 (Later done in back branch delay-slot) - new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm); + masm.ldx(new SPARCAddress(array1, length), tempReg1); masm.bind(loop); - new Ldx(new SPARCAddress(array2, length), tempReg2).emit(masm); - new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, false, false, falseLabel).emit(masm); + masm.ldx(new SPARCAddress(array2, length), tempReg2); + masm.cmp(tempReg1, tempReg2); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); // Delay slot, not annul, add for next iteration - new Addcc(length, VECTOR_SIZE, length).emit(masm); - new Bpne(Xcc, true, true, loop).emit(masm); // Annul, to prevent access past the array - new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm); // Load in delay slot + masm.addcc(length, VECTOR_SIZE, length); + // Annul, to prevent access past the array + masm.bpcc(NotEqual, ANNUL, loop, Xcc, PREDICT_TAKEN); + masm.ldx(new SPARCAddress(array1, length), tempReg1); // Load in delay slot // Tail count zero, therefore we can go to the end if (hasCBcond) { - new CBcondx(ConditionFlag.Equal, result, 0, trueLabel).emit(masm); + masm.cbcondx(Equal, result, 0, trueLabel); } else { - new Bpr(RCondition.Rc_z, true, true, result, trueLabel).emit(masm); - new Nop().emit(masm); + masm.bpr(Rc_z, NOT_ANNUL, trueLabel, PREDICT_TAKEN, result); + masm.nop(); } masm.bind(compareTailCorrectVectorEnd); // Correct the array pointers - new Add(array1, VECTOR_SIZE, array1).emit(masm); - new Add(array2, VECTOR_SIZE, array2).emit(masm); + masm.add(array1, VECTOR_SIZE, array1); + masm.add(array2, VECTOR_SIZE, array2); masm.bind(compareTail); } @@ -197,82 +204,81 @@ Register tempReg1 = asRegister(temp3); Register tempReg2 = asRegister(temp4); - boolean hasCBcond = masm.hasFeature(CPUFeature.CBCOND); + boolean hasCBcond = masm.hasFeature(CBCOND); if (kind.getByteCount() <= 4) { // Compare trailing 4 bytes, if any. if (hasCBcond) { - new CBcondx(ConditionFlag.Less, result, 4, compare2Bytes).emit(masm); + masm.cbcondx(Less, result, 4, compare2Bytes); } else { - new Cmp(result, 4).emit(masm); - new Bpl(Xcc, false, false, compare2Bytes).emit(masm); - new Nop().emit(masm); + masm.cmp(result, 4); + masm.bpcc(Less, NOT_ANNUL, compare2Bytes, Xcc, PREDICT_NOT_TAKEN); + masm.nop(); } - new Lduw(new SPARCAddress(array1, 0), tempReg1).emit(masm); - new Lduw(new SPARCAddress(array2, 0), tempReg2).emit(masm); + masm.lduw(new SPARCAddress(array1, 0), tempReg1); + masm.lduw(new SPARCAddress(array2, 0), tempReg2); if (hasCBcond) { - new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm); + masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); } else { - new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, false, false, falseLabel).emit(masm); - new Nop().emit(masm); + masm.cmp(tempReg1, tempReg2); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); + masm.nop(); } if (kind.getByteCount() <= 2) { // Move array pointers forward. - new Add(array1, 4, array1).emit(masm); - new Add(array2, 4, array2).emit(masm); - new Sub(result, 4, result).emit(masm); + masm.add(array1, 4, array1); + masm.add(array2, 4, array2); + masm.sub(result, 4, result); // Compare trailing 2 bytes, if any. masm.bind(compare2Bytes); if (hasCBcond) { - new CBcondx(ConditionFlag.Less, result, 2, compare1Byte).emit(masm); + masm.cbcondx(Less, result, 2, compare1Byte); } else { - new Cmp(result, 2).emit(masm); - new Bpl(Xcc, false, true, compare1Byte).emit(masm); - new Nop().emit(masm); + masm.cmp(result, 2); + masm.bpcc(Less, NOT_ANNUL, compare1Byte, Xcc, PREDICT_TAKEN); + masm.nop(); } - new Lduh(new SPARCAddress(array1, 0), tempReg1).emit(masm); - new Lduh(new SPARCAddress(array2, 0), tempReg2).emit(masm); + masm.lduh(new SPARCAddress(array1, 0), tempReg1); + masm.lduh(new SPARCAddress(array2, 0), tempReg2); if (hasCBcond) { - new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm); + masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); } else { - new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, false, true, falseLabel).emit(masm); - new Nop().emit(masm); + masm.cmp(tempReg1, tempReg2); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN); + masm.nop(); } // The one-byte tail compare is only required for boolean and byte arrays. if (kind.getByteCount() <= 1) { // Move array pointers forward before we compare the last trailing byte. - new Add(array1, 2, array1).emit(masm); - new Add(array2, 2, array2).emit(masm); - new Sub(result, 2, result).emit(masm); + masm.add(array1, 2, array1); + masm.add(array2, 2, array2); + masm.sub(result, 2, result); // Compare trailing byte, if any. masm.bind(compare1Byte); if (hasCBcond) { - new CBcondx(ConditionFlag.NotEqual, result, 1, trueLabel).emit(masm); + masm.cbcondx(NotEqual, result, 1, trueLabel); } else { - new Cmp(result, 1).emit(masm); - new Bpne(Xcc, trueLabel).emit(masm); - new Nop().emit(masm); + masm.cmp(result, 1); + masm.bpcc(NotEqual, NOT_ANNUL, trueLabel, Xcc, PREDICT_TAKEN); + masm.nop(); } - new Ldub(new SPARCAddress(array1, 0), tempReg1).emit(masm); - new Ldub(new SPARCAddress(array2, 0), tempReg2).emit(masm); + masm.ldub(new SPARCAddress(array1, 0), tempReg1); + masm.ldub(new SPARCAddress(array2, 0), tempReg2); if (hasCBcond) { - // new SPARCAssembler.Ldx(new SPARCAddress(o7, 1), g3).emit(masm); - new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm); + masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); } else { - new Cmp(tempReg1, tempReg2).emit(masm); - new Bpne(Xcc, falseLabel).emit(masm); - new Nop().emit(masm); + masm.cmp(tempReg1, tempReg2); + masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN); + masm.nop(); } } else { masm.bind(compare1Byte);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,19 +29,14 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Andn; -import com.oracle.graal.asm.sparc.SPARCAssembler.Or; -import com.oracle.graal.asm.sparc.SPARCAssembler.Popc; -import com.oracle.graal.asm.sparc.SPARCAssembler.Srl; -import com.oracle.graal.asm.sparc.SPARCAssembler.Srlx; -import com.oracle.graal.asm.sparc.SPARCAssembler.Sub; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; -public class SPARCBitManipulationOp extends SPARCLIRInstruction { +public final class SPARCBitManipulationOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCBitManipulationOp> TYPE = LIRInstructionClass.create(SPARCBitManipulationOp.class); public enum IntrinsicOpcode { IPOPCNT, @@ -57,6 +52,7 @@ @Temp({REG}) protected Value scratch; public SPARCBitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input, LIRGeneratorTool gen) { + super(TYPE); this.opcode = opcode; this.result = result; this.input = input; @@ -71,23 +67,23 @@ switch (opcode) { case IPOPCNT: // clear upper word for 64 bit POPC - new Srl(src, g0, dst).emit(masm); - new Popc(dst, dst).emit(masm); + masm.srl(src, g0, dst); + masm.popc(dst, dst); break; case LPOPCNT: - new Popc(src, dst).emit(masm); + masm.popc(src, dst); break; case BSF: Kind tkind = input.getKind(); if (tkind == Kind.Int) { - new Sub(src, 1, dst).emit(masm); - new Andn(dst, src, dst).emit(masm); - new Srl(dst, g0, dst).emit(masm); - new Popc(dst, dst).emit(masm); + masm.sub(src, 1, dst); + masm.andn(dst, src, dst); + masm.srl(dst, g0, dst); + masm.popc(dst, dst); } else if (tkind == Kind.Long) { - new Sub(src, 1, dst).emit(masm); - new Andn(dst, src, dst).emit(masm); - new Popc(dst, dst).emit(masm); + masm.sub(src, 1, dst); + masm.andn(dst, src, dst); + masm.popc(dst, dst); } else { throw GraalInternalError.shouldNotReachHere("missing: " + tkind); } @@ -97,19 +93,19 @@ assert ikind == Kind.Int; Register tmp = asRegister(scratch); assert !tmp.equals(dst); - new Srl(src, 1, tmp).emit(masm); - new Srl(src, 0, dst).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srl(dst, 2, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srl(dst, 4, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srl(dst, 8, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srl(dst, 16, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Popc(dst, dst).emit(masm); - new Sub(dst, 1, dst).emit(masm); + masm.srl(src, 1, tmp); + masm.srl(src, 0, dst); + masm.or(dst, tmp, dst); + masm.srl(dst, 2, tmp); + masm.or(dst, tmp, dst); + masm.srl(dst, 4, tmp); + masm.or(dst, tmp, dst); + masm.srl(dst, 8, tmp); + masm.or(dst, tmp, dst); + masm.srl(dst, 16, tmp); + masm.or(dst, tmp, dst); + masm.popc(dst, dst); + masm.sub(dst, 1, dst); break; } case LBSR: { @@ -117,20 +113,20 @@ assert lkind == Kind.Long; Register tmp = asRegister(scratch); assert !tmp.equals(dst); - new Srlx(src, 1, tmp).emit(masm); - new Or(src, tmp, dst).emit(masm); - new Srlx(dst, 2, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srlx(dst, 4, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srlx(dst, 8, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srlx(dst, 16, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Srlx(dst, 32, tmp).emit(masm); - new Or(dst, tmp, dst).emit(masm); - new Popc(dst, dst).emit(masm); - new Sub(dst, 1, dst).emit(masm); // This is required to fit the given structure. + masm.srlx(src, 1, tmp); + masm.or(src, tmp, dst); + masm.srlx(dst, 2, tmp); + masm.or(dst, tmp, dst); + masm.srlx(dst, 4, tmp); + masm.or(dst, tmp, dst); + masm.srlx(dst, 8, tmp); + masm.or(dst, tmp, dst); + masm.srlx(dst, 16, tmp); + masm.or(dst, tmp, dst); + masm.srlx(dst, 32, tmp); + masm.or(dst, tmp, dst); + masm.popc(dst, dst); + masm.sub(dst, 1, dst); // This is required to fit the given structure. break; } default: @@ -140,55 +136,16 @@ } else if (isConstant(input) && isSimm13(crb.asIntConst(input))) { switch (opcode) { case IPOPCNT: - new Popc(crb.asIntConst(input), dst).emit(masm); + masm.popc(crb.asIntConst(input), dst); break; case LPOPCNT: - new Popc(crb.asIntConst(input), dst).emit(masm); + masm.popc(crb.asIntConst(input), dst); break; default: throw GraalInternalError.shouldNotReachHere(); } } else { throw GraalInternalError.shouldNotReachHere(); - // SPARCAddress src = (SPARCAddress) crb.asAddress(input); - // switch (opcode) { - // case IPOPCNT: - // new Ldsw(src, tmp).emit(masm); - // // clear upper word for 64 bit POPC - // new Srl(tmp, g0, dst).emit(masm); - // new Popc(tmp, dst).emit(masm); - // break; - // case LPOPCNT: - // new Ldx(src, tmp).emit(masm); - // new Popc(tmp, dst).emit(masm); - // break; - // case BSF: - // assert input.getKind() == Kind.Int; - // new Ldsw(src, tmp).emit(masm); - // new Srl(tmp, 1, tmp).emit(masm); - // new Srl(tmp, 0, dst).emit(masm); - // new Or(tmp, tmp, dst).emit(masm); - // new Srl(dst, 2, tmp).emit(masm); - // new Or(dst, tmp, dst).emit(masm); - // new Srl(dst, 4, tmp).emit(masm); - // new Or(dst, tmp, dst).emit(masm); - // new Srl(dst, 8, tmp).emit(masm); - // new Or(dst, tmp, dst).emit(masm); - // new Srl(dst, 16, tmp).emit(masm); - // new Or(dst, tmp, dst).emit(masm); - // new Popc(dst, dst).emit(masm); - // new Mov(Kind.Int.getBitCount(), tmp).emit(masm); - // new Sub(tmp, dst, dst).emit(masm); - // break; - // case IBSR: - // // masm.bsrl(dst, src); - // // countLeadingZerosI_bsr masm.bsrq(dst, src); - // // masm.bsrl(dst, src); - // case LBSR: - // // masm.bsrq(dst, src); - // default: - // throw GraalInternalError.shouldNotReachHere("missing: " + opcode); - // } } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,7 +25,6 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ta; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -34,7 +33,8 @@ * Emits a breakpoint. */ @Opcode("BREAKPOINT") -public class SPARCBreakpointOp extends SPARCLIRInstruction { +public final class SPARCBreakpointOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCBreakpointOp> TYPE = LIRInstructionClass.create(SPARCBreakpointOp.class); // historical - from hotspot src/cpu/sparc/vm // <sys/trap.h> promises that the system will not use traps 16-31 @@ -47,11 +47,12 @@ @Use({REG, STACK}) protected Value[] parameters; public SPARCBreakpointOp(Value[] parameters) { + super(TYPE); this.parameters = parameters; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - new Ta(ST_RESERVED_FOR_USER_0).emit(masm); + masm.ta(ST_RESERVED_FOR_USER_0); } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -28,14 +28,15 @@ 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.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Asi; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; @Opcode("BSWAP") -public class SPARCByteSwapOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { +public final class SPARCByteSwapOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<SPARCByteSwapOp> TYPE = LIRInstructionClass.create(SPARCByteSwapOp.class); @Def({REG, HINT}) protected Value result; @Use({REG}) protected Value input; @@ -43,6 +44,7 @@ @Use({STACK}) protected StackSlotValue tmpSlot; public SPARCByteSwapOp(LIRGeneratorTool tool, Value result, Value input) { + super(TYPE); this.result = result; this.input = input; this.tmpSlot = tool.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(Kind.Long)); @@ -61,10 +63,10 @@ delayedControlTransfer.emitControlTransfer(crb, masm); switch (input.getKind()) { case Int: - new SPARCAssembler.Lduwa(addr.getBase(), addr.getIndex(), asIntReg(result), Asi.ASI_PRIMARY_LITTLE).emit(masm); + masm.lduwa(addr.getBase(), addr.getIndex(), asIntReg(result), Asi.ASI_PRIMARY_LITTLE); break; case Long: - new SPARCAssembler.Ldxa(addr.getBase(), addr.getIndex(), asLongReg(result), Asi.ASI_PRIMARY_LITTLE).emit(masm); + masm.ldxa(addr.getBase(), addr.getIndex(), asLongReg(result), Asi.ASI_PRIMARY_LITTLE); break; default: throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,10 +29,6 @@ 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.Call; -import com.oracle.graal.asm.sparc.SPARCAssembler.Jmpl; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Jmp; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Sethix; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; @@ -41,13 +37,15 @@ public class SPARCCall { public abstract static class CallOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<CallOp> TYPE = LIRInstructionClass.create(CallOp.class); @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @Temp protected Value[] temps; @State protected LIRFrameState state; - public CallOp(Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + protected CallOp(LIRInstructionClass<? extends CallOp> c, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c); this.result = result; this.parameters = parameters; this.state = state; @@ -62,34 +60,39 @@ } public abstract static class MethodCallOp extends CallOp { + public static final LIRInstructionClass<MethodCallOp> TYPE = LIRInstructionClass.create(MethodCallOp.class); protected final ResolvedJavaMethod callTarget; - public MethodCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(result, parameters, temps, state); + protected MethodCallOp(LIRInstructionClass<? extends MethodCallOp> c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, result, parameters, temps, state); this.callTarget = callTarget; } } @Opcode("CALL_DIRECT") - public static class DirectCallOp extends MethodCallOp /* implements SPARCDelayedControlTransfer */{ + public abstract static class DirectCallOp extends MethodCallOp /* + * implements + * SPARCDelayedControlTransfer + */{ + public static final LIRInstructionClass<DirectCallOp> TYPE = LIRInstructionClass.create(DirectCallOp.class); private boolean emitted = false; private int before = -1; - public DirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(callTarget, result, parameters, temps, state); + public DirectCallOp(LIRInstructionClass<? extends DirectCallOp> c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, callTarget, result, parameters, temps, state); } @Override - public final void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { if (!emitted) { emitCallPrefixCode(crb, masm); directCall(crb, masm, callTarget, null, true, state); } else { int after = masm.position(); if (after - before == 4) { - new Nop().emit(masm); + masm.nop(); } else if (after - before == 8) { // everything is fine; } else { @@ -111,7 +114,7 @@ assert !emitted; emitCallPrefixCode(crb, masm); before = masm.position(); - new Call(0).emit(masm); + masm.call(0); emitted = true; } @@ -122,12 +125,14 @@ } @Opcode("CALL_INDIRECT") - public static class IndirectCallOp extends MethodCallOp { + public abstract static class IndirectCallOp extends MethodCallOp { + public static final LIRInstructionClass<IndirectCallOp> TYPE = LIRInstructionClass.create(IndirectCallOp.class); @Use({REG}) protected Value targetAddress; - public IndirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value targetAddress, LIRFrameState state) { - super(callTarget, result, parameters, temps, state); + protected IndirectCallOp(LIRInstructionClass<? extends IndirectCallOp> c, ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value targetAddress, + LIRFrameState state) { + super(c, callTarget, result, parameters, temps, state); this.targetAddress = targetAddress; } @@ -144,11 +149,12 @@ } public abstract static class ForeignCallOp extends CallOp { + public static final LIRInstructionClass<ForeignCallOp> TYPE = LIRInstructionClass.create(ForeignCallOp.class); protected final ForeignCallLinkage callTarget; - public ForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(result, parameters, temps, state); + public ForeignCallOp(LIRInstructionClass<? extends ForeignCallOp> c, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { + super(c, result, parameters, temps, state); this.callTarget = callTarget; } @@ -159,10 +165,11 @@ } @Opcode("NEAR_FOREIGN_CALL") - public static class DirectNearForeignCallOp extends ForeignCallOp { + public static final class DirectNearForeignCallOp extends ForeignCallOp { + public static final LIRInstructionClass<DirectNearForeignCallOp> TYPE = LIRInstructionClass.create(DirectNearForeignCallOp.class); public DirectNearForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(linkage, result, parameters, temps, state); + super(TYPE, linkage, result, parameters, temps, state); } @Override @@ -172,10 +179,11 @@ } @Opcode("FAR_FOREIGN_CALL") - public static class DirectFarForeignCallOp extends ForeignCallOp { + public static final class DirectFarForeignCallOp extends ForeignCallOp { + public static final LIRInstructionClass<DirectFarForeignCallOp> TYPE = LIRInstructionClass.create(DirectFarForeignCallOp.class); public DirectFarForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) { - super(callTarget, result, parameters, temps, state); + super(TYPE, callTarget, result, parameters, temps, state); } @Override @@ -193,11 +201,11 @@ // offset might not fit a 30-bit displacement, generate an // indirect call with a 64-bit immediate new Sethix(0L, scratch, true).emit(masm); - new Jmpl(scratch, 0, o7).emit(masm); + masm.jmpl(scratch, 0, o7); } else { - new Call(0).emit(masm); + masm.call(0); } - new Nop().emit(masm); // delay slot + masm.nop(); // delay slot int after = masm.position(); crb.recordDirectCall(before, after, callTarget, info); crb.recordExceptionHandlers(after, info); @@ -207,8 +215,8 @@ public static void indirectJmp(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget target) { int before = masm.position(); new Sethix(0L, dst, true).emit(masm); - new Jmp(new SPARCAddress(dst, 0)).emit(masm); - new Nop().emit(masm); // delay slot + masm.jmp(new SPARCAddress(dst, 0)); + masm.nop(); // delay slot int after = masm.position(); crb.recordIndirectCall(before, after, target, null); masm.ensureUniquePC(); @@ -216,8 +224,8 @@ public static void indirectCall(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) { int before = masm.position(); - new Jmpl(dst, 0, o7).emit(masm); - new Nop().emit(masm); // delay slot + masm.jmpl(dst, 0, o7); + masm.nop(); // delay slot int after = masm.position(); crb.recordIndirectCall(before, after, callTarget, info); crb.recordExceptionHandlers(after, info);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,11 +24,12 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -40,13 +41,15 @@ FCMP, DCMP; - public static class CompareOp extends SPARCLIRInstruction { + public static final class CompareOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<CompareOp> TYPE = LIRInstructionClass.create(CompareOp.class); @Opcode private final SPARCCompare opcode; @Use({REG}) protected Value x; @Use({REG, CONST}) protected Value y; public CompareOp(SPARCCompare opcode, Value x, Value y) { + super(TYPE); this.opcode = opcode; this.x = x; this.y = y; @@ -79,19 +82,19 @@ if (isRegister(y)) { switch (opcode) { case ICMP: - new Cmp(asIntReg(x), asIntReg(y)).emit(masm); + masm.cmp(asIntReg(x), asIntReg(y)); break; case LCMP: - new Cmp(asLongReg(x), asLongReg(y)).emit(masm); + masm.cmp(asLongReg(x), asLongReg(y)); break; case ACMP: - new Cmp(asObjectReg(x), asObjectReg(y)).emit(masm); + masm.cmp(asObjectReg(x), asObjectReg(y)); break; case FCMP: - new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(x), asFloatReg(y)).emit(masm); + masm.fcmp(Fcc0, Fcmps, asFloatReg(x), asFloatReg(y)); break; case DCMP: - new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(x), asDoubleReg(y)).emit(masm); + masm.fcmp(Fcc0, Fcmpd, asDoubleReg(x), asDoubleReg(y)); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -101,24 +104,24 @@ switch (opcode) { case LCMP: assert isSimm13(crb.asLongConst(y)); - new Cmp(asLongReg(x), (int) crb.asLongConst(y)).emit(masm); + masm.cmp(asLongReg(x), (int) crb.asLongConst(y)); break; case ICMP: assert isSimm13(crb.asIntConst(y)); - new Cmp(asIntReg(x), crb.asIntConst(y)).emit(masm); + masm.cmp(asIntReg(x), crb.asIntConst(y)); break; case ACMP: if (((JavaConstant) y).isNull()) { - new Cmp(asObjectReg(x), 0).emit(masm); + masm.cmp(asObjectReg(x), 0); break; } else { throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons"); } case FCMP: - new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(x), asFloatReg(y)).emit(masm); + masm.fcmp(Fcc0, Fcmps, asFloatReg(x), asFloatReg(y)); break; case DCMP: - new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(x), asDoubleReg(y)).emit(masm); + masm.fcmp(Fcc0, Fcmpd, asDoubleReg(x), asDoubleReg(y)); break; default: throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -23,30 +23,41 @@ package com.oracle.graal.lir.sparc; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.asm.Assembler.LabelHint; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +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.Setx; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.StandardOp.BlockEndOp; 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 { - public static class ReturnOp extends SPARCLIRInstruction implements BlockEndOp { + public static final class ReturnOp extends SPARCLIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class); @Use({REG, ILLEGAL}) protected Value x; public ReturnOp(Value x) { + super(TYPE); this.x = x; } @@ -56,18 +67,19 @@ } public static void emitCodeHelper(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - new Ret().emit(masm); + masm.ret(); // On SPARC we always leave the frame (in the delay slot). crb.frameContext.leave(crb); } } - public static class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer { + public static final class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer { + public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class); private final SPARCCompare opcode; @Use({REG}) protected Value x; @Use({REG, CONST}) protected Value y; - protected final Condition condition; + private ConditionFlag conditionFlag; protected final LabelRef trueDestination; protected LabelHint trueDestinationHint; protected final LabelRef falseDestination; @@ -83,15 +95,17 @@ public CompareBranchOp(SPARCCompare opcode, Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue, double trueDestinationProbability) { + super(TYPE); this.opcode = opcode; this.x = x; this.y = y; - this.condition = condition; this.trueDestination = trueDestination; this.falseDestination = falseDestination; this.kind = kind; this.unorderedIsTrue = unorderedIsTrue; this.trueDestinationProbability = trueDestinationProbability; + CC conditionCodeReg = CC.forKind(kind); + conditionFlag = ConditionFlag.fromCondtition(conditionCodeReg, condition, unorderedIsTrue); } @Override @@ -101,24 +115,32 @@ } if (!emitted) { requestHints(masm); - if (canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) { + int targetPosition = getTargetPosition(masm); + if (canUseShortBranch(crb, masm, targetPosition)) { emitted = emitShortCompareBranch(crb, masm); } - if (!emitted) { + if (!emitted) { // No short compare/branch was used, so we go into fallback SPARCCompare.emit(crb, masm, opcode, x, y); - emitted = emitBranch(crb, masm, true); + emitted = emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, true, trueDestinationProbability); } } + assert emitted; + } - assert emitted; + private static int getTargetPosition(Assembler asm) { + return asm.position() + maximumSelfOffsetInstructions * asm.target.wordSize; } public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { requestHints(masm); // When we use short branches, no delay slot is available - if (!canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) { + int targetPosition = getTargetPosition(masm); + if (!canUseShortBranch(crb, masm, targetPosition)) { SPARCCompare.emit(crb, masm, opcode, x, y); - emitted = emitBranch(crb, masm, false); + emitted = emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, false, trueDestinationProbability); + if (emitted) { + delaySlotPosition = masm.position(); + } } } @@ -129,7 +151,6 @@ if (falseDestinationHint == null) { this.falseDestinationHint = masm.requestLabelHint(falseDestination.label()); } - } /** @@ -166,24 +187,25 @@ Value tmpValue; Value actualX = x; Value actualY = y; - Condition actualCondition = condition; + ConditionFlag actualConditionFlag = conditionFlag; Label actualTrueTarget = trueDestination.label(); Label actualFalseTarget = falseDestination.label(); Label tmpTarget; boolean needJump; if (crb.isSuccessorEdge(trueDestination)) { - actualCondition = actualCondition.negate(); + actualConditionFlag = conditionFlag.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)) { + int targetPosition = getTargetPosition(masm); + if (needJump && !isShortBranch(masm, targetPosition, 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(); + actualConditionFlag = actualConditionFlag.negate(); tmpTarget = actualTrueTarget; actualTrueTarget = actualFalseTarget; actualFalseTarget = tmpTarget; @@ -194,9 +216,8 @@ tmpValue = actualX; actualX = actualY; actualY = tmpValue; - actualCondition = actualCondition.mirror(); + actualConditionFlag = actualConditionFlag.mirror(); } - ConditionFlag conditionFlag = ConditionFlag.fromCondtition(CC.Icc, actualCondition, false); boolean isValidConstant = isConstant(actualY) && isSimm5(asConstant(actualY)); SPARCScratchRegister scratch = null; try { @@ -206,8 +227,8 @@ SPARCMove.move(crb, masm, scratchValue, actualY, SPARCDelayedControlTransfer.DUMMY); actualY = scratchValue; } - emitCBCond(masm, actualX, actualY, actualTrueTarget, conditionFlag); - new Nop().emit(masm); + emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag); + masm.nop(); } finally { if (scratch != null) { // release the scratch if used @@ -216,7 +237,7 @@ } if (needJump) { masm.jmp(actualFalseTarget); - new Nop().emit(masm); + masm.nop(); } return true; } @@ -229,26 +250,26 @@ case Int: if (isConstant(actualY)) { int constantY = asConstant(actualY).asInt(); - new CBcondw(conditionFlag, asIntReg(actualX), constantY, actualTrueTarget).emit(masm); + masm.cbcondw(conditionFlag, asIntReg(actualX), constantY, actualTrueTarget); } else { - new CBcondw(conditionFlag, asIntReg(actualX), asIntReg(actualY), actualTrueTarget).emit(masm); + masm.cbcondw(conditionFlag, asIntReg(actualX), asIntReg(actualY), actualTrueTarget); } break; case Long: if (isConstant(actualY)) { int constantY = (int) asConstant(actualY).asLong(); - new CBcondx(conditionFlag, asLongReg(actualX), constantY, actualTrueTarget).emit(masm); + masm.cbcondx(conditionFlag, asLongReg(actualX), constantY, actualTrueTarget); } else { - new CBcondx(conditionFlag, asLongReg(actualX), asLongReg(actualY), actualTrueTarget).emit(masm); + masm.cbcondx(conditionFlag, asLongReg(actualX), asLongReg(actualY), actualTrueTarget); } 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); + masm.cbcondx(conditionFlag, asObjectReg(actualX), 0, actualTrueTarget); } else { // this is already loaded - new CBcondx(conditionFlag, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget).emit(masm); + masm.cbcondx(conditionFlag, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget); } break; default: @@ -256,46 +277,6 @@ } } - public boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, boolean withDelayedNop) { - Label actualTarget; - Condition actualCondition; - boolean branchOnUnordered; - boolean needJump; - boolean predictBranchTaken; - if (crb.isSuccessorEdge(trueDestination)) { - actualCondition = condition != null ? condition.negate() : null; - actualTarget = falseDestination.label(); - predictBranchTaken = trueDestinationProbability < .5; // false branch needs jump - needJump = false; - branchOnUnordered = !unorderedIsTrue; - } else { - actualCondition = condition; - actualTarget = trueDestination.label(); - needJump = !crb.isSuccessorEdge(falseDestination); - predictBranchTaken = trueDestinationProbability >= .5; - branchOnUnordered = unorderedIsTrue; - } - if (!withDelayedNop && needJump) { - // We cannot make use of the delay slot when we jump in true-case and false-case - return false; - } - if (kind == Kind.Double || kind == Kind.Float) { - emitFloatBranch(masm, actualTarget, actualCondition, branchOnUnordered); - } else { - CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; - assert actualCondition != null; - SPARCControlFlow.emitBranch(masm, actualTarget, actualCondition, cc, predictBranchTaken); - } - delaySlotPosition = masm.position(); - if (withDelayedNop) { - new Nop().emit(masm); // delay slot - } - if (needJump) { - masm.jmp(falseDestination.label()); - } - return true; // emitted - } - private boolean canUseShortBranch(CompilationResultBuilder crb, SPARCAssembler asm, int position) { if (!asm.hasFeature(CPUFeature.CBCOND)) { return false; @@ -348,176 +329,68 @@ } } - public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { - // TODO: Condition code/flag handling needs to be improved; - protected final Condition condition; + public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { + public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class); protected final ConditionFlag conditionFlag; protected final LabelRef trueDestination; protected final LabelRef falseDestination; protected final Kind kind; - protected final boolean unorderedIsTrue; + protected final double trueDestinationProbability; - public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) { - this.conditionFlag = condition; + public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, Kind kind, double trueDestinationProbability) { + super(TYPE); this.trueDestination = trueDestination; this.falseDestination = falseDestination; this.kind = kind; - this.condition = null; - this.unorderedIsTrue = true; - } - - public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) { - this.condition = condition; - this.trueDestination = trueDestination; - this.falseDestination = falseDestination; - this.kind = kind; - this.conditionFlag = null; - this.unorderedIsTrue = true; - } - - public BranchOp(Condition finalCondition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue) { - this.trueDestination = trueDestination; - this.falseDestination = falseDestination; - this.kind = kind; - this.conditionFlag = null; - this.unorderedIsTrue = unorderedIsTrue; - this.condition = finalCondition; + this.conditionFlag = conditionFlag; + this.trueDestinationProbability = trueDestinationProbability; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - assert condition == null && conditionFlag != null || condition != null && conditionFlag == null; - Label actualTarget; - Condition actualCondition; - ConditionFlag actualConditionFlag; - boolean branchOnUnordered; - boolean needJump; - if (crb.isSuccessorEdge(trueDestination)) { - actualCondition = condition != null ? condition.negate() : null; - actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null; - actualTarget = falseDestination.label(); - needJump = false; - branchOnUnordered = !unorderedIsTrue; - } else { - actualCondition = condition; - actualConditionFlag = conditionFlag; - actualTarget = trueDestination.label(); - needJump = !crb.isSuccessorEdge(falseDestination); - branchOnUnordered = unorderedIsTrue; - } - assert kind == Kind.Int || kind == Kind.Long || kind == Kind.Object || kind == Kind.Double || kind == Kind.Float : kind; - if (kind == Kind.Double || kind == Kind.Float) { - emitFloatBranch(masm, actualTarget, actualCondition, branchOnUnordered); - } else { - CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; - if (actualCondition != null) { - emitBranch(masm, actualTarget, actualCondition, cc, false); - } else if (actualConditionFlag != null) { - emitBranch(masm, actualTarget, actualConditionFlag, cc); - } else { - GraalInternalError.shouldNotReachHere(); - } - } - new Nop().emit(masm); // delay slot - if (needJump) { - masm.jmp(falseDestination.label()); - } + emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, true, trueDestinationProbability); } } - private static void emitFloatBranch(SPARCMacroAssembler masm, Label target, Condition actualCondition, boolean branchOnUnordered) { - switch (actualCondition) { - case EQ: - if (branchOnUnordered) { - new Fbue(false, target).emit(masm); - } else { - new Fbe(false, target).emit(masm); - } - break; - case NE: - new Fbne(false, target).emit(masm); // Is also unordered - break; - case LT: - if (branchOnUnordered) { - new Fbul(false, target).emit(masm); - } else { - new Fbl(false, target).emit(masm); - } - break; - case LE: - if (branchOnUnordered) { - new Fbule(false, target).emit(masm); - } else { - new Fble(false, target).emit(masm); - } - break; - case GT: - if (branchOnUnordered) { - new Fbug(false, target).emit(masm); - } else { - new Fbg(false, target).emit(masm); - } - break; - case GE: - if (branchOnUnordered) { - new Fbuge(false, target).emit(masm); - } else { - new Fbge(false, target).emit(masm); - } - break; - case AE: - case AT: - case BT: - case BE: - throw GraalInternalError.unimplemented("Should not be required for float/dobule"); - default: - throw GraalInternalError.shouldNotReachHere(); + private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, + boolean withDelayedNop, double trueDestinationProbability) { + Label actualTarget; + ConditionFlag actualConditionFlag; + boolean needJump; + BranchPredict predictTaken; + if (falseDestination != null && crb.isSuccessorEdge(trueDestination)) { + actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null; + actualTarget = falseDestination.label(); + needJump = false; + predictTaken = trueDestinationProbability < .5d ? PREDICT_TAKEN : PREDICT_NOT_TAKEN; + } else { + actualConditionFlag = conditionFlag; + actualTarget = trueDestination.label(); + needJump = falseDestination != null && !crb.isSuccessorEdge(falseDestination); + predictTaken = trueDestinationProbability > .5d ? PREDICT_TAKEN : PREDICT_NOT_TAKEN; } + if (!withDelayedNop && needJump) { + // We cannot make use of the delay slot when we jump in true-case and false-case + return false; + } + + if (kind == Kind.Double || kind == Kind.Float) { + masm.fbpcc(actualConditionFlag, NOT_ANNUL, actualTarget, CC.Fcc0, predictTaken); + } else { + CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; + masm.bpcc(actualConditionFlag, NOT_ANNUL, actualTarget, cc, predictTaken); + } + if (withDelayedNop) { + masm.nop(); // delay slot + } + if (needJump) { + masm.jmp(falseDestination.label()); + } + return true; } - private static void emitBranch(SPARCMacroAssembler masm, Label target, ConditionFlag actualCondition, CC cc) { - new Fmt00c(0, actualCondition, Op2s.Bp, cc, 0, target).emit(masm); - } - - private static void emitBranch(SPARCMacroAssembler masm, Label target, Condition actualCondition, CC cc, boolean predictTaken) { - - switch (actualCondition) { - case EQ: - new Bpe(cc, false, predictTaken, target).emit(masm); - break; - case NE: - new Bpne(cc, false, predictTaken, target).emit(masm); - break; - case BT: - new Bplu(cc, false, predictTaken, target).emit(masm); - break; - case LT: - new Bpl(cc, false, predictTaken, target).emit(masm); - break; - case BE: - new Bpleu(cc, false, predictTaken, target).emit(masm); - break; - case LE: - new Bple(cc, false, predictTaken, target).emit(masm); - break; - case GE: - new Bpge(cc, false, predictTaken, target).emit(masm); - break; - case AE: - new Bpgeu(cc, false, predictTaken, target).emit(masm); - break; - case GT: - new Bpg(cc, false, predictTaken, target).emit(masm); - break; - case AT: - new Bpgu(cc, false, predictTaken, target).emit(masm); - break; - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp { + public static final class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class); @Use({CONST}) protected JavaConstant[] keyConstants; private final LabelRef[] keyTargets; private LabelRef defaultTarget; @@ -526,6 +399,7 @@ private final SwitchStrategy strategy; public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { + super(TYPE); this.strategy = strategy; this.keyConstants = strategy.keyConstants; this.keyTargets = keyTargets; @@ -543,47 +417,42 @@ BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) { @Override protected void conditionalJump(int index, Condition condition, Label target) { + SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); + CC conditionCode; + Register scratchRegister; switch (key.getKind()) { case Char: case Byte: case Short: case Int: - if (crb.codeCache.needsDataPatch(keyConstants[index])) { - crb.recordInlineDataInCode(keyConstants[index]); - } - long lc = keyConstants[index].asLong(); - if (SPARCAssembler.isSimm13(lc)) { - assert NumUtil.isInt(lc); - new Cmp(keyRegister, (int) lc).emit(masm); - } else { - new Setx(lc, asIntReg(scratch)).emit(masm); - new Cmp(keyRegister, asIntReg(scratch)).emit(masm); - } - emitBranch(masm, target, condition, CC.Icc, false); + conditionCode = CC.Icc; + scratchRegister = asIntReg(scratch); break; case Long: { - SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); - new Cmp(keyRegister, asLongReg(scratch)).emit(masm); - emitBranch(masm, target, condition, CC.Xcc, false); + conditionCode = CC.Xcc; + scratchRegister = asLongReg(scratch); break; } case Object: { - SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); - new Cmp(keyRegister, asObjectReg(scratch)).emit(masm); - emitBranch(masm, target, condition, CC.Ptrcc, false); + conditionCode = CC.Ptrcc; + scratchRegister = asObjectReg(scratch); break; } default: throw new GraalInternalError("switch only supported for int, long and object"); } - new Nop().emit(masm); // delay slot + ConditionFlag conditionFlag = ConditionFlag.fromCondtition(conditionCode, condition, false); + masm.cmp(keyRegister, scratchRegister); + masm.bpcc(conditionFlag, NOT_ANNUL, target, conditionCode, PREDICT_TAKEN); + masm.nop(); // delay slot } }; strategy.run(closure); } } - public static class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp { + public static final class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class); private final int lowKey; private final LabelRef defaultTarget; @@ -592,6 +461,7 @@ @Temp protected Value scratch; public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) { + super(TYPE); this.lowKey = lowKey; this.defaultTarget = defaultTarget; this.targets = targets; @@ -609,53 +479,53 @@ // subtract the low value from the switch value if (isSimm13(lowKey)) { - new Sub(value, lowKey, scratchReg).emit(masm); + masm.sub(value, lowKey, scratchReg); } else { try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch2 = sc.getRegister(); new Setx(lowKey, scratch2).emit(masm); - new Sub(value, scratch2, scratchReg).emit(masm); + masm.sub(value, scratch2, scratchReg); } } int upperLimit = highKey - lowKey; try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch2 = sc.getRegister(); if (isSimm13(upperLimit)) { - new Cmp(scratchReg, upperLimit).emit(masm); + masm.cmp(scratchReg, upperLimit); } else { new Setx(upperLimit, scratch2).emit(masm); - new Cmp(scratchReg, upperLimit).emit(masm); + masm.cmp(scratchReg, upperLimit); } // Jump to default target if index is not within the jump table if (defaultTarget != null) { - new Bpgu(CC.Icc, defaultTarget.label()).emit(masm); - new Nop().emit(masm); // delay slot + masm.bpcc(GreaterUnsigned, NOT_ANNUL, defaultTarget.label(), Icc, PREDICT_TAKEN); + masm.nop(); // delay slot } // Load jump table entry into scratch and jump to it - new Sll(scratchReg, 3, scratchReg).emit(masm); // Multiply by 8 + masm.sll(scratchReg, 3, scratchReg); // Multiply by 8 // Zero the left bits sll with shcnt>0 does not mask upper 32 bits - new Srl(scratchReg, 0, scratchReg).emit(masm); - new Rdpc(scratch2).emit(masm); + masm.srl(scratchReg, 0, scratchReg); + masm.rdpc(scratch2); // The jump table follows four instructions after rdpc - new Add(scratchReg, 4 * 4, scratchReg).emit(masm); - new Jmpl(scratch2, scratchReg, g0).emit(masm); + masm.add(scratchReg, 4 * 4, scratchReg); + masm.jmpl(scratch2, scratchReg, g0); } - new Nop().emit(masm); - // new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8) + masm.nop(); // Emit jump table entries for (LabelRef target : targets) { - new Bpa(target.label()).emit(masm); - new Nop().emit(masm); // delay slot + masm.bpcc(Always, NOT_ANNUL, target.label(), Xcc, PREDICT_TAKEN); + masm.nop(); // delay slot } } } @Opcode("CMOVE") - public static class CondMoveOp extends SPARCLIRInstruction { + public static final class CondMoveOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<CondMoveOp> TYPE = LIRInstructionClass.create(CondMoveOp.class); private final Kind kind; @@ -667,6 +537,7 @@ private final CC cc; public CondMoveOp(Kind kind, Variable result, CC cc, ConditionFlag condition, Value trueValue, Value falseValue) { + super(TYPE); this.kind = kind; this.result = result; this.condition = condition; @@ -677,8 +548,6 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - // check that we don't overwrite an input operand before it is used. - // assert !result.equals(trueValue); if (result.equals(trueValue)) { // We have the true value in place, do he opposite cmove(masm, cc, kind, result, condition.negate(), falseValue); } else if (result.equals(falseValue)) { @@ -708,9 +577,9 @@ } else { constant = asConstant(other).asInt(); } - new Movcc(cond, cc, constant, asRegister(result)).emit(masm); + masm.movcc(cond, cc, constant, asRegister(result)); } else { - new Movcc(cond, cc, asRegister(other), asRegister(result)).emit(masm); + masm.movcc(cond, cc, asRegister(other), asRegister(result)); } break; case Long: @@ -722,17 +591,16 @@ } else { constant = asConstant(other).asLong(); } - assert isSimm11(constant); - new Movcc(cond, cc, (int) constant, asRegister(result)).emit(masm); + masm.movcc(cond, cc, (int) constant, asRegister(result)); } else { - new Movcc(cond, cc, asRegister(other), asRegister(result)).emit(masm); + masm.movcc(cond, cc, asRegister(other), asRegister(result)); } break; case Float: - new Fmovscc(cond, cc, asFloatReg(other), asFloatReg(result)).emit(masm); + masm.fmovscc(cond, cc, asFloatReg(other), asFloatReg(result)); break; case Double: - new Fmovdcc(cond, cc, asDoubleReg(other), asDoubleReg(result)).emit(masm); + masm.fmovdcc(cond, cc, asDoubleReg(other), asDoubleReg(result)); break; default: throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ * * <pre> * Base Contents - * + * * : : ----- * caller | incoming overflow argument n | ^ * frame : ... : | positive
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,25 +22,27 @@ */ package com.oracle.graal.lir.sparc; -import com.oracle.graal.asm.sparc.SPARCAssembler.Bpa; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; + +import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.asm.*; -public class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer { +public final class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer { + public static final LIRInstructionClass<SPARCJumpOp> TYPE = LIRInstructionClass.create(SPARCJumpOp.class); private boolean emitDone = false; private int delaySlotPosition = -1; public SPARCJumpOp(LabelRef destination) { - super(destination); + super(TYPE, destination); } public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { assert !emitDone; if (!crb.isSuccessorEdge(destination())) { - new Bpa(destination().label()).emit(masm); + masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label()); delaySlotPosition = masm.position(); } emitDone = true; @@ -51,8 +53,8 @@ if (!crb.isSuccessorEdge(destination())) { if (!emitDone) { SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; - new Bpa(destination().label()).emit(masm); - new Nop().emit(masm); + masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label()); + masm.nop(); } else { assert crb.asm.position() - delaySlotPosition == 4; }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -29,7 +29,13 @@ /** * Convenience class to provide SPARCMacroAssembler for the {@link #emitCode} method. */ -public abstract class SPARCLIRInstruction extends LIRInstructionBase { +public abstract class SPARCLIRInstruction extends LIRInstruction { + public static final LIRInstructionClass<SPARCLIRInstruction> TYPE = LIRInstructionClass.create(SPARCLIRInstruction.class); + + protected SPARCLIRInstruction(LIRInstructionClass<? extends LIRInstruction> c) { + super(c); + } + protected SPARCDelayedControlTransfer delayedControlTransfer = SPARCDelayedControlTransfer.DUMMY; @Override
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,13 +25,13 @@ import static com.oracle.graal.api.code.ValueUtil.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -public class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { +public final class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<SPARCMathIntrinsicOp> TYPE = LIRInstructionClass.create(SPARCMathIntrinsicOp.class); public enum IntrinsicOpcode { SQRT, @@ -48,6 +48,7 @@ @Use protected Value input; public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) { + super(TYPE); this.opcode = opcode; this.result = result; this.input = input; @@ -61,10 +62,10 @@ case SQRT: switch (inputKind) { case Float: - new Fsqrts(asFloatReg(input), asFloatReg(result)).emit(masm); + masm.fsqrts(asFloatReg(input), asFloatReg(result)); break; case Double: - new Fsqrtd(asDoubleReg(input), asDoubleReg(result)).emit(masm); + masm.fsqrtd(asDoubleReg(input), asDoubleReg(result)); break; default: GraalInternalError.shouldNotReachHere(); @@ -73,10 +74,10 @@ case ABS: switch (inputKind) { case Float: - new Fabss(asFloatReg(input), asFloatReg(result)).emit(masm); + masm.fabss(asFloatReg(input), asFloatReg(result)); break; case Double: - new Fabsd(asDoubleReg(input), asDoubleReg(result)).emit(masm); + masm.fabsd(asDoubleReg(input), asDoubleReg(result)); break; default: GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -31,35 +31,6 @@ 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.Add; -import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovd; -import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovs; -import com.oracle.graal.asm.sparc.SPARCAssembler.Fzerod; -import com.oracle.graal.asm.sparc.SPARCAssembler.Fzeros; -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.Lduh; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; -import com.oracle.graal.asm.sparc.SPARCAssembler.Membar; -import com.oracle.graal.asm.sparc.SPARCAssembler.Movdtox; -import com.oracle.graal.asm.sparc.SPARCAssembler.Movstosw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Movstouw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Movwtos; -import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod; -import com.oracle.graal.asm.sparc.SPARCAssembler.Or; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stb; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stdf; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stf; -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.Cas; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Casx; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Clr; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; @@ -74,11 +45,13 @@ @Opcode("MOVE_TOREG") public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<MoveToRegOp> TYPE = LIRInstructionClass.create(MoveToRegOp.class); @Def({REG, HINT}) protected AllocatableValue result; @Use({REG, STACK, CONST}) protected Value input; public MoveToRegOp(AllocatableValue result, Value input) { + super(TYPE); this.result = result; this.input = input; } @@ -100,12 +73,14 @@ } @Opcode("MOVE_FROMREG") - public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<MoveFromRegOp> TYPE = LIRInstructionClass.create(MoveFromRegOp.class); @Def({REG, STACK}) protected AllocatableValue result; @Use({REG, CONST, HINT}) protected Value input; public MoveFromRegOp(AllocatableValue result, Value input) { + super(TYPE); this.result = result; this.input = input; } @@ -130,14 +105,15 @@ * Move between floating-point and general purpose register domain (WITHOUT VIS3). */ @Opcode("MOVE") - public static class MoveFpGp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final class MoveFpGp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<MoveFpGp> TYPE = LIRInstructionClass.create(MoveFpGp.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; @Use({STACK}) protected StackSlotValue temp; public MoveFpGp(AllocatableValue result, AllocatableValue input, StackSlotValue temp) { - super(); + super(TYPE); this.result = result; this.input = input; this.temp = temp; @@ -163,11 +139,11 @@ switch (inputKind) { case Float: assert resultKindSize == 4; - new Stf(asFloatReg(input), tempAddress).emit(masm); + masm.stf(asFloatReg(input), tempAddress); break; case Double: assert resultKindSize == 8; - new Stdf(asDoubleReg(input), tempAddress).emit(masm); + masm.stdf(asDoubleReg(input), tempAddress); break; case Long: case Int: @@ -175,13 +151,13 @@ case Char: case Byte: if (resultKindSize == 8) { - new Stx(asLongReg(input), tempAddress).emit(masm); + masm.stx(asLongReg(input), tempAddress); } else if (resultKindSize == 4) { - new Stw(asIntReg(input), tempAddress).emit(masm); + masm.stw(asIntReg(input), tempAddress); } else if (resultKindSize == 2) { - new Sth(asIntReg(input), tempAddress).emit(masm); + masm.sth(asIntReg(input), tempAddress); } else if (resultKindSize == 1) { - new Stb(asIntReg(input), tempAddress).emit(masm); + masm.stb(asIntReg(input), tempAddress); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -192,25 +168,25 @@ delayedControlTransfer.emitControlTransfer(crb, masm); switch (resultKind) { case Long: - new Ldx(tempAddress, asLongReg(result)).emit(masm); + masm.ldx(tempAddress, asLongReg(result)); break; case Int: - new Ldsw(tempAddress, asIntReg(result)).emit(masm); + masm.ldsw(tempAddress, asIntReg(result)); break; case Short: - new Ldsh(tempAddress, asIntReg(input)).emit(masm); + masm.ldsh(tempAddress, asIntReg(input)); break; case Char: - new Lduh(tempAddress, asIntReg(input)).emit(masm); + masm.lduh(tempAddress, asIntReg(input)); break; case Byte: - new Ldsb(tempAddress, asIntReg(input)).emit(masm); + masm.ldsb(tempAddress, asIntReg(input)); break; case Float: - new Ldf(tempAddress, asFloatReg(result)).emit(masm); + masm.ldf(tempAddress, asFloatReg(result)); break; case Double: - new Lddf(tempAddress, asDoubleReg(result)).emit(masm); + masm.lddf(tempAddress, asDoubleReg(result)); break; default: GraalInternalError.shouldNotReachHere(); @@ -224,13 +200,14 @@ * Move between floating-point and general purpose register domain (WITH VIS3). */ @Opcode("MOVE") - public static class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<MoveFpGpVIS3> TYPE = LIRInstructionClass.create(MoveFpGpVIS3.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; public MoveFpGpVIS3(AllocatableValue result, AllocatableValue input) { - super(); + super(TYPE); this.result = result; this.input = input; } @@ -250,25 +227,25 @@ delayedControlTransfer.emitControlTransfer(crb, masm); if (resultKind == Float) { if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { - new Movwtos(asIntReg(input), asFloatReg(result)).emit(masm); + masm.movwtos(asIntReg(input), asFloatReg(result)); } else { throw GraalInternalError.shouldNotReachHere(); } } else if (resultKind == Double) { if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { - new Movxtod(asIntReg(input), asDoubleReg(result)).emit(masm); + masm.movxtod(asIntReg(input), asDoubleReg(result)); } else { - new Movxtod(asLongReg(input), asDoubleReg(result)).emit(masm); + masm.movxtod(asLongReg(input), asDoubleReg(result)); } } else if (inputKind == Float) { if (resultKind == Int || resultKind == Short || resultKind == Byte) { - new Movstosw(asFloatReg(input), asIntReg(result)).emit(masm); + masm.movstosw(asFloatReg(input), asIntReg(result)); } else { - new Movstouw(asFloatReg(input), asIntReg(result)).emit(masm); + masm.movstouw(asFloatReg(input), asIntReg(result)); } } else if (inputKind == Double) { if (resultKind == Long) { - new Movdtox(asDoubleReg(input), asLongReg(result)).emit(masm); + masm.movdtox(asDoubleReg(input), asLongReg(result)); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -277,12 +254,14 @@ } public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck { + public static final LIRInstructionClass<MemOp> TYPE = LIRInstructionClass.create(MemOp.class); protected final Kind kind; @Use({COMPOSITE}) protected SPARCAddressValue address; @State protected LIRFrameState state; - public MemOp(Kind kind, SPARCAddressValue address, LIRFrameState state) { + public MemOp(LIRInstructionClass<? extends MemOp> c, Kind kind, SPARCAddressValue address, LIRFrameState state) { + super(c); this.kind = kind; this.address = address; this.state = state; @@ -304,12 +283,13 @@ } } - public static class LoadOp extends MemOp implements SPARCTailDelayedLIRInstruction { + public static final class LoadOp extends MemOp implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<LoadOp> TYPE = LIRInstructionClass.create(LoadOp.class); @Def({REG}) protected AllocatableValue result; public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.result = result; } @@ -326,28 +306,28 @@ switch (kind) { case Boolean: case Byte: - new Ldsb(addr, dst).emit(masm); + masm.ldsb(addr, dst); break; case Short: - new Ldsh(addr, dst).emit(masm); + masm.ldsh(addr, dst); break; case Char: - new Lduh(addr, dst).emit(masm); + masm.lduh(addr, dst); break; case Int: - new Ldsw(addr, dst).emit(masm); + masm.ldsw(addr, dst); break; case Long: - new Ldx(addr, dst).emit(masm); + masm.ldx(addr, dst); break; case Float: - new Ldf(addr, dst).emit(masm); + masm.ldf(addr, dst); break; case Double: - new Lddf(addr, dst).emit(masm); + masm.lddf(addr, dst); break; case Object: - new Ldx(addr, dst).emit(masm); + masm.ldx(addr, dst); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -356,12 +336,14 @@ } } - public static class LoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final class LoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<LoadAddressOp> TYPE = LIRInstructionClass.create(LoadAddressOp.class); @Def({REG}) protected AllocatableValue result; @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue addressValue; public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) { + super(TYPE); this.result = result; this.addressValue = address; } @@ -373,12 +355,14 @@ } } - public static class LoadDataAddressOp extends SPARCLIRInstruction { + public static final class LoadDataAddressOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<LoadDataAddressOp> TYPE = LIRInstructionClass.create(LoadDataAddressOp.class); @Def({REG}) protected AllocatableValue result; private final byte[] data; public LoadDataAddressOp(AllocatableValue result, byte[] data) { + super(TYPE); this.result = result; this.data = data; } @@ -393,26 +377,30 @@ } } - public static class MembarOp extends SPARCLIRInstruction { + public static final class MembarOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<MembarOp> TYPE = LIRInstructionClass.create(MembarOp.class); private final int barriers; public MembarOp(final int barriers) { + super(TYPE); this.barriers = barriers; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - new Membar(barriers).emit(masm); + masm.membar(barriers); } } - public static class NullCheckOp extends SPARCLIRInstruction implements NullCheck, SPARCTailDelayedLIRInstruction { + public static final class NullCheckOp extends SPARCLIRInstruction implements NullCheck, SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<NullCheckOp> TYPE = LIRInstructionClass.create(NullCheckOp.class); @Use({REG}) protected AllocatableValue input; @State protected LIRFrameState state; public NullCheckOp(Variable input, LIRFrameState state) { + super(TYPE); this.input = input; this.state = state; } @@ -421,7 +409,7 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { delayedControlTransfer.emitControlTransfer(crb, masm); crb.recordImplicitException(masm.position(), state); - new Ldx(new SPARCAddress(asRegister(input), 0), r0).emit(masm); + masm.ldx(new SPARCAddress(asRegister(input), 0), g0); } public Value getCheckedValue() { @@ -434,7 +422,8 @@ } @Opcode("CAS") - public static class CompareAndSwapOp extends SPARCLIRInstruction { + public static final class CompareAndSwapOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<CompareAndSwapOp> TYPE = LIRInstructionClass.create(CompareAndSwapOp.class); @Def({REG, HINT}) protected AllocatableValue result; @Alive({REG}) protected AllocatableValue address; @@ -442,6 +431,7 @@ @Use({REG}) protected AllocatableValue newValue; public CompareAndSwapOp(AllocatableValue result, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + super(TYPE); this.result = result; this.address = address; this.cmpValue = cmpValue; @@ -455,12 +445,14 @@ } } - public static class StackLoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final class StackLoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<StackLoadAddressOp> TYPE = LIRInstructionClass.create(StackLoadAddressOp.class); @Def({REG}) protected AllocatableValue result; @Use({STACK, UNINITIALIZED}) protected StackSlotValue slot; public StackLoadAddressOp(AllocatableValue result, StackSlotValue address) { + super(TYPE); this.result = result; this.slot = address; } @@ -476,26 +468,27 @@ if (address.getIndex().equals(Register.None)) { if (isSimm13(address.getDisplacement())) { delaySlotHolder.emitControlTransfer(crb, masm); - new Add(address.getBase(), address.getDisplacement(), result).emit(masm); + masm.add(address.getBase(), address.getDisplacement(), result); } else { assert result.encoding() != address.getBase().encoding(); new Setx(address.getDisplacement(), result).emit(masm); // No relocation, therefore, the add can be delayed as well delaySlotHolder.emitControlTransfer(crb, masm); - new Add(address.getBase(), result, result).emit(masm); + masm.add(address.getBase(), result, result); } } else { delaySlotHolder.emitControlTransfer(crb, masm); - new Add(address.getBase(), address.getIndex(), result).emit(masm); + masm.add(address.getBase(), address.getIndex(), result); } } public static class StoreOp extends MemOp implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<StoreOp> TYPE = LIRInstructionClass.create(StoreOp.class); @Use({REG}) protected AllocatableValue input; public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.input = input; } @@ -512,26 +505,26 @@ switch (kind) { case Boolean: case Byte: - new Stb(asRegister(input), addr).emit(masm); + masm.stb(asRegister(input), addr); break; case Short: case Char: - new Sth(asRegister(input), addr).emit(masm); + masm.sth(asRegister(input), addr); break; case Int: - new Stw(asRegister(input), addr).emit(masm); + masm.stw(asRegister(input), addr); break; case Long: - new Stx(asRegister(input), addr).emit(masm); + masm.stx(asRegister(input), addr); break; case Object: - new Stx(asRegister(input), addr).emit(masm); + masm.stx(asRegister(input), addr); break; case Float: - new Stf(asRegister(input), addr).emit(masm); + masm.stf(asRegister(input), addr); break; case Double: - new Stdf(asRegister(input), addr).emit(masm); + masm.stdf(asRegister(input), addr); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + kind); @@ -540,12 +533,13 @@ } } - public static class StoreConstantOp extends MemOp implements SPARCTailDelayedLIRInstruction { + public static final class StoreConstantOp extends MemOp implements SPARCTailDelayedLIRInstruction { + public static final LIRInstructionClass<StoreConstantOp> TYPE = LIRInstructionClass.create(StoreConstantOp.class); protected final JavaConstant input; public StoreConstantOp(Kind kind, SPARCAddressValue address, JavaConstant input, LIRFrameState state) { - super(kind, address, state); + super(TYPE, kind, address, state); this.input = input; if (!input.isDefaultForKind()) { throw GraalInternalError.shouldNotReachHere("Can only store null constants to memory"); @@ -564,18 +558,18 @@ switch (kind) { case Boolean: case Byte: - new Stb(g0, addr).emit(masm); + masm.stb(g0, addr); break; case Short: case Char: - new Sth(g0, addr).emit(masm); + masm.sth(g0, addr); break; case Int: - new Stw(g0, addr).emit(masm); + masm.stw(g0, addr); break; case Long: case Object: - new Stx(g0, addr).emit(masm); + masm.stx(g0, addr); break; case Float: case Double: @@ -614,7 +608,7 @@ Register scratch = sc.getRegister(); long value = constant.asLong(); if (isSimm13(value)) { - new Or(g0, (int) value, scratch).emit(masm); + masm.or(g0, (int) value, scratch); } else { new Setx(value, scratch).emit(masm); } @@ -644,18 +638,18 @@ case Long: case Object: delaySlotLir.emitControlTransfer(crb, masm); - new Mov(src, dst).emit(masm); + masm.mov(src, dst); break; case Float: if (result.getPlatformKind() == Kind.Float) { - new Fmovs(src, dst).emit(masm); + masm.fmovs(src, dst); } else { throw GraalInternalError.shouldNotReachHere(); } break; case Double: if (result.getPlatformKind() == Kind.Double) { - new Fmovd(src, dst).emit(masm); + masm.fmovd(src, dst); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -695,24 +689,24 @@ switch (input.getKind()) { case Byte: case Boolean: - new Stb(src, dst).emit(masm); + masm.stb(src, dst); break; case Char: case Short: - new Sth(src, dst).emit(masm); + masm.sth(src, dst); break; case Int: - new Stw(src, dst).emit(masm); + masm.stw(src, dst); break; case Long: case Object: - new Stx(src, dst).emit(masm); + masm.stx(src, dst); break; case Float: - new Stf(src, dst).emit(masm); + masm.stf(src, dst); break; case Double: - new Stdf(src, dst).emit(masm); + masm.stdf(src, dst); break; default: throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind() + "(" + input + ")"); @@ -730,26 +724,26 @@ switch (input.getKind()) { case Boolean: case Byte: - new Ldsb(src, dst).emit(masm); + masm.ldsb(src, dst); break; case Short: - new Ldsh(src, dst).emit(masm); + masm.ldsh(src, dst); break; case Char: - new Lduh(src, dst).emit(masm); + masm.lduh(src, dst); break; case Int: - new Ldsw(src, dst).emit(masm); + masm.ldsw(src, dst); break; case Long: case Object: - new Ldx(src, dst).emit(masm); + masm.ldx(src, dst); break; case Float: - new Ldf(src, dst).emit(masm); + masm.ldf(src, dst); break; case Double: - new Lddf(src, dst).emit(masm); + masm.lddf(src, dst); break; default: throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind()); @@ -765,10 +759,10 @@ case Int: if (input.isDefaultForKind()) { delaySlotLir.emitControlTransfer(crb, masm); - new Clr(asIntReg(result)).emit(masm); + masm.clr(asIntReg(result)); } else if (isSimm13(input.asLong())) { delaySlotLir.emitControlTransfer(crb, masm); - new Or(g0, input.asInt(), asIntReg(result)).emit(masm); + masm.or(g0, input.asInt(), asIntReg(result)); } else { Setx set = new Setx(input.asLong(), asIntReg(result), false, true); set.emitFirstPartOfDelayed(masm); @@ -779,10 +773,10 @@ case Long: if (input.isDefaultForKind()) { delaySlotLir.emitControlTransfer(crb, masm); - new Clr(asLongReg(result)).emit(masm); + masm.clr(asLongReg(result)); } else if (isSimm13(input.asLong())) { delaySlotLir.emitControlTransfer(crb, masm); - new Or(g0, (int) input.asLong(), asLongReg(result)).emit(masm); + masm.or(g0, (int) input.asLong(), asLongReg(result)); } else { Setx setx = new Setx(input.asLong(), asLongReg(result), false, true); setx.emitFirstPartOfDelayed(masm); @@ -795,24 +789,24 @@ int constantBits = java.lang.Float.floatToIntBits(constant); if (constantBits == 0) { delaySlotLir.emitControlTransfer(crb, masm); - new Fzeros(asFloatReg(result)).emit(masm); + masm.fzeros(asFloatReg(result)); } else { if (hasVIS3) { if (isSimm13(constantBits)) { - new Or(g0, constantBits, scratch).emit(masm); + masm.or(g0, constantBits, scratch); } else { new Setx(constantBits, scratch, false).emit(masm); } delaySlotLir.emitControlTransfer(crb, masm); // Now load the float value - new Movwtos(scratch, asFloatReg(result)).emit(masm); + masm.movwtos(scratch, asFloatReg(result)); } else { crb.asFloatConstRef(input); // First load the address into the scratch register new Setx(0, scratch, true).emit(masm); // Now load the float value delaySlotLir.emitControlTransfer(crb, masm); - new Ldf(scratch, asFloatReg(result)).emit(masm); + masm.ldf(new SPARCAddress(scratch, 0), asFloatReg(result)); } } break; @@ -822,24 +816,24 @@ long constantBits = java.lang.Double.doubleToLongBits(constant); if (constantBits == 0) { delaySlotLir.emitControlTransfer(crb, masm); - new Fzerod(asDoubleReg(result)).emit(masm); + masm.fzerod(asDoubleReg(result)); } else { if (hasVIS3) { if (isSimm13(constantBits)) { - new Or(g0, (int) constantBits, scratch).emit(masm); + masm.or(g0, (int) constantBits, scratch); } else { new Setx(constantBits, scratch, false).emit(masm); } delaySlotLir.emitControlTransfer(crb, masm); // Now load the float value - new Movxtod(scratch, asDoubleReg(result)).emit(masm); + masm.movxtod(scratch, asDoubleReg(result)); } else { crb.asDoubleConstRef(input); // First load the address into the scratch register new Setx(0, scratch, true).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); // Now load the float value - new Lddf(scratch, asDoubleReg(result)).emit(masm); + masm.lddf(new SPARCAddress(scratch, 0), asDoubleReg(result)); } } break; @@ -847,7 +841,7 @@ case Object: if (input.isNull()) { delaySlotLir.emitControlTransfer(crb, masm); - new Clr(asRegister(result)).emit(masm); + masm.clr(asRegister(result)); } else if (crb.target.inlineObjects) { crb.recordInlineDataInCode(input); // relocatable cannot be delayed new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm); @@ -864,11 +858,11 @@ protected static void compareAndSwap(SPARCMacroAssembler masm, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue) { switch (cmpValue.getKind()) { case Int: - new Cas(asRegister(address), asRegister(cmpValue), asRegister(newValue)).emit(masm); + masm.cas(asRegister(address), asRegister(cmpValue), asRegister(newValue)); break; case Long: case Object: - new Casx(asRegister(address), asRegister(cmpValue), asRegister(newValue)).emit(masm); + masm.casx(asRegister(address), asRegister(cmpValue), asRegister(newValue)); break; default: throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -29,8 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; -import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.asm.*; @@ -42,6 +40,7 @@ */ @Opcode("SAVE_REGISTER") public class SPARCSaveRegistersOp extends SPARCLIRInstruction implements SaveRegistersOp { + public static final LIRInstructionClass<SPARCSaveRegistersOp> TYPE = LIRInstructionClass.create(SPARCSaveRegistersOp.class); public static final Register RETURN_REGISTER_STORAGE = SPARC.d62; /** * The registers (potentially) saved by this operation. @@ -66,6 +65,7 @@ * @param supportsRemove determines if registers can be {@linkplain #remove(Set) pruned} */ public SPARCSaveRegistersOp(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) { + super(TYPE); assert Arrays.asList(savedRegisterLocations).stream().allMatch(ValueUtil::isVirtualStackSlot); this.savedRegisters = savedRegisters; this.slots = savedRegisterLocations; @@ -84,8 +84,8 @@ // We abuse the first stackslot for transferring i0 to return_register_storage // assert slots.length >= 1; SPARCAddress slot0Address = (SPARCAddress) crb.asAddress(slots[0]); - new Stx(SPARC.i0, slot0Address).emit(masm); - new Lddf(slot0Address, RETURN_REGISTER_STORAGE).emit(masm); + masm.stx(SPARC.i0, slot0Address); + masm.lddf(slot0Address, RETURN_REGISTER_STORAGE); // Now save the registers for (int i = 0; i < savedRegisters.length; i++) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -24,20 +24,22 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static com.oracle.graal.asm.sparc.SPARCAssembler.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; public class SPARCTestOp extends SPARCLIRInstruction { + public static final LIRInstructionClass<SPARCTestOp> TYPE = LIRInstructionClass.create(SPARCTestOp.class); @Use({REG}) protected Value x; @Use({REG, CONST}) protected Value y; public SPARCTestOp(Value x, Value y) { + super(TYPE); this.x = x; this.y = y; } @@ -51,10 +53,10 @@ case Char: case Boolean: case Int: - new Andcc(asIntReg(x), asIntReg(y), g0).emit(masm); + masm.andcc(asIntReg(x), asIntReg(y), g0); break; case Long: - new Andcc(asLongReg(x), asLongReg(y), g0).emit(masm); + masm.andcc(asLongReg(x), asLongReg(y), g0); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -66,10 +68,10 @@ case Char: case Boolean: case Int: - new Andcc(asIntReg(x), crb.asIntConst(y), g0).emit(masm); + masm.andcc(asIntReg(x), crb.asIntConst(y), g0); break; case Long: - new Andcc(asLongReg(x), crb.asIntConst(y), g0).emit(masm); + masm.andcc(asLongReg(x), crb.asIntConst(y), g0); break; default: throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -39,12 +39,13 @@ public class CompositeValueReplacementTest1 { private static class NestedCompositeValue extends CompositeValue { + public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); private static final long serialVersionUID = -8804214200173503527L; @Component({REG, OperandFlag.ILLEGAL}) protected Value value; public NestedCompositeValue(Value value) { - super(LIRKind.Illegal); + super(TYPE, LIRKind.Illegal); this.value = value; } @@ -94,11 +95,13 @@ } - private static class TestOp extends LIRInstructionBase { + private static final class TestOp extends LIRInstruction { + public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); @Use({COMPOSITE}) protected NestedCompositeValue compValue; public TestOp(NestedCompositeValue compValue) { + super(TYPE); this.compValue = compValue; }
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,12 +40,13 @@ public class CompositeValueReplacementTest2 { private static class NestedCompositeValue extends CompositeValue { + public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); private static final long serialVersionUID = -8804214200173503527L; @Component({REG, OperandFlag.ILLEGAL}) protected Value[] values; public NestedCompositeValue(Value value) { - super(LIRKind.Illegal); + super(TYPE, LIRKind.Illegal); this.values = new Value[]{value}; } @@ -95,11 +96,13 @@ } - private static class TestOp extends LIRInstructionBase { + private static final class TestOp extends LIRInstruction { + public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); @Use({COMPOSITE}) protected NestedCompositeValue compValue; public TestOp(NestedCompositeValue compValue) { + super(TYPE); this.compValue = compValue; }
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest3.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest3.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,12 +40,13 @@ public class CompositeValueReplacementTest3 { private static class NestedCompositeValue extends CompositeValue { + public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); private static final long serialVersionUID = -8804214200173503527L; @Component({REG, OperandFlag.ILLEGAL}) protected Value value; public NestedCompositeValue(Value value) { - super(LIRKind.Illegal); + super(TYPE, LIRKind.Illegal); this.value = value; } @@ -95,11 +96,13 @@ } - private static class TestOp extends LIRInstructionBase { + private static final class TestOp extends LIRInstruction { + public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); @Use({COMPOSITE}) protected NestedCompositeValue compValue; public TestOp(NestedCompositeValue compValue) { + super(TYPE); this.compValue = compValue; }
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest4.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest4.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,12 +40,13 @@ public class CompositeValueReplacementTest4 { private static class NestedCompositeValue extends CompositeValue { + public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); private static final long serialVersionUID = -8804214200173503527L; @Component({REG, OperandFlag.ILLEGAL}) protected Value[] values; public NestedCompositeValue(Value value) { - super(LIRKind.Illegal); + super(TYPE, LIRKind.Illegal); this.values = new Value[]{value}; } @@ -95,11 +96,13 @@ } - private static class TestOp extends LIRInstructionBase { + private static class TestOp extends LIRInstruction { + public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); @Use({COMPOSITE}) protected NestedCompositeValue compValue; public TestOp(NestedCompositeValue compValue) { + super(TYPE); this.compValue = compValue; }
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -37,12 +37,13 @@ public class ValuePositionTest1 { private static class NestedCompositeValue extends CompositeValue { + public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); private static final long serialVersionUID = -8804214200173503527L; @Component({REG, OperandFlag.ILLEGAL}) protected Value value; public NestedCompositeValue(Value value) { - super(LIRKind.Illegal); + super(TYPE, LIRKind.Illegal); this.value = value; } @@ -86,11 +87,13 @@ } } - private static class TestOp extends LIRInstructionBase { + private static final class TestOp extends LIRInstruction { + public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); @Use({COMPOSITE}) protected NestedCompositeValue compValue; public TestOp(NestedCompositeValue compValue) { + super(TYPE); this.compValue = compValue; }
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -37,13 +37,14 @@ public class ValuePositionTest2 { private static class NestedCompositeValue extends CompositeValue { + public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); private static final long serialVersionUID = -2243948303328857965L; @Component({REG, OperandFlag.ILLEGAL}) protected Value value1; @Component({REG, OperandFlag.ILLEGAL}) protected Value value2; public NestedCompositeValue(Value value1, Value value2) { - super(LIRKind.Illegal); + super(TYPE, LIRKind.Illegal); this.value1 = value1; this.value2 = value2; } @@ -88,11 +89,13 @@ } } - private static class TestOp extends LIRInstructionBase { + private static class TestOp extends LIRInstruction { + public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); @Use({COMPOSITE}) protected NestedCompositeValue compValue; public TestOp(NestedCompositeValue compValue) { + super(TYPE); this.compValue = compValue; }
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest3.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest3.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -38,6 +38,7 @@ public class ValuePositionTest3 { public static final class TestAddressValue extends CompositeValue { + public static final CompositeValueClass<TestAddressValue> TYPE = CompositeValueClass.create(TestAddressValue.class); private static final long serialVersionUID = -2679790860680123026L; @@ -49,7 +50,7 @@ } public TestAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index) { - super(kind); + super(TYPE, kind); this.base = base; this.index = index; } @@ -99,11 +100,13 @@ } - private static class TestOp extends LIRInstructionBase { + private static class TestOp extends LIRInstruction { + public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); @Use({COMPOSITE}) protected Value value; public TestOp(Value value) { + super(TYPE); this.value = value; }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Tue Mar 10 21:26:02 2015 +0100 @@ -48,10 +48,11 @@ private static final DebugMetric COMPOSITE_VALUE_COUNT = Debug.metric("CompositeValues"); - public CompositeValue(LIRKind kind) { + public CompositeValue(CompositeValueClass<? extends CompositeValue> c, LIRKind kind) { super(kind); COMPOSITE_VALUE_COUNT.increment(); - valueClass = CompositeValueClass.get(getClass()); + valueClass = c; + assert c.getClazz() == this.getClass(); } final CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,22 +40,8 @@ */ public class CompositeValueClass<T> extends LIRIntrospection<T> { - @SuppressWarnings("unchecked") - public static final <T extends CompositeValue> CompositeValueClass<T> get(Class<T> c) { - CompositeValueClass<T> clazz = (CompositeValueClass<T>) allClasses.get(c); - if (clazz != null) { - return clazz; - } - - // We can have a race of multiple threads creating the LIRInstructionClass at the same time. - // However, only one will be put into the map, and this is the one returned by all threads. - clazz = new CompositeValueClass<>(c); - CompositeValueClass<T> oldClazz = (CompositeValueClass<T>) allClasses.putIfAbsent(c, clazz); - if (oldClazz != null) { - return oldClazz; - } else { - return clazz; - } + public static final <T extends CompositeValue> CompositeValueClass<T> create(Class<T> c) { + return new CompositeValueClass<>(c); } public CompositeValueClass(Class<T> clazz) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,12 +41,12 @@ * Performs control flow optimizations on the given LIR graph. */ @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { LIR lir = lirGenRes.getLIR(); new Optimizer<B>(lir).deleteEmptyBlocks(codeEmittingOrder); } - private static final class Optimizer<B extends AbstractBlock<B>> { + private static final class Optimizer<B extends AbstractBlockBase<B>> { private final LIR lir; @@ -97,7 +97,7 @@ if (canDeleteBlock(block)) { // adjust successor and predecessor lists B other = block.getSuccessors().iterator().next(); - for (AbstractBlock<B> pred : block.getPredecessors()) { + for (AbstractBlockBase<B> pred : block.getPredecessors()) { Collections.replaceAll(pred.getSuccessors(), block, other); } for (int i = 0; i < other.getPredecessorCount(); i++) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java Tue Mar 10 21:26:02 2015 +0100 @@ -51,14 +51,14 @@ public final class EdgeMoveOptimizer extends PostAllocationOptimizationPhase { @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { LIR ir = lirGenRes.getLIR(); Optimizer optimizer = new Optimizer(ir); - List<? extends AbstractBlock<?>> blockList = ir.linearScanOrder(); + List<? extends AbstractBlockBase<?>> blockList = ir.linearScanOrder(); // ignore the first block in the list (index 0 is not processed) for (int i = blockList.size() - 1; i >= 1; i--) { - AbstractBlock<?> block = blockList.get(i); + AbstractBlockBase<?> block = blockList.get(i); if (block.getPredecessorCount() > 1) { optimizer.optimizeMovesAtBlockEnd(block); @@ -106,8 +106,8 @@ * Moves the longest {@linkplain #same common} subsequence at the end all predecessors of * {@code block} to the start of {@code block}. */ - private void optimizeMovesAtBlockEnd(AbstractBlock<?> block) { - for (AbstractBlock<?> pred : block.getPredecessors()) { + private void optimizeMovesAtBlockEnd(AbstractBlockBase<?> block) { + for (AbstractBlockBase<?> pred : block.getPredecessors()) { if (pred == block) { // currently we can't handle this correctly. return; @@ -121,7 +121,7 @@ assert numPreds > 1 : "do not call otherwise"; // setup a list with the LIR instructions of all predecessors - for (AbstractBlock<?> pred : block.getPredecessors()) { + for (AbstractBlockBase<?> pred : block.getPredecessors()) { assert pred != null; assert ir.getLIRforBlock(pred) != null; List<LIRInstruction> predInstructions = ir.getLIRforBlock(pred); @@ -176,7 +176,7 @@ * {@code block} to the end of {@code block} just prior to the branch instruction ending * {@code block}. */ - private void optimizeMovesAtBlockBegin(AbstractBlock<?> block) { + private void optimizeMovesAtBlockBegin(AbstractBlockBase<?> block) { edgeInstructionSeqences.clear(); int numSux = block.getSuccessorCount(); @@ -206,7 +206,7 @@ int insertIdx = instructions.size() - 1; // setup a list with the lir-instructions of all successors - for (AbstractBlock<?> sux : block.getSuccessors()) { + for (AbstractBlockBase<?> sux : block.getSuccessors()) { List<LIRInstruction> suxInstructions = ir.getLIRforBlock(sux); assert suxInstructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FullInfopointOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FullInfopointOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,13 +29,15 @@ * Emits an infopoint (only mark the position). */ @Opcode("INFOPOINT") -public class FullInfopointOp extends LIRInstructionBase { +public final class FullInfopointOp extends LIRInstruction { + public static final LIRInstructionClass<FullInfopointOp> TYPE = LIRInstructionClass.create(FullInfopointOp.class); @State protected LIRFrameState state; private final InfopointReason reason; public FullInfopointOp(LIRFrameState state, InfopointReason reason) { + super(TYPE); this.state = state; this.reason = reason; }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,7 +24,6 @@ import java.util.*; -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.LabelOp; @@ -40,32 +39,25 @@ /** * The linear-scan ordered list of blocks. */ - private final List<? extends AbstractBlock<?>> linearScanOrder; + private final List<? extends AbstractBlockBase<?>> linearScanOrder; /** * The order in which the code is emitted. */ - private final List<? extends AbstractBlock<?>> codeEmittingOrder; + private final List<? extends AbstractBlockBase<?>> codeEmittingOrder; private int firstVariableNumber; private int numVariables; - private SpillMoveFactory spillMoveFactory; - private final BlockMap<List<LIRInstruction>> lirInstructions; - public interface SpillMoveFactory { - - LIRInstruction createMove(AllocatableValue result, Value input); - } - private boolean hasArgInCallerFrame; /** * Creates a new LIR instance for the specified compilation. */ - public LIR(AbstractControlFlowGraph<?> cfg, List<? extends AbstractBlock<?>> linearScanOrder, List<? extends AbstractBlock<?>> codeEmittingOrder) { + public LIR(AbstractControlFlowGraph<?> cfg, List<? extends AbstractBlockBase<?>> linearScanOrder, List<? extends AbstractBlockBase<?>> codeEmittingOrder) { this.cfg = cfg; this.codeEmittingOrder = codeEmittingOrder; this.linearScanOrder = linearScanOrder; @@ -80,7 +72,7 @@ * Determines if any instruction in the LIR has debug info associated with it. */ public boolean hasDebugInfo() { - for (AbstractBlock<?> b : linearScanOrder()) { + for (AbstractBlockBase<?> b : linearScanOrder()) { for (LIRInstruction op : getLIRforBlock(b)) { if (op.hasState()) { return true; @@ -90,15 +82,11 @@ return false; } - public SpillMoveFactory getSpillMoveFactory() { - return spillMoveFactory; - } - - public List<LIRInstruction> getLIRforBlock(AbstractBlock<?> block) { + public List<LIRInstruction> getLIRforBlock(AbstractBlockBase<?> block) { return lirInstructions.get(block); } - public void setLIRforBlock(AbstractBlock<?> block, List<LIRInstruction> list) { + public void setLIRforBlock(AbstractBlockBase<?> block, List<LIRInstruction> list) { assert getLIRforBlock(block) == null : "lir instruction list should only be initialized once"; lirInstructions.put(block, list); } @@ -108,11 +96,11 @@ * * @return the blocks in linear scan order */ - public List<? extends AbstractBlock<?>> linearScanOrder() { + public List<? extends AbstractBlockBase<?>> linearScanOrder() { return linearScanOrder; } - public List<? extends AbstractBlock<?>> codeEmittingOrder() { + public List<? extends AbstractBlockBase<?>> codeEmittingOrder() { return codeEmittingOrder; } @@ -166,7 +154,7 @@ */ public static final int MAX_EXCEPTION_EDGE_OP_DISTANCE_FROM_END = 3; - public static boolean verifyBlock(LIR lir, AbstractBlock<?> block) { + public static boolean verifyBlock(LIR lir, AbstractBlockBase<?> block) { List<LIRInstruction> ops = lir.getLIRforBlock(block); if (ops.size() == 0) { return false; @@ -190,12 +178,12 @@ return true; } - public static boolean verifyBlocks(LIR lir, List<? extends AbstractBlock<?>> blocks) { - for (AbstractBlock<?> block : blocks) { - for (AbstractBlock<?> sux : block.getSuccessors()) { + public static boolean verifyBlocks(LIR lir, List<? extends AbstractBlockBase<?>> blocks) { + for (AbstractBlockBase<?> block : blocks) { + for (AbstractBlockBase<?> sux : block.getSuccessors()) { assert blocks.contains(sux) : "missing successor from: " + block + "to: " + sux; } - for (AbstractBlock<?> pred : block.getPredecessors()) { + for (AbstractBlockBase<?> pred : block.getPredecessors()) { assert blocks.contains(pred) : "missing predecessor from: " + block + "to: " + pred; } if (!verifyBlock(lir, block)) { @@ -205,13 +193,9 @@ return true; } - public void setSpillMoveFactory(SpillMoveFactory spillMoveFactory) { - this.spillMoveFactory = spillMoveFactory; - } - public void resetLabels() { - for (AbstractBlock<?> block : codeEmittingOrder()) { + for (AbstractBlockBase<?> 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/LIRFrameState.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Tue Mar 10 21:26:02 2015 +0100 @@ -80,39 +80,51 @@ */ protected static final EnumSet<OperandFlag> STATE_FLAGS = EnumSet.of(OperandFlag.REG, OperandFlag.STACK); - protected void processValues(LIRInstruction inst, JavaValue[] values, InstructionValueProcedure proc) { + protected void processValues(LIRInstruction inst, Value[] values, InstructionValueProcedure proc) { for (int i = 0; i < values.length; i++) { - if (values[i] instanceof Value) { - Value value = (Value) values[i]; - values[i] = (JavaValue) processValue(inst, proc, value); - } + Value value = values[i]; + values[i] = processValue(inst, proc, value); } } protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { - if (processed(value)) { - return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + if (value instanceof StackLockValue) { + StackLockValue monitor = (StackLockValue) value; + Value owner = monitor.getOwner(); + if (owner instanceof AllocatableValue) { + monitor.setOwner(proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS)); + } + Value slot = monitor.getSlot(); + if (isVirtualStackSlot(slot)) { + monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS))); + } + } else { + if (!isIllegal(value) && value instanceof AllocatableValue) { + return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + } else { + assert unprocessed(value); + } } return value; } - protected boolean processed(Value value) { + private boolean unprocessed(Value value) { if (isIllegal(value)) { // Ignore dead local variables. - return false; + return true; } else if (isConstant(value)) { // Ignore constants, the register allocator does not need to see them. - return false; + return true; } else if (isVirtualObject(value)) { assert Arrays.asList(virtualObjects).contains(value); - return false; + return true; } else { - return true; + return false; } } /** - * Called by the register allocator before {@link #markLocation} to initialize the frame state. + * Called by the register allocator before {@link #updateUnion} to initialize the frame state. * * @param frameMap The frame map. * @param canHaveRegisters True if there can be any register map entries. @@ -122,33 +134,12 @@ } /** - * Called by the register allocator to mark the specified location as a reference in the - * reference map of the debug information. The tracked location can be a {@link RegisterValue} - * or a {@link StackSlot}. Note that a {@link JavaConstant} is automatically tracked. - * - * @param location The location to be added to the reference map. - * @param frameMap The frame map. - */ - public void markLocation(Value location, FrameMap frameMap) { - frameMap.setReference(location, debugInfo.getReferenceMap()); - } - - /** * Updates this reference map with all references that are marked in {@code refMap}. */ public void updateUnion(ReferenceMap refMap) { debugInfo.getReferenceMap().updateUnion(refMap); } - /** - * Called by the register allocator after all locations are marked. - * - * @param op The instruction to which this frame state belongs. - * @param frameMap The frame map. - */ - public void finish(LIRInstruction op, FrameMap frameMap) { - } - @Override public String toString() { return debugInfo != null ? debugInfo.toString() : topFrame != null ? topFrame.toString() : "<empty>";
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -22,24 +22,27 @@ */ package com.oracle.graal.lir; -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import java.lang.annotation.*; +import java.util.*; -import java.lang.annotation.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.lir.LIRInstruction.OperandMode.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; import com.oracle.graal.lir.asm.*; /** - * The {@code LIRInstruction} interface definition. + * The base class for an {@code LIRInstruction}. */ -public interface LIRInstruction { - Value[] NO_OPERANDS = {}; +public abstract class LIRInstruction { + public static final Value[] NO_OPERANDS = {}; /** * Constants denoting how a LIR instruction uses an operand. */ - enum OperandMode { + public enum OperandMode { /** * The value must have been defined before. It is alive before the instruction until the * beginning of the instruction, but not necessarily throughout the instruction. A register @@ -72,41 +75,41 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) - static @interface Use { + public static @interface Use { - OperandFlag[] value() default REG; + OperandFlag[] value() default OperandFlag.REG; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) - static @interface Alive { + public static @interface Alive { - OperandFlag[] value() default REG; + OperandFlag[] value() default OperandFlag.REG; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) - static @interface Temp { + public static @interface Temp { - OperandFlag[] value() default REG; + OperandFlag[] value() default OperandFlag.REG; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) - static @interface Def { + public static @interface Def { - OperandFlag[] value() default REG; + OperandFlag[] value() default OperandFlag.REG; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) - static @interface State { + public static @interface State { } /** * Flags for an operand. */ - enum OperandFlag { + public enum OperandFlag { /** * The value can be a {@link RegisterValue}. */ @@ -145,115 +148,205 @@ UNINITIALIZED, } - void emitCode(CompilationResultBuilder crb); + /** + * For validity checking of the operand flags defined by instruction subclasses. + */ + protected static final EnumMap<OperandMode, EnumSet<OperandFlag>> ALLOWED_FLAGS; + + static { + ALLOWED_FLAGS = new EnumMap<>(OperandMode.class); + ALLOWED_FLAGS.put(OperandMode.USE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); + ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); + ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, COMPOSITE, CONST, ILLEGAL, HINT)); + ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, HINT)); + } - int id(); + /** + * The flags of the base and index value of an address. + */ + protected static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(REG, ILLEGAL); + + private final LIRInstructionClass<?> instructionClass; - void setId(int id); + /** + * Instruction id for register allocation. + */ + private int id; + + private static final DebugMetric LIR_NODE_COUNT = Debug.metric("LIRNodes"); /** - * Gets the instruction name. + * Constructs a new LIR instruction. */ - String name(); + public LIRInstruction(LIRInstructionClass<? extends LIRInstruction> c) { + LIR_NODE_COUNT.increment(); + instructionClass = c; + assert c.getClazz() == this.getClass(); + id = -1; + } - boolean hasOperands(); + public abstract void emitCode(CompilationResultBuilder crb); + + public final int id() { + return id; + } - boolean hasState(); + public final void setId(int id) { + this.id = id; + } + + public final String name() { + return instructionClass.getOpcode(this); + } - /** - * Determines if this instruction destroys all caller-saved registers.. - */ - boolean destroysCallerSavedRegisters(); + public final boolean hasOperands() { + return instructionClass.hasOperands() || hasState() || destroysCallerSavedRegisters(); + } + + public final boolean hasState() { + return instructionClass.hasState(this); + } + + public boolean destroysCallerSavedRegisters() { + return false; + } // ValuePositionProcedures - void forEachInputPos(ValuePositionProcedure proc); + public final void forEachInputPos(ValuePositionProcedure proc) { + instructionClass.forEachUsePos(this, proc); + } - void forEachAlivePos(ValuePositionProcedure proc); + public final void forEachAlivePos(ValuePositionProcedure proc) { + instructionClass.forEachAlivePos(this, proc); + } - void forEachTempPos(ValuePositionProcedure proc); + public final void forEachTempPos(ValuePositionProcedure proc) { + instructionClass.forEachTempPos(this, proc); + } - void forEachOutputPos(ValuePositionProcedure proc); + public final void forEachOutputPos(ValuePositionProcedure proc) { + instructionClass.forEachDefPos(this, proc); + } // InstructionValueProcedures - void forEachInput(InstructionValueProcedure proc); + public final void forEachInput(InstructionValueProcedure proc) { + instructionClass.forEachUse(this, proc); + } - void forEachAlive(InstructionValueProcedure proc); + public final void forEachAlive(InstructionValueProcedure proc) { + instructionClass.forEachAlive(this, proc); + } - void forEachTemp(InstructionValueProcedure proc); + public final void forEachTemp(InstructionValueProcedure proc) { + instructionClass.forEachTemp(this, proc); + } - void forEachOutput(InstructionValueProcedure proc); + public final void forEachOutput(InstructionValueProcedure proc) { + instructionClass.forEachDef(this, proc); + } - void forEachState(InstructionValueProcedure proc); + public final void forEachState(InstructionValueProcedure proc) { + instructionClass.forEachState(this, proc); + } // ValueProcedures - void forEachInput(ValueProcedure proc); + public final void forEachInput(ValueProcedure proc) { + instructionClass.forEachUse(this, proc); + } - void forEachAlive(ValueProcedure proc); + public final void forEachAlive(ValueProcedure proc) { + instructionClass.forEachAlive(this, proc); + } - void forEachTemp(ValueProcedure proc); + public final void forEachTemp(ValueProcedure proc) { + instructionClass.forEachTemp(this, proc); + } - void forEachOutput(ValueProcedure proc); + public final void forEachOutput(ValueProcedure proc) { + instructionClass.forEachDef(this, proc); + } - void forEachState(ValueProcedure proc); + public final void forEachState(ValueProcedure proc) { + instructionClass.forEachState(this, proc); + } // States - void forEachState(InstructionStateProcedure proc); + public final void forEachState(InstructionStateProcedure proc) { + instructionClass.forEachState(this, proc); + } - void forEachState(StateProcedure proc); + public final void forEachState(StateProcedure proc) { + instructionClass.forEachState(this, proc); + } // InstructionValueConsumers - void visitEachInput(InstructionValueConsumer proc); + public final void visitEachInput(InstructionValueConsumer proc) { + instructionClass.forEachUse(this, proc); + } - void visitEachAlive(InstructionValueConsumer proc); + public final void visitEachAlive(InstructionValueConsumer proc) { + instructionClass.forEachAlive(this, proc); + } - void visitEachTemp(InstructionValueConsumer proc); + public final void visitEachTemp(InstructionValueConsumer proc) { + instructionClass.forEachTemp(this, proc); + } - void visitEachOutput(InstructionValueConsumer proc); + public final void visitEachOutput(InstructionValueConsumer proc) { + instructionClass.forEachDef(this, proc); + } - void visitEachState(InstructionValueConsumer proc); + public final void visitEachState(InstructionValueConsumer proc) { + instructionClass.forEachState(this, proc); + } // ValueConsumers - void visitEachInput(ValueConsumer proc); + public final void visitEachInput(ValueConsumer proc) { + instructionClass.forEachUse(this, proc); + } - void visitEachAlive(ValueConsumer proc); + public final void visitEachAlive(ValueConsumer proc) { + instructionClass.forEachAlive(this, proc); + } + + public final void visitEachTemp(ValueConsumer proc) { + instructionClass.forEachTemp(this, proc); + } - void visitEachTemp(ValueConsumer proc); + public final void visitEachOutput(ValueConsumer proc) { + instructionClass.forEachDef(this, proc); + } - void visitEachOutput(ValueConsumer proc); + public final void visitEachState(ValueConsumer proc) { + instructionClass.forEachState(this, proc); + } - void visitEachState(ValueConsumer proc); + @SuppressWarnings("unused") + public final Value forEachRegisterHint(Value value, OperandMode mode, InstructionValueProcedure proc) { + return instructionClass.forEachRegisterHint(this, mode, proc); + } - /** - * Iterates all register hints for the specified value, i.e., all preferred candidates for the - * register to be assigned to the value. - * <p> - * Subclasses can override this method. The default implementation processes all Input operands - * as the hints for an Output operand, and all Output operands as the hints for an Input - * operand. - * - * @param value The value the hints are needed for. - * @param mode The operand mode of the value. - * @param proc The procedure invoked for all the hints. If the procedure returns a non-null - * value, the iteration is stopped and the value is returned by this method, i.e., - * clients can stop the iteration once a suitable hint has been found. - * @return The non-null value returned by the procedure, or null. - */ - Value forEachRegisterHint(Value value, OperandMode mode, InstructionValueProcedure proc); + @SuppressWarnings("unused") + public final Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc) { + return instructionClass.forEachRegisterHint(this, mode, proc); + } + + public void verify() { + } - /** - * @see #forEachRegisterHint(Value, OperandMode, InstructionValueProcedure) - * @param value The value the hints are needed for. - * @param mode The operand mode of the value. - * @param proc The procedure invoked for all the hints. If the procedure returns a non-null - * value, the iteration is stopped and the value is returned by this method, i.e., - * clients can stop the iteration once a suitable hint has been found. - * @return The non-null value returned by the procedure, or null. - */ - Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc); + public final String toStringWithIdPrefix() { + if (id != -1) { + return String.format("%4d %s", id, toString()); + } + return " " + toString(); + } - String toStringWithIdPrefix(); + @Override + public String toString() { + return instructionClass.toString(this); + } - void verify(); - - LIRInstructionClass<?> getLIRInstructionClass(); + public LIRInstructionClass<?> getLIRInstructionClass() { + return instructionClass; + } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionBase.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2009, 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.lir; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static com.oracle.graal.lir.LIRInstruction.OperandMode.*; - -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.lir.asm.*; - -/** - * The base class for an {@code LIRInstruction}. - */ -public abstract class LIRInstructionBase implements LIRInstruction { - - /** - * For validity checking of the operand flags defined by instruction subclasses. - */ - protected static final EnumMap<OperandMode, EnumSet<OperandFlag>> ALLOWED_FLAGS; - - static { - ALLOWED_FLAGS = new EnumMap<>(OperandMode.class); - ALLOWED_FLAGS.put(USE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); - ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); - ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, COMPOSITE, CONST, ILLEGAL, HINT)); - ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, HINT)); - } - - /** - * The flags of the base and index value of an address. - */ - protected static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(REG, ILLEGAL); - - private final LIRInstructionClass<?> instructionClass; - - /** - * Instruction id for register allocation. - */ - private int id; - - private static final DebugMetric LIR_NODE_COUNT = Debug.metric("LIRNodes"); - - /** - * Constructs a new LIR instruction. - */ - public LIRInstructionBase() { - LIR_NODE_COUNT.increment(); - instructionClass = LIRInstructionClass.get(getClass()); - id = -1; - } - - public abstract void emitCode(CompilationResultBuilder crb); - - public final int id() { - return id; - } - - public final void setId(int id) { - this.id = id; - } - - public final String name() { - return instructionClass.getOpcode(this); - } - - public final boolean hasOperands() { - return instructionClass.hasOperands() || hasState() || destroysCallerSavedRegisters(); - } - - public final boolean hasState() { - return instructionClass.hasState(this); - } - - public boolean destroysCallerSavedRegisters() { - return false; - } - - // ValuePositionProcedures - public final void forEachInputPos(ValuePositionProcedure proc) { - instructionClass.forEachUsePos(this, proc); - } - - public final void forEachAlivePos(ValuePositionProcedure proc) { - instructionClass.forEachAlivePos(this, proc); - } - - public final void forEachTempPos(ValuePositionProcedure proc) { - instructionClass.forEachTempPos(this, proc); - } - - public final void forEachOutputPos(ValuePositionProcedure proc) { - instructionClass.forEachDefPos(this, proc); - } - - // InstructionValueProcedures - public final void forEachInput(InstructionValueProcedure proc) { - instructionClass.forEachUse(this, proc); - } - - public final void forEachAlive(InstructionValueProcedure proc) { - instructionClass.forEachAlive(this, proc); - } - - public final void forEachTemp(InstructionValueProcedure proc) { - instructionClass.forEachTemp(this, proc); - } - - public final void forEachOutput(InstructionValueProcedure proc) { - instructionClass.forEachDef(this, proc); - } - - public final void forEachState(InstructionValueProcedure proc) { - instructionClass.forEachState(this, proc); - } - - // ValueProcedures - public final void forEachInput(ValueProcedure proc) { - instructionClass.forEachUse(this, proc); - } - - public final void forEachAlive(ValueProcedure proc) { - instructionClass.forEachAlive(this, proc); - } - - public final void forEachTemp(ValueProcedure proc) { - instructionClass.forEachTemp(this, proc); - } - - public final void forEachOutput(ValueProcedure proc) { - instructionClass.forEachDef(this, proc); - } - - public final void forEachState(ValueProcedure proc) { - instructionClass.forEachState(this, proc); - } - - // States - public final void forEachState(InstructionStateProcedure proc) { - instructionClass.forEachState(this, proc); - } - - public final void forEachState(StateProcedure proc) { - instructionClass.forEachState(this, proc); - } - - // InstructionValueConsumers - public final void visitEachInput(InstructionValueConsumer proc) { - instructionClass.forEachUse(this, proc); - } - - public final void visitEachAlive(InstructionValueConsumer proc) { - instructionClass.forEachAlive(this, proc); - } - - public final void visitEachTemp(InstructionValueConsumer proc) { - instructionClass.forEachTemp(this, proc); - } - - public final void visitEachOutput(InstructionValueConsumer proc) { - instructionClass.forEachDef(this, proc); - } - - public final void visitEachState(InstructionValueConsumer proc) { - instructionClass.forEachState(this, proc); - } - - // ValueConsumers - public final void visitEachInput(ValueConsumer proc) { - instructionClass.forEachUse(this, proc); - } - - public final void visitEachAlive(ValueConsumer proc) { - instructionClass.forEachAlive(this, proc); - } - - public final void visitEachTemp(ValueConsumer proc) { - instructionClass.forEachTemp(this, proc); - } - - public final void visitEachOutput(ValueConsumer proc) { - instructionClass.forEachDef(this, proc); - } - - public final void visitEachState(ValueConsumer proc) { - instructionClass.forEachState(this, proc); - } - - public Value forEachRegisterHint(Value value, OperandMode mode, InstructionValueProcedure proc) { - return instructionClass.forEachRegisterHint(this, mode, proc); - } - - public Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc) { - return instructionClass.forEachRegisterHint(this, mode, proc); - } - - public void verify() { - } - - public final String toStringWithIdPrefix() { - if (id != -1) { - return String.format("%4d %s", id, toString()); - } - return " " + toString(); - } - - @Override - public String toString() { - return instructionClass.toString(this); - } - - public LIRInstructionClass<?> getLIRInstructionClass() { - return instructionClass; - } -}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,22 +33,8 @@ public class LIRInstructionClass<T> extends LIRIntrospection<T> { - @SuppressWarnings("unchecked") - public static final <T extends LIRInstruction> LIRInstructionClass<T> get(Class<T> c) { - LIRInstructionClass<T> clazz = (LIRInstructionClass<T>) allClasses.get(c); - if (clazz != null) { - return clazz; - } - - // We can have a race of multiple threads creating the LIRInstructionClass at the same time. - // However, only one will be put into the map, and this is the one returned by all threads. - clazz = new LIRInstructionClass<>(c); - LIRInstructionClass<T> oldClazz = (LIRInstructionClass<T>) allClasses.putIfAbsent(c, clazz); - if (oldClazz != null) { - return oldClazz; - } else { - return clazz; - } + public static final <T extends LIRInstruction> LIRInstructionClass<T> create(Class<T> c) { + return new LIRInstructionClass<>(c); } private static final Class<LIRInstruction> INSTRUCTION_CLASS = LIRInstruction.class; @@ -135,7 +121,7 @@ } opcodeField = null; - super.scan(clazz, LIRInstructionBase.class, false); + super.scan(clazz, LIRInstruction.class, false); if (opcodeConstant == null && opcodeField == null) { opcodeConstant = clazz.getSimpleName();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Tue Mar 10 21:26:02 2015 +0100 @@ -202,7 +202,7 @@ protected static void forEach(LIRInstruction inst, Values values, OperandMode mode, InstructionValueProcedure proc) { for (int i = 0; i < values.getCount(); i++) { - assert LIRInstructionBase.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i)); + assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i)); if (i < values.getDirectCount()) { Value value = values.getValue(inst, i); @@ -238,7 +238,7 @@ protected static CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, Values values, OperandMode mode, InstructionValueProcedure proc) { CompositeValue newCompValue = null; for (int i = 0; i < values.getCount(); i++) { - assert LIRInstructionBase.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i)); + assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i)); if (i < values.getDirectCount()) { Value value = values.getValue(obj, i); @@ -286,7 +286,7 @@ protected static void forEach(LIRInstruction inst, Object obj, Values values, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition) { for (int i = 0; i < values.getCount(); i++) { - assert LIRInstructionBase.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i)); + assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i)); if (i < values.getDirectCount()) { Value value = values.getValue(obj, i);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Tue Mar 10 21:26:02 2015 +0100 @@ -46,11 +46,11 @@ private final BitSet[] blockLiveOut; private final Object[] variableDefinitions; - private BitSet liveOutFor(AbstractBlock<?> block) { + private BitSet liveOutFor(AbstractBlockBase<?> block) { return blockLiveOut[block.getId()]; } - private void setLiveOutFor(AbstractBlock<?> block, BitSet liveOut) { + private void setLiveOutFor(AbstractBlockBase<?> block, BitSet liveOut) { blockLiveOut[block.getId()] = liveOut; } @@ -91,7 +91,7 @@ private BitSet curVariablesLive; private Value[] curRegistersLive; - private AbstractBlock<?> curBlock; + private AbstractBlockBase<?> curBlock; private Object curInstruction; private BitSet curRegistersDefined; @@ -113,7 +113,7 @@ int maxRegisterNum = maxRegisterNum(); curRegistersDefined = new BitSet(); - for (AbstractBlock<?> block : lir.linearScanOrder()) { + for (AbstractBlockBase<?> block : lir.linearScanOrder()) { curBlock = block; curVariablesLive = new BitSet(); curRegistersLive = new Value[maxRegisterNum];
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LabelRef.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LabelRef.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,16 +29,17 @@ /** * LIR instructions such as {@link JumpOp} and {@link BranchOp} need to reference their target - * {@link AbstractBlock}. However, direct references are not possible since the control flow graph - * (and therefore successors lists) can be changed by optimizations - and fixing the instructions is - * error prone. Therefore, we represent an edge to block B from block A via the tuple {@code (A, + * {@link AbstractBlockBase}. However, direct references are not possible since the control flow + * graph (and therefore successors lists) can be changed by optimizations - and fixing the + * instructions is error prone. Therefore, we represent an edge to block B from block A via the + * tuple {@code (A, * successor-index-of-B)}. That is, indirectly by storing the index into the successor list of A. * Note therefore that the successor list cannot be re-ordered. */ public final class LabelRef { private final LIR lir; - private final AbstractBlock<?> block; + private final AbstractBlockBase<?> block; private final int suxIndex; /** @@ -48,7 +49,7 @@ * @param suxIndex The index of the successor. * @return The newly created label reference. */ - public static LabelRef forSuccessor(final LIR lir, final AbstractBlock<?> block, final int suxIndex) { + public static LabelRef forSuccessor(final LIR lir, final AbstractBlockBase<?> block, final int suxIndex) { return new LabelRef(lir, block, suxIndex); } @@ -58,17 +59,17 @@ * @param block The base block that contains the successor list. * @param suxIndex The index of the successor. */ - private LabelRef(final LIR lir, final AbstractBlock<?> block, final int suxIndex) { + private LabelRef(final LIR lir, final AbstractBlockBase<?> block, final int suxIndex) { this.lir = lir; this.block = block; this.suxIndex = suxIndex; } - public AbstractBlock<?> getSourceBlock() { + public AbstractBlockBase<?> getSourceBlock() { return block; } - public AbstractBlock<?> getTargetBlock() { + public AbstractBlockBase<?> getTargetBlock() { return block.getSuccessors().get(suxIndex); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,14 +34,14 @@ public final class NullCheckOptimizer extends PostAllocationOptimizationPhase { @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { LIR ir = lirGenRes.getLIR(); - List<? extends AbstractBlock<?>> blocks = ir.codeEmittingOrder(); + List<? extends AbstractBlockBase<?>> blocks = ir.codeEmittingOrder(); NullCheckOptimizer.foldNullChecks(ir, blocks, target.implicitNullCheckLimit); } - private static void foldNullChecks(LIR ir, List<? extends AbstractBlock<?>> blocks, int implicitNullCheckLimit) { - for (AbstractBlock<?> block : blocks) { + private static void foldNullChecks(LIR ir, List<? extends AbstractBlockBase<?>> blocks, int implicitNullCheckLimit) { + for (AbstractBlockBase<?> block : blocks) { List<LIRInstruction> list = ir.getLIRforBlock(block); if (!list.isEmpty()) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Tue Mar 10 21:26:02 2015 +0100 @@ -44,7 +44,7 @@ public final class RedundantMoveElimination extends PostAllocationOptimizationPhase { @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { Optimization redundantMoveElimination = new Optimization(); redundantMoveElimination.doOptimize(lirGenRes.getLIR(), lirGenRes.getFrameMap()); } @@ -87,7 +87,7 @@ private static final class Optimization { - Map<AbstractBlock<?>, BlockData> blockData = CollectionsFactory.newMap(); + Map<AbstractBlockBase<?>, BlockData> blockData = CollectionsFactory.newMap(); Register[] callerSaveRegs; @@ -142,7 +142,7 @@ private void initBlockData(LIR lir) { - List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder(); + List<? extends AbstractBlockBase<?>> blocks = lir.linearScanOrder(); numRegs = 0; int maxStackLocations = COMPLEXITY_LIMIT / blocks.size(); @@ -151,7 +151,7 @@ * Search for relevant locations which can be optimized. These are register or stack * slots which occur as destinations of move instructions. */ - for (AbstractBlock<?> block : blocks) { + for (AbstractBlockBase<?> block : blocks) { List<LIRInstruction> instructions = lir.getLIRforBlock(block); for (LIRInstruction op : instructions) { if (isEligibleMove(op)) { @@ -176,7 +176,7 @@ */ int numLocations = numRegs + stackIndices.size(); Debug.log("num locations = %d (regs = %d, stack = %d)", numLocations, numRegs, stackIndices.size()); - for (AbstractBlock<?> block : blocks) { + for (AbstractBlockBase<?> block : blocks) { BlockData data = new BlockData(numLocations); blockData.put(block, data); } @@ -191,7 +191,7 @@ try (Indent indent = Debug.logAndIndent("solve data flow")) { - List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder(); + List<? extends AbstractBlockBase<?>> blocks = lir.linearScanOrder(); int numIter = 0; @@ -205,7 +205,7 @@ changed = false; try (Indent indent2 = Debug.logAndIndent("new iteration")) { - for (AbstractBlock<?> block : blocks) { + for (AbstractBlockBase<?> block : blocks) { BlockData data = blockData.get(block); /* @@ -235,7 +235,7 @@ /* * Merge the states of predecessor blocks */ - for (AbstractBlock<?> predecessor : block.getPredecessors()) { + for (AbstractBlockBase<?> predecessor : block.getPredecessors()) { BlockData predData = blockData.get(predecessor); newState |= mergeState(data.entryState, predData.exitState, valueNum); } @@ -291,9 +291,9 @@ try (Indent indent = Debug.logAndIndent("eliminate moves")) { - List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder(); + List<? extends AbstractBlockBase<?>> blocks = lir.linearScanOrder(); - for (AbstractBlock<?> block : blocks) { + for (AbstractBlockBase<?> block : blocks) { try (Indent indent2 = Debug.logAndIndent("eliminate moves in block %d", block.getId())) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SimpleInfopointOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SimpleInfopointOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,11 +26,13 @@ import com.oracle.graal.lir.asm.*; @Opcode("SIMPLE_INFOPOINT") -public class SimpleInfopointOp extends LIRInstructionBase { +public final class SimpleInfopointOp extends LIRInstruction { + public static final LIRInstructionClass<SimpleInfopointOp> TYPE = LIRInstructionClass.create(SimpleInfopointOp.class); private final InfopointReason reason; private final BytecodePosition position; public SimpleInfopointOp(InfopointReason reason, BytecodePosition position) { + super(TYPE); this.reason = reason; this.position = position; }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Tue Mar 10 21:26:02 2015 +0100 @@ -44,23 +44,24 @@ * A block delimiter. Every well formed block must contain exactly one such operation and it * must be the last operation in the block. */ - public interface BlockEndOp extends LIRInstruction { + public interface BlockEndOp { } - public interface NullCheck extends LIRInstruction { + public interface NullCheck { Value getCheckedValue(); LIRFrameState getState(); } - public interface ImplicitNullCheck extends LIRInstruction { + public interface ImplicitNullCheck { boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit); } /** * LIR operation that defines the position of a label. */ - public static class LabelOp extends LIRInstructionBase { + public static final class LabelOp extends LIRInstruction { + public static final LIRInstructionClass<LabelOp> TYPE = LIRInstructionClass.create(LabelOp.class); private static final Value[] NO_VALUES = new Value[0]; @@ -78,6 +79,7 @@ private final boolean align; public LabelOp(Label label, boolean align) { + super(TYPE); this.label = label; this.align = align; this.incomingValues = NO_VALUES; @@ -104,11 +106,17 @@ /** * LIR operation that is an unconditional jump to a {@link #destination()}. */ - public static class JumpOp extends LIRInstructionBase implements BlockEndOp { + public static class JumpOp extends LIRInstruction implements BlockEndOp { + public static final LIRInstructionClass<JumpOp> TYPE = LIRInstructionClass.create(JumpOp.class); private final LabelRef destination; public JumpOp(LabelRef destination) { + this(TYPE, destination); + } + + protected JumpOp(LIRInstructionClass<? extends JumpOp> c, LabelRef destination) { + super(c); this.destination = destination; } @@ -134,7 +142,7 @@ * Marker interface for a LIR operation that moves a value from {@link #getInput()} to * {@link #getResult()}. */ - public interface MoveOp extends LIRInstruction { + public interface MoveOp { Value getInput(); @@ -146,7 +154,7 @@ * {@linkplain #remove(Set) pruned} and a mapping from registers to the frame slots in which * they are saved can be {@linkplain #getMap(FrameMap) retrieved}. */ - public interface SaveRegistersOp extends LIRInstruction { + public interface SaveRegistersOp { /** * Determines if the {@link #remove(Set)} operation is supported for this object. @@ -178,19 +186,21 @@ * A LIR operation that does nothing. If the operation records its position, it can be * subsequently {@linkplain #replace(LIR, LIRInstruction) replaced}. */ - public static class NoOp extends LIRInstructionBase { + public static final class NoOp extends LIRInstruction { + public static final LIRInstructionClass<NoOp> TYPE = LIRInstructionClass.create(NoOp.class); /** * The block in which this instruction is located. */ - final AbstractBlock<?> block; + final AbstractBlockBase<?> block; /** * The block index of this instruction. */ final int index; - public NoOp(AbstractBlock<?> block, int index) { + public NoOp(AbstractBlockBase<?> block, int index) { + super(TYPE); this.block = block; this.index = index; } @@ -208,11 +218,13 @@ } @Opcode("BLACKHOLE") - public static class BlackholeOp extends LIRInstructionBase { + public static final class BlackholeOp extends LIRInstruction { + public static final LIRInstructionClass<BlackholeOp> TYPE = LIRInstructionClass.create(BlackholeOp.class); @Use({REG, STACK}) private Value value; public BlackholeOp(Value value) { + super(TYPE); this.value = value; }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SwitchStrategy.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SwitchStrategy.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ /** * This class encapsulates different strategies on how to generate code for switch instructions. - * + * * The {@link #getBestStrategy(double[], JavaConstant[], LabelRef[])} method can be used to get * strategy with the smallest average effort (average number of comparisons until a decision is * reached). The strategy returned by this method will have its averageEffort set, while a strategy @@ -43,7 +43,7 @@ /** * Generates a conditional or unconditional jump. The jump will be unconditional if * condition is null. If defaultTarget is true, then the jump will go the the default. - * + * * @param index Index of the value and the jump target (only used if defaultTarget == false) * @param condition The condition on which to jump (can be null) * @param defaultTarget true if the jump should go to the default target, false if index @@ -54,7 +54,7 @@ /** * Generates a conditional jump to the target with the specified index. The fall through * should go to the default target. - * + * * @param index Index of the value and the jump target * @param condition The condition on which to jump * @param canFallThrough true if this is the last instruction in the switch statement, to @@ -64,7 +64,7 @@ /** * Create a new label and generate a conditional jump to it. - * + * * @param index Index of the value and the jump target * @param condition The condition on which to jump * @return a new Label
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/IntervalWalker.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/IntervalWalker.java Tue Mar 10 21:26:02 2015 +0100 @@ -104,63 +104,65 @@ private void walkTo(State state, int from) { assert state == State.Active || state == State.Inactive : "wrong state"; for (RegisterBinding binding : RegisterBinding.VALUES) { - Interval prevprev = null; - Interval prev = (state == State.Active) ? activeLists.get(binding) : inactiveLists.get(binding); - Interval next = prev; - while (next.currentFrom() <= from) { - Interval cur = next; - next = cur.next; + walkTo(state, from, binding); + } + } - boolean rangeHasChanged = false; - while (cur.currentTo() <= from) { - cur.nextRange(); - rangeHasChanged = true; - } + private void walkTo(State state, int from, RegisterBinding binding) { + Interval prevprev = null; + Interval prev = (state == State.Active) ? activeLists.get(binding) : inactiveLists.get(binding); + Interval next = prev; + while (next.currentFrom() <= from) { + Interval cur = next; + next = cur.next; - // also handle move from inactive list to active list - rangeHasChanged = rangeHasChanged || (state == State.Inactive && cur.currentFrom() <= from); + boolean rangeHasChanged = false; + while (cur.currentTo() <= from) { + cur.nextRange(); + rangeHasChanged = true; + } - if (rangeHasChanged) { - // remove cur from list - if (prevprev == null) { - if (state == State.Active) { - activeLists.set(binding, next); - } else { - inactiveLists.set(binding, next); - } + // also handle move from inactive list to active list + rangeHasChanged = rangeHasChanged || (state == State.Inactive && cur.currentFrom() <= from); + + if (rangeHasChanged) { + // remove cur from list + if (prevprev == null) { + if (state == State.Active) { + activeLists.set(binding, next); } else { - prevprev.next = next; + inactiveLists.set(binding, next); } - prev = next; - if (cur.currentAtEnd()) { - // move to handled state (not maintained as a list) - cur.state = State.Handled; - intervalMoved(cur, state, State.Handled); - } else if (cur.currentFrom() <= from) { + } else { + prevprev.next = next; + } + prev = next; + Interval.State newState; + if (cur.currentAtEnd()) { + // move to handled state (not maintained as a list) + newState = State.Handled; + cur.state = newState; + } else { + if (cur.currentFrom() <= from) { // sort into active list activeLists.addToListSortedByCurrentFromPositions(binding, cur); - cur.state = State.Active; - if (prev == cur) { - assert state == State.Active : "check"; - prevprev = prev; - prev = cur.next; - } - intervalMoved(cur, state, State.Active); + newState = State.Active; } else { // sort into inactive list inactiveLists.addToListSortedByCurrentFromPositions(binding, cur); - cur.state = State.Inactive; - if (prev == cur) { - assert state == State.Inactive : "check"; - prevprev = prev; - prev = cur.next; - } - intervalMoved(cur, state, State.Inactive); + newState = State.Inactive; } - } else { - prevprev = prev; - prev = cur.next; + cur.state = newState; + if (prev == cur) { + assert state == newState; + prevprev = prev; + prev = cur.next; + } } + intervalMoved(cur, state, newState); + } else { + prevprev = prev; + prev = cur.next; } } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java Tue Mar 10 21:26:02 2015 +0100 @@ -48,6 +48,7 @@ import com.oracle.graal.lir.alloc.lsra.Interval.SpillState; import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; import com.oracle.graal.options.*; /** @@ -62,6 +63,7 @@ final LIRGenerationResult res; final LIR ir; final FrameMapBuilder frameMapBuilder; + final SpillMoveFactory spillMoveFactory; final RegisterAttributes[] registerAttributes; final Register[] registers; @@ -114,7 +116,7 @@ /** * List of blocks in linear-scan order. This is only correct as long as the CFG does not change. */ - final List<? extends AbstractBlock<?>> sortedBlocks; + final List<? extends AbstractBlockBase<?>> sortedBlocks; /** * Map from {@linkplain #operandNumber(Value) operand numbers} to intervals. @@ -145,11 +147,11 @@ LIRInstruction[] opIdToInstructionMap; /** - * Map from an instruction {@linkplain LIRInstruction#id id} to the {@linkplain AbstractBlock - * block} containing the instruction. Entries should be retrieved with {@link #blockForId(int)} - * as the id is not simply an index into this array. + * Map from an instruction {@linkplain LIRInstruction#id id} to the + * {@linkplain AbstractBlockBase block} containing the instruction. Entries should be retrieved + * with {@link #blockForId(int)} as the id is not simply an index into this array. */ - AbstractBlock<?>[] opIdToBlockMap; + AbstractBlockBase<?>[] opIdToBlockMap; /** * Bit set for each variable that is contained in each loop. @@ -161,10 +163,11 @@ */ private final int firstVariableNumber; - LinearScan(TargetDescription target, LIRGenerationResult res) { + LinearScan(TargetDescription target, LIRGenerationResult res, SpillMoveFactory spillMoveFactory) { this.target = target; this.res = res; this.ir = res.getLIR(); + this.spillMoveFactory = spillMoveFactory; this.frameMapBuilder = res.getFrameMapBuilder(); this.sortedBlocks = ir.linearScanOrder(); this.registerAttributes = frameMapBuilder.getRegisterConfig().getAttributesMap(); @@ -178,19 +181,23 @@ this.callKillsRegisters = this.frameMapBuilder.getRegisterConfig().areAllAllocatableRegistersCallerSaved(); } - int getFirstLirInstructionId(AbstractBlock<?> block) { + int getFirstLirInstructionId(AbstractBlockBase<?> block) { int result = ir.getLIRforBlock(block).get(0).id(); assert result >= 0; return result; } - int getLastLirInstructionId(AbstractBlock<?> block) { + int getLastLirInstructionId(AbstractBlockBase<?> block) { List<LIRInstruction> instructions = ir.getLIRforBlock(block); int result = instructions.get(instructions.size() - 1).id(); assert result >= 0; return result; } + SpillMoveFactory getSpillMoveFactory() { + return spillMoveFactory; + } + public static boolean isVariableOrRegister(Value value) { return isVariable(value) || isRegister(value); } @@ -312,7 +319,7 @@ return sortedBlocks.size(); } - AbstractBlock<?> blockAt(int index) { + AbstractBlockBase<?> blockAt(int index) { return sortedBlocks.get(index); } @@ -388,7 +395,7 @@ * @param opId an instruction {@linkplain LIRInstruction#id id} * @return the block containing the instruction denoted by {@code opId} */ - AbstractBlock<?> blockForId(int opId) { + AbstractBlockBase<?> blockForId(int opId) { assert opIdToBlockMap.length > 0 && opId >= 0 && opId <= maxOpId() + 1 : "opId out of range"; return opIdToBlockMap[opIdToIndex(opId)]; } @@ -522,7 +529,7 @@ } LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer(); - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { List<LIRInstruction> instructions = ir.getLIRforBlock(block); int numInst = instructions.size(); @@ -571,7 +578,7 @@ assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState(); assert isStackSlotValue(toLocation) : "to operand must be a stack slot"; - insertionBuffer.append(j + 1, ir.getSpillMoveFactory().createMove(toLocation, fromLocation)); + insertionBuffer.append(j + 1, getSpillMoveFactory().createMove(toLocation, fromLocation)); Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId); } @@ -627,17 +634,17 @@ // Assign IDs to LIR nodes and build a mapping, lirOps, from ID to LIRInstruction node. int numInstructions = 0; - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { numInstructions += ir.getLIRforBlock(block).size(); } // initialize with correct length opIdToInstructionMap = new LIRInstruction[numInstructions]; - opIdToBlockMap = new AbstractBlock<?>[numInstructions]; + opIdToBlockMap = new AbstractBlockBase<?>[numInstructions]; int opId = 0; int index = 0; - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { blockData.put(block, new BlockData()); List<LIRInstruction> instructions = ir.getLIRforBlock(block); @@ -672,7 +679,7 @@ intervalInLoop = new BitMap2D(operandSize(), numLoops()); // iterate all blocks - for (final AbstractBlock<?> block : sortedBlocks) { + for (final AbstractBlockBase<?> block : sortedBlocks) { try (Indent indent = Debug.logAndIndent("compute local live sets for block %d", block.getId())) { final BitSet liveGen = new BitSet(liveSize); @@ -763,7 +770,7 @@ } } - private void verifyInput(AbstractBlock<?> block, BitSet liveKill, Value operand) { + private void verifyInput(AbstractBlockBase<?> block, BitSet liveKill, Value operand) { // fixed intervals are never live at block boundaries, so // they need not be processed in live sets. // this is checked by these assertions to be sure about it. @@ -797,7 +804,7 @@ // iterate all blocks in reverse order for (int i = numBlocks - 1; i >= 0; i--) { - AbstractBlock<?> block = blockAt(i); + AbstractBlockBase<?> block = blockAt(i); BlockData blockSets = blockData.get(block); changeOccurredInBlock = false; @@ -808,7 +815,7 @@ liveOut.clear(); // block has successors if (n > 0) { - for (AbstractBlock<?> successor : block.getSuccessors()) { + for (AbstractBlockBase<?> successor : block.getSuccessors()) { liveOut.or(blockData.get(successor).liveIn); } } @@ -852,7 +859,7 @@ } // check that the liveIn set of the first block is empty - AbstractBlock<?> startBlock = ir.getControlFlowGraph().getStartBlock(); + AbstractBlockBase<?> startBlock = ir.getControlFlowGraph().getStartBlock(); if (blockData.get(startBlock).liveIn.cardinality() != 0) { if (DetailedAsserts.getValue()) { reportFailure(numBlocks); @@ -891,9 +898,9 @@ } try (Indent indent2 = Debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, valueForOperandFromDebugContext)) { - Deque<AbstractBlock<?>> definedIn = new ArrayDeque<>(); - HashSet<AbstractBlock<?>> usedIn = new HashSet<>(); - for (AbstractBlock<?> block : sortedBlocks) { + Deque<AbstractBlockBase<?>> definedIn = new ArrayDeque<>(); + HashSet<AbstractBlockBase<?>> usedIn = new HashSet<>(); + for (AbstractBlockBase<?> block : sortedBlocks) { if (blockData.get(block).liveGen.get(operandNum)) { usedIn.add(block); try (Indent indent3 = Debug.logAndIndent("used in block B%d", block.getId())) { @@ -920,9 +927,9 @@ int[] hitCount = new int[numBlocks]; while (!definedIn.isEmpty()) { - AbstractBlock<?> block = definedIn.removeFirst(); + AbstractBlockBase<?> block = definedIn.removeFirst(); usedIn.remove(block); - for (AbstractBlock<?> successor : block.getSuccessors()) { + for (AbstractBlockBase<?> successor : block.getSuccessors()) { if (successor.isLoopHeader()) { if (!block.isLoopEnd()) { definedIn.add(successor); @@ -935,7 +942,7 @@ } } try (Indent indent3 = Debug.logAndIndent("**** offending usages are in: ")) { - for (AbstractBlock<?> block : usedIn) { + for (AbstractBlockBase<?> block : usedIn) { Debug.log("B%d", block.getId()); } } @@ -950,7 +957,7 @@ private void verifyLiveness() { // check that fixed intervals are not live at block boundaries // (live set must be empty at fixed intervals) - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { for (int j = 0; j <= maxRegisterNumber(); j++) { assert !blockData.get(block).liveIn.get(j) : "liveIn set of fixed register must be empty"; assert !blockData.get(block).liveOut.get(j) : "liveOut set of fixed register must be empty"; @@ -1167,7 +1174,7 @@ // iterate all blocks in reverse order for (int i = blockCount() - 1; i >= 0; i--) { - AbstractBlock<?> block = blockAt(i); + AbstractBlockBase<?> block = blockAt(i); try (Indent indent2 = Debug.logAndIndent("handle block %d", block.getId())) { List<LIRInstruction> instructions = ir.getLIRforBlock(block); @@ -1411,15 +1418,15 @@ throw new BailoutException("LinearScan: interval is null"); } - Interval intervalAtBlockBegin(AbstractBlock<?> block, int operandNumber) { + Interval intervalAtBlockBegin(AbstractBlockBase<?> block, int operandNumber) { return splitChildAtOpId(intervalFor(operandNumber), getFirstLirInstructionId(block), LIRInstruction.OperandMode.DEF); } - Interval intervalAtBlockEnd(AbstractBlock<?> block, int operandNumber) { + Interval intervalAtBlockEnd(AbstractBlockBase<?> block, int operandNumber) { return splitChildAtOpId(intervalFor(operandNumber), getLastLirInstructionId(block) + 1, LIRInstruction.OperandMode.DEF); } - void resolveCollectMappings(AbstractBlock<?> fromBlock, AbstractBlock<?> toBlock, MoveResolver moveResolver) { + void resolveCollectMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { assert moveResolver.checkEmpty(); int numOperands = operandSize(); @@ -1440,7 +1447,7 @@ } } - void resolveFindInsertPos(AbstractBlock<?> fromBlock, AbstractBlock<?> toBlock, MoveResolver moveResolver) { + void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { if (fromBlock.getSuccessorCount() <= 1) { Debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId()); @@ -1463,7 +1470,7 @@ // successor edges, blocks which are reached by switch statements // may have be more than one predecessor but it will be guaranteed // that all predecessors will be the same. - for (AbstractBlock<?> predecessor : toBlock.getPredecessors()) { + for (AbstractBlockBase<?> predecessor : toBlock.getPredecessors()) { assert fromBlock == predecessor : "all critical edges must be broken"; } } @@ -1484,7 +1491,7 @@ BitSet blockCompleted = new BitSet(numBlocks); BitSet alreadyResolved = new BitSet(numBlocks); - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { // check if block has only one predecessor and only one successor if (block.getPredecessorCount() == 1 && block.getSuccessorCount() == 1) { @@ -1494,8 +1501,8 @@ // check if block is empty (only label and branch) if (instructions.size() == 2) { - AbstractBlock<?> pred = block.getPredecessors().iterator().next(); - AbstractBlock<?> sux = block.getSuccessors().iterator().next(); + AbstractBlockBase<?> pred = block.getPredecessors().iterator().next(); + AbstractBlockBase<?> sux = block.getSuccessors().iterator().next(); // prevent optimization of two consecutive blocks if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) { @@ -1516,12 +1523,12 @@ } } - for (AbstractBlock<?> fromBlock : sortedBlocks) { + for (AbstractBlockBase<?> fromBlock : sortedBlocks) { if (!blockCompleted.get(fromBlock.getLinearScanNumber())) { alreadyResolved.clear(); alreadyResolved.or(blockCompleted); - for (AbstractBlock<?> toBlock : fromBlock.getSuccessors()) { + for (AbstractBlockBase<?> toBlock : fromBlock.getSuccessors()) { // check for duplicate edges between the same blocks (can happen with switch // blocks) @@ -1566,7 +1573,7 @@ if (opId != -1) { if (DetailedAsserts.getValue()) { - AbstractBlock<?> block = blockForId(opId); + AbstractBlockBase<?> block = blockForId(opId); if (block.getSuccessorCount() <= 1 && opId == getLastLirInstructionId(block)) { // check if spill moves could have been appended at the end of this block, but // before the branch instruction. So the split child information for this branch @@ -1639,7 +1646,7 @@ } int tempOpId = op.id(); OperandMode mode = OperandMode.USE; - AbstractBlock<?> block = blockForId(tempOpId); + AbstractBlockBase<?> block = blockForId(tempOpId); if (block.getSuccessorCount() == 1 && tempOpId == getLastLirInstructionId(block)) { // generating debug information for the last instruction of a block. // if this instruction is a branch, spill moves are inserted before this branch @@ -1723,7 +1730,7 @@ private void assignLocations() { try (Indent indent = Debug.logAndIndent("assign locations")) { - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { try (Indent indent2 = Debug.logAndIndent("assign locations in block B%d", block.getId())) { assignLocations(ir.getLIRforBlock(block)); } @@ -1804,15 +1811,15 @@ } } - private DebugMetric betterSpillPos = Debug.metric("BetterSpillPosition"); - private DebugMetric betterSpillPosWithLowerProbability = Debug.metric("BetterSpillPositionWithLowerProbability"); + private static final DebugMetric betterSpillPos = Debug.metric("BetterSpillPosition"); + private static final DebugMetric betterSpillPosWithLowerProbability = Debug.metric("BetterSpillPositionWithLowerProbability"); private void optimizeSpillPosition() { LIRInsertionBuffer[] insertionBuffers = new LIRInsertionBuffer[ir.linearScanOrder().size()]; for (Interval interval : intervals) { if (interval != null && interval.isSplitParent() && interval.spillState() == SpillState.SpillInDominator) { - AbstractBlock<?> defBlock = blockForId(interval.spillDefinitionPos()); - AbstractBlock<?> spillBlock = null; + AbstractBlockBase<?> defBlock = blockForId(interval.spillDefinitionPos()); + AbstractBlockBase<?> spillBlock = null; Interval firstSpillChild = null; try (Indent indent = Debug.logAndIndent("interval %s (%s)", interval, defBlock)) { for (Interval splitChild : interval.getSplitChildren()) { @@ -1823,7 +1830,7 @@ assert firstSpillChild.from() < splitChild.from(); } // iterate all blocks where the interval has use positions - for (AbstractBlock<?> splitBlock : blocksForInterval(splitChild)) { + for (AbstractBlockBase<?> splitBlock : blocksForInterval(splitChild)) { if (dominates(defBlock, splitBlock)) { Debug.log("Split interval %s, block %s", splitChild, splitBlock); if (spillBlock == null) { @@ -1851,7 +1858,7 @@ */ assert firstSpillChild != null; if (!defBlock.equals(spillBlock) && spillBlock.equals(blockForId(firstSpillChild.from()))) { - AbstractBlock<?> dom = spillBlock.getDominator(); + AbstractBlockBase<?> dom = spillBlock.getDominator(); Debug.log("Spill block (%s) is the beginning of a spill child -> use dominator (%s)", spillBlock, dom); spillBlock = dom; } @@ -1875,7 +1882,7 @@ // insert spill move AllocatableValue fromLocation = interval.getSplitChildAtOpId(spillOpId, OperandMode.DEF, this).location(); AllocatableValue toLocation = canonicalSpillOpr(interval); - LIRInstruction move = ir.getSpillMoveFactory().createMove(toLocation, fromLocation); + LIRInstruction move = getSpillMoveFactory().createMove(toLocation, fromLocation); move.setId(DOMINATOR_SPILL_MOVE_ID); /* * We can use the insertion buffer directly because we always insert @@ -1903,20 +1910,20 @@ } /** - * Iterate over all {@link AbstractBlock blocks} of an interval. + * Iterate over all {@link AbstractBlockBase blocks} of an interval. */ - private class IntervalBlockIterator implements Iterator<AbstractBlock<?>> { + private class IntervalBlockIterator implements Iterator<AbstractBlockBase<?>> { Range range; - AbstractBlock<?> block; + AbstractBlockBase<?> block; public IntervalBlockIterator(Interval interval) { range = interval.first(); block = blockForId(range.from); } - public AbstractBlock<?> next() { - AbstractBlock<?> currentBlock = block; + public AbstractBlockBase<?> next() { + AbstractBlockBase<?> currentBlock = block; int nextBlockIndex = block.getLinearScanNumber() + 1; if (nextBlockIndex < sortedBlocks.size()) { block = sortedBlocks.get(nextBlockIndex); @@ -1939,17 +1946,17 @@ } } - private Iterable<AbstractBlock<?>> blocksForInterval(Interval interval) { - return new Iterable<AbstractBlock<?>>() { - public Iterator<AbstractBlock<?>> iterator() { + private Iterable<AbstractBlockBase<?>> blocksForInterval(Interval interval) { + return new Iterable<AbstractBlockBase<?>>() { + public Iterator<AbstractBlockBase<?>> iterator() { return new IntervalBlockIterator(interval); } }; } - private static AbstractBlock<?> moveSpillOutOfLoop(AbstractBlock<?> defBlock, AbstractBlock<?> spillBlock) { + private static AbstractBlockBase<?> moveSpillOutOfLoop(AbstractBlockBase<?> defBlock, AbstractBlockBase<?> spillBlock) { int defLoopDepth = defBlock.getLoopDepth(); - for (AbstractBlock<?> block = spillBlock.getDominator(); !defBlock.equals(block); block = block.getDominator()) { + for (AbstractBlockBase<?> block = spillBlock.getDominator(); !defBlock.equals(block); block = block.getDominator()) { assert block != null : "spill block not dominated by definition block?"; if (block.getLoopDepth() <= defLoopDepth) { assert block.getLoopDepth() == defLoopDepth : "Cannot spill an interval outside of the loop where it is defined!"; @@ -1970,7 +1977,7 @@ try (Indent indent2 = Debug.logAndIndent("Basic Blocks")) { for (int i = 0; i < blockCount(); i++) { - AbstractBlock<?> block = blockAt(i); + AbstractBlockBase<?> block = blockAt(i); Debug.log("B%d [%d, %d, %s] ", block.getId(), getFirstLirInstructionId(block), getLastLirInstructionId(block), block.getLoop()); } } @@ -2103,7 +2110,7 @@ otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals); - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { List<LIRInstruction> instructions = ir.getLIRforBlock(block); for (int j = 0; j < instructions.size(); j++) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,13 +27,14 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; import com.oracle.graal.lir.phases.*; public final class LinearScanPhase extends AllocationPhase { @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { - new LinearScan(target, lirGenRes).allocate(); + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory) { + new LinearScan(target, lirGenRes, spillMoveFactory).allocate(); } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanWalker.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanWalker.java Tue Mar 10 21:26:02 2015 +0100 @@ -63,11 +63,11 @@ return allocator.blockCount(); } - AbstractBlock<?> blockAt(int idx) { + AbstractBlockBase<?> blockAt(int idx) { return allocator.blockAt(idx); } - AbstractBlock<?> blockOfOpWithId(int opId) { + AbstractBlockBase<?> blockOfOpWithId(int opId) { return allocator.blockForId(opId); } @@ -239,7 +239,7 @@ // optimized away later in assignRegNums int opId = (operandId + 1) & ~1; - AbstractBlock<?> opBlock = allocator.blockForId(opId); + AbstractBlockBase<?> opBlock = allocator.blockForId(opId); assert opId > 0 && allocator.blockForId(opId - 2) == opBlock : "cannot insert move at block boundary"; // calculate index of instruction inside instruction list of current block @@ -263,7 +263,7 @@ moveResolver.addMapping(srcIt, dstIt); } - int findOptimalSplitPos(AbstractBlock<?> minBlock, AbstractBlock<?> maxBlock, int maxSplitPos) { + int findOptimalSplitPos(AbstractBlockBase<?> minBlock, AbstractBlockBase<?> maxBlock, int maxSplitPos) { int fromBlockNr = minBlock.getLinearScanNumber(); int toBlockNr = maxBlock.getLinearScanNumber(); @@ -280,7 +280,7 @@ int minLoopDepth = maxBlock.getLoopDepth(); for (int i = toBlockNr - 1; i >= fromBlockNr; i--) { - AbstractBlock<?> cur = blockAt(i); + AbstractBlockBase<?> cur = blockAt(i); if (cur.getLoopDepth() < minLoopDepth) { // block with lower loop-depth found . split at the end of this block @@ -308,13 +308,13 @@ // beginning of a block, then minSplitPos is also a possible split position. // Use the block before as minBlock, because then minBlock.lastLirInstructionId() + 2 == // minSplitPos - AbstractBlock<?> minBlock = allocator.blockForId(minSplitPos - 1); + AbstractBlockBase<?> minBlock = allocator.blockForId(minSplitPos - 1); // reason for using maxSplitPos - 1: otherwise there would be an assert on failure // when an interval ends at the end of the last block of the method // (in this case, maxSplitPos == allocator().maxLirOpId() + 2, and there is no // block at this opId) - AbstractBlock<?> maxBlock = allocator.blockForId(maxSplitPos - 1); + AbstractBlockBase<?> maxBlock = allocator.blockForId(maxSplitPos - 1); assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order"; if (minBlock == maxBlock) { @@ -352,7 +352,7 @@ // Desired result: uses tagged as shouldHaveRegister inside a loop cause // a reloading // of the interval (normally, only mustHaveRegister causes a reloading) - AbstractBlock<?> loopBlock = allocator.blockForId(loopEndPos); + AbstractBlockBase<?> loopBlock = allocator.blockForId(loopEndPos); Debug.log("interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(), loopBlock.getId()); assert loopBlock != minBlock : "loopBlock and minBlock must be different because block boundary is needed between";
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,6 +35,7 @@ import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; @@ -52,7 +53,7 @@ } @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory) { new Marker(lirGenRes.getLIR(), lirGenRes.getFrameMap()).build(); } @@ -72,32 +73,23 @@ } private void build() { - Deque<AbstractBlock<?>> worklist = new ArrayDeque<>(); + Deque<AbstractBlockBase<?>> worklist = new ArrayDeque<>(); for (int i = lir.getControlFlowGraph().getBlocks().size() - 1; i >= 0; i--) { worklist.add(lir.getControlFlowGraph().getBlocks().get(i)); } - for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) { + for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) { liveInMap.put(block, frameMap.initReferenceMap(true)); } while (!worklist.isEmpty()) { - AbstractBlock<?> block = worklist.poll(); + AbstractBlockBase<?> block = worklist.poll(); processBlock(block, worklist); } - // finish states - for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) { - List<LIRInstruction> instructions = lir.getLIRforBlock(block); - for (int i = instructions.size() - 1; i >= 0; i--) { - LIRInstruction inst = instructions.get(i); - inst.forEachState((op, info) -> info.finish(op, frameMap)); - } - - } } /** * Merge outSet with in-set of successors. */ - private boolean updateOutBlock(AbstractBlock<?> block) { + private boolean updateOutBlock(AbstractBlockBase<?> block) { ReferenceMap union = frameMap.initReferenceMap(true); block.getSuccessors().forEach(succ -> union.updateUnion(liveInMap.get(succ))); ReferenceMap outSet = liveOutMap.get(block); @@ -109,7 +101,7 @@ return false; } - private void processBlock(AbstractBlock<?> block, Deque<AbstractBlock<?>> worklist) { + private void processBlock(AbstractBlockBase<?> block, Deque<AbstractBlockBase<?>> worklist) { if (updateOutBlock(block)) { try (Indent indent = Debug.logAndIndent("handle block %s", block)) { BlockClosure closure = new BlockClosure(liveOutMap.get(block).clone());
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java Tue Mar 10 21:26:02 2015 +0100 @@ -203,7 +203,7 @@ AllocatableValue fromOpr = fromInterval.operand; AllocatableValue toOpr = toInterval.operand; - insertionBuffer.append(insertIdx, allocator.ir.getSpillMoveFactory().createMove(toOpr, fromOpr)); + insertionBuffer.append(insertIdx, allocator.getSpillMoveFactory().createMove(toOpr, fromOpr)); Debug.log("insert move from %s to %s at %d", fromInterval, toInterval, insertIdx); } @@ -213,7 +213,7 @@ assert insertIdx != -1 : "must setup insert position first"; AllocatableValue toOpr = toInterval.operand; - insertionBuffer.append(insertIdx, allocator.ir.getSpillMoveFactory().createMove(toOpr, fromOpr)); + insertionBuffer.append(insertIdx, allocator.getSpillMoveFactory().createMove(toOpr, fromOpr)); Debug.log("insert move from value %s to %s at %d", fromOpr, toInterval, insertIdx); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/OptimizingLinearScanWalker.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/OptimizingLinearScanWalker.java Tue Mar 10 21:26:02 2015 +0100 @@ -71,14 +71,14 @@ @Override void walk() { try (Scope s = Debug.scope("OptimizingLinearScanWalker")) { - for (AbstractBlock<?> block : allocator.sortedBlocks) { + for (AbstractBlockBase<?> block : allocator.sortedBlocks) { optimizeBlock(block); } } super.walk(); } - private void optimizeBlock(AbstractBlock<?> block) { + private void optimizeBlock(AbstractBlockBase<?> block) { if (block.getPredecessorCount() == 1) { int nextBlock = allocator.getFirstLirInstructionId(block); try (Scope s1 = Debug.scope("LSRAOptimization")) { @@ -114,7 +114,7 @@ } } - private boolean optimize(int currentPos, AbstractBlock<?> currentBlock, Interval currentInterval, RegisterBinding binding) { + private boolean optimize(int currentPos, AbstractBlockBase<?> currentBlock, Interval currentInterval, RegisterBinding binding) { // BEGIN initialize and sanity checks assert currentBlock != null : "block must not be null"; assert currentInterval != null : "interval must not be null"; @@ -136,7 +136,7 @@ assert currentLocation != null : "active intervals must have a location assigned!"; // get predecessor stuff - AbstractBlock<?> predecessorBlock = currentBlock.getPredecessors().get(0); + AbstractBlockBase<?> predecessorBlock = currentBlock.getPredecessors().get(0); int predEndId = allocator.getLastLirInstructionId(predecessorBlock); Interval predecessorInterval = currentInterval.getIntervalCoveringOpId(predEndId); assert predecessorInterval != null : "variable not live at the end of the only predecessor! " + predecessorBlock + " -> " + currentBlock + " interval: " + currentInterval;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Range.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Range.java Tue Mar 10 21:26:02 2015 +0100 @@ -50,7 +50,7 @@ /** * Creates a new range. - * + * * @param from the start of the range, inclusive * @param to the end of the range, exclusive * @param next link to the next range in a linked list
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/RegisterVerifier.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/RegisterVerifier.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ final class RegisterVerifier { LinearScan allocator; - List<AbstractBlock<?>> workList; // all blocks that must be processed + List<AbstractBlockBase<?>> workList; // all blocks that must be processed ArrayMap<Interval[]> savedStates; // saved information of previous check // simplified access to methods of LinearScan @@ -55,15 +55,15 @@ } // accessors - Interval[] stateForBlock(AbstractBlock<?> block) { + Interval[] stateForBlock(AbstractBlockBase<?> block) { return savedStates.get(block.getId()); } - void setStateForBlock(AbstractBlock<?> block, Interval[] savedState) { + void setStateForBlock(AbstractBlockBase<?> block, Interval[] savedState) { savedStates.put(block.getId(), savedState); } - void addToWorkList(AbstractBlock<?> block) { + void addToWorkList(AbstractBlockBase<?> block) { if (!workList.contains(block)) { workList.add(block); } @@ -76,7 +76,7 @@ } - void verify(AbstractBlock<?> start) { + void verify(AbstractBlockBase<?> start) { // setup input registers (method arguments) for first block Interval[] inputState = new Interval[stateSize()]; setStateForBlock(start, inputState); @@ -84,14 +84,14 @@ // main loop for verification do { - AbstractBlock<?> block = workList.get(0); + AbstractBlockBase<?> block = workList.get(0); workList.remove(0); processBlock(block); } while (!workList.isEmpty()); } - private void processBlock(AbstractBlock<?> block) { + private void processBlock(AbstractBlockBase<?> block) { try (Indent indent = Debug.logAndIndent("processBlock B%d", block.getId())) { // must copy state because it is modified Interval[] inputState = copy(stateForBlock(block)); @@ -110,13 +110,13 @@ processOperations(allocator.ir.getLIRforBlock(block), inputState); // iterate all successors - for (AbstractBlock<?> succ : block.getSuccessors()) { + for (AbstractBlockBase<?> succ : block.getSuccessors()) { processSuccessor(succ, inputState); } } } - private void processSuccessor(AbstractBlock<?> block, Interval[] inputState) { + private void processSuccessor(AbstractBlockBase<?> block, Interval[] inputState) { Interval[] savedState = stateForBlock(block); if (savedState != null) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Tue Mar 10 21:26:02 2015 +0100 @@ -330,7 +330,7 @@ */ public boolean isSuccessorEdge(LabelRef edge) { assert lir != null; - List<? extends AbstractBlock<?>> order = lir.codeEmittingOrder(); + List<? extends AbstractBlockBase<?>> order = lir.codeEmittingOrder(); assert order.get(currentBlockIndex) == edge.getSourceBlock(); return currentBlockIndex < order.size() - 1 && order.get(currentBlockIndex + 1) == edge.getTargetBlock(); } @@ -344,7 +344,7 @@ this.lir = lir; this.currentBlockIndex = 0; frameContext.enter(this); - for (AbstractBlock<?> b : lir.codeEmittingOrder()) { + for (AbstractBlockBase<?> b : lir.codeEmittingOrder()) { emitBlock(b); currentBlockIndex++; } @@ -352,7 +352,7 @@ this.currentBlockIndex = 0; } - private void emitBlock(AbstractBlock<?> block) { + private void emitBlock(AbstractBlockBase<?> block) { if (Debug.isDumpEnabled()) { blockComment(String.format("block B%d %s", block.getId(), block.getLoop())); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRValueUtil.*; +import static com.oracle.graal.lir.phases.LIRPhase.Options.*; import java.util.*; @@ -52,12 +53,12 @@ public static class Options { // @formatter:off @Option(help = "Enable constant load optimization.", type = OptionType.Debug) - public static final OptionValue<Boolean> LIROptConstantLoadOptimization = new OptionValue<>(true); + public static final NestedBooleanOptionValue LIROptConstantLoadOptimization = new NestedBooleanOptionValue(LIROptimization, true); // @formatter:on } @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, LIRGeneratorTool lirGen) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, LIRGeneratorTool lirGen) { new Optimization(lirGenRes.getLIR(), lirGen).apply(); } @@ -135,7 +136,7 @@ assert !operand.equals(var) : "constant usage through variable in frame state " + var; } }; - for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) { + for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) { for (LIRInstruction inst : lir.getLIRforBlock(block)) { // set instruction id to the index in the lir instruction list inst.visitEachState(stateConsumer); @@ -152,7 +153,7 @@ } private void addUsageToBlockMap(UseEntry entry) { - AbstractBlock<?> block = entry.getBlock(); + AbstractBlockBase<?> block = entry.getBlock(); List<UseEntry> list = blockMap.get(block); if (list == null) { list = new ArrayList<>(); @@ -164,7 +165,7 @@ /** * Collects def-use information for a {@code block}. */ - private void analyzeBlock(AbstractBlock<?> block) { + private void analyzeBlock(AbstractBlockBase<?> block) { try (Indent indent = Debug.logAndIndent("Block: %s", block)) { InstructionValueConsumer loadConsumer = (instruction, value, mode, flags) -> { @@ -195,14 +196,13 @@ } }; - ValuePositionProcedure useProcedure = (instruction, position) -> { - Value value = position.get(instruction); + InstructionValueConsumer useConsumer = (instruction, value, mode, flags) -> { if (isVariable(value)) { Variable var = (Variable) value; if (!phiConstants.get(var.index)) { DefUseTree tree = map.get(var); if (tree != null) { - tree.addUsage(block, instruction, position); + tree.addUsage(block, instruction, value); Debug.log("usage of %s : %s", var, instruction); } } @@ -214,8 +214,8 @@ // set instruction id to the index in the lir instruction list inst.setId(opId++); inst.visitEachOutput(loadConsumer); - inst.forEachInputPos(useProcedure); - inst.forEachAlivePos(useProcedure); + inst.forEachInput(useConsumer); + inst.forEachAlive(useConsumer); } } @@ -267,17 +267,17 @@ Debug.dump(constTree, "ConstantTree for " + tree.getVariable()); } - private void createLoads(DefUseTree tree, ConstantTree constTree, AbstractBlock<?> startBlock) { - Deque<AbstractBlock<?>> worklist = new ArrayDeque<>(); + private void createLoads(DefUseTree tree, ConstantTree constTree, AbstractBlockBase<?> startBlock) { + Deque<AbstractBlockBase<?>> worklist = new ArrayDeque<>(); worklist.add(startBlock); while (!worklist.isEmpty()) { - AbstractBlock<?> block = worklist.pollLast(); + AbstractBlockBase<?> block = worklist.pollLast(); if (constTree.get(Flags.CANDIDATE, block)) { constTree.set(Flags.MATERIALIZE, block); // create and insert load insertLoad(tree.getConstant(), tree.getVariable().getLIRKind(), block, constTree.getCost(block).getUsages()); } else { - for (AbstractBlock<?> dominated : block.getDominated()) { + for (AbstractBlockBase<?> dominated : block.getDominated()) { if (constTree.isMarked(dominated)) { worklist.addLast(dominated); } @@ -286,18 +286,18 @@ } } - private void insertLoad(JavaConstant constant, LIRKind kind, AbstractBlock<?> block, List<UseEntry> usages) { + private void insertLoad(JavaConstant constant, LIRKind kind, AbstractBlockBase<?> block, List<UseEntry> usages) { assert usages != null && usages.size() > 0 : String.format("No usages %s %s %s", constant, block, usages); // create variable Variable variable = lirGen.newVariable(kind); // create move - LIRInstruction move = lir.getSpillMoveFactory().createMove(variable, constant); + LIRInstruction move = lirGen.getSpillMoveFactory().createMove(variable, constant); // insert instruction getInsertionBuffer(block).append(1, move); Debug.log("new move (%s) and inserted in block %s", move, block); // update usages for (UseEntry u : usages) { - u.getPosition().set(u.getInstruction(), variable); + u.setValue(variable); Debug.log("patched instruction %s", u.getInstruction()); } } @@ -306,7 +306,7 @@ * Inserts the constant loads created in {@link #createConstantTree} and deletes the * original definition. */ - private void rewriteBlock(AbstractBlock<?> block) { + private void rewriteBlock(AbstractBlockBase<?> block) { // insert moves LIRInsertionBuffer buffer = insertionBuffers.get(block); if (buffer != null) { @@ -331,13 +331,13 @@ } private void deleteInstruction(DefUseTree tree) { - AbstractBlock<?> block = tree.getBlock(); + AbstractBlockBase<?> block = tree.getBlock(); LIRInstruction instruction = tree.getInstruction(); Debug.log("deleting instruction %s from block %s", instruction, block); lir.getLIRforBlock(block).set(instruction.id(), null); } - private LIRInsertionBuffer getInsertionBuffer(AbstractBlock<?> block) { + private LIRInsertionBuffer getInsertionBuffer(AbstractBlockBase<?> block) { LIRInsertionBuffer insertionBuffer = insertionBuffers.get(block); if (insertionBuffer == null) { insertionBuffer = new LIRInsertionBuffer();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTree.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTree.java Tue Mar 10 21:26:02 2015 +0100 @@ -99,7 +99,7 @@ tree.forEach(u -> getOrInitList(u.getBlock()).add(u)); } - private List<UseEntry> getOrInitList(AbstractBlock<?> block) { + private List<UseEntry> getOrInitList(AbstractBlockBase<?> block) { List<UseEntry> list = blockMap.get(block); if (list == null) { list = new ArrayList<>(); @@ -108,7 +108,7 @@ return list; } - public List<UseEntry> getUsages(AbstractBlock<?> block) { + public List<UseEntry> getUsages(AbstractBlockBase<?> block) { List<UseEntry> list = blockMap.get(block); if (list == null) { return Collections.emptyList(); @@ -120,7 +120,7 @@ * Returns the cost object associated with {@code block}. If there is none, a new cost object is * created. */ - NodeCost getOrInitCost(AbstractBlock<?> block) { + NodeCost getOrInitCost(AbstractBlockBase<?> block) { NodeCost cost = getCost(block); if (cost == null) { cost = new NodeCost(block.probability(), blockMap.get(block), 1); @@ -145,7 +145,7 @@ } @Override - public void forEachPropertyPair(AbstractBlock<?> block, BiConsumer<String, String> action) { + public void forEachPropertyPair(AbstractBlockBase<?> block, BiConsumer<String, String> action) { if (get(Flags.SUBTREE, block) && (block.getDominator() == null || !get(Flags.SUBTREE, block.getDominator()))) { action.accept("hasDefinition", "true"); } @@ -156,7 +156,7 @@ return stream(Flags.SUBTREE).count(); } - public AbstractBlock<?> getStartBlock() { + public AbstractBlockBase<?> getStartBlock() { return stream(Flags.SUBTREE).findFirst().get(); } @@ -164,15 +164,15 @@ stream(Flags.USAGE).forEach(block -> setDominatorPath(Flags.SUBTREE, block)); } - public boolean isMarked(AbstractBlock<?> block) { + public boolean isMarked(AbstractBlockBase<?> block) { return get(Flags.SUBTREE, block); } - public boolean isLeafBlock(AbstractBlock<?> block) { + public boolean isLeafBlock(AbstractBlockBase<?> block) { return block.getDominated().stream().noneMatch(this::isMarked); } - public void setSolution(AbstractBlock<?> block) { + public void setSolution(AbstractBlockBase<?> block) { set(Flags.MATERIALIZE, block); } @@ -180,7 +180,7 @@ return getBlocks().size(); } - public void traverseTreeWhileTrue(AbstractBlock<?> block, Predicate<AbstractBlock<?>> action) { + public void traverseTreeWhileTrue(AbstractBlockBase<?> block, Predicate<AbstractBlockBase<?>> action) { assert block != null : "block must not be null!"; if (action.test(block)) { block.getDominated().stream().filter(this::isMarked).forEach(dominated -> traverseTreeWhileTrue(dominated, action));
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTreeAnalyzer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTreeAnalyzer.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ private final ConstantTree tree; private final BitSet visited; - public static NodeCost analyze(ConstantTree tree, AbstractBlock<?> startBlock) { + public static NodeCost analyze(ConstantTree tree, AbstractBlockBase<?> startBlock) { try (Scope s = Debug.scope("ConstantTreeAnalyzer")) { ConstantTreeAnalyzer analyzer = new ConstantTreeAnalyzer(tree); analyzer.analyzeBlocks(startBlock); @@ -60,11 +60,11 @@ * * @param startBlock The start block of the dominator subtree. */ - private void analyzeBlocks(AbstractBlock<?> startBlock) { - Deque<AbstractBlock<?>> worklist = new ArrayDeque<>(); + private void analyzeBlocks(AbstractBlockBase<?> startBlock) { + Deque<AbstractBlockBase<?>> worklist = new ArrayDeque<>(); worklist.offerLast(startBlock); while (!worklist.isEmpty()) { - AbstractBlock<?> block = worklist.pollLast(); + AbstractBlockBase<?> block = worklist.pollLast(); try (Indent i = Debug.logAndIndent(3, "analyze: %s", block)) { assert block != null : "worklist is empty!"; assert isMarked(block) : "Block not part of the dominator tree: " + block; @@ -79,7 +79,7 @@ // if not yet visited (and not a leaf block) process all children first! Debug.log(3, "not marked"); worklist.offerLast(block); - List<? extends AbstractBlock<?>> children = block.getDominated(); + List<? extends AbstractBlockBase<?>> children = block.getDominated(); children.forEach(child -> filteredPush(worklist, child)); visited.set(block.getId()); } else { @@ -97,15 +97,15 @@ * * @param block The block to be processed. */ - private void process(AbstractBlock<?> block) { + private void process(AbstractBlockBase<?> block) { List<UseEntry> usages = new ArrayList<>(); double bestCost = 0; int numMat = 0; - List<? extends AbstractBlock<?>> children = block.getDominated(); + List<? extends AbstractBlockBase<?>> children = block.getDominated(); assert children.stream().anyMatch(this::isMarked) : "no children? should have called leafCost(): " + block; // collect children costs - for (AbstractBlock<?> child : children) { + for (AbstractBlockBase<?> child : children) { if (isMarked(child)) { NodeCost childCost = tree.getCost(child); assert childCost != null : "Child with null cost? block: " + child; @@ -151,23 +151,23 @@ return probabilityBlock * Math.pow(0.9, numMat - 1) < probabilityChildren; } - private void filteredPush(Deque<AbstractBlock<?>> worklist, AbstractBlock<?> block) { + private void filteredPush(Deque<AbstractBlockBase<?>> worklist, AbstractBlockBase<?> block) { if (isMarked(block)) { Debug.log(3, "adding %s to the worklist", block); worklist.offerLast(block); } } - private void leafCost(AbstractBlock<?> block) { + private void leafCost(AbstractBlockBase<?> block) { tree.set(Flags.CANDIDATE, block); tree.getOrInitCost(block); } - private boolean isMarked(AbstractBlock<?> block) { + private boolean isMarked(AbstractBlockBase<?> block) { return tree.isMarked(block); } - private boolean isLeafBlock(AbstractBlock<?> block) { + private boolean isLeafBlock(AbstractBlockBase<?> block) { return tree.isLeafBlock(block); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/DefUseTree.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/DefUseTree.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,10 +35,10 @@ */ class DefUseTree { private final LIRInstruction instruction; - private final AbstractBlock<?> block; + private final AbstractBlockBase<?> block; private final List<UseEntry> uses; - public DefUseTree(LIRInstruction instruction, AbstractBlock<?> block) { + public DefUseTree(LIRInstruction instruction, AbstractBlockBase<?> block) { assert instruction instanceof MoveOp : "Not a MoveOp: " + instruction; this.instruction = instruction; this.block = block; @@ -57,7 +57,7 @@ return instruction; } - public AbstractBlock<?> getBlock() { + public AbstractBlockBase<?> getBlock() { return block; } @@ -66,8 +66,8 @@ return "DefUseTree [" + instruction + "|" + block + "," + uses + "]"; } - public void addUsage(AbstractBlock<?> b, LIRInstruction inst, ValuePosition position) { - uses.add(new UseEntry(b, inst, position)); + public void addUsage(AbstractBlockBase<?> b, LIRInstruction inst, Value value) { + uses.add(new UseEntry(b, inst, value)); } public int usageCount() {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/UseEntry.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/UseEntry.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,34 +31,44 @@ */ class UseEntry { - private final AbstractBlock<?> block; + private final AbstractBlockBase<?> block; private final LIRInstruction instruction; - private final ValuePosition position; + private final Value value; - public UseEntry(AbstractBlock<?> block, LIRInstruction instruction, ValuePosition position) { + public UseEntry(AbstractBlockBase<?> block, LIRInstruction instruction, Value value) { this.block = block; this.instruction = instruction; - this.position = position; + this.value = value; } public LIRInstruction getInstruction() { return instruction; } - public AbstractBlock<?> getBlock() { + public AbstractBlockBase<?> getBlock() { return block; } - public ValuePosition getPosition() { - return position; + public void setValue(Value newValue) { + replaceValue(instruction, value, newValue); + } + + private static void replaceValue(LIRInstruction op, Value oldValue, Value newValue) { + ValueProcedure proc = (value, mode, flags) -> value.identityEquals(oldValue) ? newValue : value; + op.forEachAlive(proc); + op.forEachInput(proc); + op.forEachOutput(proc); + op.forEachTemp(proc); + op.forEachState(proc); } public Value getValue() { - return position.get(instruction); + return value; } @Override public String toString() { return "Use[" + getValue() + ":" + instruction + ":" + block + "]"; } + }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -117,7 +117,7 @@ InstructionValueConsumer verifySlots = (LIRInstruction op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) -> { assert !isVirtualStackSlot(value) : String.format("Instruction %s contains a virtual stack slot %s", op, value); }; - for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) { + for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) { lir.getLIRforBlock(block).forEach(op -> { op.visitEachInput(verifySlots); op.visitEachAlive(verifySlots);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Mar 10 21:26:02 2015 +0100 @@ -60,7 +60,7 @@ private final CodeGenProviders providers; private final CallingConvention cc; - private AbstractBlock<?> currentBlock; + private AbstractBlockBase<?> currentBlock; private LIRGenerationResult res; @@ -186,7 +186,7 @@ res.getLIR().getLIRforBlock(currentBlock).add(op); } - public boolean hasBlockEnd(AbstractBlock<?> block) { + public boolean hasBlockEnd(AbstractBlockBase<?> block) { List<LIRInstruction> ops = getResult().getLIR().getLIRforBlock(block); if (ops.size() == 0) { return false; @@ -194,7 +194,7 @@ return ops.get(ops.size() - 1) instanceof BlockEndOp; } - public final void doBlockStart(AbstractBlock<?> block) { + public final void doBlockStart(AbstractBlockBase<?> block) { if (Options.PrintIRWithLIR.getValue()) { TTY.print(block.toString()); } @@ -212,7 +212,7 @@ } } - public final void doBlockEnd(AbstractBlock<?> block) { + public final void doBlockEnd(AbstractBlockBase<?> block) { if (Options.TraceLIRGeneratorLevel.getValue() >= 1) { TTY.println("END Generating LIR for block B" + block.getId()); @@ -226,7 +226,7 @@ } public void emitIncomingValues(Value[] params) { - ((LabelOp) res.getLIR().getLIRforBlock(currentBlock).get(0)).setIncomingValues(params); + ((LabelOp) res.getLIR().getLIRforBlock(getCurrentBlock()).get(0)).setIncomingValues(params); } public abstract void emitJump(LabelRef label); @@ -379,14 +379,10 @@ } } - public AbstractBlock<?> getCurrentBlock() { + public AbstractBlockBase<?> getCurrentBlock() { return currentBlock; } - void setCurrentBlock(AbstractBlock<?> block) { - currentBlock = block; - } - public LIRGenerationResult getResult() { return res; }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,6 +32,11 @@ public interface LIRGeneratorTool extends ArithmeticLIRGenerator { + public interface SpillMoveFactory { + + LIRInstruction createMove(AllocatableValue result, Value input); + } + CodeGenProviders getProviders(); TargetDescription target(); @@ -42,15 +47,17 @@ ForeignCallsProvider getForeignCalls(); - AbstractBlock<?> getCurrentBlock(); + AbstractBlockBase<?> getCurrentBlock(); LIRGenerationResult getResult(); - boolean hasBlockEnd(AbstractBlock<?> block); + boolean hasBlockEnd(AbstractBlockBase<?> block); + + SpillMoveFactory getSpillMoveFactory(); - void doBlockStart(AbstractBlock<?> block); + void doBlockStart(AbstractBlockBase<?> block); - void doBlockEnd(AbstractBlock<?> block); + void doBlockEnd(AbstractBlockBase<?> block); Value emitLoadConstant(LIRKind kind, Constant constant);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/AllocationPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/AllocationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,17 +27,24 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGeneratorTool.*; public abstract class AllocationPhase extends LIRPhase<AllocationPhase.AllocationContext> { public static final class AllocationContext { + private final SpillMoveFactory spillMoveFactory; + + public AllocationContext(SpillMoveFactory spillMoveFactory) { + this.spillMoveFactory = spillMoveFactory; + } } @Override - protected final <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, AllocationContext context) { - run(target, lirGenRes, codeEmittingOrder, linearScanOrder); + protected final <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, AllocationContext context) { + run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context.spillMoveFactory); } - protected abstract <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder); + protected abstract <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, + SpillMoveFactory spillMoveFactory); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,10 +29,9 @@ import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.DebugMemUseTracker.Closeable; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.options.*; /** * Base class for all {@link LIR low-level} phases. Subclasses should be stateless. There will be @@ -40,6 +39,13 @@ */ public abstract class LIRPhase<C> { + public static class Options { + // @formatter:off + @Option(help = "Enable LIR level optimiztations.", type = OptionType.Debug) + public static final OptionValue<Boolean> LIROptimization = new OptionValue<>(true); + // @formatter:on + } + private static final int PHASE_DUMP_LEVEL = 2; private CharSequence name; @@ -73,22 +79,24 @@ memUseTracker = Debug.memUseTracker("LIRPhaseMemUse_%s", getClass()); } - public final <B extends AbstractBlock<B>> void apply(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context) { + public final <B extends AbstractBlockBase<B>> void apply(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context) { apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, context, true); } - public final <B extends AbstractBlock<B>> void apply(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context, boolean dumpLIR) { - try (TimerCloseable a = timer.start(); Scope s = Debug.scope(getName(), this); Closeable c = memUseTracker.start()) { - run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context); - if (dumpLIR && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) { - Debug.dump(PHASE_DUMP_LEVEL, lirGenRes.getLIR(), "After phase %s", getName()); + public final <B extends AbstractBlockBase<B>> void apply(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context, boolean dumpLIR) { + try (Scope s = Debug.scope(getName(), this)) { + try (DebugCloseable a = timer.start(); DebugCloseable c = memUseTracker.start()) { + run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context); + if (dumpLIR && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) { + Debug.dump(PHASE_DUMP_LEVEL, lirGenRes.getLIR(), "After phase %s", getName()); + } } } catch (Throwable e) { throw Debug.handle(e); } } - protected abstract <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context); + protected abstract <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context); protected CharSequence createName() { String className = LIRPhase.this.getClass().getName();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhaseSuite.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhaseSuite.java Tue Mar 10 21:26:02 2015 +0100 @@ -69,7 +69,7 @@ } @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context) { for (LIRPhase<C> phase : phases) { phase.apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, context); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,11 +34,11 @@ } @Override - protected final <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, + protected final <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, PostAllocationOptimizationContext context) { run(target, lirGenRes, codeEmittingOrder, linearScanOrder); } - protected abstract <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder); + protected abstract <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationStage.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationStage.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.lir.phases; +import static com.oracle.graal.lir.phases.LIRPhase.Options.*; + import com.oracle.graal.lir.*; import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*; import com.oracle.graal.options.*; @@ -30,13 +32,13 @@ public static class Options { // @formatter:off @Option(help = "", type = OptionType.Debug) - public static final OptionValue<Boolean> LIROptEdgeMoveOptimizer = new OptionValue<>(true); + public static final NestedBooleanOptionValue LIROptEdgeMoveOptimizer = new NestedBooleanOptionValue(LIROptimization, true); @Option(help = "", type = OptionType.Debug) - public static final OptionValue<Boolean> LIROptControlFlowOptmizer = new OptionValue<>(true); + public static final NestedBooleanOptionValue LIROptControlFlowOptmizer = new NestedBooleanOptionValue(LIROptimization, true); @Option(help = "", type = OptionType.Debug) - public static final OptionValue<Boolean> LIROptRedundantMoveElimination = new OptionValue<>(true); + public static final NestedBooleanOptionValue LIROptRedundantMoveElimination = new NestedBooleanOptionValue(LIROptimization, true); @Option(help = "", type = OptionType.Debug) - public static final OptionValue<Boolean> LIROptNullCheckOptimizer = new OptionValue<>(true); + public static final NestedBooleanOptionValue LIROptNullCheckOptimizer = new NestedBooleanOptionValue(LIROptimization, true); // @formatter:on }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PreAllocationOptimizationPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PreAllocationOptimizationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,11 +40,11 @@ } @Override - protected final <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, + protected final <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, PreAllocationOptimizationContext context) { run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context.lirGen); } - protected abstract <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, LIRGeneratorTool lirGen); + protected abstract <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, LIRGeneratorTool lirGen); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java Tue Mar 10 21:26:02 2015 +0100 @@ -65,15 +65,15 @@ * virtual stack slots. */ Set<LIRInstruction> build() { - Deque<AbstractBlock<?>> worklist = new ArrayDeque<>(); + Deque<AbstractBlockBase<?>> worklist = new ArrayDeque<>(); for (int i = lir.getControlFlowGraph().getBlocks().size() - 1; i >= 0; i--) { worklist.add(lir.getControlFlowGraph().getBlocks().get(i)); } - for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) { + for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) { liveInMap.put(block, new BitSet(stackSlotMap.length)); } while (!worklist.isEmpty()) { - AbstractBlock<?> block = worklist.poll(); + AbstractBlockBase<?> block = worklist.poll(); processBlock(block, worklist); } return usePos; @@ -82,7 +82,7 @@ /** * Merge outSet with in-set of successors. */ - private boolean updateOutBlock(AbstractBlock<?> block) { + private boolean updateOutBlock(AbstractBlockBase<?> block) { BitSet union = new BitSet(stackSlotMap.length); block.getSuccessors().forEach(succ -> union.or(liveInMap.get(succ))); BitSet outSet = liveOutMap.get(block); @@ -94,7 +94,7 @@ return false; } - private void processBlock(AbstractBlock<?> block, Deque<AbstractBlock<?>> worklist) { + private void processBlock(AbstractBlockBase<?> block, Deque<AbstractBlockBase<?>> worklist) { if (updateOutBlock(block)) { try (Indent indent = Debug.logAndIndent("handle block %s", block)) { List<LIRInstruction> instructions = lir.getLIRforBlock(block);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Tue Mar 10 21:26:02 2015 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.lir.stackslotalloc; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.phases.LIRPhase.Options.*; import java.util.*; import java.util.function.*; @@ -32,12 +33,12 @@ import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; @@ -56,7 +57,7 @@ public static class Options { // @formatter:off @Option(help = "Use linear scan stack slot allocation.", type = OptionType.Debug) - public static final OptionValue<Boolean> LIROptLSStackSlotAllocator = new OptionValue<>(true); + public static final NestedBooleanOptionValue LIROptLSStackSlotAllocator = new NestedBooleanOptionValue(LIROptimization, true); // @formatter:on } @@ -68,12 +69,12 @@ private static final DebugTimer AssignSlotsTimer = Debug.timer("LSStackSlotAllocator[AssignSlots]"); @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory) { lirGenRes.buildFrameMap(this); } public void allocateStackSlots(FrameMapBuilderTool builder, LIRGenerationResult res) { - try (TimerCloseable t = MainTimer.start()) { + try (DebugCloseable t = MainTimer.start()) { new Allocator(res.getLIR(), builder).allocate(); } } @@ -84,7 +85,7 @@ private final StackInterval[] stackSlotMap; private final PriorityQueue<StackInterval> unhandled; private final PriorityQueue<StackInterval> active; - private final List<? extends AbstractBlock<?>> sortedBlocks; + private final List<? extends AbstractBlockBase<?>> sortedBlocks; private final int maxOpId; private Allocator(LIR lir, FrameMapBuilderTool frameMapBuilder) { @@ -98,7 +99,7 @@ // insert by to this.active = new PriorityQueue<>((a, b) -> a.to() - b.to()); - try (TimerCloseable t = NumInstTimer.start()) { + try (DebugCloseable t = NumInstTimer.start()) { // step 1: number instructions this.maxOpId = numberInstructions(lir, sortedBlocks); } @@ -110,12 +111,12 @@ long currentFrameSize = Debug.isMeterEnabled() ? frameMapBuilder.getFrameMap().currentFrameSize() : 0; Set<LIRInstruction> usePos; // step 2: build intervals - try (Scope s = Debug.scope("StackSlotAllocationBuildIntervals"); Indent indent = Debug.logAndIndent("BuildIntervals"); TimerCloseable t = BuildIntervalsTimer.start()) { + try (Scope s = Debug.scope("StackSlotAllocationBuildIntervals"); Indent indent = Debug.logAndIndent("BuildIntervals"); DebugCloseable t = BuildIntervalsTimer.start()) { usePos = buildIntervals(); } // step 3: verify intervals if (Debug.isEnabled()) { - try (TimerCloseable t = VerifyIntervalsTimer.start()) { + try (DebugCloseable t = VerifyIntervalsTimer.start()) { verifyIntervals(); } } @@ -123,7 +124,7 @@ dumpIntervals("Before stack slot allocation"); } // step 4: allocate stack slots - try (TimerCloseable t = AllocateSlotsTimer.start()) { + try (DebugCloseable t = AllocateSlotsTimer.start()) { allocateStackSlots(); } if (Debug.isDumpEnabled()) { @@ -131,7 +132,7 @@ } // step 5: assign stack slots - try (TimerCloseable t = AssignSlotsTimer.start()) { + try (DebugCloseable t = AssignSlotsTimer.start()) { assignStackSlots(usePos); } Debug.dump(lir, "After StackSlot assignment"); @@ -149,10 +150,10 @@ * * @return The id of the last operation. */ - private static int numberInstructions(LIR lir, List<? extends AbstractBlock<?>> sortedBlocks) { + private static int numberInstructions(LIR lir, List<? extends AbstractBlockBase<?>> sortedBlocks) { int opId = 0; int index = 0; - for (AbstractBlock<?> block : sortedBlocks) { + for (AbstractBlockBase<?> block : sortedBlocks) { List<LIRInstruction> instructions = lir.getLIRforBlock(block);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/SimpleStackSlotAllocator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/SimpleStackSlotAllocator.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,12 +34,13 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; import com.oracle.graal.lir.phases.*; public class SimpleStackSlotAllocator extends AllocationPhase implements StackSlotAllocator { @Override - protected <B extends AbstractBlock<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder) { + protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory) { lirGenRes.buildFrameMap(this); } @@ -75,7 +76,7 @@ } return value; }; - for (AbstractBlock<?> block : res.getLIR().getControlFlowGraph().getBlocks()) { + for (AbstractBlockBase<?> block : res.getLIR().getControlFlowGraph().getBlocks()) { try (Indent indent0 = Debug.logAndIndent("block: %s", block)) { for (LIRInstruction inst : res.getLIR().getLIRforBlock(block)) { try (Indent indent1 = Debug.logAndIndent("Inst: %d: %s", inst.id(), inst)) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Tue Mar 10 21:26:02 2015 +0100 @@ -175,13 +175,13 @@ negated = true; } LogicNode ifTest = ifNode.condition(); - if (!(ifTest instanceof IntegerLessThanNode)) { + if (!(ifTest instanceof IntegerLessThanNode) && !(ifTest instanceof IntegerEqualsNode)) { if (ifTest instanceof IntegerBelowNode) { Debug.log("Ignored potential Counted loop at %s with |<|", loopBegin); } return false; } - IntegerLessThanNode lessThan = (IntegerLessThanNode) ifTest; + CompareNode lessThan = (CompareNode) ifTest; Condition condition = null; InductionVariable iv = null; ValueNode limit = null; @@ -198,6 +198,9 @@ limit = lessThan.getY(); } } + if (iv != null && iv.isConstantStride() && iv.constantStride() != 1 && !(ifTest instanceof IntegerLessThanNode)) { + return false; + } if (condition == null) { return false; } @@ -206,6 +209,24 @@ } boolean oneOff = false; switch (condition) { + case EQ: + return false; + case NE: { + IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp(); + IntegerStamp limitStamp = (IntegerStamp) limit.stamp(); + if (iv.direction() == Direction.Up) { + if (initStamp.upperBound() > limitStamp.lowerBound()) { + return false; + } + } else { + assert iv.direction() == Direction.Down; + if (initStamp.lowerBound() < limitStamp.upperBound()) { + return false; + } + } + oneOff = true; + break; + } case LE: oneOff = true; // fall through case LT:
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Tue Mar 10 21:26:02 2015 +0100 @@ -312,9 +312,9 @@ if (newEarlyExit == null) { continue; } - AbstractMergeNode merge = graph.add(new MergeNode()); - AbstractEndNode originalEnd = graph.add(new EndNode()); - AbstractEndNode newEnd = graph.add(new EndNode()); + MergeNode merge = graph.add(new MergeNode()); + EndNode originalEnd = graph.add(new EndNode()); + EndNode newEnd = graph.add(new EndNode()); merge.addForwardEnd(originalEnd); merge.addForwardEnd(newEnd); loopEarlyExit.setNext(originalEnd); @@ -332,7 +332,7 @@ * VirtualState nodes contained in the old exit's state may be shared by other * dominated VirtualStates. Those dominated virtual states need to see the * proxy->phi update that are applied below. - * + * * We now update the original fragment's nodes accordingly: */ originalExitState.applyToVirtual(node -> original.nodes.clearAndGrow(node));
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Tue Mar 10 21:26:02 2015 +0100 @@ -293,14 +293,14 @@ private AbstractBeginNode mergeEnds() { assert isDuplicate(); - List<AbstractEndNode> endsToMerge = new LinkedList<>(); + List<EndNode> endsToMerge = new LinkedList<>(); // map peel exits to the corresponding loop exits Map<AbstractEndNode, LoopEndNode> reverseEnds = CollectionsFactory.newMap(); LoopBeginNode loopBegin = original().loop().loopBegin(); for (LoopEndNode le : loopBegin.loopEnds()) { AbstractEndNode duplicate = getDuplicatedNode(le); if (duplicate != null) { - endsToMerge.add(duplicate); + endsToMerge.add((EndNode) duplicate); reverseEnds.put(duplicate, le); } } @@ -323,7 +323,7 @@ duplicateState = state.duplicateWithVirtualState(); newExitMerge.setStateAfter(duplicateState); } - for (AbstractEndNode end : endsToMerge) { + for (EndNode end : endsToMerge) { newExitMerge.addForwardEnd(end); }
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -62,7 +62,7 @@ PhaseContext context = new PhaseContext(getProviders()); Assert.assertEquals(5, graph.getNodes().filter(loopPhis).count()); - new CanonicalizerPhase(false).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); Assert.assertEquals(2, graph.getNodes().filter(loopPhis).count()); test("loopSnippet");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,12 +33,11 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.util.*; @NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor}) public abstract class AbstractBeginNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, GuardingNode, AnchoringNode, IterableNodeType { - public static final NodeClass<AbstractBeginNode> TYPE = NodeClass.get(AbstractBeginNode.class); + public static final NodeClass<AbstractBeginNode> TYPE = NodeClass.create(AbstractBeginNode.class); protected AbstractBeginNode(NodeClass<? extends AbstractBeginNode> c) { this(c, StampFactory.forVoid()); @@ -64,8 +63,13 @@ } public static AbstractBeginNode prevBegin(FixedNode from) { - for (AbstractBeginNode begin : GraphUtil.predecessorIterable(from).filter(AbstractBeginNode.class)) { - return begin; + Node next = from; + while (next != null) { + if (next instanceof AbstractBeginNode) { + AbstractBeginNode begin = (AbstractBeginNode) next; + return begin; + } + next = next.predecessor(); } return null; } @@ -90,10 +94,19 @@ } public void removeProxies() { - for (ProxyNode vpn : proxies().snapshot()) { - // can not use graph.replaceFloating because vpn.value may be null during killCFG - vpn.replaceAtUsages(vpn.value()); - vpn.safeDelete(); + if (this.hasUsages()) { + outer: while (true) { + for (ProxyNode vpn : proxies().snapshot()) { + ValueNode value = vpn.value(); + vpn.replaceAtUsages(value); + vpn.safeDelete(); + if (value == this) { + // Guard proxy could have this input as value. + continue outer; + } + } + break; + } } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode.DeoptBefore { - public static final NodeClass<AbstractDeoptimizeNode> TYPE = NodeClass.get(AbstractDeoptimizeNode.class); + public static final NodeClass<AbstractDeoptimizeNode> TYPE = NodeClass.create(AbstractDeoptimizeNode.class); @OptionalInput(InputType.State) FrameState stateBefore; protected AbstractDeoptimizeNode(NodeClass<? extends AbstractDeoptimizeNode> c, FrameState stateBefore) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractEndNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public abstract class AbstractEndNode extends FixedNode implements IterableNodeType, LIRLowerable { - public static final NodeClass<AbstractEndNode> TYPE = NodeClass.get(AbstractEndNode.class); + public static final NodeClass<AbstractEndNode> TYPE = NodeClass.create(AbstractEndNode.class); protected AbstractEndNode(NodeClass<? extends AbstractEndNode> c) { super(c, StampFactory.forVoid());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public abstract class AbstractFixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, GuardingNode { - public static final NodeClass<AbstractFixedGuardNode> TYPE = NodeClass.get(AbstractFixedGuardNode.class); + public static final NodeClass<AbstractFixedGuardNode> TYPE = NodeClass.create(AbstractFixedGuardNode.class); @Input(InputType.Condition) protected LogicNode condition; protected final DeoptimizationReason reason; protected final DeoptimizationAction action;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public abstract class AbstractLocalNode extends FloatingNode { - public static final NodeClass<AbstractLocalNode> TYPE = NodeClass.get(AbstractLocalNode.class); + public static final NodeClass<AbstractLocalNode> TYPE = NodeClass.create(AbstractLocalNode.class); protected final int index; protected AbstractLocalNode(NodeClass<? extends AbstractLocalNode> c, int index, Stamp stamp) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public abstract class AbstractMemoryCheckpoint extends AbstractStateSplit implements MemoryCheckpoint { - public static final NodeClass<AbstractMemoryCheckpoint> TYPE = NodeClass.get(AbstractMemoryCheckpoint.class); + public static final NodeClass<AbstractMemoryCheckpoint> TYPE = NodeClass.create(AbstractMemoryCheckpoint.class); protected AbstractMemoryCheckpoint(NodeClass<? extends AbstractMemoryCheckpoint> c, Stamp stamp) { this(c, stamp, null);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,24 +39,24 @@ */ @NodeInfo(allowedUsageTypes = {InputType.Association}) public abstract class AbstractMergeNode extends BeginStateSplitNode implements IterableNodeType, LIRLowerable { - public static final NodeClass<AbstractMergeNode> TYPE = NodeClass.get(AbstractMergeNode.class); + public static final NodeClass<AbstractMergeNode> TYPE = NodeClass.create(AbstractMergeNode.class); protected AbstractMergeNode(NodeClass<? extends AbstractMergeNode> c) { super(c); } - @Input(InputType.Association) protected NodeInputList<AbstractEndNode> ends = new NodeInputList<>(this); + @Input(InputType.Association) protected NodeInputList<EndNode> ends = new NodeInputList<>(this); @Override public void generate(NodeLIRBuilderTool gen) { gen.visitMerge(this); } - public int forwardEndIndex(AbstractEndNode end) { + public int forwardEndIndex(EndNode end) { return ends.indexOf(end); } - public void addForwardEnd(AbstractEndNode end) { + public void addForwardEnd(EndNode end) { ends.add(end); } @@ -64,12 +64,12 @@ return ends.size(); } - public AbstractEndNode forwardEndAt(int index) { + public EndNode forwardEndAt(int index) { return ends.get(index); } @Override - public NodeIterable<AbstractEndNode> cfgPredecessors() { + public NodeIterable<EndNode> cfgPredecessors() { return ends; } @@ -113,7 +113,7 @@ ends.clear(); } - public NodeInputList<AbstractEndNode> forwardEnds() { + public NodeInputList<EndNode> forwardEnds() { return ends; } @@ -122,7 +122,7 @@ } public int phiPredecessorIndex(AbstractEndNode pred) { - return forwardEndIndex(pred); + return forwardEndIndex((EndNode) pred); } public AbstractEndNode phiPredecessorAt(int index) { @@ -176,8 +176,9 @@ if (merge instanceof LoopBeginNode) { newEnd = graph().add(new LoopEndNode((LoopBeginNode) merge)); } else { - newEnd = graph().add(new EndNode()); - merge.addForwardEnd(newEnd); + EndNode tmpEnd = graph().add(new EndNode()); + merge.addForwardEnd(tmpEnd); + newEnd = tmpEnd; } for (PhiNode phi : merge.phis()) { ValueNode v = phi.valueAt(origLoopEnd); @@ -213,8 +214,8 @@ } ValuePhiNode returnValuePhi = returnNode.result() == null || !isPhiAtMerge(returnNode.result()) ? null : (ValuePhiNode) returnNode.result(); - List<AbstractEndNode> endNodes = forwardEnds().snapshot(); - for (AbstractEndNode end : endNodes) { + List<EndNode> endNodes = forwardEnds().snapshot(); + for (EndNode end : endNodes) { ReturnNode newReturn = graph().add(new ReturnNode(returnValuePhi == null ? returnNode.result() : returnValuePhi.valueAt(end))); if (tool != null) { tool.addToWorkList(end.predecessor()); @@ -222,7 +223,7 @@ end.replaceAtPredecessor(newReturn); } GraphUtil.killCFG(this); - for (AbstractEndNode end : endNodes) { + for (EndNode end : endNodes) { end.safeDelete(); } for (PhiNode phi : phis) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public abstract class AbstractStateSplit extends FixedWithNextNode implements StateSplit { - public static final NodeClass<AbstractStateSplit> TYPE = NodeClass.get(AbstractStateSplit.class); + public static final NodeClass<AbstractStateSplit> TYPE = NodeClass.create(AbstractStateSplit.class); @OptionalInput(InputType.State) protected FrameState stateAfter; public FrameState stateAfter() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public final class BeginNode extends AbstractBeginNode { - public static final NodeClass<BeginNode> TYPE = NodeClass.get(BeginNode.class); + public static final NodeClass<BeginNode> TYPE = NodeClass.create(BeginNode.class); public BeginNode() { super(TYPE, StampFactory.forVoid()); @@ -39,6 +39,17 @@ super(TYPE, stamp); } + public void trySimplify() { + FixedNode prev = (FixedNode) this.predecessor(); + if (prev instanceof ControlSplitNode) { + // This begin node is necessary. + } else { + // This begin node can be removed and all guards moved up to the preceding begin node. + prepareDelete(); + graph().removeFixed(this); + } + } + public static AbstractBeginNode begin(FixedNode with) { if (with instanceof AbstractBeginNode) { return (AbstractBeginNode) with;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public abstract class BeginStateSplitNode extends AbstractBeginNode implements StateSplit { - public static final NodeClass<BeginStateSplitNode> TYPE = NodeClass.get(BeginStateSplitNode.class); + public static final NodeClass<BeginStateSplitNode> TYPE = NodeClass.create(BeginStateSplitNode.class); @OptionalInput(InputType.State) protected FrameState stateAfter; protected BeginStateSplitNode(NodeClass<? extends BeginStateSplitNode> c) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; @@ -30,7 +32,7 @@ @NodeInfo public abstract class BinaryOpLogicNode extends LogicNode implements LIRLowerable, Canonicalizable.Binary<ValueNode> { - public static final NodeClass<BinaryOpLogicNode> TYPE = NodeClass.get(BinaryOpLogicNode.class); + public static final NodeClass<BinaryOpLogicNode> TYPE = NodeClass.create(BinaryOpLogicNode.class); @Input protected ValueNode x; @Input protected ValueNode y; @@ -58,4 +60,35 @@ @Override public void generate(NodeLIRBuilderTool gen) { } + + /** + * Ensure a canonical ordering of inputs for commutative nodes to improve GVN results. Order the + * inputs by increasing {@link Node#id} and call {@link Graph#findDuplicate(Node)} on the node + * if it's currently in a graph. + * + * @return the original node or another node with the same inputs, ignoring ordering. + */ + @SuppressWarnings("deprecation") + public LogicNode maybeCommuteInputs() { + assert this instanceof BinaryCommutative; + if (x.getId() > y.getId()) { + ValueNode tmp = x; + x = y; + y = tmp; + if (graph() != null) { + // See if this node already exists + LogicNode duplicate = graph().findDuplicate(this); + if (duplicate != null) { + return duplicate; + } + } + } + return this; + } + + public abstract Stamp getSucceedingStampForX(boolean negated); + + public abstract Stamp getSucceedingStampForY(boolean negated); + + public abstract TriState tryFold(Stamp xStamp, Stamp yStamp); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BreakpointNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BreakpointNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -48,7 +48,7 @@ @NodeInfo public final class BreakpointNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<BreakpointNode> TYPE = NodeClass.get(BreakpointNode.class); + public static final NodeClass<BreakpointNode> TYPE = NodeClass.create(BreakpointNode.class); @Input NodeInputList<ValueNode> arguments; public BreakpointNode(ValueNode[] arguments) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Extension}) public abstract class CallTargetNode extends ValueNode implements LIRLowerable { - public static final NodeClass<CallTargetNode> TYPE = NodeClass.get(CallTargetNode.class); + public static final NodeClass<CallTargetNode> TYPE = NodeClass.create(CallTargetNode.class); public enum InvokeKind { Interface(false),
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo(nameTemplate = "ConditionAnchor(!={p#negated})", allowedUsageTypes = {InputType.Guard}) public final class ConditionAnchorNode extends FixedWithNextNode implements Canonicalizable.Unary<Node>, Lowerable, GuardingNode { - public static final NodeClass<ConditionAnchorNode> TYPE = NodeClass.get(ConditionAnchorNode.class); + public static final NodeClass<ConditionAnchorNode> TYPE = NodeClass.create(ConditionAnchorNode.class); @Input(InputType.Condition) LogicNode condition; protected boolean negated; @@ -76,6 +76,9 @@ return new ValueAnchorNode(null); } } + if (this.hasNoUsages()) { + return null; + } return this; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo(shortName = "Const", nameTemplate = "Const({p#rawvalue})") public final class ConstantNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<ConstantNode> TYPE = NodeClass.get(ConstantNode.class); + public static final NodeClass<ConstantNode> TYPE = NodeClass.create(ConstantNode.class); private static final DebugMetric ConstantNodes = Debug.metric("ConstantNodes"); protected final Constant value;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ @NodeInfo public abstract class ControlSinkNode extends FixedNode { - public static final NodeClass<ControlSinkNode> TYPE = NodeClass.get(ControlSinkNode.class); + public static final NodeClass<ControlSinkNode> TYPE = NodeClass.create(ControlSinkNode.class); protected ControlSinkNode(NodeClass<? extends ControlSinkNode> c, Stamp stamp) { super(c, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,11 +32,19 @@ */ @NodeInfo public abstract class ControlSplitNode extends FixedNode implements IterableNodeType { - public static final NodeClass<ControlSplitNode> TYPE = NodeClass.get(ControlSplitNode.class); + public static final NodeClass<ControlSplitNode> TYPE = NodeClass.create(ControlSplitNode.class); protected ControlSplitNode(NodeClass<? extends ControlSplitNode> c, Stamp stamp) { super(c, stamp); } public abstract double probability(AbstractBeginNode successor); + + /** + * Primary successor of the control split. Data dependencies on the node have to be scheduled in + * the primary successor. + * + * @return the primary successor + */ + public abstract AbstractBeginNode getPrimarySuccessor(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -23,21 +23,23 @@ package com.oracle.graal.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") public final class DeoptimizeNode extends AbstractDeoptimizeNode implements Lowerable, LIRLowerable { + public static final int DEFAULT_DEBUG_ID = 0; - public static final NodeClass<DeoptimizeNode> TYPE = NodeClass.get(DeoptimizeNode.class); + public static final NodeClass<DeoptimizeNode> TYPE = NodeClass.create(DeoptimizeNode.class); protected final DeoptimizationAction action; protected final DeoptimizationReason reason; protected final int debugId; protected final JavaConstant speculation; public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) { - this(action, reason, 0, JavaConstant.NULL_POINTER, null); + this(action, reason, DEFAULT_DEBUG_ID, JavaConstant.NULL_POINTER, null); } public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, int debugId, JavaConstant speculation, FrameState stateBefore) { @@ -64,14 +66,23 @@ tool.getLowerer().lower(this, tool); } + @SuppressWarnings("deprecation") + public int getDebugId() { + int deoptDebugId = debugId; + if (deoptDebugId == DEFAULT_DEBUG_ID && (Debug.isDumpEnabledForMethod() || Debug.isLogEnabledForMethod())) { + deoptDebugId = this.getId(); + } + return deoptDebugId; + } + @Override public void generate(NodeLIRBuilderTool gen) { - gen.getLIRGeneratorTool().emitDeoptimize(gen.getLIRGeneratorTool().getMetaAccess().encodeDeoptActionAndReason(action, reason, debugId), speculation, gen.state(this)); + gen.getLIRGeneratorTool().emitDeoptimize(gen.getLIRGeneratorTool().getMetaAccess().encodeDeoptActionAndReason(action, reason, getDebugId()), speculation, gen.state(this)); } @Override public ValueNode getActionAndReason(MetaAccessProvider metaAccess) { - return ConstantNode.forConstant(metaAccess.encodeDeoptActionAndReason(action, reason, debugId), metaAccess, graph()); + return ConstantNode.forConstant(metaAccess.encodeDeoptActionAndReason(action, reason, getDebugId()), metaAccess, graph()); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode.DeoptBefore { - public static final NodeClass<DeoptimizingFixedWithNextNode> TYPE = NodeClass.get(DeoptimizingFixedWithNextNode.class); + public static final NodeClass<DeoptimizingFixedWithNextNode> TYPE = NodeClass.create(DeoptimizingFixedWithNextNode.class); @OptionalInput(InputType.State) protected FrameState stateBefore; protected DeoptimizingFixedWithNextNode(NodeClass<? extends DeoptimizingFixedWithNextNode> c, Stamp stamp) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public abstract class DirectCallTargetNode extends LoweredCallTargetNode { - public static final NodeClass<DirectCallTargetNode> TYPE = NodeClass.get(DirectCallTargetNode.class); + public static final NodeClass<DirectCallTargetNode> TYPE = NodeClass.create(DirectCallTargetNode.class); protected DirectCallTargetNode(NodeClass<? extends DirectCallTargetNode> c, List<ValueNode> arguments, Stamp returnStamp, JavaType[] signature, ResolvedJavaMethod target, CallingConvention.Type callType, InvokeKind invokeKind) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DispatchBeginNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DispatchBeginNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public class DispatchBeginNode extends BeginStateSplitNode { - public static final NodeClass<DispatchBeginNode> TYPE = NodeClass.get(DispatchBeginNode.class); + public static final NodeClass<DispatchBeginNode> TYPE = NodeClass.create(DispatchBeginNode.class); public DispatchBeginNode() { super(TYPE);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable, Lowerable, Canonicalizable { - public static final NodeClass<DynamicDeoptimizeNode> TYPE = NodeClass.get(DynamicDeoptimizeNode.class); + public static final NodeClass<DynamicDeoptimizeNode> TYPE = NodeClass.create(DynamicDeoptimizeNode.class); @Input ValueNode actionAndReason; @Input ValueNode speculation;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,7 +27,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Association}) public final class EndNode extends AbstractEndNode { - public static final NodeClass<EndNode> TYPE = NodeClass.get(EndNode.class); + public static final NodeClass<EndNode> TYPE = NodeClass.create(EndNode.class); public EndNode() { super(TYPE);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ */ @NodeInfo(allowedUsageTypes = {InputType.Association}) public final class EntryMarkerNode extends BeginStateSplitNode implements IterableNodeType, Simplifiable, LIRLowerable { - public static final NodeClass<EntryMarkerNode> TYPE = NodeClass.get(EntryMarkerNode.class); + public static final NodeClass<EntryMarkerNode> TYPE = NodeClass.create(EntryMarkerNode.class); public EntryMarkerNode() { super(TYPE);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}", allowedUsageTypes = {InputType.Guard}) public final class FixedGuardNode extends AbstractFixedGuardNode implements Lowerable, IterableNodeType { - public static final NodeClass<FixedGuardNode> TYPE = NodeClass.get(FixedGuardNode.class); + public static final NodeClass<FixedGuardNode> TYPE = NodeClass.create(FixedGuardNode.class); public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) { this(condition, deoptReason, action, false);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ @NodeInfo public abstract class FixedNode extends ValueNode { - public static final NodeClass<FixedNode> TYPE = NodeClass.get(FixedNode.class); + public static final NodeClass<FixedNode> TYPE = NodeClass.create(FixedNode.class); protected FixedNode(NodeClass<? extends FixedNode> c, Stamp stamp) { super(c, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ */ @NodeInfo public abstract class FixedWithNextNode extends FixedNode { - public static final NodeClass<FixedWithNextNode> TYPE = NodeClass.get(FixedWithNextNode.class); + public static final NodeClass<FixedWithNextNode> TYPE = NodeClass.create(FixedWithNextNode.class); @Successor protected FixedNode next;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingAnchoredNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingAnchoredNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public abstract class FloatingAnchoredNode extends FloatingNode { - public static final NodeClass<FloatingAnchoredNode> TYPE = NodeClass.get(FloatingAnchoredNode.class); + public static final NodeClass<FloatingAnchoredNode> TYPE = NodeClass.create(FloatingAnchoredNode.class); @Input(InputType.Anchor) protected AnchoringNode anchor;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public abstract class FloatingGuardedNode extends FloatingNode implements GuardedNode { - public static final NodeClass<FloatingGuardedNode> TYPE = NodeClass.get(FloatingGuardedNode.class); + public static final NodeClass<FloatingGuardedNode> TYPE = NodeClass.create(FloatingGuardedNode.class); @OptionalInput(InputType.Guard) protected GuardingNode guard;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ */ @NodeInfo(nameTemplate = "FrameState@{p#method/s}:{p#bci}") public final class FrameState extends VirtualState implements IterableNodeType { - public static final NodeClass<FrameState> TYPE = NodeClass.get(FrameState.class); + public static final NodeClass<FrameState> TYPE = NodeClass.create(FrameState.class); private static final DebugMetric METRIC_FRAMESTATE_COUNT = Debug.metric("FrameStateCount"); @@ -251,14 +251,20 @@ * changed to newBci. */ private FrameState duplicateModified(int newBci, boolean newRethrowException, boolean newDuringCall, Kind popKind, ValueNode... pushedValues) { - ArrayList<ValueNode> copy = new ArrayList<>(values.subList(0, localsSize + stackSize)); - if (popKind != Kind.Void) { - if (stackAt(stackSize() - 1) == null) { + ArrayList<ValueNode> copy; + if (newRethrowException && !rethrowException && popKind == Kind.Void) { + assert popKind == Kind.Void; + copy = new ArrayList<>(values.subList(0, localsSize)); + } else { + copy = new ArrayList<>(values.subList(0, localsSize + stackSize)); + if (popKind != Kind.Void) { + if (stackAt(stackSize() - 1) == null) { + copy.remove(copy.size() - 1); + } + ValueNode lastSlot = copy.get(copy.size() - 1); + assert lastSlot.getKind().getStackKind() == popKind.getStackKind(); copy.remove(copy.size() - 1); } - ValueNode lastSlot = copy.get(copy.size() - 1); - assert lastSlot.getKind().getStackKind() == popKind.getStackKind(); - copy.remove(copy.size() - 1); } for (ValueNode node : pushedValues) { copy.add(node); @@ -269,7 +275,7 @@ int newStackSize = copy.size() - localsSize; copy.addAll(values.subList(localsSize + stackSize, values.size())); - assert checkStackDepth(bci, stackSize, duringCall, newBci, newStackSize, newDuringCall); + assert checkStackDepth(bci, stackSize, duringCall, rethrowException, newBci, newStackSize, newDuringCall, newRethrowException); return graph().add(new FrameState(outerFrameState(), method, newBci, copy, localsSize, newStackSize, newRethrowException, newDuringCall, monitorIds, virtualObjectMappings)); } @@ -277,7 +283,7 @@ * Perform a few sanity checks on the transformation of the stack state. The current expectation * is that a stateAfter is being transformed into a stateDuring, so the stack depth may change. */ - private boolean checkStackDepth(int oldBci, int oldStackSize, boolean oldDuringCall, int newBci, int newStackSize, boolean newDuringCall) { + private boolean checkStackDepth(int oldBci, int oldStackSize, boolean oldDuringCall, boolean oldRethrowException, int newBci, int newStackSize, boolean newDuringCall, boolean newRethrowException) { /* * It would be nice to have a complete check of the shape of the FrameState based on a * dataflow of the bytecodes but for now just check for obvious expression stack depth @@ -290,7 +296,7 @@ } byte newCode = codes[newBci]; if (oldBci == newBci) { - assert oldStackSize == newStackSize || oldDuringCall != newDuringCall : "bci is unchanged, stack depth shouldn't change"; + assert oldStackSize == newStackSize || oldDuringCall != newDuringCall || oldRethrowException != newRethrowException : "bci is unchanged, stack depth shouldn't change"; } else { byte oldCode = codes[oldBci]; assert Bytecodes.lengthOf(newCode) + newBci == oldBci || Bytecodes.lengthOf(oldCode) + oldBci == newBci : "expecting roll back or forward";
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ */ @NodeInfo public final class FullInfopointNode extends InfopointNode implements LIRLowerable, NodeWithState { - public static final NodeClass<FullInfopointNode> TYPE = NodeClass.get(FullInfopointNode.class); + public static final NodeClass<FullInfopointNode> TYPE = NodeClass.create(FullInfopointNode.class); @Input(InputType.State) FrameState state; public FullInfopointNode(InfopointReason reason, FrameState state) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -44,7 +44,7 @@ @NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}", allowedUsageTypes = {InputType.Guard}) public class GuardNode extends FloatingAnchoredNode implements Canonicalizable, GuardingNode { - public static final NodeClass<GuardNode> TYPE = NodeClass.get(GuardNode.class); + public static final NodeClass<GuardNode> TYPE = NodeClass.create(GuardNode.class); @Input(InputType.Condition) protected LogicNode condition; protected final DeoptimizationReason reason; protected JavaConstant speculation;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(nameTemplate = "GuardPhi({i#values})", allowedUsageTypes = {InputType.Guard}) public final class GuardPhiNode extends PhiNode implements GuardingNode { - public static final NodeClass<GuardPhiNode> TYPE = NodeClass.get(GuardPhiNode.class); + public static final NodeClass<GuardPhiNode> TYPE = NodeClass.create(GuardPhiNode.class); @OptionalInput(InputType.Guard) NodeInputList<ValueNode> values; public GuardPhiNode(AbstractMergeNode merge) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,8 +31,8 @@ @NodeInfo(allowedUsageTypes = {InputType.Guard}) public final class GuardProxyNode extends ProxyNode implements GuardingNode, Proxy, LIRLowerable { - public static final NodeClass<GuardProxyNode> TYPE = NodeClass.get(GuardProxyNode.class); - @Input(InputType.Guard) GuardingNode value; + public static final NodeClass<GuardProxyNode> TYPE = NodeClass.create(GuardProxyNode.class); + @OptionalInput(InputType.Guard) GuardingNode value; public GuardProxyNode(GuardingNode value, AbstractBeginNode proxyPoint) { super(TYPE, StampFactory.forVoid(), proxyPoint); @@ -43,12 +43,17 @@ public void generate(NodeLIRBuilderTool generator) { } + public void setValue(GuardingNode newValue) { + this.updateUsages(value.asNode(), newValue.asNode()); + this.value = newValue; + } + @Override public ValueNode value() { - return value.asNode(); + return (value == null ? null : value.asNode()); } public Node getOriginalNode() { - return value.asNode(); + return (value == null ? null : value.asNode()); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class GuardedValueNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy { - public static final NodeClass<GuardedValueNode> TYPE = NodeClass.get(GuardedValueNode.class); + public static final NodeClass<GuardedValueNode> TYPE = NodeClass.create(GuardedValueNode.class); @Input ValueNode object; protected final Stamp piStamp;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ @NodeInfo(nameTemplate = "GuardingPi(!={p#negated}) {p#reason/s}") public final class GuardingPiNode extends FixedWithNextNode implements Lowerable, Virtualizable, Canonicalizable, ValueProxy { - public static final NodeClass<GuardingPiNode> TYPE = NodeClass.get(GuardingPiNode.class); + public static final NodeClass<GuardingPiNode> TYPE = NodeClass.create(GuardingPiNode.class); @Input ValueNode object; @Input(InputType.Condition) LogicNode condition; protected final DeoptimizationReason reason;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,13 +22,10 @@ */ package com.oracle.graal.nodes; -import static com.oracle.graal.graph.Edges.Type.*; - import java.util.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -48,7 +45,7 @@ */ @NodeInfo public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable { - public static final NodeClass<IfNode> TYPE = NodeClass.get(IfNode.class); + public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class); private static final DebugMetric CORRECTED_PROBABILITIES = Debug.metric("CorrectedProbabilities"); @@ -96,6 +93,10 @@ return falseSuccessor; } + public double getTrueSuccessorProbability() { + return this.trueSuccessorProbability; + } + public void setTrueSuccessor(AbstractBeginNode node) { updatePredecessor(trueSuccessor, node); trueSuccessor = node; @@ -237,7 +238,7 @@ FixedWithNextNode falseNext = (FixedWithNextNode) falseSucc.next(); NodeClass<?> nodeClass = trueNext.getNodeClass(); if (trueNext.getClass() == falseNext.getClass()) { - if (nodeClass.getEdges(Inputs).areEqualIn(trueNext, falseNext) && trueNext.valueEquals(falseNext)) { + if (nodeClass.getInputEdges().areEqualIn(trueNext, falseNext) && trueNext.valueEquals(falseNext)) { falseNext.replaceAtUsages(trueNext); graph().removeFixed(falseNext); GraphUtil.unlinkFixedNode(trueNext); @@ -750,7 +751,7 @@ MergeNode falseMerge = null; assert merge.stateAfter() == null; - for (AbstractEndNode end : merge.forwardEnds().snapshot()) { + for (EndNode end : merge.forwardEnds().snapshot()) { Node value = phi.valueAt(end); Node result = null; if (condition() instanceof Canonicalizable.Binary<?>) { @@ -906,7 +907,7 @@ } } - List<AbstractEndNode> mergePredecessors = merge.cfgPredecessors().snapshot(); + List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot(); assert phi.valueCount() == merge.forwardEndCount(); Constant[] xs = constantValues(compare.getX(), merge, false); @@ -920,8 +921,8 @@ return false; } - List<AbstractEndNode> falseEnds = new ArrayList<>(mergePredecessors.size()); - List<AbstractEndNode> trueEnds = new ArrayList<>(mergePredecessors.size()); + List<EndNode> falseEnds = new ArrayList<>(mergePredecessors.size()); + List<EndNode> trueEnds = new ArrayList<>(mergePredecessors.size()); Map<AbstractEndNode, ValueNode> phiValues = CollectionsFactory.newMap(mergePredecessors.size()); AbstractBeginNode oldFalseSuccessor = falseSuccessor(); @@ -930,9 +931,9 @@ setFalseSuccessor(null); setTrueSuccessor(null); - Iterator<AbstractEndNode> ends = mergePredecessors.iterator(); + Iterator<EndNode> ends = mergePredecessors.iterator(); for (int i = 0; i < xs.length; i++) { - AbstractEndNode end = ends.next(); + EndNode end = ends.next(); phiValues.put(end, phi.valueAt(end)); if (compare.condition().foldCondition(xs[i], ys[i], tool.getConstantReflection(), compare.unorderedIsTrue())) { trueEnds.add(end); @@ -1062,7 +1063,7 @@ * @param oldMerge the merge being removed * @param phiValues the values of the phi at the merge, keyed by the merge ends */ - private void connectEnds(List<AbstractEndNode> ends, Map<AbstractEndNode, ValueNode> phiValues, AbstractBeginNode successor, AbstractMergeNode oldMerge, SimplifierTool tool) { + private void connectEnds(List<EndNode> ends, Map<AbstractEndNode, ValueNode> phiValues, AbstractBeginNode successor, AbstractMergeNode oldMerge, SimplifierTool tool) { if (!ends.isEmpty()) { if (ends.size() == 1) { AbstractEndNode end = ends.get(0); @@ -1076,7 +1077,7 @@ PhiNode oldPhi = (PhiNode) oldMerge.usages().first(); PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(), newMerge)); - for (AbstractEndNode end : ends) { + for (EndNode end : ends) { newPhi.addInput(phiValues.get(end)); newMerge.addForwardEnd(end); } @@ -1126,4 +1127,13 @@ return null; } + + @Override + public AbstractBeginNode getPrimarySuccessor() { + return this.trueSuccessor(); + } + + public AbstractBeginNode getSuccessor(boolean result) { + return result ? this.trueSuccessor() : this.falseSuccessor(); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public abstract class IndirectCallTargetNode extends LoweredCallTargetNode { - public static final NodeClass<IndirectCallTargetNode> TYPE = NodeClass.get(IndirectCallTargetNode.class); + public static final NodeClass<IndirectCallTargetNode> TYPE = NodeClass.create(IndirectCallTargetNode.class); @Input protected ValueNode computedAddress;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public abstract class InfopointNode extends FixedWithNextNode { - public static final NodeClass<InfopointNode> TYPE = NodeClass.get(InfopointNode.class); + public static final NodeClass<InfopointNode> TYPE = NodeClass.create(InfopointNode.class); protected final InfopointReason reason; public InfopointNode(NodeClass<? extends InfopointNode> c, InfopointReason reason) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ */ @NodeInfo(nameTemplate = "Invoke#{p#targetMethod/s}", allowedUsageTypes = {InputType.Memory}) public final class InvokeNode extends AbstractMemoryCheckpoint implements Invoke, LIRLowerable, MemoryCheckpoint.Single { - public static final NodeClass<InvokeNode> TYPE = NodeClass.get(InvokeNode.class); + public static final NodeClass<InvokeNode> TYPE = NodeClass.create(InvokeNode.class); @Input(InputType.Extension) CallTargetNode callTarget; @OptionalInput(InputType.State) FrameState stateDuring;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo(nameTemplate = "Invoke!#{p#targetMethod/s}", allowedUsageTypes = {InputType.Memory}) public final class InvokeWithExceptionNode extends ControlSplitNode implements Invoke, MemoryCheckpoint.Single, LIRLowerable { - public static final NodeClass<InvokeWithExceptionNode> TYPE = NodeClass.get(InvokeWithExceptionNode.class); + public static final NodeClass<InvokeWithExceptionNode> TYPE = NodeClass.create(InvokeWithExceptionNode.class); private static final double EXCEPTION_PROBA = 1e-5; @@ -232,4 +232,9 @@ updateUsagesInterface(this.guard, guard); this.guard = guard; } + + @Override + public AbstractBeginNode getPrimarySuccessor() { + return this.next(); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single { - public static final NodeClass<KillingBeginNode> TYPE = NodeClass.get(KillingBeginNode.class); + public static final NodeClass<KillingBeginNode> TYPE = NodeClass.create(KillingBeginNode.class); protected LocationIdentity locationIdentity; public KillingBeginNode(LocationIdentity locationIdentity) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo(nameTemplate = "{p#value}") public final class LogicConstantNode extends LogicNode implements LIRLowerable { - public static final NodeClass<LogicConstantNode> TYPE = NodeClass.get(LogicConstantNode.class); + public static final NodeClass<LogicConstantNode> TYPE = NodeClass.create(LogicConstantNode.class); protected final boolean value; public LogicConstantNode(boolean value) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public final class LogicNegationNode extends LogicNode implements Canonicalizable.Unary<LogicNode> { - public static final NodeClass<LogicNegationNode> TYPE = NodeClass.get(LogicNegationNode.class); + public static final NodeClass<LogicNegationNode> TYPE = NodeClass.create(LogicNegationNode.class); @Input(InputType.Condition) LogicNode value; public LogicNegationNode(LogicNode value) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo(allowedUsageTypes = {Condition}) public abstract class LogicNode extends FloatingNode { - public static final NodeClass<LogicNode> TYPE = NodeClass.get(LogicNode.class); + public static final NodeClass<LogicNode> TYPE = NodeClass.create(LogicNode.class); public LogicNode(NodeClass<? extends LogicNode> c) { super(c, StampFactory.forVoid());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class LoopBeginNode extends AbstractMergeNode implements IterableNodeType, LIRLowerable { - public static final NodeClass<LoopBeginNode> TYPE = NodeClass.get(LoopBeginNode.class); + public static final NodeClass<LoopBeginNode> TYPE = NodeClass.create(LoopBeginNode.class); protected double loopFrequency; protected int nextEndIndex; protected int unswitches; @@ -98,16 +98,12 @@ * * @return the set of {@code LoopEndNode} that correspond to back-edges for this loop */ - public List<LoopEndNode> orderedLoopEnds() { - List<LoopEndNode> snapshot = loopEnds().snapshot(); - Collections.sort(snapshot, new Comparator<LoopEndNode>() { - - @Override - public int compare(LoopEndNode o1, LoopEndNode o2) { - return o1.endIndex() - o2.endIndex(); - } - }); - return snapshot; + public LoopEndNode[] orderedLoopEnds() { + LoopEndNode[] result = new LoopEndNode[this.getLoopEndCount()]; + for (LoopEndNode end : loopEnds()) { + result[end.endIndex()] = end; + } + return result; } public AbstractEndNode forwardEnd() { @@ -153,7 +149,7 @@ return loopEnd.endIndex() + forwardEndCount(); } } else { - return super.forwardEndIndex(pred); + return super.forwardEndIndex((EndNode) pred); } throw ValueNodeUtil.shouldNotReachHere("unknown pred : " + pred); } @@ -183,6 +179,10 @@ return nextEndIndex++; } + public int getLoopEndCount() { + return nextEndIndex; + } + public int unswitches() { return unswitches; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class LoopEndNode extends AbstractEndNode { - public static final NodeClass<LoopEndNode> TYPE = NodeClass.get(LoopEndNode.class); + public static final NodeClass<LoopEndNode> TYPE = NodeClass.create(LoopEndNode.class); @Input(InputType.Association) LoopBeginNode loopBegin; protected boolean canSafepoint; protected int endIndex;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Association}) public final class LoopExitNode extends BeginStateSplitNode implements IterableNodeType { - public static final NodeClass<LoopExitNode> TYPE = NodeClass.get(LoopExitNode.class); + public static final NodeClass<LoopExitNode> TYPE = NodeClass.create(LoopExitNode.class); @Input(InputType.Association) LoopBeginNode loopBegin; public LoopExitNode(LoopBeginNode loop) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public abstract class LoweredCallTargetNode extends CallTargetNode { - public static final NodeClass<LoweredCallTargetNode> TYPE = NodeClass.get(LoweredCallTargetNode.class); + public static final NodeClass<LoweredCallTargetNode> TYPE = NodeClass.create(LoweredCallTargetNode.class); protected final Stamp returnStamp; protected final JavaType[] signature; protected final CallingConvention.Type callType;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Extension}) public final class MemoryMapNode extends FloatingNode implements MemoryMap, LIRLowerable { - public static final NodeClass<MemoryMapNode> TYPE = NodeClass.get(MemoryMapNode.class); + public static final NodeClass<MemoryMapNode> TYPE = NodeClass.create(MemoryMapNode.class); protected final List<LocationIdentity> locationIdentities; @Input(InputType.Memory) NodeInputList<ValueNode> nodes;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo(nameTemplate = "MemoryPhi({i#values}) {p#locationIdentity/s}", allowedUsageTypes = {InputType.Memory}) public final class MemoryPhiNode extends PhiNode implements MemoryNode { - public static final NodeClass<MemoryPhiNode> TYPE = NodeClass.get(MemoryPhiNode.class); + public static final NodeClass<MemoryPhiNode> TYPE = NodeClass.create(MemoryPhiNode.class); @Input(InputType.Memory) NodeInputList<ValueNode> values; protected final LocationIdentity locationIdentity;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,9 +31,26 @@ @NodeInfo public final class MergeNode extends AbstractMergeNode { - public static final NodeClass<MergeNode> TYPE = NodeClass.get(MergeNode.class); + public static final NodeClass<MergeNode> TYPE = NodeClass.create(MergeNode.class); public MergeNode() { super(TYPE); } + + public static void removeMergeIfDegenerated(MergeNode node) { + if (node.forwardEndCount() == 1 && node.hasNoUsages()) { + FixedNode currentNext = node.next(); + node.setNext(null); + EndNode forwardEnd = node.forwardEndAt(0); + forwardEnd.replaceAtPredecessor(currentNext); + node.markDeleted(); + forwardEnd.markDeleted(); + } + } + + @Override + public boolean verify() { + assertTrue(this.forwardEndCount() > 1, "Must merge more than one end."); + return true; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ParameterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ParameterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo(nameTemplate = "Param({p#index})") public final class ParameterNode extends AbstractLocalNode implements IterableNodeType, UncheckedInterfaceProvider { - public static final NodeClass<ParameterNode> TYPE = NodeClass.get(ParameterNode.class); + public static final NodeClass<ParameterNode> TYPE = NodeClass.create(ParameterNode.class); public ParameterNode(int index, Stamp stamp) { super(TYPE, index, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public abstract class PhiNode extends FloatingNode implements Simplifiable { - public static final NodeClass<PhiNode> TYPE = NodeClass.get(PhiNode.class); + public static final NodeClass<PhiNode> TYPE = NodeClass.create(PhiNode.class); @Input(InputType.Association) protected AbstractMergeNode merge; protected PhiNode(NodeClass<? extends PhiNode> c, Stamp stamp, AbstractMergeNode merge) { @@ -145,7 +145,7 @@ @NodeInfo static final class MultipleValuesNode extends ValueNode { - public static final NodeClass<MultipleValuesNode> TYPE = NodeClass.get(MultipleValuesNode.class); + public static final NodeClass<MultipleValuesNode> TYPE = NodeClass.create(MultipleValuesNode.class); public MultipleValuesNode() { super(TYPE, null);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class PiArrayNode extends PiNode implements ArrayLengthProvider { - public static final NodeClass<PiArrayNode> TYPE = NodeClass.get(PiArrayNode.class); + public static final NodeClass<PiArrayNode> TYPE = NodeClass.create(PiArrayNode.class); @Input ValueNode length; public ValueNode length() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -44,7 +44,7 @@ @NodeInfo public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy { - public static final NodeClass<PiNode> TYPE = NodeClass.get(PiNode.class); + public static final NodeClass<PiNode> TYPE = NodeClass.create(PiNode.class); @Input ValueNode object; protected final Stamp piStamp;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public abstract class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable { - public static final NodeClass<ProxyNode> TYPE = NodeClass.get(ProxyNode.class); + public static final NodeClass<ProxyNode> TYPE = NodeClass.create(ProxyNode.class); @Input(InputType.Association) AbstractBeginNode proxyPoint; protected ProxyNode(NodeClass<? extends ProxyNode> c, Stamp stamp, AbstractBeginNode proxyPoint) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class ReturnNode extends ControlSinkNode implements LIRLowerable, IterableNodeType { - public static final NodeClass<ReturnNode> TYPE = NodeClass.get(ReturnNode.class); + public static final NodeClass<ReturnNode> TYPE = NodeClass.create(ReturnNode.class); @OptionalInput ValueNode result; @OptionalInput(InputType.Extension) MemoryMapNode memoryMap;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public final class SafepointNode extends DeoptimizingFixedWithNextNode implements LIRLowerable { - public static final NodeClass<SafepointNode> TYPE = NodeClass.get(SafepointNode.class); + public static final NodeClass<SafepointNode> TYPE = NodeClass.create(SafepointNode.class); public SafepointNode() { super(TYPE, StampFactory.forVoid());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public final class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable.Binary<LogicNode> { - public static final NodeClass<ShortCircuitOrNode> TYPE = NodeClass.get(ShortCircuitOrNode.class); + public static final NodeClass<ShortCircuitOrNode> TYPE = NodeClass.create(ShortCircuitOrNode.class); @Input(InputType.Condition) LogicNode x; @Input(InputType.Condition) LogicNode y; protected boolean xNegated;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class SimpleInfopointNode extends InfopointNode implements LIRLowerable, IterableNodeType, Simplifiable { - public static final NodeClass<SimpleInfopointNode> TYPE = NodeClass.get(SimpleInfopointNode.class); + public static final NodeClass<SimpleInfopointNode> TYPE = NodeClass.create(SimpleInfopointNode.class); protected BytecodePosition position; public SimpleInfopointNode(InfopointReason reason, BytecodePosition position) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ */ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public class StartNode extends BeginStateSplitNode implements MemoryCheckpoint.Single { - public static final NodeClass<StartNode> TYPE = NodeClass.get(StartNode.class); + public static final NodeClass<StartNode> TYPE = NodeClass.create(StartNode.class); protected StartNode(NodeClass<? extends StartNode> c) { super(c);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Tue Mar 10 21:26:02 2015 +0100 @@ -324,7 +324,7 @@ if (node instanceof AbstractBeginNode) { ((AbstractBeginNode) node).prepareDelete(); } - assert node.hasNoUsages() : node + " " + node.usages(); + assert node.hasNoUsages() : node + " " + node.usages().count() + ", " + node.usages().first(); GraphUtil.unlinkFixedNode(node); node.safeDelete(); } @@ -534,4 +534,12 @@ public Set<ResolvedJavaMethod> getInlinedMethods() { return inlinedMethods; } + + /** + * + * @return true if the graph contains only a {@link StartNode} and {@link ReturnNode} + */ + public boolean isTrivial() { + return !(start.next() instanceof ReturnNode); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class TypeProfileProxyNode extends UnaryNode implements IterableNodeType, ValueProxy { - public static final NodeClass<TypeProfileProxyNode> TYPE = NodeClass.get(TypeProfileProxyNode.class); + public static final NodeClass<TypeProfileProxyNode> TYPE = NodeClass.create(TypeProfileProxyNode.class); protected final JavaTypeProfile profile; protected transient ResolvedJavaType lastCheckedType; protected transient JavaTypeProfile lastCheckedProfile;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; @@ -30,7 +32,7 @@ @NodeInfo public abstract class UnaryOpLogicNode extends LogicNode implements LIRLowerable, Canonicalizable.Unary<ValueNode> { - public static final NodeClass<UnaryOpLogicNode> TYPE = NodeClass.get(UnaryOpLogicNode.class); + public static final NodeClass<UnaryOpLogicNode> TYPE = NodeClass.create(UnaryOpLogicNode.class); @Input protected ValueNode value; public ValueNode getValue() { @@ -46,4 +48,8 @@ @Override public void generate(NodeLIRBuilderTool gen) { } + + public abstract Stamp getSucceedingStampForValue(boolean negated); + + public abstract TriState tryFold(Stamp valueStamp); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public final class UnwindNode extends ControlSinkNode implements Lowerable, LIRLowerable { - public static final NodeClass<UnwindNode> TYPE = NodeClass.get(UnwindNode.class); + public static final NodeClass<UnwindNode> TYPE = NodeClass.create(UnwindNode.class); @Input ValueNode exception; public ValueNode exception() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public abstract class ValueNode extends com.oracle.graal.graph.Node implements KindProvider { - public static final NodeClass<ValueNode> TYPE = NodeClass.get(ValueNode.class); + public static final NodeClass<ValueNode> TYPE = NodeClass.create(ValueNode.class); /** * The kind of this value. This is {@link Kind#Void} for instructions that produce no value. * This kind is guaranteed to be a {@linkplain Kind#getStackKind() stack kind}.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java Tue Mar 10 21:26:02 2015 +0100 @@ -88,7 +88,7 @@ * Converts a given instruction to a value string. The representation of an node as a value is * formed by concatenating the {@linkplain com.oracle.graal.api.meta.Kind#getTypeChar character} * denoting its {@linkplain ValueNode#getKind kind} and its id. For example, {@code "i13"}. - * + * * @param value the instruction to convert to a value string. If {@code value == null}, then "-" * is returned. * @return the instruction representation as a string
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(nameTemplate = "ValuePhi({i#values})") public class ValuePhiNode extends PhiNode { - public static final NodeClass<ValuePhiNode> TYPE = NodeClass.get(ValuePhiNode.class); + public static final NodeClass<ValuePhiNode> TYPE = NodeClass.create(ValuePhiNode.class); @Input protected NodeInputList<ValueNode> values; public ValuePhiNode(Stamp stamp, AbstractMergeNode merge) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class ValueProxyNode extends ProxyNode implements Canonicalizable, Virtualizable, ValueProxy { - public static final NodeClass<ValueProxyNode> TYPE = NodeClass.get(ValueProxyNode.class); + public static final NodeClass<ValueProxyNode> TYPE = NodeClass.create(ValueProxyNode.class); @Input ValueNode value; public ValueProxyNode(ValueNode value, AbstractBeginNode proxyPoint) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ super(c); } - public static final NodeClass<VirtualState> TYPE = NodeClass.get(VirtualState.class); + public static final NodeClass<VirtualState> TYPE = NodeClass.create(VirtualState.class); public abstract static class NodeClosure<T extends Node> {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AbsNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AbsNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ */ @NodeInfo public final class AbsNode extends UnaryArithmeticNode<Abs> implements ArithmeticLIRLowerable, NarrowableArithmeticNode { - public static final NodeClass<AbsNode> TYPE = NodeClass.get(AbsNode.class); + public static final NodeClass<AbsNode> TYPE = NodeClass.create(AbsNode.class); public AbsNode(ValueNode x) { super(TYPE, ArithmeticOpTable::getAbs, x);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Add; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -34,9 +35,9 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "+") -public class AddNode extends BinaryArithmeticNode<Add> implements NarrowableArithmeticNode { +public class AddNode extends BinaryArithmeticNode<Add> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> { - public static final NodeClass<AddNode> TYPE = NodeClass.get(AddNode.class); + public static final NodeClass<AddNode> TYPE = NodeClass.create(AddNode.class); public AddNode(ValueNode x, ValueNode y) { this(TYPE, x, y); @@ -53,7 +54,7 @@ if (tryConstantFold != null) { return tryConstantFold; } else { - return new AddNode(x, y); + return new AddNode(x, y).maybeCommuteInputs(); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,9 +25,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.And; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -36,9 +37,9 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "&") -public final class AndNode extends BinaryArithmeticNode<And> implements NarrowableArithmeticNode { +public final class AndNode extends BinaryArithmeticNode<And> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> { - public static final NodeClass<AndNode> TYPE = NodeClass.get(AndNode.class); + public static final NodeClass<AndNode> TYPE = NodeClass.create(AndNode.class); public AndNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getAnd, x, y); @@ -51,7 +52,7 @@ if (tryConstantFold != null) { return tryConstantFold; } else { - return new AndNode(x, y); + return new AndNode(x, y).maybeCommuteInputs(); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,9 +37,9 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo -public abstract class BinaryArithmeticNode<OP> extends BinaryNode implements ArithmeticLIRLowerable { +public abstract class BinaryArithmeticNode<OP> extends BinaryNode implements ArithmeticLIRLowerable, Canonicalizable.Binary<ValueNode> { - @SuppressWarnings("rawtypes") public static final NodeClass<BinaryArithmeticNode> TYPE = NodeClass.get(BinaryArithmeticNode.class); + @SuppressWarnings("rawtypes") public static final NodeClass<BinaryArithmeticNode> TYPE = NodeClass.create(BinaryArithmeticNode.class); protected interface SerializableBinaryFunction<T> extends Function<ArithmeticOpTable, BinaryOp<T>>, Serializable { } @@ -252,4 +252,30 @@ } return false; } + + /** + * Ensure a canonical ordering of inputs for commutative nodes to improve GVN results. Order the + * inputs by increasing {@link Node#id} and call {@link Graph#findDuplicate(Node)} on the node + * if it's currently in a graph. It's assumed that if there was a constant on the left it's been + * moved to the right by other code and that ordering is left alone. + * + * @return the original node or another node with the same input ordering + */ + @SuppressWarnings("deprecation") + public BinaryNode maybeCommuteInputs() { + assert this instanceof BinaryCommutative; + if (!y.isConstant() && x.getId() > y.getId()) { + ValueNode tmp = x; + x = y; + y = tmp; + if (graph() != null) { + // See if this node already exists + BinaryNode duplicate = graph().findDuplicate(this); + if (duplicate != null) { + return duplicate; + } + } + } + return this; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public abstract class BinaryNode extends FloatingNode implements Canonicalizable.Binary<ValueNode> { - public static final NodeClass<BinaryNode> TYPE = NodeClass.get(BinaryNode.class); + public static final NodeClass<BinaryNode> TYPE = NodeClass.create(BinaryNode.class); @Input protected ValueNode x; @Input protected ValueNode y;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,9 +38,9 @@ * into variants that do not materialize the value (CompareIf, CompareGuard...) */ @NodeInfo -public abstract class CompareNode extends BinaryOpLogicNode { +public abstract class CompareNode extends BinaryOpLogicNode implements Canonicalizable.Binary<ValueNode> { - public static final NodeClass<CompareNode> TYPE = NodeClass.get(CompareNode.class); + public static final NodeClass<CompareNode> TYPE = NodeClass.create(CompareNode.class); protected final Condition condition; protected final boolean unorderedIsTrue;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class ConditionalNode extends FloatingNode implements Canonicalizable, LIRLowerable { - public static final NodeClass<ConditionalNode> TYPE = NodeClass.get(ConditionalNode.class); + public static final NodeClass<ConditionalNode> TYPE = NodeClass.create(ConditionalNode.class); @Input(InputType.Condition) LogicNode condition; @Input ValueNode trueValue; @Input ValueNode falseValue;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo(shortName = "/") public final class DivNode extends BinaryArithmeticNode<Div> { - public static final NodeClass<DivNode> TYPE = NodeClass.get(DivNode.class); + public static final NodeClass<DivNode> TYPE = NodeClass.create(DivNode.class); public DivNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getDiv, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public abstract class FixedBinaryNode extends DeoptimizingFixedWithNextNode implements Canonicalizable.Binary<ValueNode> { - public static final NodeClass<FixedBinaryNode> TYPE = NodeClass.get(FixedBinaryNode.class); + public static final NodeClass<FixedBinaryNode> TYPE = NodeClass.create(FixedBinaryNode.class); @Input protected ValueNode x; @Input protected ValueNode y;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo public final class FloatConvertNode extends UnaryArithmeticNode<FloatConvertOp> implements ConvertNode, Lowerable, ArithmeticLIRLowerable { - public static final NodeClass<FloatConvertNode> TYPE = NodeClass.get(FloatConvertNode.class); + public static final NodeClass<FloatConvertNode> TYPE = NodeClass.create(FloatConvertNode.class); protected final FloatConvert op;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,14 +27,15 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public final class FloatEqualsNode extends CompareNode { - public static final NodeClass<FloatEqualsNode> TYPE = NodeClass.get(FloatEqualsNode.class); +public final class FloatEqualsNode extends CompareNode implements BinaryCommutative<ValueNode> { + public static final NodeClass<FloatEqualsNode> TYPE = NodeClass.create(FloatEqualsNode.class); public FloatEqualsNode(ValueNode x, ValueNode y) { super(TYPE, Condition.EQ, false, x, y); @@ -47,7 +48,7 @@ if (result != null) { return result; } else { - return new FloatEqualsNode(x, y); + return new FloatEqualsNode(x, y).maybeCommuteInputs(); } } @@ -57,9 +58,11 @@ if (result != this) { return result; } - if (forX.stamp() instanceof FloatStamp && forY.stamp() instanceof FloatStamp) { - FloatStamp xStamp = (FloatStamp) forX.stamp(); - FloatStamp yStamp = (FloatStamp) forY.stamp(); + Stamp xStampGeneric = forX.stamp(); + Stamp yStampGeneric = forY.stamp(); + if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) { + FloatStamp xStamp = (FloatStamp) xStampGeneric; + FloatStamp yStamp = (FloatStamp) yStampGeneric; if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && xStamp.isNonNaN() && yStamp.isNonNaN()) { return LogicConstantNode.tautology(); } else if (xStamp.alwaysDistinct(yStamp)) { @@ -78,4 +81,34 @@ } throw GraalInternalError.shouldNotReachHere(); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) { + FloatStamp xStamp = (FloatStamp) xStampGeneric; + FloatStamp yStamp = (FloatStamp) yStampGeneric; + if (xStamp.alwaysDistinct(yStamp)) { + return TriState.FALSE; + } else if (xStamp.neverDistinct(yStamp)) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo(shortName = "<") public final class FloatLessThanNode extends CompareNode { - public static final NodeClass<FloatLessThanNode> TYPE = NodeClass.get(FloatLessThanNode.class); + public static final NodeClass<FloatLessThanNode> TYPE = NodeClass.create(FloatLessThanNode.class); public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) { super(TYPE, Condition.LT, unorderedIsTrue, x, y); @@ -72,4 +72,19 @@ } throw GraalInternalError.shouldNotReachHere(); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public abstract class FloatingNode extends ValueNode implements Node.ValueNumberable { - public static final NodeClass<FloatingNode> TYPE = NodeClass.get(FloatingNode.class); + public static final NodeClass<FloatingNode> TYPE = NodeClass.create(FloatingNode.class); public FloatingNode(NodeClass<? extends FloatingNode> c, Stamp stamp) { super(c, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -33,7 +34,7 @@ @NodeInfo(shortName = "|<|") public final class IntegerBelowNode extends CompareNode { - public static final NodeClass<IntegerBelowNode> TYPE = NodeClass.get(IntegerBelowNode.class); + public static final NodeClass<IntegerBelowNode> TYPE = NodeClass.create(IntegerBelowNode.class); public IntegerBelowNode(ValueNode x, ValueNode y) { super(TYPE, Condition.BT, false, x, y); @@ -92,4 +93,97 @@ protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { return new IntegerBelowNode(newX, newY); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // x >= y + if (xStamp.isPositive() && yStamp.isPositive()) { + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (yLowerBound > xLowerBound) { + return new IntegerStamp(bits, yLowerBound, xStamp.upperBound(), xStamp.downMask(), xStamp.upMask()); + } + } + } else { + // x < y + if (yStamp.isPositive()) { + // x >= 0 && x < y + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (yUpperBound <= xUpperBound || !xStamp.isPositive()) { + if (yUpperBound != 0) { + yUpperBound--; + } + return new IntegerStamp(bits, Math.max(0, xStamp.lowerBound()), Math.min(xUpperBound, yUpperBound), xStamp.downMask(), xStamp.upMask()); + } + } + } + } + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // y <= x + if (xStamp.isPositive()) { + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (xUpperBound < yUpperBound || !yStamp.isPositive()) { + return new IntegerStamp(bits, Math.max(0, yStamp.lowerBound()), Math.min(xUpperBound, yUpperBound), yStamp.downMask(), yStamp.upMask()); + } + } + } else { + // y > x + if (xStamp.isPositive() && yStamp.isPositive()) { + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (xLowerBound >= yLowerBound) { + if (xLowerBound != CodeUtil.maxValue(bits)) { + xLowerBound++; + } + return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); + } + } + } + } + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + if (yStamp.isPositive()) { + if (xStamp.isPositive() && xStamp.upperBound() < yStamp.lowerBound()) { + return TriState.TRUE; + } else if (xStamp.isStrictlyNegative() || xStamp.lowerBound() >= yStamp.upperBound()) { + return TriState.FALSE; + } + } + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo public abstract class IntegerConvertNode<OP, REV> extends UnaryNode implements ConvertNode, ArithmeticLIRLowerable { - @SuppressWarnings("rawtypes") public static final NodeClass<IntegerConvertNode> TYPE = NodeClass.get(IntegerConvertNode.class); + @SuppressWarnings("rawtypes") public static final NodeClass<IntegerConvertNode> TYPE = NodeClass.create(IntegerConvertNode.class); protected final SerializableIntegerConvertFunction<OP> getOp; protected final SerializableIntegerConvertFunction<REV> getReverseOp;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,8 +22,6 @@ */ package com.oracle.graal.nodes.calc; -import static com.oracle.graal.graph.Edges.Type.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; @@ -34,7 +32,7 @@ @NodeInfo(shortName = "/") public final class IntegerDivNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - public static final NodeClass<IntegerDivNode> TYPE = NodeClass.get(IntegerDivNode.class); + public static final NodeClass<IntegerDivNode> TYPE = NodeClass.create(IntegerDivNode.class); public IntegerDivNode(ValueNode x, ValueNode y) { super(TYPE, IntegerStamp.OPS.getDiv().foldStamp(x.stamp(), y.stamp()), x, y); @@ -96,7 +94,7 @@ if (next() instanceof IntegerDivNode) { NodeClass<?> nodeClass = getNodeClass(); - if (next().getClass() == this.getClass() && nodeClass.getEdges(Inputs).areEqualIn(this, next()) && valueEquals(next())) { + if (next().getClass() == this.getClass() && nodeClass.getInputEdges().areEqualIn(this, next()) && valueEquals(next())) { return next(); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,14 +27,15 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public final class IntegerEqualsNode extends CompareNode { - public static final NodeClass<IntegerEqualsNode> TYPE = NodeClass.get(IntegerEqualsNode.class); +public final class IntegerEqualsNode extends CompareNode implements BinaryCommutative<ValueNode> { + public static final NodeClass<IntegerEqualsNode> TYPE = NodeClass.create(IntegerEqualsNode.class); public IntegerEqualsNode(ValueNode x, ValueNode y) { super(TYPE, Condition.EQ, false, x, y); @@ -65,7 +66,7 @@ } } - return new IntegerEqualsNode(x, y); + return new IntegerEqualsNode(x, y).maybeCommuteInputs(); } } @@ -153,4 +154,34 @@ } return super.canonicalizeSymmetricConstant(tool, constant, nonConstant, mirrored); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + if (!negated) { + return getX().stamp().join(getY().stamp()); + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof IntegerStamp && yStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + if (xStamp.alwaysDistinct(yStamp)) { + return TriState.FALSE; + } else if (xStamp.neverDistinct(yStamp)) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; @@ -34,7 +35,7 @@ @NodeInfo(shortName = "<") public final class IntegerLessThanNode extends CompareNode { - public static final NodeClass<IntegerLessThanNode> TYPE = NodeClass.get(IntegerLessThanNode.class); + public static final NodeClass<IntegerLessThanNode> TYPE = NodeClass.create(IntegerLessThanNode.class); public IntegerLessThanNode(ValueNode x, ValueNode y) { super(TYPE, Condition.LT, false, x, y); @@ -114,4 +115,85 @@ } throw GraalInternalError.shouldNotReachHere(); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // x >= y + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (yLowerBound > xLowerBound) { + return new IntegerStamp(bits, yLowerBound, xStamp.upperBound(), xStamp.downMask(), xStamp.upMask()); + } + } else { + // x < y + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (yUpperBound <= xUpperBound) { + if (yUpperBound != CodeUtil.minValue(bits)) { + yUpperBound--; + } + return new IntegerStamp(bits, xStamp.lowerBound(), yUpperBound, xStamp.downMask(), xStamp.upMask()); + } + } + } + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + Stamp xStampGeneric = getX().stamp(); + Stamp yStampGeneric = getY().stamp(); + if (xStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + int bits = xStamp.getBits(); + if (yStampGeneric instanceof IntegerStamp) { + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + assert yStamp.getBits() == bits; + if (negated) { + // y <= x + long xUpperBound = xStamp.upperBound(); + long yUpperBound = yStamp.upperBound(); + if (xUpperBound < yUpperBound) { + return new IntegerStamp(bits, yStamp.lowerBound(), xUpperBound, yStamp.downMask(), yStamp.upMask()); + } + } else { + // y > x + long xLowerBound = xStamp.lowerBound(); + long yLowerBound = yStamp.lowerBound(); + if (xLowerBound >= yLowerBound) { + if (xLowerBound != CodeUtil.maxValue(bits)) { + xLowerBound++; + } + return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); + } + } + } + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof IntegerStamp && yStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + if (xStamp.upperBound() < yStamp.lowerBound()) { + return TriState.TRUE; + } + if (xStamp.lowerBound() >= yStamp.upperBound()) { + return TriState.FALSE; + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo(shortName = "%") public final class IntegerRemNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - public static final NodeClass<IntegerRemNode> TYPE = NodeClass.get(IntegerRemNode.class); + public static final NodeClass<IntegerRemNode> TYPE = NodeClass.create(IntegerRemNode.class); public IntegerRemNode(ValueNode x, ValueNode y) { super(TYPE, IntegerStamp.OPS.getRem().foldStamp(x.stamp(), y.stamp()), x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,8 +22,10 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -34,8 +36,8 @@ * both x and y. */ @NodeInfo -public final class IntegerTestNode extends BinaryOpLogicNode { - public static final NodeClass<IntegerTestNode> TYPE = NodeClass.get(IntegerTestNode.class); +public final class IntegerTestNode extends BinaryOpLogicNode implements BinaryCommutative<ValueNode> { + public static final NodeClass<IntegerTestNode> TYPE = NodeClass.create(IntegerTestNode.class); public IntegerTestNode(ValueNode x, ValueNode y) { super(TYPE, x, y); @@ -57,4 +59,53 @@ } return this; } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + Stamp xStampGeneric = this.getX().stamp(); + Stamp yStampGeneric = this.getY().stamp(); + return getSucceedingStamp(negated, xStampGeneric, yStampGeneric); + } + + private static Stamp getSucceedingStamp(boolean negated, Stamp xStampGeneric, Stamp otherStampGeneric) { + if (xStampGeneric instanceof IntegerStamp && otherStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + IntegerStamp otherStamp = (IntegerStamp) otherStampGeneric; + if (negated) { + if (Long.bitCount(otherStamp.upMask()) == 1) { + long newDownMask = xStamp.downMask() | otherStamp.upMask(); + if (xStamp.downMask() != newDownMask) { + return IntegerStamp.stampForMask(xStamp.getBits(), newDownMask, xStamp.upMask()).join(xStamp); + } + } + } else { + long restrictedUpMask = ((~otherStamp.downMask()) & xStamp.upMask()); + if (xStamp.upMask() != restrictedUpMask) { + return IntegerStamp.stampForMask(xStamp.getBits(), xStamp.downMask(), restrictedUpMask).join(xStamp); + } + } + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + Stamp xStampGeneric = this.getX().stamp(); + Stamp yStampGeneric = this.getY().stamp(); + return getSucceedingStamp(negated, yStampGeneric, xStampGeneric); + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof IntegerStamp && yStampGeneric instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) xStampGeneric; + IntegerStamp yStamp = (IntegerStamp) yStampGeneric; + if ((xStamp.upMask() & yStamp.upMask()) == 0) { + return TriState.TRUE; + } else if ((xStamp.downMask() & yStamp.downMask()) != 0) { + return TriState.FALSE; + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -36,7 +37,7 @@ @NodeInfo public final class IsNullNode extends UnaryOpLogicNode implements LIRLowerable, Virtualizable, PiPushable { - public static final NodeClass<IsNullNode> TYPE = NodeClass.get(IsNullNode.class); + public static final NodeClass<IsNullNode> TYPE = NodeClass.create(IsNullNode.class); public IsNullNode(ValueNode object) { super(TYPE, object); @@ -86,4 +87,22 @@ @NodeIntrinsic public static native IsNullNode isNull(Object object); + + @Override + public Stamp getSucceedingStampForValue(boolean negated) { + return negated ? StampFactory.objectNonNull() : StampFactory.alwaysNull(); + } + + @Override + public TriState tryFold(Stamp valueStamp) { + if (valueStamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) valueStamp; + if (objectStamp.alwaysNull()) { + return TriState.TRUE; + } else if (objectStamp.nonNull()) { + return TriState.FALSE; + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo(shortName = "<<") public final class LeftShiftNode extends ShiftNode<Shl> { - public static final NodeClass<LeftShiftNode> TYPE = NodeClass.get(LeftShiftNode.class); + public static final NodeClass<LeftShiftNode> TYPE = NodeClass.create(LeftShiftNode.class); public LeftShiftNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getShl, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,8 +26,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Mul; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -35,9 +36,9 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "*") -public class MulNode extends BinaryArithmeticNode<Mul> implements NarrowableArithmeticNode { +public class MulNode extends BinaryArithmeticNode<Mul> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> { - public static final NodeClass<MulNode> TYPE = NodeClass.get(MulNode.class); + public static final NodeClass<MulNode> TYPE = NodeClass.create(MulNode.class); public MulNode(ValueNode x, ValueNode y) { this(TYPE, x, y); @@ -54,7 +55,7 @@ if (tryConstantFold != null) { return tryConstantFold; } else { - return new MulNode(x, y); + return new MulNode(x, y).maybeCommuteInputs(); } } @@ -77,33 +78,8 @@ if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getKind().isNumericInteger()) { long i = ((PrimitiveConstant) c).asLong(); - boolean signFlip = false; - if (i < 0) { - i = -i; - signFlip = true; - } - if (i > 0) { - ValueNode mulResult = null; - long bit1 = i & -i; - long bit2 = i - bit1; - bit2 = bit2 & -bit2; // Extract 2nd bit - if (CodeUtil.isPowerOf2(i)) { // - mulResult = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i))); - } else if (bit2 + bit1 == i) { // We can work with two shifts and add - ValueNode shift1 = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(bit1))); - ValueNode shift2 = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(bit2))); - mulResult = new AddNode(shift1, shift2); - } else if (CodeUtil.isPowerOf2(i + 1)) { // shift and subtract - ValueNode shift1 = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i + 1))); - mulResult = new SubNode(shift1, forX); - } - if (mulResult != null) { - if (signFlip) { - return new NegateNode(mulResult); - } else { - return mulResult; - } - } + if (i > 0 && CodeUtil.isPowerOf2(i)) { + return new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i))); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class NarrowNode extends IntegerConvertNode<Narrow, SignExtend> { - public static final NodeClass<NarrowNode> TYPE = NodeClass.get(NarrowNode.class); + public static final NodeClass<NarrowNode> TYPE = NodeClass.create(NarrowNode.class); public NarrowNode(ValueNode input, int resultBits) { this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class NegateNode extends UnaryArithmeticNode<Neg> implements NarrowableArithmeticNode { - public static final NodeClass<NegateNode> TYPE = NodeClass.get(NegateNode.class); + public static final NodeClass<NegateNode> TYPE = NodeClass.create(NegateNode.class); public NegateNode(ValueNode value) { super(TYPE, ArithmeticOpTable::getNeg, value);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class NormalizeCompareNode extends BinaryNode implements Lowerable { - public static final NodeClass<NormalizeCompareNode> TYPE = NodeClass.get(NormalizeCompareNode.class); + public static final NodeClass<NormalizeCompareNode> TYPE = NodeClass.create(NormalizeCompareNode.class); protected final boolean isUnorderedLess; public NormalizeCompareNode(ValueNode x, ValueNode y, boolean isUnorderedLess) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class NotNode extends UnaryArithmeticNode<Not> implements ArithmeticLIRLowerable, NarrowableArithmeticNode { - public static final NodeClass<NotNode> TYPE = NodeClass.get(NotNode.class); + public static final NodeClass<NotNode> TYPE = NodeClass.create(NotNode.class); public NotNode(ValueNode x) { super(TYPE, ArithmeticOpTable::getNot, x);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo(shortName = "==") public final class ObjectEqualsNode extends PointerEqualsNode implements Virtualizable { - public static final NodeClass<ObjectEqualsNode> TYPE = NodeClass.get(ObjectEqualsNode.class); + public static final NodeClass<ObjectEqualsNode> TYPE = NodeClass.create(ObjectEqualsNode.class); public ObjectEqualsNode(ValueNode x, ValueNode y) { super(TYPE, x, y); @@ -92,7 +92,7 @@ /* * One of the two objects has identity, the other doesn't. In code, this looks like * "Integer.valueOf(a) == new Integer(b)", which is always false. - * + * * In other words: an object created via valueOf can never be equal to one created * by new in the same compilation unit. */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,9 +25,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Or; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -36,9 +37,9 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "|") -public final class OrNode extends BinaryArithmeticNode<Or> { +public final class OrNode extends BinaryArithmeticNode<Or> implements BinaryCommutative<ValueNode> { - public static final NodeClass<OrNode> TYPE = NodeClass.get(OrNode.class); + public static final NodeClass<OrNode> TYPE = NodeClass.create(OrNode.class); public OrNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getOr, x, y); @@ -51,7 +52,7 @@ if (tryConstantFold != null) { return tryConstantFold; } else { - return new OrNode(x, y); + return new OrNode(x, y).maybeCommuteInputs(); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,18 +22,20 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public class PointerEqualsNode extends CompareNode { +public class PointerEqualsNode extends CompareNode implements BinaryCommutative<ValueNode> { - public static final NodeClass<PointerEqualsNode> TYPE = NodeClass.get(PointerEqualsNode.class); + public static final NodeClass<PointerEqualsNode> TYPE = NodeClass.create(PointerEqualsNode.class); public PointerEqualsNode(ValueNode x, ValueNode y) { this(TYPE, x, y); @@ -72,4 +74,42 @@ protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { return new PointerEqualsNode(newX, newY); } + + @Override + public Stamp getSucceedingStampForX(boolean negated) { + if (!negated) { + Stamp xStamp = getX().stamp(); + Stamp newStamp = xStamp.join(getY().stamp()); + if (!newStamp.equals(xStamp)) { + return newStamp; + } + } + return null; + } + + @Override + public Stamp getSucceedingStampForY(boolean negated) { + if (!negated) { + Stamp yStamp = getY().stamp(); + Stamp newStamp = yStamp.join(getX().stamp()); + if (!newStamp.equals(yStamp)) { + return newStamp; + } + } + return null; + } + + @Override + public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) { + if (xStampGeneric instanceof ObjectStamp && yStampGeneric instanceof ObjectStamp) { + ObjectStamp xStamp = (ObjectStamp) xStampGeneric; + ObjectStamp yStamp = (ObjectStamp) yStampGeneric; + if (xStamp.alwaysDistinct(yStamp)) { + return TriState.FALSE; + } else if (xStamp.neverDistinct(yStamp)) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class ReinterpretNode extends UnaryNode implements ArithmeticLIRLowerable { - public static final NodeClass<ReinterpretNode> TYPE = NodeClass.get(ReinterpretNode.class); + public static final NodeClass<ReinterpretNode> TYPE = NodeClass.create(ReinterpretNode.class); public ReinterpretNode(Kind to, ValueNode value) { this(StampFactory.forKind(to), value);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RemNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RemNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(shortName = "%") public final class RemNode extends BinaryArithmeticNode<Rem> implements Lowerable { - public static final NodeClass<RemNode> TYPE = NodeClass.get(RemNode.class); + public static final NodeClass<RemNode> TYPE = NodeClass.create(RemNode.class); public RemNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getRem, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo(shortName = ">>") public final class RightShiftNode extends ShiftNode<Shr> { - public static final NodeClass<RightShiftNode> TYPE = NodeClass.get(RightShiftNode.class); + public static final NodeClass<RightShiftNode> TYPE = NodeClass.create(RightShiftNode.class); public RightShiftNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getShr, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo public abstract class ShiftNode<OP> extends BinaryNode implements ArithmeticLIRLowerable { - @SuppressWarnings("rawtypes") public static final NodeClass<ShiftNode> TYPE = NodeClass.get(ShiftNode.class); + @SuppressWarnings("rawtypes") public static final NodeClass<ShiftNode> TYPE = NodeClass.create(ShiftNode.class); protected interface SerializableShiftFunction<T> extends Function<ArithmeticOpTable, ShiftOp<T>>, Serializable { }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class SignExtendNode extends IntegerConvertNode<SignExtend, Narrow> { - public static final NodeClass<SignExtendNode> TYPE = NodeClass.get(SignExtendNode.class); + public static final NodeClass<SignExtendNode> TYPE = NodeClass.create(SignExtendNode.class); public SignExtendNode(ValueNode input, int resultBits) { this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SqrtNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SqrtNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public final class SqrtNode extends UnaryArithmeticNode<Sqrt> implements ArithmeticLIRLowerable, NarrowableArithmeticNode { - public static final NodeClass<SqrtNode> TYPE = NodeClass.get(SqrtNode.class); + public static final NodeClass<SqrtNode> TYPE = NodeClass.create(SqrtNode.class); public SqrtNode(ValueNode x) { super(TYPE, ArithmeticOpTable::getSqrt, x);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo(shortName = "-") public class SubNode extends BinaryArithmeticNode<Sub> implements NarrowableArithmeticNode { - public static final NodeClass<SubNode> TYPE = NodeClass.get(SubNode.class); + public static final NodeClass<SubNode> TYPE = NodeClass.create(SubNode.class); public SubNode(ValueNode x, ValueNode y) { this(TYPE, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public abstract class UnaryArithmeticNode<OP> extends UnaryNode implements ArithmeticLIRLowerable { - @SuppressWarnings("rawtypes") public static final NodeClass<UnaryArithmeticNode> TYPE = NodeClass.get(UnaryArithmeticNode.class); + @SuppressWarnings("rawtypes") public static final NodeClass<UnaryArithmeticNode> TYPE = NodeClass.create(UnaryArithmeticNode.class); protected interface SerializableUnaryFunction<T> extends Function<ArithmeticOpTable, UnaryOp<T>>, Serializable { }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public abstract class UnaryNode extends FloatingNode implements Canonicalizable.Unary<ValueNode> { - public static final NodeClass<UnaryNode> TYPE = NodeClass.get(UnaryNode.class); + public static final NodeClass<UnaryNode> TYPE = NodeClass.create(UnaryNode.class); @Input protected ValueNode value; public ValueNode getValue() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(shortName = "|/|") public final class UnsignedDivNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - public static final NodeClass<UnsignedDivNode> TYPE = NodeClass.get(UnsignedDivNode.class); + public static final NodeClass<UnsignedDivNode> TYPE = NodeClass.create(UnsignedDivNode.class); public UnsignedDivNode(ValueNode x, ValueNode y) { super(TYPE, x.stamp().unrestricted(), x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(shortName = "|%|") public final class UnsignedRemNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - public static final NodeClass<UnsignedRemNode> TYPE = NodeClass.get(UnsignedRemNode.class); + public static final NodeClass<UnsignedRemNode> TYPE = NodeClass.create(UnsignedRemNode.class); public UnsignedRemNode(ValueNode x, ValueNode y) { super(TYPE, x.stamp().unrestricted(), x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo(shortName = ">>>") public final class UnsignedRightShiftNode extends ShiftNode<UShr> { - public static final NodeClass<UnsignedRightShiftNode> TYPE = NodeClass.get(UnsignedRightShiftNode.class); + public static final NodeClass<UnsignedRightShiftNode> TYPE = NodeClass.create(UnsignedRightShiftNode.class); public UnsignedRightShiftNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getUShr, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,9 +25,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Xor; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -36,9 +37,9 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "^") -public final class XorNode extends BinaryArithmeticNode<Xor> { +public final class XorNode extends BinaryArithmeticNode<Xor> implements BinaryCommutative<ValueNode> { - public static final NodeClass<XorNode> TYPE = NodeClass.get(XorNode.class); + public static final NodeClass<XorNode> TYPE = NodeClass.create(XorNode.class); public XorNode(ValueNode x, ValueNode y) { super(TYPE, ArithmeticOpTable::getXor, x, y); @@ -52,7 +53,7 @@ if (tryConstantFold != null) { return tryConstantFold; } else { - return new XorNode(x, y); + return new XorNode(x, y).maybeCommuteInputs(); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo public final class ZeroExtendNode extends IntegerConvertNode<ZeroExtend, Narrow> { - public static final NodeClass<ZeroExtendNode> TYPE = NodeClass.get(ZeroExtendNode.class); + public static final NodeClass<ZeroExtendNode> TYPE = NodeClass.create(ZeroExtendNode.class); public ZeroExtendNode(ValueNode input, int resultBits) { this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,6 +38,7 @@ protected Loop<Block> loop; protected Block postdominator; + protected Block distancedDominatorCache; protected Block(AbstractBeginNode node) { this.beginNode = node; @@ -51,6 +52,7 @@ return endNode; } + @Override public Loop<Block> getLoop() { return loop; } @@ -59,18 +61,22 @@ this.loop = loop; } + @Override public int getLoopDepth() { return loop == null ? 0 : loop.getDepth(); } + @Override public boolean isLoopHeader() { return getBeginNode() instanceof LoopBeginNode; } + @Override public boolean isLoopEnd() { return getEndNode() instanceof LoopEndNode; } + @Override public boolean isExceptionEntry() { Node predecessor = getBeginNode().predecessor(); return predecessor != null && predecessor instanceof InvokeWithExceptionNode && getBeginNode() == ((InvokeWithExceptionNode) predecessor).exceptionEdge(); @@ -97,6 +103,7 @@ return b; } + @Override public Block getPostdominator() { return postdominator; } @@ -117,10 +124,15 @@ @Override public FixedNode next() { FixedNode result = cur; - if (cur == getEndNode()) { + if (result instanceof FixedWithNextNode) { + FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) result; + FixedNode next = fixedWithNextNode.next(); + if (next instanceof AbstractBeginNode) { + next = null; + } + cur = next; + } else { cur = null; - } else { - cur = ((FixedWithNextNode) cur).next(); } assert !(cur instanceof AbstractBeginNode); return result; @@ -159,6 +171,7 @@ return "B" + id; } + @Override public double probability() { return probability; } @@ -167,4 +180,13 @@ assert probability >= 0 && Double.isFinite(probability); this.probability = probability; } + + @Override + public Block getDominator(int distance) { + Block result = this; + for (int i = 0; i < distance; ++i) { + result = result.getDominator(); + } + return result; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue Mar 10 21:26:02 2015 +0100 @@ -78,6 +78,10 @@ return reversePostOrder.get(0); } + public Iterable<Block> reversePostOrder() { + return reversePostOrder; + } + public Iterable<Block> postOrder() { return new Iterable<Block>() { @@ -173,6 +177,7 @@ // First time we see this block: push all successors. for (Node suxNode : block.getEndNode().cfgSuccessors()) { Block suxBlock = blockFor(suxNode); + assert suxBlock != null : suxNode; if (suxBlock.getId() == BLOCK_ID_INITIAL) { stack.add(suxBlock); } @@ -200,14 +205,19 @@ } // Connect blocks (including loop backward edges), but ignoring dead code (blocks with id < 0). + // Predecessors need to be in the order expected when iterating phi inputs. private void connectBlocks() { for (Block block : reversePostOrder) { - List<Block> predecessors = new ArrayList<>(4); + List<Block> predecessors = new ArrayList<>(1); double probability = block.getBeginNode() instanceof StartNode ? 1D : 0D; for (Node predNode : block.getBeginNode().cfgPredecessors()) { Block predBlock = nodeToBlock.get(predNode); if (predBlock.getId() >= 0) { predecessors.add(predBlock); + if (predBlock.getSuccessors() == null) { + predBlock.setSuccessors(new ArrayList<>(1)); + } + predBlock.getSuccessors().add(block); probability += predBlock.probability; } } @@ -222,6 +232,10 @@ assert predBlock != null : predNode; if (predBlock.getId() >= 0) { predecessors.add(predBlock); + if (predBlock.getSuccessors() == null) { + predBlock.setSuccessors(new ArrayList<>(1)); + } + predBlock.getSuccessors().add(block); } } } @@ -230,19 +244,9 @@ } block.setPredecessors(predecessors); block.setProbability(probability); - - List<Block> successors = new ArrayList<>(4); - for (Node suxNode : block.getEndNode().cfgSuccessors()) { - Block suxBlock = nodeToBlock.get(suxNode); - assert suxBlock.getId() >= 0; - successors.add(suxBlock); + if (block.getSuccessors() == null) { + block.setSuccessors(new ArrayList<>(1)); } - if (block.getEndNode() instanceof LoopEndNode) { - Block suxBlock = nodeToBlock.get(((LoopEndNode) block.getEndNode()).loopBegin()); - assert suxBlock.getId() >= 0; - successors.add(suxBlock); - } - block.setSuccessors(successors); } } @@ -266,29 +270,30 @@ computeLoopBlocks(exitBlock.getFirstPredecessor(), loop); loop.getExits().add(exitBlock); } - List<Block> unexpected = new LinkedList<>(); - for (Block b : loop.getBlocks()) { + + // The following loop can add new blocks to the end of the loop's block list. + int size = loop.getBlocks().size(); + for (int i = 0; i < size; ++i) { + Block b = loop.getBlocks().get(i); for (Block sux : b.getSuccessors()) { if (sux.loop != loop) { AbstractBeginNode begin = sux.getBeginNode(); if (!(begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == loopBegin)) { Debug.log(3, "Unexpected loop exit with %s, including whole branch in the loop", sux); - unexpected.add(sux); + addBranchToLoop(loop, sux); } } } } - for (Block b : unexpected) { - addBranchToLoop(loop, b); - } } } } private static void addBranchToLoop(Loop<Block> l, Block b) { - if (l.getBlocks().contains(b)) { + if (b.loop == l) { return; } + assert !(l.getBlocks().contains(b)); l.getBlocks().add(b); b.loop = l; for (Block sux : b.getSuccessors()) { @@ -313,7 +318,7 @@ } } - private void computePostdominators() { + public void computePostdominators() { outer: for (Block block : postOrder()) { if (block.isLoopEnd()) { // We do not want the loop header registered as the postdominator of the loop end.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/BlackholeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/BlackholeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class BlackholeNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<BlackholeNode> TYPE = NodeClass.get(BlackholeNode.class); + public static final NodeClass<BlackholeNode> TYPE = NodeClass.create(BlackholeNode.class); @Input ValueNode value; public BlackholeNode(ValueNode value) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/ControlFlowAnchorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/ControlFlowAnchorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class ControlFlowAnchorNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<ControlFlowAnchorNode> TYPE = NodeClass.get(ControlFlowAnchorNode.class); + public static final NodeClass<ControlFlowAnchorNode> TYPE = NodeClass.create(ControlFlowAnchorNode.class); private static class Unique { }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public class DynamicCounterNode extends FixedWithNextNode implements Lowerable { - public static final NodeClass<DynamicCounterNode> TYPE = NodeClass.get(DynamicCounterNode.class); + public static final NodeClass<DynamicCounterNode> TYPE = NodeClass.create(DynamicCounterNode.class); @Input ValueNode increment; protected final String name;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,14 +31,18 @@ @NodeInfo public final class OpaqueNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<OpaqueNode> TYPE = NodeClass.get(OpaqueNode.class); - @Input ValueNode value; + public static final NodeClass<OpaqueNode> TYPE = NodeClass.create(OpaqueNode.class); + @Input protected ValueNode value; public OpaqueNode(ValueNode value) { super(TYPE, value.stamp().unrestricted()); this.value = value; } + public ValueNode getValue() { + return value; + } + @Override public void generate(NodeLIRBuilderTool gen) { gen.setResult(this, gen.operand(value));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/VerifyHeapNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/VerifyHeapNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class VerifyHeapNode extends FixedWithNextNode implements Lowerable { - public static final NodeClass<VerifyHeapNode> TYPE = NodeClass.get(VerifyHeapNode.class); + public static final NodeClass<VerifyHeapNode> TYPE = NodeClass.create(VerifyHeapNode.class); public VerifyHeapNode() { super(TYPE, StampFactory.forVoid());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class WeakCounterNode extends DynamicCounterNode implements Simplifiable, Virtualizable { - public static final NodeClass<WeakCounterNode> TYPE = NodeClass.get(WeakCounterNode.class); + public static final NodeClass<WeakCounterNode> TYPE = NodeClass.create(WeakCounterNode.class); @Input ValueNode checkedValue; public WeakCounterNode(String group, String name, ValueNode increment, boolean addContext, ValueNode checkedValue) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public abstract class AbstractWriteNode extends FixedAccessNode implements StateSplit, MemoryCheckpoint.Single, MemoryAccess, GuardingNode { - public static final NodeClass<AbstractWriteNode> TYPE = NodeClass.get(AbstractWriteNode.class); + public static final NodeClass<AbstractWriteNode> TYPE = NodeClass.create(AbstractWriteNode.class); @Input ValueNode value; @OptionalInput(InputType.State) FrameState stateAfter; @OptionalInput(InputType.Memory) Node lastLocationAccess;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo(nameTemplate = "AddLoc {p#locationIdentity/s}") public final class AddLocationNode extends LocationNode implements Canonicalizable.Binary<LocationNode> { - public static final NodeClass<AddLocationNode> TYPE = NodeClass.get(AddLocationNode.class); + public static final NodeClass<AddLocationNode> TYPE = NodeClass.create(AddLocationNode.class); @Input(InputType.Association) ValueNode x; @Input(InputType.Association) ValueNode y;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public abstract class ArrayRangeWriteNode extends AbstractMemoryCheckpoint { - public static final NodeClass<ArrayRangeWriteNode> TYPE = NodeClass.get(ArrayRangeWriteNode.class); + public static final NodeClass<ArrayRangeWriteNode> TYPE = NodeClass.create(ArrayRangeWriteNode.class); protected ArrayRangeWriteNode(NodeClass<? extends ArrayRangeWriteNode> c, Stamp stamp) { super(c, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,7 +43,7 @@ @NodeInfo public final class BoxNode extends UnaryNode implements VirtualizableAllocation, Lowerable { - public static final NodeClass<BoxNode> TYPE = NodeClass.get(BoxNode.class); + public static final NodeClass<BoxNode> TYPE = NodeClass.create(BoxNode.class); protected final Kind boxingKind; public BoxNode(ValueNode value, ResolvedJavaType resultType, Kind boxingKind) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class BranchProbabilityNode extends FloatingNode implements Simplifiable, Lowerable { - public static final NodeClass<BranchProbabilityNode> TYPE = NodeClass.get(BranchProbabilityNode.class); + public static final NodeClass<BranchProbabilityNode> TYPE = NodeClass.create(BranchProbabilityNode.class); public static final double LIKELY_PROBABILITY = 0.6; public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY; @@ -100,12 +100,17 @@ couldSet = true; ifNodeUsages.setTrueSuccessorProbability(probabilityToSet); } + + if (!couldSet && node.usages().filter(FixedGuardNode.class).isNotEmpty()) { + couldSet = true; + } } } } if (couldSet) { - replaceAndDelete(condition); - tool.addToWorkList(condition.usages()); + ValueNode currentCondition = condition; + replaceAndDelete(currentCondition); + tool.addToWorkList(currentCondition.usages()); } else { if (!isSubstitutionGraph()) { throw new GraalInternalError("Wrong usage of branch probability injection!");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public final class BytecodeExceptionNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { - public static final NodeClass<BytecodeExceptionNode> TYPE = NodeClass.get(BytecodeExceptionNode.class); + public static final NodeClass<BytecodeExceptionNode> TYPE = NodeClass.create(BytecodeExceptionNode.class); protected final Class<? extends Throwable> exceptionClass; @Input NodeInputList<ValueNode> arguments;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public final class ComputeAddressNode extends FloatingNode implements LIRLowerable { - public static final NodeClass<ComputeAddressNode> TYPE = NodeClass.get(ComputeAddressNode.class); + public static final NodeClass<ComputeAddressNode> TYPE = NodeClass.create(ComputeAddressNode.class); @Input ValueNode object; @Input(InputType.Association) ValueNode location;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo(nameTemplate = "Loc {p#locationIdentity/s}") public final class ConstantLocationNode extends LocationNode { - public static final NodeClass<ConstantLocationNode> TYPE = NodeClass.get(ConstantLocationNode.class); + public static final NodeClass<ConstantLocationNode> TYPE = NodeClass.create(ConstantLocationNode.class); protected final LocationIdentity locationIdentity; protected final long displacement;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ */ @NodeInfo public abstract class FixedAccessNode extends DeoptimizingFixedWithNextNode implements Access { - public static final NodeClass<FixedAccessNode> TYPE = NodeClass.get(FixedAccessNode.class); + public static final NodeClass<FixedAccessNode> TYPE = NodeClass.create(FixedAccessNode.class); @OptionalInput(InputType.Guard) protected GuardingNode guard; @Input protected ValueNode object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class FixedValueAnchorNode extends FixedWithNextNode implements LIRLowerable, ValueProxy { - public static final NodeClass<FixedValueAnchorNode> TYPE = NodeClass.get(FixedValueAnchorNode.class); + public static final NodeClass<FixedValueAnchorNode> TYPE = NodeClass.create(FixedValueAnchorNode.class); @Input ValueNode object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ */ @NodeInfo public abstract class FloatableAccessNode extends FixedAccessNode { - public static final NodeClass<FloatableAccessNode> TYPE = NodeClass.get(FloatableAccessNode.class); + public static final NodeClass<FloatableAccessNode> TYPE = NodeClass.create(FloatableAccessNode.class); protected FloatableAccessNode(NodeClass<? extends FloatableAccessNode> c, ValueNode object, ValueNode location, Stamp stamp) { super(c, object, location, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public abstract class FloatingAccessNode extends FloatingGuardedNode implements Access, MemoryAccess { - public static final NodeClass<FloatingAccessNode> TYPE = NodeClass.get(FloatingAccessNode.class); + public static final NodeClass<FloatingAccessNode> TYPE = NodeClass.create(FloatingAccessNode.class); @Input ValueNode object; @Input(InputType.Association) LocationNode location;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ */ @NodeInfo public final class FloatingReadNode extends FloatingAccessNode implements LIRLowerable, Canonicalizable { - public static final NodeClass<FloatingReadNode> TYPE = NodeClass.get(FloatingReadNode.class); + public static final NodeClass<FloatingReadNode> TYPE = NodeClass.create(FloatingReadNode.class); @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ */ @NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}", allowedUsageTypes = {InputType.Memory}) public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode.DeoptDuring, MemoryCheckpoint.Multi { - public static final NodeClass<ForeignCallNode> TYPE = NodeClass.get(ForeignCallNode.class); + public static final NodeClass<ForeignCallNode> TYPE = NodeClass.create(ForeignCallNode.class); @Input protected NodeInputList<ValueNode> arguments; @OptionalInput(InputType.State) protected FrameState stateDuring;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo(nameTemplate = "IdxLoc {p#locationIdentity/s}") public final class IndexedLocationNode extends LocationNode implements Canonicalizable { - public static final NodeClass<IndexedLocationNode> TYPE = NodeClass.get(IndexedLocationNode.class); + public static final NodeClass<IndexedLocationNode> TYPE = NodeClass.create(IndexedLocationNode.class); protected final LocationIdentity locationIdentity; protected final long displacement;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo public final class IntegerSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable { - public static final NodeClass<IntegerSwitchNode> TYPE = NodeClass.get(IntegerSwitchNode.class); + public static final NodeClass<IntegerSwitchNode> TYPE = NodeClass.create(IntegerSwitchNode.class); protected final int[] keys;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class JavaReadNode extends FixedAccessNode implements Lowerable, GuardingNode, Canonicalizable { - public static final NodeClass<JavaReadNode> TYPE = NodeClass.get(JavaReadNode.class); + public static final NodeClass<JavaReadNode> TYPE = NodeClass.create(JavaReadNode.class); protected final Kind readKind; protected final boolean compressible;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class JavaWriteNode extends AbstractWriteNode implements Lowerable, StateSplit, MemoryAccess, MemoryCheckpoint.Single { - public static final NodeClass<JavaWriteNode> TYPE = NodeClass.get(JavaWriteNode.class); + public static final NodeClass<JavaWriteNode> TYPE = NodeClass.create(JavaWriteNode.class); protected final Kind writeKind; protected final boolean compressible;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public final class LoadHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, Virtualizable { - public static final NodeClass<LoadHubNode> TYPE = NodeClass.get(LoadHubNode.class); + public static final NodeClass<LoadHubNode> TYPE = NodeClass.create(LoadHubNode.class); @Input ValueNode value; public ValueNode getValue() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class LoadMethodNode extends FixedWithNextNode implements Lowerable, Canonicalizable { - public static final NodeClass<LoadMethodNode> TYPE = NodeClass.get(LoadMethodNode.class); + public static final NodeClass<LoadMethodNode> TYPE = NodeClass.create(LoadMethodNode.class); @Input ValueNode hub; protected final ResolvedJavaMethod method; protected final ResolvedJavaType receiverType;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Association}) public abstract class LocationNode extends FloatingNode implements LIRLowerable, ValueNumberable { - public static final NodeClass<LocationNode> TYPE = NodeClass.get(LocationNode.class); + public static final NodeClass<LocationNode> TYPE = NodeClass.create(LocationNode.class); /** * Marker interface for locations in snippets.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class MembarNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { - public static final NodeClass<MembarNode> TYPE = NodeClass.get(MembarNode.class); + public static final NodeClass<MembarNode> TYPE = NodeClass.create(MembarNode.class); protected final int barriers; public MembarNode(int barriers) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,14 +32,10 @@ LocationIdentity getLocationIdentity(); - default MemoryNode getLastLocationAccess() { - return null; - } + MemoryNode getLastLocationAccess(); /** * @param lla the {@link MemoryNode} that represents the last kill of the location */ - default void setLastLocationAccess(MemoryNode lla) { - // empty - } + void setLastLocationAccess(MemoryNode lla); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Guard}) public final class NullCheckNode extends DeoptimizingFixedWithNextNode implements LIRLowerable, GuardingNode { - public static final NodeClass<NullCheckNode> TYPE = NodeClass.get(NullCheckNode.class); + public static final NodeClass<NullCheckNode> TYPE = NodeClass.create(NullCheckNode.class); @Input ValueNode object; public NullCheckNode(ValueNode object) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo(nameTemplate = "OSRLocal({p#index})") public final class OSRLocalNode extends AbstractLocalNode implements IterableNodeType { - public static final NodeClass<OSRLocalNode> TYPE = NodeClass.get(OSRLocalNode.class); + public static final NodeClass<OSRLocalNode> TYPE = NodeClass.create(OSRLocalNode.class); public OSRLocalNode(int index, Stamp stamp) { super(TYPE, index, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class OSRStartNode extends StartNode implements Lowerable { - public static final NodeClass<OSRStartNode> TYPE = NodeClass.get(OSRStartNode.class); + public static final NodeClass<OSRStartNode> TYPE = NodeClass.create(OSRStartNode.class); public OSRStartNode() { super(TYPE);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class ReadNode extends FloatableAccessNode implements LIRLowerable, Canonicalizable, PiPushable, Virtualizable, GuardingNode { - public static final NodeClass<ReadNode> TYPE = NodeClass.get(ReadNode.class); + public static final NodeClass<ReadNode> TYPE = NodeClass.create(ReadNode.class); public ReadNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) { super(TYPE, object, location, stamp, null, barrierType);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class StoreHubNode extends FixedWithNextNode implements Lowerable { - public static final NodeClass<StoreHubNode> TYPE = NodeClass.get(StoreHubNode.class); + public static final NodeClass<StoreHubNode> TYPE = NodeClass.create(StoreHubNode.class); @Input ValueNode value; @Input ValueNode object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public abstract class SwitchNode extends ControlSplitNode { - public static final NodeClass<SwitchNode> TYPE = NodeClass.get(SwitchNode.class); + public static final NodeClass<SwitchNode> TYPE = NodeClass.create(SwitchNode.class); @Successor protected NodeSuccessorList<AbstractBeginNode> successors; @Input protected ValueNode value; @@ -159,4 +159,9 @@ } return successors.get(defaultSuccessorIndex()); } + + @Override + public AbstractBeginNode getPrimarySuccessor() { + return this.defaultSuccessor(); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public final class UnboxNode extends UnaryNode implements Virtualizable, Lowerable { - public static final NodeClass<UnboxNode> TYPE = NodeClass.get(UnboxNode.class); + public static final NodeClass<UnboxNode> TYPE = NodeClass.create(UnboxNode.class); protected final Kind boxingKind; protected UnboxNode(ValueNode value, Kind boxingKind) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public abstract class UnsafeAccessNode extends FixedWithNextNode implements Canonicalizable { - public static final NodeClass<UnsafeAccessNode> TYPE = NodeClass.get(UnsafeAccessNode.class); + public static final NodeClass<UnsafeAccessNode> TYPE = NodeClass.create(UnsafeAccessNode.class); @Input ValueNode object; @Input ValueNode offset; protected final Kind accessKind;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo public final class UnsafeCastNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, GuardingNode, IterableNodeType, Canonicalizable, ValueProxy { - public static final NodeClass<UnsafeCastNode> TYPE = NodeClass.get(UnsafeCastNode.class); + public static final NodeClass<UnsafeCastNode> TYPE = NodeClass.create(UnsafeCastNode.class); @Input ValueNode object; public UnsafeCastNode(ValueNode object, Stamp stamp) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ */ @NodeInfo public final class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable { - public static final NodeClass<UnsafeLoadNode> TYPE = NodeClass.get(UnsafeLoadNode.class); + public static final NodeClass<UnsafeLoadNode> TYPE = NodeClass.create(UnsafeLoadNode.class); @OptionalInput(InputType.Condition) LogicNode guardingCondition; public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class UnsafeStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, MemoryCheckpoint.Single { - public static final NodeClass<UnsafeStoreNode> TYPE = NodeClass.get(UnsafeStoreNode.class); + public static final NodeClass<UnsafeStoreNode> TYPE = NodeClass.create(UnsafeStoreNode.class); @Input ValueNode value; @OptionalInput(InputType.State) FrameState stateAfter;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Anchor, InputType.Guard}) public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable, AnchoringNode, GuardingNode { - public static final NodeClass<ValueAnchorNode> TYPE = NodeClass.get(ValueAnchorNode.class); + public static final NodeClass<ValueAnchorNode> TYPE = NodeClass.create(ValueAnchorNode.class); @OptionalInput(InputType.Guard) ValueNode anchored; public ValueAnchorNode(ValueNode value) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class WriteNode extends AbstractWriteNode implements LIRLowerable, Simplifiable, Virtualizable { - public static final NodeClass<WriteNode> TYPE = NodeClass.get(WriteNode.class); + public static final NodeClass<WriteNode> TYPE = NodeClass.create(WriteNode.class); public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType) { super(TYPE, object, value, location, barrierType);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public abstract class AbstractNewArrayNode extends AbstractNewObjectNode implements ArrayLengthProvider { - public static final NodeClass<AbstractNewArrayNode> TYPE = NodeClass.get(AbstractNewArrayNode.class); + public static final NodeClass<AbstractNewArrayNode> TYPE = NodeClass.create(AbstractNewArrayNode.class); @Input protected ValueNode length; @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public abstract class AbstractNewObjectNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable { - public static final NodeClass<AbstractNewObjectNode> TYPE = NodeClass.get(AbstractNewObjectNode.class); + public static final NodeClass<AbstractNewObjectNode> TYPE = NodeClass.create(AbstractNewObjectNode.class); protected final boolean fillContents; public AbstractNewObjectNode(NodeClass<? extends AbstractNewObjectNode> c, Stamp stamp, boolean fillContents) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public abstract class AccessArrayNode extends FixedWithNextNode { - public static final NodeClass<AccessArrayNode> TYPE = NodeClass.get(AccessArrayNode.class); + public static final NodeClass<AccessArrayNode> TYPE = NodeClass.create(AccessArrayNode.class); @Input protected ValueNode array; public ValueNode array() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public abstract class AccessFieldNode extends FixedWithNextNode implements Lowerable { - public static final NodeClass<AccessFieldNode> TYPE = NodeClass.get(AccessFieldNode.class); + public static final NodeClass<AccessFieldNode> TYPE = NodeClass.create(AccessFieldNode.class); @OptionalInput ValueNode object; protected final ResolvedJavaField field;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public abstract class AccessIndexedNode extends AccessArrayNode implements Lowerable { - public static final NodeClass<AccessIndexedNode> TYPE = NodeClass.get(AccessIndexedNode.class); + public static final NodeClass<AccessIndexedNode> TYPE = NodeClass.create(AccessIndexedNode.class); @Input protected ValueNode index; protected final Kind elementKind;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode.DeoptBefore, DeoptimizingNode.DeoptAfter { - public static final NodeClass<AccessMonitorNode> TYPE = NodeClass.get(AccessMonitorNode.class); + public static final NodeClass<AccessMonitorNode> TYPE = NodeClass.create(AccessMonitorNode.class); @OptionalInput(InputType.State) FrameState stateBefore; @Input ValueNode object; @Input(InputType.Association) MonitorIdNode monitorId;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class ArrayLengthNode extends FixedWithNextNode implements Canonicalizable.Unary<ValueNode>, Lowerable, Virtualizable { - public static final NodeClass<ArrayLengthNode> TYPE = NodeClass.get(ArrayLengthNode.class); + public static final NodeClass<ArrayLengthNode> TYPE = NodeClass.create(ArrayLengthNode.class); @Input ValueNode array; public ValueNode array() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class AtomicReadAndAddNode extends AbstractMemoryCheckpoint implements LIRLowerable, MemoryCheckpoint.Single { - public static final NodeClass<AtomicReadAndAddNode> TYPE = NodeClass.get(AtomicReadAndAddNode.class); + public static final NodeClass<AtomicReadAndAddNode> TYPE = NodeClass.create(AtomicReadAndAddNode.class); @Input ValueNode object; @Input ValueNode offset; @Input ValueNode delta;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndWriteNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndWriteNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo public final class AtomicReadAndWriteNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { - public static final NodeClass<AtomicReadAndWriteNode> TYPE = NodeClass.get(AtomicReadAndWriteNode.class); + public static final NodeClass<AtomicReadAndWriteNode> TYPE = NodeClass.create(AtomicReadAndWriteNode.class); @Input ValueNode object; @Input ValueNode offset; @Input ValueNode newValue;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class CheckCastDynamicNode extends FixedWithNextNode implements Canonicalizable.Binary<ValueNode>, Lowerable { - public static final NodeClass<CheckCastDynamicNode> TYPE = NodeClass.get(CheckCastDynamicNode.class); + public static final NodeClass<CheckCastDynamicNode> TYPE = NodeClass.create(CheckCastDynamicNode.class); @Input ValueNode object; @Input ValueNode hub;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -44,7 +43,7 @@ @NodeInfo public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Simplifiable, Lowerable, Virtualizable, ValueProxy { - public static final NodeClass<CheckCastNode> TYPE = NodeClass.get(CheckCastNode.class); + public static final NodeClass<CheckCastNode> TYPE = NodeClass.create(CheckCastNode.class); @Input protected ValueNode object; protected final ResolvedJavaType type; protected final JavaTypeProfile profile; @@ -239,4 +238,17 @@ public ValueNode getOriginalNode() { return object; } + + public TriState tryFold(Stamp testStamp) { + if (testStamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) testStamp; + ResolvedJavaType objectType = objectStamp.type(); + if (objectType != null && type.isAssignableFrom(objectType)) { + return TriState.TRUE; + } else if (objectStamp.alwaysNull()) { + return TriState.TRUE; + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ClassIsAssignableFromNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ClassIsAssignableFromNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public final class ClassIsAssignableFromNode extends LogicNode implements Canonicalizable.Binary<ValueNode>, Lowerable { - public static final NodeClass<ClassIsAssignableFromNode> TYPE = NodeClass.get(ClassIsAssignableFromNode.class); + public static final NodeClass<ClassIsAssignableFromNode> TYPE = NodeClass.create(ClassIsAssignableFromNode.class); @Input ValueNode thisClass; @Input ValueNode otherClass;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class CompareAndSwapNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { - public static final NodeClass<CompareAndSwapNode> TYPE = NodeClass.get(CompareAndSwapNode.class); + public static final NodeClass<CompareAndSwapNode> TYPE = NodeClass.create(CompareAndSwapNode.class); @Input ValueNode object; @Input ValueNode offset; @Input ValueNode expected;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo public class DynamicNewArrayNode extends AbstractNewArrayNode { - public static final NodeClass<DynamicNewArrayNode> TYPE = NodeClass.get(DynamicNewArrayNode.class); + public static final NodeClass<DynamicNewArrayNode> TYPE = NodeClass.create(DynamicNewArrayNode.class); @Input ValueNode elementType;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class DynamicNewInstanceNode extends AbstractNewObjectNode implements Canonicalizable { - public static final NodeClass<DynamicNewInstanceNode> TYPE = NodeClass.get(DynamicNewInstanceNode.class); + public static final NodeClass<DynamicNewInstanceNode> TYPE = NodeClass.create(DynamicNewInstanceNode.class); @Input ValueNode clazz;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ */ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class ExceptionObjectNode extends DispatchBeginNode implements Lowerable, MemoryCheckpoint.Single { - public static final NodeClass<ExceptionObjectNode> TYPE = NodeClass.get(ExceptionObjectNode.class); + public static final NodeClass<ExceptionObjectNode> TYPE = NodeClass.create(ExceptionObjectNode.class); public ExceptionObjectNode(MetaAccessProvider metaAccess) { super(TYPE, StampFactory.declaredNonNull(metaAccess.lookupJavaType(Throwable.class)));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ */ @NodeInfo public class InstanceOfDynamicNode extends LogicNode implements Canonicalizable.Binary<ValueNode>, Lowerable { - public static final NodeClass<InstanceOfDynamicNode> TYPE = NodeClass.get(InstanceOfDynamicNode.class); + public static final NodeClass<InstanceOfDynamicNode> TYPE = NodeClass.create(InstanceOfDynamicNode.class); @Input ValueNode object; @Input ValueNode mirror;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ */ @NodeInfo public final class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable { - public static final NodeClass<InstanceOfNode> TYPE = NodeClass.get(InstanceOfNode.class); + public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class); protected final ResolvedJavaType type; protected JavaTypeProfile profile; @@ -160,4 +160,43 @@ tool.replaceWithValue(LogicConstantNode.forBoolean(type().isAssignableFrom(state.getVirtualObject().type()), graph())); } } + + @Override + public Stamp getSucceedingStampForValue(boolean negated) { + if (negated) { + return null; + } else { + return StampFactory.declaredTrustedNonNull(type); + } + } + + @Override + public TriState tryFold(Stamp valueStamp) { + if (valueStamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) valueStamp; + if (objectStamp.alwaysNull()) { + return TriState.FALSE; + } + + ResolvedJavaType objectType = objectStamp.type(); + if (objectType != null) { + ResolvedJavaType instanceofType = type; + if (instanceofType.isAssignableFrom(objectType)) { + if (objectStamp.nonNull()) { + return TriState.TRUE; + } + } else { + if (objectStamp.isExactType()) { + return TriState.FALSE; + } else { + boolean superType = objectType.isAssignableFrom(instanceofType); + if (!superType && !objectType.isInterface() && !instanceofType.isInterface()) { + return TriState.FALSE; + } + } + } + } + } + return TriState.UNKNOWN; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class LoadExceptionObjectNode extends AbstractStateSplit implements Lowerable { - public static final NodeClass<LoadExceptionObjectNode> TYPE = NodeClass.get(LoadExceptionObjectNode.class); + public static final NodeClass<LoadExceptionObjectNode> TYPE = NodeClass.create(LoadExceptionObjectNode.class); public LoadExceptionObjectNode(Stamp stamp) { super(TYPE, stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ @NodeInfo(nameTemplate = "LoadField#{p#field/s}") public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable.Unary<ValueNode>, VirtualizableRoot, UncheckedInterfaceProvider { - public static final NodeClass<LoadFieldNode> TYPE = NodeClass.get(LoadFieldNode.class); + public static final NodeClass<LoadFieldNode> TYPE = NodeClass.create(LoadFieldNode.class); public LoadFieldNode(ValueNode object, ResolvedJavaField field) { super(TYPE, createStamp(field), object, field);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo public class LoadIndexedNode extends AccessIndexedNode implements Virtualizable, Canonicalizable { - public static final NodeClass<LoadIndexedNode> TYPE = NodeClass.get(LoadIndexedNode.class); + public static final NodeClass<LoadIndexedNode> TYPE = NodeClass.create(LoadIndexedNode.class); /** * Creates a new LoadIndexedNode.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class LoweredAtomicReadAndWriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single { - public static final NodeClass<LoweredAtomicReadAndWriteNode> TYPE = NodeClass.get(LoweredAtomicReadAndWriteNode.class); + public static final NodeClass<LoweredAtomicReadAndWriteNode> TYPE = NodeClass.create(LoweredAtomicReadAndWriteNode.class); @Input ValueNode newValue; @OptionalInput(InputType.State) FrameState stateAfter;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Value, InputType.Memory}) public final class LoweredCompareAndSwapNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single { - public static final NodeClass<LoweredCompareAndSwapNode> TYPE = NodeClass.get(LoweredCompareAndSwapNode.class); + public static final NodeClass<LoweredCompareAndSwapNode> TYPE = NodeClass.create(LoweredCompareAndSwapNode.class); @Input ValueNode expectedValue; @Input ValueNode newValue; @OptionalInput(InputType.State) FrameState stateAfter;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Simplifiable { - public static final NodeClass<MethodCallTargetNode> TYPE = NodeClass.get(MethodCallTargetNode.class); + public static final NodeClass<MethodCallTargetNode> TYPE = NodeClass.create(MethodCallTargetNode.class); protected final JavaType returnType; public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) { @@ -190,7 +190,6 @@ if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) { ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true); if (singleImplementorMethod != null) { - assert graph().getGuardsStage().allowsFloatingGuards() : "Graph already fixed!"; /** * We have an invoke on an interface with a single implementor. We can replace this * with an invoke virtual. @@ -203,9 +202,8 @@ * properties by checking of the receiver is an instance of the single implementor. */ LogicNode condition = graph().unique(new InstanceOfNode(singleImplementor, receiver, getProfile())); - GuardNode guard = graph().unique( - new GuardNode(condition, AbstractBeginNode.prevBegin(invoke().asNode()), DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, - false, JavaConstant.NULL_POINTER)); + FixedGuardNode guard = graph().add(new FixedGuardNode(condition, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, false)); + graph().addBeforeFixed(invoke().asNode(), guard); PiNode piNode = graph().unique(new PiNode(receiver, StampFactory.declaredNonNull(singleImplementor), guard)); arguments().set(0, piNode); setInvokeKind(InvokeKind.Virtual);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorEnter, MemoryCheckpoint.Single { - public static final NodeClass<MonitorEnterNode> TYPE = NodeClass.get(MonitorEnterNode.class); + public static final NodeClass<MonitorEnterNode> TYPE = NodeClass.create(MonitorEnterNode.class); public MonitorEnterNode(ValueNode object, MonitorIdNode monitorId) { super(TYPE, object, monitorId);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Simplifiable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single { - public static final NodeClass<MonitorExitNode> TYPE = NodeClass.get(MonitorExitNode.class); + public static final NodeClass<MonitorExitNode> TYPE = NodeClass.create(MonitorExitNode.class); @OptionalInput ValueNode escapedReturnValue; public MonitorExitNode(ValueNode object, MonitorIdNode monitorId, ValueNode escapedReturnValue) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Association}) public class MonitorIdNode extends ValueNode implements IterableNodeType, LIRLowerable { - public static final NodeClass<MonitorIdNode> TYPE = NodeClass.get(MonitorIdNode.class); + public static final NodeClass<MonitorIdNode> TYPE = NodeClass.create(MonitorIdNode.class); protected int lockDepth; public MonitorIdNode(int lockDepth) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public class NewArrayNode extends AbstractNewArrayNode implements VirtualizableAllocation { - public static final NodeClass<NewArrayNode> TYPE = NodeClass.get(NewArrayNode.class); + public static final NodeClass<NewArrayNode> TYPE = NodeClass.create(NewArrayNode.class); public NewArrayNode(ResolvedJavaType elementType, ValueNode length, boolean fillContents) { super(TYPE, StampFactory.exactNonNull(elementType.getArrayClass()), length, fillContents);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo(nameTemplate = "New {p#instanceClass/s}") public final class NewInstanceNode extends AbstractNewObjectNode implements VirtualizableAllocation { - public static final NodeClass<NewInstanceNode> TYPE = NodeClass.get(NewInstanceNode.class); + public static final NodeClass<NewInstanceNode> TYPE = NodeClass.create(NewInstanceNode.class); protected final ResolvedJavaType instanceClass; public NewInstanceNode(ResolvedJavaType type, boolean fillContents) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable, ArrayLengthProvider { - public static final NodeClass<NewMultiArrayNode> TYPE = NodeClass.get(NewMultiArrayNode.class); + public static final NodeClass<NewMultiArrayNode> TYPE = NodeClass.create(NewMultiArrayNode.class); @Input protected NodeInputList<ValueNode> dimensions; protected final ResolvedJavaType type;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable.Unary<ValueNode>, LIRLowerable, Virtualizable, DeoptimizingNode.DeoptAfter { - public static final NodeClass<RegisterFinalizerNode> TYPE = NodeClass.get(RegisterFinalizerNode.class); + public static final NodeClass<RegisterFinalizerNode> TYPE = NodeClass.create(RegisterFinalizerNode.class); @OptionalInput(InputType.State) FrameState deoptState; @Input ValueNode value;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class SelfReplacingMethodCallTargetNode extends MethodCallTargetNode implements Lowerable { - public static final NodeClass<SelfReplacingMethodCallTargetNode> TYPE = NodeClass.get(SelfReplacingMethodCallTargetNode.class); + public static final NodeClass<SelfReplacingMethodCallTargetNode> TYPE = NodeClass.create(SelfReplacingMethodCallTargetNode.class); // Replacement method data protected final ResolvedJavaMethod replacementTargetMethod; protected final JavaType replacementReturnType;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ */ @NodeInfo(nameTemplate = "StoreField#{p#field/s}") public final class StoreFieldNode extends AccessFieldNode implements StateSplit, VirtualizableRoot { - public static final NodeClass<StoreFieldNode> TYPE = NodeClass.get(StoreFieldNode.class); + public static final NodeClass<StoreFieldNode> TYPE = NodeClass.create(StoreFieldNode.class); @Input ValueNode value; @OptionalInput(InputType.State) FrameState stateAfter;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable, Virtualizable { - public static final NodeClass<StoreIndexedNode> TYPE = NodeClass.get(StoreIndexedNode.class); + public static final NodeClass<StoreIndexedNode> TYPE = NodeClass.create(StoreIndexedNode.class); @Input ValueNode value; @OptionalInput(InputType.State) FrameState stateAfter;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,7 @@ @NodeInfo public final class TypeSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable { - public static final NodeClass<TypeSwitchNode> TYPE = NodeClass.get(TypeSwitchNode.class); + public static final NodeClass<TypeSwitchNode> TYPE = NodeClass.create(TypeSwitchNode.class); protected final ResolvedJavaType[] keys; public TypeSwitchNode(ValueNode value, AbstractBeginNode[] successors, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/PiPushable.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/PiPushable.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ public interface PiPushable { /** - * + * * @param parent PiNode * @return true if node was moved */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Tue Mar 10 21:26:02 2015 +0100 @@ -60,7 +60,7 @@ * tool, and not directly on the node, because by the time this method is called the * virtualized/non-virtualized state is still speculative and might not hold because of loops, * etc. - * + * * @param tool the tool used to describe the effects of this node */ void virtualize(VirtualizerTool tool);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizableAllocation.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizableAllocation.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,7 +25,7 @@ /** * This interface allows a node to convey information about what its effect would be if some of its * inputs were virtualized. - * + * * The difference to {@link VirtualizableRoot} is that removing {@link VirtualizableAllocation} * nodes is not considered progress during the escape analysis iterations. */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizableRoot.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizableRoot.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,12 +25,12 @@ /** * This interface allows a node to convey information about what its effect would be if some of its * inputs were virtualized. - * + * * The difference to {@link Virtualizable} is that the {@link #virtualize(VirtualizerTool)} method * will be called regardless of whether this node had any interaction with virtualized nodes. This * interface can therefore be used for object allocations, for which virtualization introduces new * virtualized objects. - * + * */ public interface VirtualizableRoot extends Virtualizable {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,15 +24,14 @@ import java.util.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.virtual.*; public class GraphUtil { @@ -40,7 +39,7 @@ @Override public final boolean apply(Node n) { - return n instanceof FloatingNode || n instanceof VirtualState || n instanceof CallTargetNode || n instanceof VirtualObjectNode; + return !(n instanceof FixedNode); } }; @@ -50,7 +49,7 @@ // We reached a control flow end. AbstractEndNode end = (AbstractEndNode) node; killEnd(end, tool); - } else { + } else if (node instanceof FixedNode) { // Normal control flow node. /* * We do not take a successor snapshot because this iterator supports concurrent @@ -62,6 +61,7 @@ killCFG(successor, tool); } } + node.replaceAtPredecessor(null); propagateKill(node); } @@ -112,21 +112,36 @@ return FLOATING; } - public static void propagateKill(Node node) { + private static void propagateKill(Node node) { if (node != null && node.isAlive()) { - List<Node> usagesSnapshot = node.usages().filter(isFloatingNode()).snapshot(); + node.markDeleted(); + + node.acceptInputs((n, in) -> { + if (in.isAlive()) { + in.removeUsage(n); + if (in.hasNoUsages() && !(in instanceof FixedNode)) { + killWithUnusedFloatingInputs(in); + } + } + }); - // null out remaining usages - node.replaceAtUsages(null); - node.replaceAtPredecessor(null); - killWithUnusedFloatingInputs(node); - - for (Node usage : usagesSnapshot) { - if (!usage.isDeleted()) { - if (usage instanceof PhiNode) { - usage.replaceFirstInput(node, null); - } else { - propagateKill(usage); + ArrayList<Node> usageToKill = null; + for (Node usage : node.usages()) { + if (usage.isAlive() && !(usage instanceof FixedNode)) { + if (usageToKill == null) { + usageToKill = new ArrayList<>(); + } + usageToKill.add(usage); + } + } + if (usageToKill != null) { + for (Node usage : usageToKill) { + if (usage.isAlive()) { + if (usage instanceof PhiNode) { + usage.replaceFirstInput(node, null); + } else { + propagateKill(usage); + } } } } @@ -134,11 +149,9 @@ } public static void killWithUnusedFloatingInputs(Node node) { - List<Node> floatingInputs = node.inputs().filter(isFloatingNode()).snapshot(); node.safeDelete(); - - for (Node in : floatingInputs) { - if (in.isAlive() && in.hasNoUsages()) { + for (Node in : node.inputs()) { + if (in.isAlive() && in.hasNoUsages() && !(in instanceof FixedNode)) { killWithUnusedFloatingInputs(in); } } @@ -241,13 +254,7 @@ if (n instanceof StateSplit) { FrameState state = ((StateSplit) n).stateAfter(); - while (state != null) { - ResolvedJavaMethod method = state.method(); - if (method != null) { - elements.add(method.asStackTraceElement(state.bci - 1)); - } - state = state.outerFrameState(); - } + elements.addAll(Arrays.asList(approxSourceStackTraceElement(state))); break; } n = n.predecessor(); @@ -256,22 +263,42 @@ } /** + * Gets an approximate source code location for frame state. + * + * @return the StackTraceElements if an approximate source location is found, null otherwise + */ + public static StackTraceElement[] approxSourceStackTraceElement(FrameState frameState) { + ArrayList<StackTraceElement> elements = new ArrayList<>(); + FrameState state = frameState; + while (state != null) { + ResolvedJavaMethod method = state.method(); + if (method != null) { + elements.add(method.asStackTraceElement(state.bci - 1)); + } + state = state.outerFrameState(); + } + return elements.toArray(new StackTraceElement[0]); + } + + /** * Gets an approximate source code location for a node, encoded as an exception, if possible. * * @return the exception with the location */ public static RuntimeException approxSourceException(Node node, Throwable cause) { final StackTraceElement[] elements = approxSourceStackTraceElement(node); - @SuppressWarnings("serial") - RuntimeException exception = new RuntimeException((cause == null) ? null : cause.getMessage(), cause) { + return createBailoutException(cause == null ? "" : cause.getMessage(), cause, elements); + } - @Override - public final synchronized Throwable fillInStackTrace() { - setStackTrace(elements); - return this; - } - }; - return exception; + /** + * Creates a bailout exception with the given stack trace elements and message. + * + * @param message the message of the exception + * @param elements the stack trace elements + * @return the exception + */ + public static BailoutException createBailoutException(String message, Throwable cause, StackTraceElement[] elements) { + return SourceStackTrace.create(cause, message, elements); } /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public final class AllocatedObjectNode extends FloatingNode implements Virtualizable, ArrayLengthProvider { - public static final NodeClass<AllocatedObjectNode> TYPE = NodeClass.get(AllocatedObjectNode.class); + public static final NodeClass<AllocatedObjectNode> TYPE = NodeClass.create(AllocatedObjectNode.class); @Input VirtualObjectNode virtualObject; @Input(InputType.Extension) CommitAllocationNode commit;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo(nameTemplate = "Alloc {i#virtualObjects}", allowedUsageTypes = {InputType.Extension}) public final class CommitAllocationNode extends FixedWithNextNode implements VirtualizableAllocation, Lowerable, Simplifiable { - public static final NodeClass<CommitAllocationNode> TYPE = NodeClass.get(CommitAllocationNode.class); + public static final NodeClass<CommitAllocationNode> TYPE = NodeClass.create(CommitAllocationNode.class); @Input NodeInputList<VirtualObjectNode> virtualObjects = new NodeInputList<>(this); @Input NodeInputList<ValueNode> values = new NodeInputList<>(this); @Input(InputType.Association) NodeInputList<MonitorIdNode> locks = new NodeInputList<>(this);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,7 @@ @NodeInfo public abstract class EscapeObjectState extends VirtualState implements ValueNumberable { - public static final NodeClass<EscapeObjectState> TYPE = NodeClass.get(EscapeObjectState.class); + public static final NodeClass<EscapeObjectState> TYPE = NodeClass.create(EscapeObjectState.class); @Input protected VirtualObjectNode object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo(nameTemplate = "VirtualArray {p#componentType/s}[{p#length}]") public final class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider { - public static final NodeClass<VirtualArrayNode> TYPE = NodeClass.get(VirtualArrayNode.class); + public static final NodeClass<VirtualArrayNode> TYPE = NodeClass.create(VirtualArrayNode.class); protected final ResolvedJavaType componentType; protected final int length;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class VirtualBoxingNode extends VirtualInstanceNode { - public static final NodeClass<VirtualBoxingNode> TYPE = NodeClass.get(VirtualBoxingNode.class); + public static final NodeClass<VirtualBoxingNode> TYPE = NodeClass.create(VirtualBoxingNode.class); protected final Kind boxingKind; public VirtualBoxingNode(ResolvedJavaType type, Kind boxingKind) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo(nameTemplate = "VirtualInstance {p#type/s}") public class VirtualInstanceNode extends VirtualObjectNode { - public static final NodeClass<VirtualInstanceNode> TYPE = NodeClass.get(VirtualInstanceNode.class); + public static final NodeClass<VirtualInstanceNode> TYPE = NodeClass.create(VirtualInstanceNode.class); protected final ResolvedJavaType type; protected final ResolvedJavaField[] fields;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ @NodeInfo public abstract class VirtualObjectNode extends ValueNode implements LIRLowerable, IterableNodeType { - public static final NodeClass<VirtualObjectNode> TYPE = NodeClass.get(VirtualObjectNode.class); + public static final NodeClass<VirtualObjectNode> TYPE = NodeClass.create(VirtualObjectNode.class); protected boolean hasIdentity; protected VirtualObjectNode(NodeClass<? extends VirtualObjectNode> c, ResolvedJavaType type, boolean hasIdentity) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/NestedBooleanOptionValueTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 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.options.test; + +import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.*; +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.graal.options.*; +import com.oracle.graal.options.OptionValue.OverrideScope; + +public class NestedBooleanOptionValueTest { + + public static class Options { + public static final OptionValue<Boolean> Master0 = new OptionValue<>(true); + public static final OptionValue<Boolean> NestedOption0 = new NestedBooleanOptionValue(Master0, true); + public static final OptionValue<Boolean> Master1 = new OptionValue<>(true); + public static final OptionValue<Boolean> NestedOption1 = new NestedBooleanOptionValue(Master1, true); + public static final OptionValue<Boolean> Master2 = new OptionValue<>(true); + public static final OptionValue<Boolean> NestedOption2 = new NestedBooleanOptionValue(Master2, false); + } + + static final OptionDescriptor master0 = new OptionDescriptor("Master0", Boolean.class, "", Options.class, "Master0", Master0); + static final OptionDescriptor nestedOption0 = new OptionDescriptor("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0); + static final OptionDescriptor master1 = new OptionDescriptor("Master1", Boolean.class, "", Options.class, "Master1", Master1); + static final OptionDescriptor nestedOption1 = new OptionDescriptor("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1); + static final OptionDescriptor master2 = new OptionDescriptor("Master2", Boolean.class, "", Options.class, "Master2", Master2); + static final OptionDescriptor nestedOption2 = new OptionDescriptor("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2); + + @Test + public void runOverrides() { + assertTrue(Master0.getValue()); + assertTrue(NestedOption0.getValue()); + try (OverrideScope s1 = OptionValue.override(Master0, false)) { + assertFalse(Master0.getValue()); + assertFalse(NestedOption0.getValue()); + try (OverrideScope s2 = OptionValue.override(NestedOption0, false)) { + assertFalse(NestedOption0.getValue()); + } + try (OverrideScope s2 = OptionValue.override(NestedOption0, true)) { + assertTrue(NestedOption0.getValue()); + } + } + assertTrue(Master0.getValue()); + try (OverrideScope s1 = OptionValue.override(NestedOption0, false)) { + assertFalse(NestedOption0.getValue()); + } + try (OverrideScope s1 = OptionValue.override(NestedOption0, true)) { + assertTrue(NestedOption0.getValue()); + } + } + + @Test + public void runDefaultTrue() { + Master1.setValue(true); + assertTrue(Master1.getValue()); + assertTrue(NestedOption1.getValue()); + // nested value unset + Master1.setValue(false); + assertFalse(Master1.getValue()); + assertFalse(NestedOption1.getValue()); + // set false + Master1.setValue(false); + NestedOption1.setValue(false); + assertFalse(Master1.getValue()); + assertFalse(NestedOption1.getValue()); + Master1.setValue(true); + assertTrue(Master1.getValue()); + assertFalse(NestedOption1.getValue()); + // set true + Master1.setValue(false); + NestedOption1.setValue(true); + assertFalse(Master1.getValue()); + assertTrue(NestedOption1.getValue()); + Master1.setValue(true); + assertTrue(Master1.getValue()); + assertTrue(NestedOption1.getValue()); + } + + @Test + public void runDefaultFalse() { + Master2.setValue(true); + assertTrue(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + // nested value unset + Master2.setValue(false); + assertFalse(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + // set false + Master2.setValue(false); + NestedOption2.setValue(false); + assertFalse(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + Master2.setValue(true); + assertTrue(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + // set true + Master2.setValue(false); + NestedOption2.setValue(true); + assertFalse(Master2.getValue()); + assertTrue(NestedOption2.getValue()); + Master2.setValue(true); + assertTrue(Master2.getValue()); + assertTrue(NestedOption2.getValue()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/NestedBooleanOptionValue.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.options; + +/** + * A nested Boolean {@link OptionValue} that can be overridden by a {@link #masterOption master + * option}. + * <p> + * <li>If the option is present on the command line the specified value is used. + * <li>Otherwise {@link #getValue()} depends on the {@link #masterOption} and evaluates as follows: + * <ul> + * <li>If {@link #masterOption} is set, this value equals to {@link #initialValue}. + * <li>Otherwise, if {@link #masterOption} is {@code false}, this option is {@code false}. + */ +public class NestedBooleanOptionValue extends OptionValue<Boolean> { + private final OptionValue<Boolean> masterOption; + private final Boolean initialValue; + + public NestedBooleanOptionValue(OptionValue<Boolean> masterOption, Boolean initialValue) { + super(null); + this.masterOption = masterOption; + this.initialValue = initialValue; + } + + public OptionValue<Boolean> getMasterOption() { + return masterOption; + } + + @Override + public Boolean getValue() { + Boolean v = super.getValue(); + if (v == null) { + return initialValue && masterOption.getValue(); + } + return v; + } + +}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,6 +30,7 @@ import com.oracle.graal.graph.Graph.NodeEventListener; import com.oracle.graal.graph.Graph.NodeEventScope; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -48,7 +49,8 @@ private static final DebugMetric METRIC_SIMPLIFICATION_CONSIDERED_NODES = Debug.metric("SimplificationConsideredNodes"); private static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits"); - private final boolean canonicalizeReads; + private boolean canonicalizeReads = true; + private boolean simplify = true; private final CustomCanonicalizer customCanonicalizer; public abstract static class CustomCanonicalizer { @@ -62,22 +64,25 @@ } } - public CanonicalizerPhase(boolean canonicalizeReads) { - this(canonicalizeReads, null); + public CanonicalizerPhase() { + this(null); } - public CanonicalizerPhase(boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { - this.canonicalizeReads = canonicalizeReads; + public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer) { this.customCanonicalizer = customCanonicalizer; } - public boolean getCanonicalizeReads() { - return canonicalizeReads; + public void disableReadCanonicalization() { + canonicalizeReads = false; + } + + public void disableSimplification() { + simplify = false; } @Override protected void run(StructuredGraph graph, PhaseContext context) { - new Instance(context, canonicalizeReads, customCanonicalizer).run(graph); + new Instance(context).run(graph); } /** @@ -89,7 +94,7 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Mark newNodesMark, boolean dumpGraph) { - new Instance(context, canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, newNodesMark).apply(graph, dumpGraph); } /** @@ -101,7 +106,7 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> workingSet, boolean dumpGraph) { - new Instance(context, canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, workingSet).apply(graph, dumpGraph); } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> workingSet, Mark newNodesMark) { @@ -109,38 +114,34 @@ } public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> workingSet, Mark newNodesMark, boolean dumpGraph) { - new Instance(context, canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph); + new Instance(context, workingSet, newNodesMark).apply(graph, dumpGraph); } - private static final class Instance extends Phase { + private final class Instance extends Phase { private final Mark newNodesMark; private final PhaseContext context; - private final CustomCanonicalizer customCanonicalizer; private final Iterable<? extends Node> initWorkingSet; - private final boolean canonicalizeReads; private NodeWorkList workList; private Tool tool; - private Instance(PhaseContext context, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) { - this(context, canonicalizeReads, null, null, customCanonicalizer); + private Instance(PhaseContext context) { + this(context, null, null); } - private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<? extends Node> workingSet, CustomCanonicalizer customCanonicalizer) { - this(context, canonicalizeReads, workingSet, null, customCanonicalizer); + private Instance(PhaseContext context, Iterable<? extends Node> workingSet) { + this(context, workingSet, null); } - private Instance(PhaseContext context, boolean canonicalizeReads, Mark newNodesMark, CustomCanonicalizer customCanonicalizer) { - this(context, canonicalizeReads, null, newNodesMark, customCanonicalizer); + private Instance(PhaseContext context, Mark newNodesMark) { + this(context, null, newNodesMark); } - private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<? extends Node> workingSet, Mark newNodesMark, CustomCanonicalizer customCanonicalizer) { + private Instance(PhaseContext context, Iterable<? extends Node> workingSet, Mark newNodesMark) { super("Canonicalizer"); this.newNodesMark = newNodesMark; this.context = context; - this.canonicalizeReads = canonicalizeReads; - this.customCanonicalizer = customCanonicalizer; this.initWorkingSet = workingSet; } @@ -213,7 +214,7 @@ } } - public static boolean tryGlobalValueNumbering(Node node, NodeClass<?> nodeClass) { + public boolean tryGlobalValueNumbering(Node node, NodeClass<?> nodeClass) { if (nodeClass.valueNumberable() && !nodeClass.isLeafNode()) { Node newNode = node.graph().findDuplicate(node); if (newNode != null) { @@ -228,19 +229,7 @@ return false; } - public boolean tryCanonicalize(final Node node, NodeClass<?> nodeClass) { - if (customCanonicalizer != null) { - Node canonical = customCanonicalizer.canonicalize(node); - if (performReplacement(node, canonical)) { - return true; - } else { - customCanonicalizer.simplify(node, tool); - } - } - return baseTryCanonicalize(node, nodeClass); - } - - private static AutoCloseable getCanonicalizeableContractAssertion(Node node) { + private AutoCloseable getCanonicalizeableContractAssertion(Node node) { boolean needsAssertion = false; assert (needsAssertion = true) == true; if (needsAssertion) { @@ -254,13 +243,24 @@ } } - public boolean baseTryCanonicalize(final Node node, NodeClass<?> nodeClass) { + public boolean tryCanonicalize(final Node node, NodeClass<?> nodeClass) { + if (customCanonicalizer != null) { + Node canonical = customCanonicalizer.canonicalize(node); + if (performReplacement(node, canonical)) { + return true; + } else { + customCanonicalizer.simplify(node, tool); + } + } if (nodeClass.isCanonicalizable()) { METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); try (Scope s = Debug.scope("CanonicalizeNode", node)) { Node canonical; try (AutoCloseable verify = getCanonicalizeableContractAssertion(node)) { canonical = ((Canonicalizable) node).canonical(tool); + if (canonical == node && nodeClass.isCommutative()) { + canonical = ((BinaryCommutative<?>) node).maybeCommuteInputs(); + } } if (performReplacement(node, canonical)) { return true; @@ -270,7 +270,7 @@ } } - if (nodeClass.isSimplifiable()) { + if (nodeClass.isSimplifiable() && simplify) { Debug.log(3, "Canonicalizer: simplifying %s", node); METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment(); try (Scope s = Debug.scope("SimplifyNode", node)) { @@ -311,9 +311,6 @@ if (canonical != null && !canonical.isAlive()) { assert !canonical.isDeleted(); canonical = graph.addOrUniqueWithInputs(canonical); - if (canonical == node) { - graph.addOrUniqueWithInputs(newCanonical); - } } if (node instanceof FloatingNode) { if (canonical == null) { @@ -425,4 +422,8 @@ } } } + + public boolean getCanonicalizeReads() { + return canonicalizeReads; + } }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -778,6 +778,8 @@ ResolvedJavaType type = state.getNodeType(object); if (isNull || (type != null && checkCast.type().isAssignableFrom(type))) { boolean nonNull = state.isNonNull(object); + // if (true) + // throw new RuntimeException(checkCast.toString()); GuardingNode replacementAnchor = null; if (nonNull) { replacementAnchor = searchAnchor(GraphUtil.unproxify(object), type); @@ -785,6 +787,7 @@ if (replacementAnchor == null) { replacementAnchor = AbstractBeginNode.prevBegin(checkCast); } + assert !(replacementAnchor instanceof FloatingNode) : "unsafe to mix unlowered Checkcast with floating guards"; PiNode piNode; if (isNull) { ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.tiers.*; /** * This phase will find branches which always end with a {@link DeoptimizeNode} and replace their @@ -48,7 +49,7 @@ * {@link DeoptimizeNode} as close to the {@link ControlSplitNode} as possible. * */ -public class ConvertDeoptimizeToGuardPhase extends Phase { +public class ConvertDeoptimizeToGuardPhase extends BasePhase<PhaseContext> { private SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, false); private static AbstractBeginNode findBeginNode(FixedNode startNode) { @@ -56,7 +57,7 @@ } @Override - protected void run(final StructuredGraph graph) { + protected void run(final StructuredGraph graph, PhaseContext context) { assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies"; if (graph.getNodes(DeoptimizeNode.TYPE).isEmpty()) { return; @@ -66,46 +67,71 @@ visitDeoptBegin(AbstractBeginNode.prevBegin(d), d.action(), d.reason(), graph); } - for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.TYPE)) { - - AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard); - if (pred instanceof AbstractMergeNode) { - AbstractMergeNode merge = (AbstractMergeNode) pred; - if (fixedGuard.condition() instanceof CompareNode) { - CompareNode compare = (CompareNode) fixedGuard.condition(); - List<AbstractEndNode> mergePredecessors = merge.cfgPredecessors().snapshot(); - - Constant[] xs = IfNode.constantValues(compare.getX(), merge, true); - if (xs == null) { - continue; - } - Constant[] ys = IfNode.constantValues(compare.getY(), merge, true); - if (ys == null) { - continue; - } - for (int i = 0; i < mergePredecessors.size(); ++i) { - AbstractEndNode mergePredecessor = mergePredecessors.get(i); - if (!mergePredecessor.isAlive()) { - break; - } - if (xs[i] == null) { - continue; - } - if (ys[i] == null) { - continue; - } - if (xs[i] instanceof PrimitiveConstant && ys[i] instanceof PrimitiveConstant && - compare.condition().foldCondition(xs[i], ys[i], null, compare.unorderedIsTrue()) == fixedGuard.isNegated()) { - visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), graph); - } - } - } + if (context != null) { + for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.TYPE)) { + trySplitFixedGuard(fixedGuard, context); } } new DeadCodeEliminationPhase(Optional).apply(graph); } + private void trySplitFixedGuard(FixedGuardNode fixedGuard, PhaseContext context) { + LogicNode condition = fixedGuard.condition(); + if (condition instanceof CompareNode) { + CompareNode compare = (CompareNode) condition; + ValueNode x = compare.getX(); + ValuePhiNode xPhi = (x instanceof ValuePhiNode) ? (ValuePhiNode) x : null; + if (x instanceof ConstantNode || xPhi != null) { + ValueNode y = compare.getY(); + ValuePhiNode yPhi = (y instanceof ValuePhiNode) ? (ValuePhiNode) y : null; + if (y instanceof ConstantNode || yPhi != null) { + processFixedGuardAndPhis(fixedGuard, context, compare, x, xPhi, y, yPhi); + } + } + } + } + + private void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi) { + AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard); + if (pred instanceof AbstractMergeNode) { + AbstractMergeNode merge = (AbstractMergeNode) pred; + if (xPhi != null && xPhi.merge() != merge) { + return; + } + if (yPhi != null && yPhi.merge() != merge) { + return; + } + + processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge); + } + } + + private void processFixedGuardAndMerge(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, AbstractMergeNode merge) { + List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot(); + for (int i = 0; i < mergePredecessors.size(); ++i) { + AbstractEndNode mergePredecessor = mergePredecessors.get(i); + if (!mergePredecessor.isAlive()) { + break; + } + Constant xs; + if (xPhi == null) { + xs = x.asConstant(); + } else { + xs = xPhi.valueAt(mergePredecessor).asConstant(); + } + Constant ys; + if (yPhi == null) { + ys = y.asConstant(); + } else { + ys = yPhi.valueAt(mergePredecessor).asConstant(); + } + if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) { + visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), fixedGuard.graph()); + } + } + } + private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) { if (deoptBegin instanceof AbstractMergeNode) { AbstractMergeNode mergeNode = (AbstractMergeNode) deoptBegin;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,6 +24,8 @@ import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Options.*; +import java.util.function.*; + import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -70,93 +72,52 @@ if (optional && ReduceDCE.getValue()) { return; } + NodeFlood flood = graph.createNodeFlood(); - + int totalNodeCount = graph.getNodeCount(); flood.add(graph.start()); - iterateSuccessors(flood); - disconnectCFGNodes(flood, graph); - iterateInputs(flood, graph); + iterateSuccessorsAndInputs(flood); + int totalMarkedCount = flood.getTotalMarkedCount(); + if (totalNodeCount == totalMarkedCount) { + // All nodes are live => nothing more to do. + return; + } else { + // Some nodes are not marked alive and therefore dead => proceed. + assert totalNodeCount > totalMarkedCount; + } + deleteNodes(flood, graph); - - // remove chained Merges - for (AbstractMergeNode merge : graph.getNodes(AbstractMergeNode.TYPE)) { - if (merge.forwardEndCount() == 1 && !(merge instanceof LoopBeginNode)) { - graph.reduceTrivialMerge(merge); - } - } } - private static void iterateSuccessors(NodeFlood flood) { + private static void iterateSuccessorsAndInputs(NodeFlood flood) { + BiConsumer<Node, Node> consumer = (n, succOrInput) -> { + assert succOrInput.isAlive() : succOrInput; + flood.add(succOrInput); + }; for (Node current : flood) { if (current instanceof AbstractEndNode) { AbstractEndNode end = (AbstractEndNode) current; flood.add(end.merge()); } else { - for (Node successor : current.successors()) { - flood.add(successor); - } - } - } - } - - private static void disconnectCFGNodes(NodeFlood flood, StructuredGraph graph) { - for (AbstractEndNode node : graph.getNodes(AbstractEndNode.TYPE)) { - if (!flood.isMarked(node)) { - AbstractMergeNode merge = node.merge(); - if (merge != null && flood.isMarked(merge)) { - // We are a dead end node leading to a live merge. - merge.removeEnd(node); - } - } - } - for (LoopBeginNode loop : graph.getNodes(LoopBeginNode.TYPE)) { - if (flood.isMarked(loop)) { - boolean reachable = false; - for (LoopEndNode end : loop.loopEnds()) { - if (flood.isMarked(end)) { - reachable = true; - break; - } - } - if (!reachable) { - Debug.log("Removing loop with unreachable end: %s", loop); - for (LoopEndNode end : loop.loopEnds().snapshot()) { - loop.removeEnd(end); - } - graph.reduceDegenerateLoopBegin(loop); - } + current.acceptSuccessors(consumer); + current.acceptInputs(consumer); } } } private static void deleteNodes(NodeFlood flood, StructuredGraph graph) { + BiConsumer<Node, Node> consumer = (n, input) -> { + if (input.isAlive() && flood.isMarked(input)) { + input.removeUsage(n); + } + }; + for (Node node : graph.getNodes()) { if (!flood.isMarked(node)) { - node.clearInputs(); - node.clearSuccessors(); - } - } - for (Node node : graph.getNodes()) { - if (!flood.isMarked(node)) { + node.markDeleted(); + node.acceptInputs(consumer); metricNodesRemoved.increment(); - node.safeDelete(); } } } - - private static void iterateInputs(NodeFlood flood, StructuredGraph graph) { - for (Node node : graph.getNodes()) { - if (flood.isMarked(node)) { - for (Node input : node.inputs()) { - flood.add(input); - } - } - } - for (Node current : flood) { - for (Node input : current.inputs()) { - flood.add(input); - } - } - } - }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.common; + +import static com.oracle.graal.api.meta.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; + +import java.util.*; +import java.util.function.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.schedule.*; + +public class DominatorConditionalEliminationPhase extends Phase { + + private static final DebugMetric metricStampsRegistered = Debug.metric("StampsRegistered"); + private static final DebugMetric metricStampsFound = Debug.metric("StampsFound"); + private final boolean fullSchedule; + + public DominatorConditionalEliminationPhase(boolean fullSchedule) { + this.fullSchedule = fullSchedule; + } + + private static final class InfoElement { + private Stamp stamp; + private ValueNode guard; + + public InfoElement(Stamp stamp, ValueNode guard) { + this.stamp = stamp; + this.guard = guard; + } + + public Stamp getStamp() { + return stamp; + } + + public ValueNode getGuard() { + return guard; + } + } + + private static final class Info { + private ArrayList<InfoElement> infos; + + public Info() { + infos = new ArrayList<>(); + } + + public Iterable<InfoElement> getElements() { + return infos; + } + + public void pushElement(InfoElement element) { + infos.add(element); + } + + public void popElement() { + infos.remove(infos.size() - 1); + } + } + + @Override + protected void run(StructuredGraph graph) { + + Function<Block, Iterable<? extends Node>> blockToNodes; + Function<Node, Block> nodeToBlock; + Block startBlock; + + if (fullSchedule) { + SchedulePhase schedule = new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST); + schedule.apply(graph); + ControlFlowGraph cfg = schedule.getCFG(); + cfg.computePostdominators(); + blockToNodes = b -> schedule.getBlockToNodesMap().get(b); + nodeToBlock = n -> schedule.getNodeToBlockMap().get(n); + startBlock = cfg.getStartBlock(); + } else { + ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, false, true, true); + cfg.computePostdominators(); + BlockMap<List<FixedNode>> nodes = new BlockMap<>(cfg); + for (Block b : cfg.getBlocks()) { + ArrayList<FixedNode> curNodes = new ArrayList<>(); + for (FixedNode node : b.getNodes()) { + if (node instanceof AbstractBeginNode || node instanceof FixedGuardNode || node instanceof CheckCastNode || node instanceof ConditionAnchorNode || node instanceof IfNode) { + curNodes.add(node); + } + } + nodes.put(b, curNodes); + } + blockToNodes = b -> nodes.get(b); + nodeToBlock = n -> cfg.blockFor(n); + startBlock = cfg.getStartBlock(); + } + + Instance instance = new Instance(graph, blockToNodes, nodeToBlock); + instance.processBlock(startBlock); + } + + private static class Instance { + + private final NodeMap<Info> map; + private final Stack<LoopExitNode> loopExits; + private final Function<Block, Iterable<? extends Node>> blockToNodes; + private final Function<Node, Block> nodeToBlock; + + public Instance(StructuredGraph graph, Function<Block, Iterable<? extends Node>> blockToNodes, Function<Node, Block> nodeToBlock) { + map = graph.createNodeMap(); + loopExits = new Stack<>(); + this.blockToNodes = blockToNodes; + this.nodeToBlock = nodeToBlock; + } + + private void processBlock(Block block) { + + List<Runnable> undoOperations = new ArrayList<>(); + + preprocess(block, undoOperations); + + // Process always reached block first. + Block postdominator = block.getPostdominator(); + if (postdominator != null && postdominator.getDominator() == block) { + processBlock(postdominator); + } + + // Now go for the other dominators. + for (Block dominated : block.getDominated()) { + if (dominated != postdominator) { + assert dominated.getDominator() == block; + processBlock(dominated); + } + } + + postprocess(undoOperations); + } + + private static void postprocess(List<Runnable> undoOperations) { + for (Runnable r : undoOperations) { + r.run(); + } + } + + private void preprocess(Block block, List<Runnable> undoOperations) { + AbstractBeginNode beginNode = block.getBeginNode(); + if (beginNode instanceof LoopExitNode && beginNode.isAlive()) { + LoopExitNode loopExitNode = (LoopExitNode) beginNode; + this.loopExits.push(loopExitNode); + undoOperations.add(() -> loopExits.pop()); + } + for (Node n : blockToNodes.apply(block)) { + if (n.isAlive()) { + processNode(n, undoOperations); + } + } + } + + private void processNode(Node node, List<Runnable> undoOperations) { + if (node instanceof AbstractBeginNode) { + processAbstractBegin((AbstractBeginNode) node, undoOperations); + } else if (node instanceof FixedGuardNode) { + processFixedGuard((FixedGuardNode) node, undoOperations); + } else if (node instanceof GuardNode) { + processGuard((GuardNode) node, undoOperations); + } else if (node instanceof CheckCastNode) { + processCheckCast((CheckCastNode) node); + } else if (node instanceof ConditionAnchorNode) { + processConditionAnchor((ConditionAnchorNode) node); + } else if (node instanceof IfNode) { + processIf((IfNode) node, undoOperations); + } else { + return; + } + } + + private void processCheckCast(CheckCastNode node) { + tryProofCondition(node, (guard, result) -> { + if (result) { + PiNode piNode = node.graph().unique(new PiNode(node.object(), node.stamp(), guard)); + node.replaceAtUsages(piNode); + GraphUtil.unlinkFixedNode(node); + node.safeDelete(); + } else { + DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode)); + node.replaceAtPredecessor(deopt); + GraphUtil.killCFG(node); + } + }); + } + + private void processIf(IfNode node, List<Runnable> undoOperations) { + tryProofCondition(node.condition(), (guard, result) -> { + AbstractBeginNode survivingSuccessor = node.getSuccessor(result); + survivingSuccessor.replaceAtUsages(InputType.Guard, guard); + survivingSuccessor.replaceAtPredecessor(null); + node.replaceAtPredecessor(survivingSuccessor); + GraphUtil.killCFG(node); + if (survivingSuccessor instanceof BeginNode) { + undoOperations.add(() -> ((BeginNode) survivingSuccessor).trySimplify()); + } + }); + } + + private void registerNewCondition(LogicNode condition, boolean negated, ValueNode guard, List<Runnable> undoOperations) { + if (condition instanceof UnaryOpLogicNode) { + UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) condition; + Stamp newStamp = unaryLogicNode.getSucceedingStampForValue(negated); + registerNewStamp(unaryLogicNode.getValue(), newStamp, guard, undoOperations); + } else if (condition instanceof BinaryOpLogicNode) { + BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) condition; + ValueNode x = binaryOpLogicNode.getX(); + if (!x.isConstant()) { + Stamp newStampX = binaryOpLogicNode.getSucceedingStampForX(negated); + registerNewStamp(x, newStampX, guard, undoOperations); + } + + ValueNode y = binaryOpLogicNode.getY(); + if (!y.isConstant()) { + Stamp newStampY = binaryOpLogicNode.getSucceedingStampForY(negated); + registerNewStamp(y, newStampY, guard, undoOperations); + } + registerCondition(condition, negated, guard, undoOperations); + } + } + + private void registerCondition(LogicNode condition, boolean negated, ValueNode guard, List<Runnable> undoOperations) { + this.registerNewStamp(condition, negated ? StampFactory.contradiction() : StampFactory.tautology(), guard, undoOperations); + } + + private Iterable<InfoElement> getInfoElements(ValueNode proxiedValue) { + ValueNode value = GraphUtil.unproxify(proxiedValue); + Info info = map.get(value); + if (info == null) { + return Collections.emptyList(); + } else { + return info.getElements(); + } + } + + private boolean rewireGuards(ValueNode guard, boolean result, BiConsumer<ValueNode, Boolean> rewireGuardFunction) { + assert guard instanceof GuardingNode; + metricStampsFound.increment(); + ValueNode proxiedGuard = proxyGuard(guard); + rewireGuardFunction.accept(proxiedGuard, result); + return true; + } + + private ValueNode proxyGuard(ValueNode guard) { + ValueNode proxiedGuard = guard; + if (!this.loopExits.isEmpty()) { + while (proxiedGuard instanceof GuardProxyNode) { + proxiedGuard = ((GuardProxyNode) proxiedGuard).value(); + } + Block guardBlock = nodeToBlock.apply(proxiedGuard); + assert guardBlock != null; + for (int i = 0; i < loopExits.size(); ++i) { + LoopExitNode loopExitNode = loopExits.get(i); + Block loopExitBlock = nodeToBlock.apply(loopExitNode); + if (guardBlock != loopExitBlock && AbstractControlFlowGraph.dominates(guardBlock, loopExitBlock)) { + Block loopBeginBlock = nodeToBlock.apply(loopExitNode.loopBegin()); + if (!AbstractControlFlowGraph.dominates(guardBlock, loopBeginBlock) || guardBlock == loopBeginBlock) { + proxiedGuard = proxiedGuard.graph().unique(new GuardProxyNode((GuardingNode) proxiedGuard, loopExitNode)); + } + } + } + } + return proxiedGuard; + } + + private boolean tryProofCondition(Node node, BiConsumer<ValueNode, Boolean> rewireGuardFunction) { + if (node instanceof UnaryOpLogicNode) { + UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) node; + ValueNode value = unaryLogicNode.getValue(); + for (InfoElement infoElement : getInfoElements(value)) { + Stamp stamp = infoElement.getStamp(); + TriState result = unaryLogicNode.tryFold(stamp); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + } else if (node instanceof BinaryOpLogicNode) { + BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) node; + for (InfoElement infoElement : getInfoElements(binaryOpLogicNode)) { + if (infoElement.getStamp().equals(StampFactory.contradiction())) { + return rewireGuards(infoElement.getGuard(), false, rewireGuardFunction); + } else if (infoElement.getStamp().equals(StampFactory.tautology())) { + return rewireGuards(infoElement.getGuard(), true, rewireGuardFunction); + } + } + + ValueNode x = binaryOpLogicNode.getX(); + ValueNode y = binaryOpLogicNode.getY(); + for (InfoElement infoElement : getInfoElements(x)) { + TriState result = binaryOpLogicNode.tryFold(infoElement.getStamp(), y.stamp()); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + + for (InfoElement infoElement : getInfoElements(y)) { + TriState result = binaryOpLogicNode.tryFold(x.stamp(), infoElement.getStamp()); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + } else if (node instanceof CheckCastNode) { + CheckCastNode checkCastNode = (CheckCastNode) node; + for (InfoElement infoElement : getInfoElements(checkCastNode.object())) { + TriState result = checkCastNode.tryFold(infoElement.getStamp()); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + } else if (node instanceof ShortCircuitOrNode) { + final ShortCircuitOrNode shortCircuitOrNode = (ShortCircuitOrNode) node; + if (this.loopExits.isEmpty()) { + tryProofCondition(shortCircuitOrNode.getX(), (guard, result) -> { + if (result == !shortCircuitOrNode.isXNegated()) { + rewireGuards(guard, result, rewireGuardFunction); + } else { + tryProofCondition(shortCircuitOrNode.getY(), (innerGuard, innerResult) -> { + if (innerGuard == guard) { + rewireGuards(guard, shortCircuitOrNode.isYNegated() ? !innerResult : innerResult, rewireGuardFunction); + } + }); + } + }); + } + } + + return false; + } + + private void registerNewStamp(ValueNode proxiedValue, Stamp newStamp, ValueNode guard, List<Runnable> undoOperations) { + if (newStamp != null) { + ValueNode value = GraphUtil.unproxify(proxiedValue); + Info info = map.get(value); + if (info == null) { + info = new Info(); + map.set(value, info); + } + metricStampsRegistered.increment(); + final Info finalInfo = info; + finalInfo.pushElement(new InfoElement(newStamp, guard)); + undoOperations.add(() -> finalInfo.popElement()); + } + } + + private void processConditionAnchor(ConditionAnchorNode node) { + tryProofCondition(node.condition(), (guard, result) -> { + if (result == node.isNegated()) { + node.replaceAtUsages(guard); + GraphUtil.unlinkFixedNode(node); + GraphUtil.killWithUnusedFloatingInputs(node); + } else { + ValueAnchorNode valueAnchor = node.graph().add(new ValueAnchorNode(null)); + node.replaceAtUsages(valueAnchor); + node.graph().replaceFixedWithFixed(node, valueAnchor); + } + }); + } + + private void processGuard(GuardNode node, List<Runnable> undoOperations) { + if (!tryProofCondition(node.condition(), (guard, result) -> { + if (result != node.isNegated()) { + node.replaceAndDelete(guard); + } else { + DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.action(), node.reason())); + Block block = nodeToBlock.apply(node); + AbstractBeginNode beginNode = block.getBeginNode(); + FixedNode next = beginNode.next(); + beginNode.setNext(deopt); + GraphUtil.killCFG(next); + } + })) { + registerNewCondition(node.condition(), node.isNegated(), node, undoOperations); + } + } + + private void processFixedGuard(FixedGuardNode node, List<Runnable> undoOperations) { + if (!tryProofCondition(node.condition(), (guard, result) -> { + if (result != node.isNegated()) { + node.replaceAtUsages(guard); + GraphUtil.unlinkFixedNode(node); + GraphUtil.killWithUnusedFloatingInputs(node); + } else { + DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.getAction(), node.getReason())); + deopt.setStateBefore(node.stateBefore()); + node.replaceAtPredecessor(deopt); + GraphUtil.killCFG(node); + } + })) { + registerNewCondition(node.condition(), node.isNegated(), node, undoOperations); + } + } + + private void processAbstractBegin(AbstractBeginNode beginNode, List<Runnable> undoOperations) { + Node predecessor = beginNode.predecessor(); + if (predecessor instanceof IfNode) { + IfNode ifNode = (IfNode) predecessor; + boolean negated = (ifNode.falseSuccessor() == beginNode); + LogicNode condition = ifNode.condition(); + registerNewCondition(condition, negated, beginNode, undoOperations); + } else if (predecessor instanceof TypeSwitchNode) { + TypeSwitchNode typeSwitch = (TypeSwitchNode) predecessor; + processTypeSwitch(beginNode, undoOperations, predecessor, typeSwitch); + } else if (predecessor instanceof IntegerSwitchNode) { + IntegerSwitchNode integerSwitchNode = (IntegerSwitchNode) predecessor; + processIntegerSwitch(beginNode, undoOperations, predecessor, integerSwitchNode); + } + } + + private void processIntegerSwitch(AbstractBeginNode beginNode, List<Runnable> undoOperations, Node predecessor, IntegerSwitchNode integerSwitchNode) { + Stamp stamp = null; + for (int i = 0; i < integerSwitchNode.keyCount(); i++) { + if (integerSwitchNode.keySuccessor(i) == predecessor) { + if (stamp == null) { + stamp = StampFactory.forConstant(integerSwitchNode.keyAt(i)); + } else { + stamp = stamp.meet(StampFactory.forConstant(integerSwitchNode.keyAt(i))); + } + } + } + + if (stamp != null) { + registerNewStamp(integerSwitchNode.value(), stamp, beginNode, undoOperations); + } + } + + private void processTypeSwitch(AbstractBeginNode beginNode, List<Runnable> undoOperations, Node predecessor, TypeSwitchNode typeSwitch) { + ValueNode hub = typeSwitch.value(); + if (hub instanceof LoadHubNode) { + LoadHubNode loadHub = (LoadHubNode) hub; + Stamp stamp = null; + for (int i = 0; i < typeSwitch.keyCount(); i++) { + if (typeSwitch.keySuccessor(i) == predecessor) { + if (stamp == null) { + stamp = StampFactory.exactNonNull(typeSwitch.typeAt(i)); + } else { + stamp = stamp.meet(StampFactory.exactNonNull(typeSwitch.typeAt(i))); + } + } + } + if (stamp != null) { + registerNewStamp(loadHub.getValue(), stamp, beginNode, undoOperations); + } + } + } + } +}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -60,9 +60,9 @@ double firstIfProbability = shortCircuitProbability; /* * P(Y | not(X)) = P(Y inter not(X)) / P(not(X)) = (P(X union Y) - P(X)) / (1 - P(X)) - * + * * P(X) = shortCircuitProbability - * + * * P(X union Y) = ifNode.probability(trueTarget) */ double secondIfProbability = (ifNode.probability(trueTarget) - shortCircuitProbability) / (1 - shortCircuitProbability);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -45,7 +45,6 @@ private boolean createFloatingReads; private boolean createMemoryMapNodes; - private boolean updateExistingPhis; public static class MemoryMapImpl implements MemoryMap { @@ -90,7 +89,7 @@ } public FloatingReadPhase() { - this(true, false, false); + this(true, false); } /** @@ -99,13 +98,10 @@ * {@link FloatingReadNode}s) where possible * @param createMemoryMapNodes a {@link MemoryMapNode} will be created for each return if this * is true - * @param updateExistingPhis if true, then existing {@link MemoryPhiNode}s in the graph will be - * updated */ - public FloatingReadPhase(boolean createFloatingReads, boolean createMemoryMapNodes, boolean updateExistingPhis) { + public FloatingReadPhase(boolean createFloatingReads, boolean createMemoryMapNodes) { this.createFloatingReads = createFloatingReads; this.createMemoryMapNodes = createMemoryMapNodes; - this.updateExistingPhis = updateExistingPhis; } /** @@ -135,7 +131,7 @@ ReentrantNodeIterator.apply(new CollectMemoryCheckpointsClosure(modifiedInLoops), graph.start(), CollectionsFactory.newSet()); HashSetNodeEventListener listener = new HashSetNodeEventListener(EnumSet.of(NODE_ADDED, ZERO_USAGES)); try (NodeEventScope nes = graph.trackNodeEvents(listener)) { - ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, createFloatingReads, createMemoryMapNodes, updateExistingPhis), graph.start(), new MemoryMapImpl(graph.start())); + ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, createFloatingReads, createMemoryMapNodes), graph.start(), new MemoryMapImpl(graph.start())); } for (Node n : removeExternallyUsedNodes(listener.getNodes())) { @@ -150,7 +146,7 @@ } } - public static MemoryMapImpl mergeMemoryMaps(AbstractMergeNode merge, List<? extends MemoryMap> states, boolean updateExistingPhis) { + public static MemoryMapImpl mergeMemoryMaps(AbstractMergeNode merge, List<? extends MemoryMap> states) { MemoryMapImpl newState = new MemoryMapImpl(); Set<LocationIdentity> keys = CollectionsFactory.newSet(); @@ -159,17 +155,6 @@ } assert checkNoImmutableLocations(keys); - Map<LocationIdentity, MemoryPhiNode> existingPhis = null; - if (updateExistingPhis) { - for (MemoryPhiNode phi : merge.phis().filter(MemoryPhiNode.class)) { - if (existingPhis == null) { - existingPhis = CollectionsFactory.newMap(); - } - phi.values().clear(); - existingPhis.put(phi.getLocationIdentity(), phi); - } - } - for (LocationIdentity key : keys) { int mergedStatesCount = 0; boolean isPhi = false; @@ -184,10 +169,7 @@ } else if (merged == null) { merged = last; } else { - MemoryPhiNode phi = null; - if (existingPhis == null || (phi = existingPhis.remove(key)) == null) { - phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); - } + MemoryPhiNode phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); for (int j = 0; j < mergedStatesCount; j++) { phi.addInput(ValueNodeUtil.asNode(merged)); } @@ -200,11 +182,6 @@ } newState.lastMemorySnapshot.put(key, merged); } - if (existingPhis != null) { - for (Map.Entry<LocationIdentity, MemoryPhiNode> entry : existingPhis.entrySet()) { - entry.getValue().replaceAndDelete(newState.getLastLocationAccess(entry.getKey()).asNode()); - } - } return newState; } @@ -273,13 +250,11 @@ private final Map<LoopBeginNode, Set<LocationIdentity>> modifiedInLoops; private boolean createFloatingReads; private boolean createMemoryMapNodes; - private boolean updateExistingPhis; - public FloatingReadClosure(Map<LoopBeginNode, Set<LocationIdentity>> modifiedInLoops, boolean createFloatingReads, boolean createMemoryMapNodes, boolean updateExistingPhis) { + public FloatingReadClosure(Map<LoopBeginNode, Set<LocationIdentity>> modifiedInLoops, boolean createFloatingReads, boolean createMemoryMapNodes) { this.modifiedInLoops = modifiedInLoops; this.createFloatingReads = createFloatingReads; this.createMemoryMapNodes = createMemoryMapNodes; - this.updateExistingPhis = updateExistingPhis; } @Override @@ -347,7 +322,7 @@ @Override protected MemoryMapImpl merge(AbstractMergeNode merge, List<MemoryMapImpl> states) { - return mergeMemoryMaps(merge, states, updateExistingPhis); + return mergeMemoryMaps(merge, states); } @Override @@ -378,24 +353,10 @@ Map<LocationIdentity, MemoryPhiNode> phis = CollectionsFactory.newMap(); - if (updateExistingPhis) { - for (MemoryPhiNode phi : loop.phis().filter(MemoryPhiNode.class).snapshot()) { - if (modifiedLocations.contains(phi.getLocationIdentity())) { - phi.values().clear(); - phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(phi.getLocationIdentity()))); - phis.put(phi.getLocationIdentity(), phi); - } else { - phi.replaceAndDelete(initialState.getLastLocationAccess(phi.getLocationIdentity()).asNode()); - } - } - } - for (LocationIdentity location : modifiedLocations) { - if (!updateExistingPhis || !phis.containsKey(location)) { - MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); - phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); - phis.put(location, phi); - } + MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); + phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); + phis.put(location, phi); } for (Map.Entry<LocationIdentity, MemoryPhiNode> entry : phis.entrySet()) { initialState.lastMemorySnapshot.put(entry.getKey(), entry.getValue());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -163,7 +163,8 @@ StructuredGraph graph = guard.graph(); AbstractBeginNode fastPath = graph.add(new BeginNode()); @SuppressWarnings("deprecation") - DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason(), useGuardIdAsDebugId ? guard.getId() : 0, guard.getSpeculation(), null)); + int debugId = useGuardIdAsDebugId ? guard.getId() : DeoptimizeNode.DEFAULT_DEBUG_ID; + DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason(), debugId, guard.getSpeculation(), null)); AbstractBeginNode deoptBranch = BeginNode.begin(deopt); AbstractBeginNode trueSuccessor; AbstractBeginNode falseSuccessor;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,19 +38,20 @@ private static final int MAX_ITERATIONS = 256; private final CanonicalizerPhase canonicalizer; + private final boolean fullSchedule; - public IterativeConditionalEliminationPhase(CanonicalizerPhase canonicalizer) { + public IterativeConditionalEliminationPhase(CanonicalizerPhase canonicalizer, boolean fullSchedule) { this.canonicalizer = canonicalizer; + this.fullSchedule = fullSchedule; } @Override protected void run(StructuredGraph graph, PhaseContext context) { - ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(); - HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED); + HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED).exclude(ZERO_USAGES); int count = 0; while (true) { try (NodeEventScope nes = graph.trackNodeEvents(listener)) { - eliminate.apply(graph); + new DominatorConditionalEliminationPhase(fullSchedule).apply(graph); } if (listener.getNodes().isEmpty()) { break;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -48,7 +48,7 @@ @NodeInfo static final class DummyGuardHandle extends ValueNode implements GuardedNode { - public static final NodeClass<DummyGuardHandle> TYPE = NodeClass.get(DummyGuardHandle.class); + public static final NodeClass<DummyGuardHandle> TYPE = NodeClass.create(DummyGuardHandle.class); @Input(InputType.Guard) GuardingNode guard; public DummyGuardHandle(GuardingNode guard) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -63,7 +63,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor}) static final class DummyAnchorNode extends FixedWithNextNode implements GuardingNode, AnchoringNode { - public static final NodeClass<DummyAnchorNode> TYPE = NodeClass.get(DummyAnchorNode.class); + public static final NodeClass<DummyAnchorNode> TYPE = NodeClass.create(DummyAnchorNode.class); public DummyAnchorNode() { super(TYPE, StampFactory.forVoid()); @@ -280,11 +280,11 @@ mergeAfter.clearEnds(); expandDuplicated(duplicatedNodes, mergeAfter); - List<AbstractEndNode> endSnapshot = merge.forwardEnds().snapshot(); + List<EndNode> endSnapshot = merge.forwardEnds().snapshot(); List<PhiNode> phiSnapshot = merge.phis().snapshot(); int endIndex = 0; - for (final AbstractEndNode forwardEnd : merge.forwardEnds()) { + for (final EndNode forwardEnd : merge.forwardEnds()) { Map<Node, Node> duplicates; if (replacements == null || replacements.get(endIndex) == null) { duplicates = graph.addDuplicates(duplicatedNodes, graph, duplicatedNodes.size(), (DuplicationReplacement) null); @@ -296,7 +296,7 @@ for (Map.Entry<ValueNode, PhiNode> phi : bottomPhis.entrySet()) { phi.getValue().initializeValueAt(merge.forwardEndIndex(forwardEnd), (ValueNode) duplicates.get(phi.getKey())); } - mergeAfter.addForwardEnd((AbstractEndNode) duplicates.get(endAfter)); + mergeAfter.addForwardEnd((EndNode) duplicates.get(endAfter)); // re-wire the duplicated ValueAnchorNode to the predecessor of the corresponding // EndNode @@ -452,8 +452,8 @@ * @return The newly created end node. */ private AbstractEndNode createNewMerge(FixedNode successor, FrameState stateAfterMerge) { - AbstractMergeNode newBottomMerge = graph.add(new MergeNode()); - AbstractEndNode newBottomEnd = graph.add(new EndNode()); + MergeNode newBottomMerge = graph.add(new MergeNode()); + EndNode newBottomEnd = graph.add(new EndNode()); newBottomMerge.addForwardEnd(newBottomEnd); newBottomMerge.setStateAfter(stateAfterMerge); ((FixedWithNextNode) successor.predecessor()).setNext(newBottomEnd);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Tue Mar 10 21:26:02 2015 +0100 @@ -226,8 +226,10 @@ assert invoke.next() == continuation; invoke.setNext(null); returnMerge.setNext(continuation); - invoke.asNode().replaceAtUsages(returnValuePhi); - invoke.asNode().replaceAndDelete(null); + if (returnValuePhi != null) { + invoke.asNode().replaceAtUsages(returnValuePhi); + } + invoke.asNode().safeDelete(); ArrayList<GuardedValueNode> replacementNodes = new ArrayList<>(); @@ -276,7 +278,10 @@ metricInliningTailDuplication.increment(); Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities); PhaseContext phaseContext = new PhaseContext(providers); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + if (ImmutableCode.getValue()) { + canonicalizer.disableReadCanonicalization(); + } TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer); } } @@ -464,7 +469,7 @@ AbstractBeginNode calleeEntryNode = graph.add(new BeginNode()); calleeEntryNode.setNext(duplicatedInvoke.asNode()); - AbstractEndNode endNode = graph.add(new EndNode()); + EndNode endNode = graph.add(new EndNode()); duplicatedInvoke.setNext(endNode); returnMerge.addForwardEnd(endNode); @@ -499,7 +504,7 @@ // set new state (pop old exception object, push new one) newExceptionEdge.setStateAfter(stateAfterException.duplicateModified(Kind.Object, newExceptionEdge)); - AbstractEndNode endNode = graph.add(new EndNode()); + EndNode endNode = graph.add(new EndNode()); newExceptionEdge.setNext(endNode); exceptionMerge.addForwardEnd(endNode); exceptionObjectPhi.addInput(newExceptionEdge);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Tue Mar 10 21:26:02 2015 +0100 @@ -211,7 +211,7 @@ if (context.getGraphBuilderSuite() != null) { context.getGraphBuilderSuite().apply(newGraph, context); } - assert newGraph.start().next() != null : "graph needs to be populated by the GraphBuilderSuite"; + assert newGraph.start().next() != null : "graph needs to be populated by the GraphBuilderSuite " + method + ", " + method.canBeInlined(); new DeadCodeEliminationPhase(Optional).apply(newGraph);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,8 +26,6 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.DebugMemUseTracker.Closeable; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -96,7 +94,7 @@ } public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) { - try (TimerCloseable a = timer.start(); Scope s = Debug.scope(getClass(), this); Closeable c = memUseTracker.start()) { + try (DebugCloseable a = timer.start(); Scope s = Debug.scope(getClass(), this); DebugCloseable c = memUseTracker.start()) { if (dumpGraph && Debug.isDumpEnabled(BEFORE_PHASE_DUMP_LEVEL)) { Debug.dump(BEFORE_PHASE_DUMP_LEVEL, graph, "Before phase %s", getName()); }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/VerifyPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/VerifyPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -54,7 +54,7 @@ /** * Performs the actual verification. - * + * * @throws VerificationError if the verification fails */ protected abstract boolean verify(StructuredGraph graph, C context);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java Tue Mar 10 21:26:02 2015 +0100 @@ -101,7 +101,7 @@ if (current.predecessor() == null) { if (current instanceof AbstractMergeNode) { AbstractMergeNode currentMerge = (AbstractMergeNode) current; - NodeInputList<AbstractEndNode> currentForwardEnds = currentMerge.forwardEnds(); + NodeInputList<EndNode> currentForwardEnds = currentMerge.forwardEnds(); /* * Use simple iteration instead of streams, since the stream infrastructure adds * many frames which causes the recursion to overflow the stack earlier than it
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java Tue Mar 10 21:26:02 2015 +0100 @@ -56,6 +56,8 @@ } boolean stampChanged; + // The algorithm is not guaranteed to reach a stable state. + int z = 0; do { stampChanged = false; /* @@ -72,7 +74,8 @@ } } } - } while (stampChanged); + ++z; + } while (stampChanged && z < 10000); /* * Check that all the illegal stamps we introduced above are correctly replaced with real
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ScheduledNodeIterator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ScheduledNodeIterator.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ /** * Iterates over a list of nodes, which usually comes from * {@link SchedulePhase#getBlockToNodesMap()}. - * + * * While iterating, it is possible to {@link #insert(FixedNode, FixedWithNextNode) insert} and * {@link #replaceCurrent(FixedWithNextNode) replace} nodes. */
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -42,7 +42,6 @@ import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; -import com.oracle.graal.phases.util.*; public final class SchedulePhase extends Phase { @@ -76,8 +75,6 @@ LATEST_OUT_OF_LOOPS } - static int created; - private class LocationSet { private LocationIdentity firstLocation; private List<LocationIdentity> list; @@ -306,6 +303,7 @@ private BlockMap<LocationSet> blockToKillSet; private final SchedulingStrategy selectedStrategy; private boolean scheduleConstants; + private NodeMap<Block> nodeToBlockMap; public SchedulePhase() { this(OptScheduleOutOfLoops.getValue() ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST); @@ -321,15 +319,20 @@ @Override protected void run(StructuredGraph graph) { - assert GraphOrder.assertNonCyclicGraph(graph); - cfg = ControlFlowGraph.compute(graph, true, true, true, true); + // assert GraphOrder.assertNonCyclicGraph(graph); + cfg = ControlFlowGraph.compute(graph, true, true, true, false); earliestCache = graph.createNodeMap(); blockToNodesMap = new BlockMap<>(cfg); - if (selectedStrategy != SchedulingStrategy.EARLIEST) { + if (selectedStrategy != SchedulingStrategy.EARLIEST && graph.isAfterFloatingReadPhase()) { blockToKillSet = new BlockMap<>(cfg); } + if (selectedStrategy == SchedulingStrategy.EARLIEST) { + scheduleEarliestIterative(blockToNodesMap, graph); + return; + } + assignBlockToNodes(graph, selectedStrategy); printSchedule("after assign nodes to blocks"); @@ -337,6 +340,154 @@ printSchedule("after sorting nodes within blocks"); } + private void scheduleEarliestIterative(BlockMap<List<ValueNode>> blockToNodes, StructuredGraph graph) { + NodeMap<Block> nodeToBlock = graph.createNodeMap(); + NodeBitMap visited = graph.createNodeBitMap(); + + // Add begin nodes as the first entry and set the block for phi nodes. + for (Block b : cfg.getBlocks()) { + AbstractBeginNode beginNode = b.getBeginNode(); + ArrayList<ValueNode> nodes = new ArrayList<>(); + nodeToBlock.set(beginNode, b); + nodes.add(beginNode); + blockToNodes.put(b, nodes); + + if (beginNode instanceof AbstractMergeNode) { + AbstractMergeNode mergeNode = (AbstractMergeNode) beginNode; + for (PhiNode phi : mergeNode.phis()) { + nodeToBlock.set(phi, b); + } + } else if (beginNode instanceof LoopExitNode) { + LoopExitNode loopExitNode = (LoopExitNode) beginNode; + for (ProxyNode proxy : loopExitNode.proxies()) { + nodeToBlock.set(proxy, b); + } + } + } + + Stack<Node> stack = new Stack<>(); + + // Start analysis with control flow ends. + for (Block b : cfg.postOrder()) { + FixedNode endNode = b.getEndNode(); + stack.push(endNode); + nodeToBlock.set(endNode, b); + } + + processStack(blockToNodes, nodeToBlock, visited, stack); + + // Visit back input edges of loop phis. + for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.TYPE)) { + for (PhiNode phi : loopBegin.phis()) { + if (visited.isMarked(phi)) { + for (int i = 0; i < loopBegin.getLoopEndCount(); ++i) { + Node node = phi.valueAt(i + loopBegin.forwardEndCount()); + if (node != null && !visited.isMarked(node)) { + stack.push(node); + processStack(blockToNodes, nodeToBlock, visited, stack); + } + } + } + } + } + + // Check for dead nodes. + if (visited.getCounter() < graph.getNodeCount()) { + for (Node n : graph.getNodes()) { + if (!visited.isMarked(n)) { + n.clearInputs(); + n.markDeleted(); + } + } + } + + // Add end nodes as the last nodes in each block. + for (Block b : cfg.getBlocks()) { + FixedNode endNode = b.getEndNode(); + if (endNode != b.getBeginNode()) { + addNode(blockToNodes, b, endNode); + } + } + + this.blockToNodesMap = blockToNodes; + this.nodeToBlockMap = nodeToBlock; + } + + private static void addNode(BlockMap<List<ValueNode>> blockToNodes, Block b, ValueNode endNode) { + assert !blockToNodes.get(b).contains(endNode) : endNode; + blockToNodes.get(b).add(endNode); + } + + private void processStack(BlockMap<List<ValueNode>> blockToNodes, NodeMap<Block> nodeToBlock, NodeBitMap visited, Stack<Node> stack) { + Block startBlock = cfg.getStartBlock(); + while (!stack.isEmpty()) { + Node current = stack.peek(); + if (visited.checkAndMarkInc(current)) { + + // Push inputs and predecessor. + Node predecessor = current.predecessor(); + if (predecessor != null) { + stack.push(predecessor); + } + + if (current instanceof PhiNode) { + PhiNode phiNode = (PhiNode) current; + AbstractMergeNode merge = phiNode.merge(); + for (int i = 0; i < merge.forwardEndCount(); ++i) { + Node input = phiNode.valueAt(i); + if (input != null) { + stack.push(input); + } + } + } else { + for (Node input : current.inputs()) { + if (current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current) { + // Ignore the cycle. + } else { + stack.push(input); + } + } + } + } else { + + stack.pop(); + + if (nodeToBlock.get(current) == null) { + Node predecessor = current.predecessor(); + Block curBlock; + if (predecessor != null) { + // Predecessor determines block. + curBlock = nodeToBlock.get(predecessor); + } else { + Block earliest = startBlock; + for (Node input : current.inputs()) { + if (current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current) { + // ignore + } else { + Block inputEarliest; + if (input instanceof ControlSplitNode) { + inputEarliest = nodeToBlock.get(((ControlSplitNode) input).getPrimarySuccessor()); + } else { + inputEarliest = nodeToBlock.get(input); + } + assert inputEarliest != null : current + " / " + input; + if (earliest.getDominatorDepth() < inputEarliest.getDominatorDepth()) { + earliest = inputEarliest; + } + } + } + curBlock = earliest; + } + assert curBlock != null; + if (current instanceof ValueNode) { + addNode(blockToNodes, curBlock, (ValueNode) current); + } + nodeToBlock.set(current, curBlock); + } + } + } + } + private Block blockForMemoryNode(MemoryNode memory) { MemoryNode current = memory; while (current instanceof MemoryProxy) { @@ -359,7 +510,6 @@ for (Block b : getCFG().getBlocks()) { buf.format("==== b: %s (loopDepth: %s). ", b, b.getLoopDepth()); buf.format("dom: %s. ", b.getDominator()); - buf.format("post-dom: %s. ", b.getPostdominator()); buf.format("preds: %s. ", b.getPredecessors()); buf.format("succs: %s ====%n", b.getSuccessors()); BlockMap<LocationSet> killSets = blockToKillSet; @@ -418,6 +568,10 @@ return blockToNodesMap; } + public NodeMap<Block> getNodeToBlockMap() { + return this.nodeToBlockMap; + } + /** * Gets the nodes in a given block. */ @@ -621,42 +775,23 @@ * @param earliestBlock */ private Block latestBlock(ValueNode node, SchedulingStrategy strategy, Block earliestBlock) { - CommonDominatorBlockClosure cdbc = new CommonDominatorBlockClosure(null); - ensureScheduledUsages(node, strategy); + Block block = null; for (Node usage : node.usages()) { - blocksForUsage(node, usage, cdbc, strategy); - if (cdbc.block == earliestBlock) { + block = blocksForUsage(node, usage, block, earliestBlock, strategy); + if (block == earliestBlock) { break; } } - assert assertLatestBlockResult(node, cdbc); - return cdbc.block; - } - - private boolean assertLatestBlockResult(ValueNode node, CommonDominatorBlockClosure cdbc) throws SchedulingError { - if (cdbc.block != null && !dominates(earliestBlock(node), cdbc.block)) { - throw new SchedulingError("failed to find correct latest schedule for %s. cdbc: %s, earliest: %s", node, cdbc.block, earliestBlock(node)); - } - return true; + assert assertLatestBlockResult(node, block); + return block; } - /** - * A closure that will calculate the common dominator of all blocks passed to its - * {@link #apply(Block)} method. - */ - private static class CommonDominatorBlockClosure implements BlockClosure { - - public Block block; - - public CommonDominatorBlockClosure(Block block) { - this.block = block; + private boolean assertLatestBlockResult(ValueNode node, Block block) throws SchedulingError { + if (block != null && !dominates(earliestBlock(node), block)) { + throw new SchedulingError("failed to find correct latest schedule for %s. cdbc: %s, earliest: %s", node, block, earliestBlock(node)); } - - @Override - public void apply(Block newBlock) { - this.block = commonDominatorTyped(this.block, newBlock); - } + return true; } /** @@ -671,41 +806,32 @@ if (earliest != null) { return earliest; } + return earliestBlockHelper(node, earliest); + } + + private Block earliestBlockHelper(Node node, Block earliestStart) throws SchedulingError { /* * All inputs must be in a dominating block, otherwise the graph cannot be scheduled. This * implies that the inputs' blocks have a total ordering via their dominance relation. So in * order to find the earliest block placement for this node we need to find the input block * that is dominated by all other input blocks. */ + Block earliest = earliestStart; if (node.predecessor() != null) { throw new SchedulingError(); } - for (Node input : node.inputs().nonNull()) { - assert input instanceof ValueNode; - Block inputEarliest; - if (input instanceof InvokeWithExceptionNode) { - inputEarliest = cfg.getNodeToBlock().get(((InvokeWithExceptionNode) input).next()); - } else { - inputEarliest = earliestBlock(input); - } - if (earliest == null) { - earliest = inputEarliest; - } else if (earliest != inputEarliest) { - // Find out whether earliest or inputEarliest is earlier. - Block a = earliest.getDominator(); - Block b = inputEarliest; - while (true) { - if (a == inputEarliest || b == null) { - // Nothing to change, the previous earliest block is still earliest. - break; - } else if (b == earliest || a == null) { - // New earliest is the earliest. - earliest = inputEarliest; - break; - } - a = a.getDominator(); - b = b.getDominator(); + for (Node input : node.inputs()) { + if (input != null) { + assert input instanceof ValueNode; + Block inputEarliest; + if (input instanceof InvokeWithExceptionNode) { + inputEarliest = cfg.getNodeToBlock().get(((InvokeWithExceptionNode) input).next()); + } else { + inputEarliest = earliestBlock(input); + } + if (earliest == null || earliest.getDominatorDepth() < inputEarliest.getDominatorDepth()) { + earliest = inputEarliest; } } } @@ -732,14 +858,19 @@ } Block cur = latestBlock; Block result = latestBlock; - while (cur.getLoop() != null && cur != earliest && cur.getDominator() != null) { - Block dom = cur.getDominator(); - if (dom.getLoopDepth() < result.getLoopDepth()) { - result = dom; + Loop<?> earliestLoop = earliest.getLoop(); + while (true) { + Loop<?> curLoop = cur.getLoop(); + if (curLoop == earliestLoop) { + return result; + } else { + Block dom = cur.getDominator(); + if (dom.getLoopDepth() < result.getLoopDepth()) { + result = dom; + } + cur = dom; } - cur = dom; } - return result; } /** @@ -748,11 +879,11 @@ * * @param node the node that needs to be scheduled * @param usage the usage whose blocks need to be considered - * @param closure the closure that will be called for each block + * @param earliestBlock */ - private void blocksForUsage(ValueNode node, Node usage, CommonDominatorBlockClosure closure, SchedulingStrategy strategy) { + private Block blocksForUsage(ValueNode node, Node usage, Block startCurrentBlock, Block earliestBlock, SchedulingStrategy strategy) { assert !(node instanceof PhiNode); - + Block currentBlock = startCurrentBlock; if (usage instanceof PhiNode) { // An input to a PhiNode is used at the end of the predecessor block that corresponds to // the PhiNode input. @@ -763,7 +894,10 @@ Block mergeBlock = cfg.getNodeToBlock().get(merge); for (int i = 0; i < phi.valueCount(); ++i) { if (phi.valueAt(i) == node) { - closure.apply(mergeBlock.getPredecessors().get(i)); + currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, mergeBlock.getPredecessors().get(i)); + if (currentBlock == earliestBlock) { + break; + } } } } else if (usage instanceof VirtualState) { @@ -773,19 +907,19 @@ if (unscheduledUsage instanceof VirtualState) { // If a FrameState is an outer FrameState this method behaves as if the inner // FrameState was the actual usage, by recursing. - blocksForUsage(node, unscheduledUsage, closure, strategy); + currentBlock = blocksForUsage(node, unscheduledUsage, currentBlock, earliestBlock, strategy); } else if (unscheduledUsage instanceof AbstractBeginNode) { // Only FrameStates can be connected to BeginNodes. if (!(usage instanceof FrameState)) { throw new SchedulingError(usage.toString()); } if (unscheduledUsage instanceof StartNode) { - closure.apply(cfg.getNodeToBlock().get(unscheduledUsage)); + currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, cfg.getNodeToBlock().get(unscheduledUsage)); } else { // If a FrameState belongs to a BeginNode then it's inputs will be placed at // the common dominator of all EndNodes. for (Node pred : unscheduledUsage.cfgPredecessors()) { - closure.apply(cfg.getNodeToBlock().get(pred)); + currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, cfg.getNodeToBlock().get(pred)); } } } else { @@ -798,21 +932,18 @@ } // Otherwise: Put the input into the same block as the usage. assignBlockToNode((ValueNode) unscheduledUsage, strategy); - closure.apply(cfg.getNodeToBlock().get(unscheduledUsage)); + currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, cfg.getNodeToBlock().get(unscheduledUsage)); + } + if (currentBlock == earliestBlock) { + break; } } } else { // All other types of usages: Put the input into the same block as the usage. assignBlockToNode((ValueNode) usage, strategy); - closure.apply(cfg.getNodeToBlock().get(usage)); + currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, cfg.getNodeToBlock().get(usage)); } - } - - private void ensureScheduledUsages(Node node, SchedulingStrategy strategy) { - for (Node usage : node.usages().filter(ValueNode.class)) { - assignBlockToNode((ValueNode) usage, strategy); - } - // now true usages are ready + return currentBlock; } private void sortNodesWithinBlocks(StructuredGraph graph, SchedulingStrategy strategy) { @@ -839,17 +970,8 @@ } List<ValueNode> sortedInstructions; - switch (strategy) { - case EARLIEST: - sortedInstructions = sortNodesWithinBlockEarliest(b, visited); - break; - case LATEST: - case LATEST_OUT_OF_LOOPS: - sortedInstructions = sortNodesWithinBlockLatest(b, visited, beforeLastLocation); - break; - default: - throw new GraalInternalError("unknown scheduling strategy"); - } + assert strategy == SchedulingStrategy.LATEST || strategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS; + sortedInstructions = sortNodesWithinBlockLatest(b, visited, beforeLastLocation); assert filterSchedulableNodes(blockToNodesMap.get(b)).size() == removeProxies(sortedInstructions).size() : "sorted block does not contain the same amount of nodes: " + filterSchedulableNodes(blockToNodesMap.get(b)) + " vs. " + removeProxies(sortedInstructions); assert sameOrderForFixedNodes(blockToNodesMap.get(b), sortedInstructions) : "fixed nodes in sorted block are not in the same order"; @@ -1006,25 +1128,8 @@ List<ValueNode> sortedInstructions = state.getSortedInstructions(); Node lastSorted = sortedInstructions.get(sortedInstructions.size() - 1); if (lastSorted != b.getEndNode()) { - int idx = sortedInstructions.indexOf(b.getEndNode()); - boolean canNotMove = false; - for (int i = idx + 1; i < sortedInstructions.size(); i++) { - if (sortedInstructions.get(i).inputs().contains(b.getEndNode())) { - canNotMove = true; - break; - } - } - if (canNotMove) { - if (b.getEndNode() instanceof ControlSplitNode) { - throw new GraalGraphInternalError("Schedule is not possible : needs to move a node after the last node of the block which can not be move").addContext(lastSorted).addContext( - b.getEndNode()); - } - - // b.setLastNode(lastSorted); - } else { - sortedInstructions.remove(b.getEndNode()); - sortedInstructions.add(b.getEndNode()); - } + sortedInstructions.remove(b.getEndNode()); + sortedInstructions.add(b.getEndNode()); } return sortedInstructions; } @@ -1071,20 +1176,23 @@ return; } + if (i instanceof LoopExitNode) { + LoopExitNode loopExitNode = (LoopExitNode) i; + for (ProxyNode proxy : loopExitNode.proxies()) { + addToLatestSorting(proxy, state); + } + } + + addToLatestSortingHelper(i, state); + } + + private void addToLatestSortingHelper(ValueNode i, SortState state) { FrameState stateAfter = null; if (i instanceof StateSplit) { stateAfter = ((StateSplit) i).stateAfter(); } - for (Node input : i.inputs()) { - if (input instanceof FrameState) { - if (input != stateAfter) { - addUnscheduledToLatestSorting((FrameState) input, state); - } - } else { - addToLatestSorting((ValueNode) input, state); - } - } + addInputsToLatestSorting(i, state, stateAfter); if (state.readsSize() != 0) { if (i instanceof MemoryCheckpoint.Single) { @@ -1112,45 +1220,14 @@ } } - /** - * Sorts the nodes within a block by adding the nodes to a list in a post-order iteration over - * all usages. The resulting list is reversed to create an earliest-possible scheduling of - * nodes. - */ - private List<ValueNode> sortNodesWithinBlockEarliest(Block b, NodeBitMap visited) { - List<ValueNode> sortedInstructions = new ArrayList<>(blockToNodesMap.get(b).size() + 2); - addToEarliestSorting(b, b.getEndNode(), sortedInstructions, visited); - Collections.reverse(sortedInstructions); - return sortedInstructions; - } - - private void addToEarliestSorting(Block b, ValueNode i, List<ValueNode> sortedInstructions, NodeBitMap visited) { - ValueNode instruction = i; - while (true) { - if (instruction == null || visited.isMarked(instruction) || cfg.getNodeToBlock().get(instruction) != b || instruction instanceof PhiNode || instruction instanceof ProxyNode) { - return; - } - - visited.mark(instruction); - for (Node usage : instruction.usages()) { - if (usage instanceof VirtualState) { - // only fixed nodes can have VirtualState -> no need to schedule them - } else { - addToEarliestSorting(b, (ValueNode) usage, sortedInstructions, visited); + private void addInputsToLatestSorting(ValueNode i, SortState state, FrameState stateAfter) { + for (Node input : i.inputs()) { + if (input instanceof FrameState) { + if (input != stateAfter) { + addUnscheduledToLatestSorting((FrameState) input, state); } - } - - if (instruction instanceof AbstractBeginNode) { - for (ValueNode inBlock : blockToNodesMap.get(b)) { - if (!visited.isMarked(inBlock)) { - addToEarliestSorting(b, inBlock, sortedInstructions, visited); - } - } - sortedInstructions.add(instruction); - break; } else { - sortedInstructions.add(instruction); - instruction = (ValueNode) instruction.predecessor(); + addToLatestSorting((ValueNode) input, state); } } }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/BlockWorkList.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/BlockWorkList.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ /** * Adds a block to this list in an unsorted fashion, like a stack. - * + * * @param block the block to add */ public void add(AbstractMergeNode block) { @@ -55,7 +55,7 @@ /** * Adds a block to this list, sorted by the supplied number. The block with the lowest number is * returned upon subsequent removes. - * + * * @param block the block to add * @param number the number used to sort the block */ @@ -89,7 +89,7 @@ * Removes the next block from this work list. If the blocks have been added in a sorted order, * then the block with the lowest number is returned. Otherwise, the last block added is * returned. - * + * * @return the next block in the list */ public AbstractMergeNode removeFromWorkList() { @@ -101,7 +101,7 @@ /** * Checks whether the list is empty. - * + * * @return {@code true} if this list is empty */ public boolean isEmpty() {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Tue Mar 10 21:26:02 2015 +0100 @@ -251,7 +251,9 @@ @Override protected NodeBitMap getInitialState() { - return graph.createNodeBitMap(); + NodeBitMap ret = graph.createNodeBitMap(); + ret.markAll(graph.getNodes().filter(ConstantNode.class)); + return ret; } @Override
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Mar 10 21:26:02 2015 +0100 @@ -441,11 +441,12 @@ private void writeEdges(Node node, Edges.Type type) throws IOException { NodeClass<?> nodeClass = node.getNodeClass(); Edges edges = nodeClass.getEdges(type); + final long[] curOffsets = edges.getOffsets(); for (int i = 0; i < edges.getDirectCount(); i++) { - writeNodeRef(edges.getNode(node, i)); + writeNodeRef(Edges.getNode(node, curOffsets, i)); } for (int i = edges.getDirectCount(); i < edges.getCount(); i++) { - NodeList<Node> list = edges.getNodeList(node, i); + NodeList<Node> list = Edges.getNodeList(node, curOffsets, i); if (list == null) { writeShort((char) 0); } else {
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.lir.*; import com.oracle.graal.lir.alloc.lsra.*; import com.oracle.graal.lir.alloc.lsra.Interval.*; @@ -131,10 +130,10 @@ * @param label A label describing the compilation phase that produced the control flow graph. * @param blocks The list of blocks to be printed. */ - public void printCFG(String label, List<? extends AbstractBlock<?>> blocks, boolean printNodes) { + public void printCFG(String label, List<? extends AbstractBlockBase<?>> blocks, boolean printNodes) { if (lir == null) { latestScheduling = new NodeMap<>(cfg.getNodeToBlock()); - for (AbstractBlock<?> abstractBlock : blocks) { + for (AbstractBlockBase<?> abstractBlock : blocks) { Block block = (Block) abstractBlock; Node cur = block.getBeginNode(); while (true) { @@ -152,7 +151,7 @@ begin("cfg"); out.print("name \"").print(label).println('"'); - for (AbstractBlock<?> block : blocks) { + for (AbstractBlockBase<?> block : blocks) { printBlock(block, printNodes); } end("cfg"); @@ -194,7 +193,7 @@ } } - private void printBlock(AbstractBlock<?> block, boolean printNodes) { + private void printBlock(AbstractBlockBase<?> block, boolean printNodes) { printBlockProlog(block); if (printNodes) { assert block instanceof Block; @@ -203,31 +202,26 @@ printBlockEpilog(block); } - private void printBlockEpilog(AbstractBlock<?> block) { + private void printBlockEpilog(AbstractBlockBase<?> block) { printLIR(block); end("block"); } - private void printBlockProlog(AbstractBlock<?> block) { + private void printBlockProlog(AbstractBlockBase<?> block) { begin("block"); out.print("name \"").print(blockToString(block)).println('"'); - if (block instanceof BciBlock) { - out.print("from_bci ").println(((BciBlock) block).startBci); - out.print("to_bci ").println(((BciBlock) block).endBci); - } else { - out.println("from_bci -1"); - out.println("to_bci -1"); - } + out.println("from_bci -1"); + out.println("to_bci -1"); out.print("predecessors "); - for (AbstractBlock<?> pred : block.getPredecessors()) { + for (AbstractBlockBase<?> pred : block.getPredecessors()) { out.print("\"").print(blockToString(pred)).print("\" "); } out.println(); out.print("successors "); - for (AbstractBlock<?> succ : block.getSuccessors()) { + for (AbstractBlockBase<?> succ : block.getSuccessors()) { if (!succ.isExceptionEntry()) { out.print("\"").print(blockToString(succ)).print("\" "); } @@ -235,7 +229,7 @@ out.println(); out.print("xhandlers"); - for (AbstractBlock<?> succ : block.getSuccessors()) { + for (AbstractBlockBase<?> succ : block.getSuccessors()) { if (succ.isExceptionEntry()) { out.print("\"").print(blockToString(succ)).print("\" "); } @@ -437,7 +431,7 @@ * * @param block the block to print */ - private void printLIR(AbstractBlock<?> block) { + private void printLIR(AbstractBlockBase<?> block) { if (lir == null) { return; } @@ -500,7 +494,7 @@ return prefix + node.toString(Verbosity.Id); } - private String blockToString(AbstractBlock<?> block) { + private String blockToString(AbstractBlockBase<?> block) { if (lir == null && schedule == null && block instanceof Block) { // During all the front-end phases, the block schedule is built only for the debug // output.
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Tue Mar 10 21:26:02 2015 +0100 @@ -182,7 +182,7 @@ return sb.toString(); } - protected String valueToString(JavaValue value, List<VirtualObject> virtualObjects) { + protected String valueToString(Value value, List<VirtualObject> virtualObjects) { if (value == null) { return "-"; }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,23 +39,23 @@ * * <pre> * HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)* - * + * * OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable - * + * * Platform ::= "Platform" ISA WordWidth - * + * * HexCode ::= "HexCode" StartAddress HexDigits - * + * * Comment ::= "Comment" Position String - * + * * OperandComment ::= "OperandComment" Position String - * + * * JumpTable ::= "JumpTable" Position EntrySize Low High - * + * * LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize - * + * * Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int - * + * * Delim := "<||@" * </pre> *
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ */ @NodeInfo public final class AMD64CountLeadingZerosNode extends UnaryNode implements LIRLowerable { - public static final NodeClass<AMD64CountLeadingZerosNode> TYPE = NodeClass.get(AMD64CountLeadingZerosNode.class); + public static final NodeClass<AMD64CountLeadingZerosNode> TYPE = NodeClass.create(AMD64CountLeadingZerosNode.class); public AMD64CountLeadingZerosNode(ValueNode value) { super(TYPE, StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ */ @NodeInfo public final class AMD64CountTrailingZerosNode extends UnaryNode implements LIRLowerable { - public static final NodeClass<AMD64CountTrailingZerosNode> TYPE = NodeClass.get(AMD64CountTrailingZerosNode.class); + public static final NodeClass<AMD64CountTrailingZerosNode> TYPE = NodeClass.create(AMD64CountTrailingZerosNode.class); public AMD64CountTrailingZerosNode(ValueNode value) { super(TYPE, StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo public final class AMD64FloatConvertNode extends UnaryArithmeticNode<FloatConvertOp> implements ArithmeticLIRLowerable { - public static final NodeClass<AMD64FloatConvertNode> TYPE = NodeClass.get(AMD64FloatConvertNode.class); + public static final NodeClass<AMD64FloatConvertNode> TYPE = NodeClass.create(AMD64FloatConvertNode.class); protected final FloatConvert op;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -332,8 +332,8 @@ public void testCanonicalLength() { StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0); } @@ -348,8 +348,8 @@ public void testCanonicalEqual() { StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1); } @@ -362,10 +362,10 @@ public void testVirtualEqual() { StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new PartialEscapePhase(false, new CanonicalizerPhase(false)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1); } @@ -380,10 +380,10 @@ public void testVirtualNotEqual() { StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); - new PartialEscapePhase(false, new CanonicalizerPhase(false)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); + new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0); }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -249,7 +249,7 @@ private ValueNode parseAndInline(String name, Class<? extends ValueNode> expectedClass) { StructuredGraph graph = parseEager(name, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); new InliningPhase(canonicalizer).apply(graph, context); canonicalizer.apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,6 +26,7 @@ import org.junit.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.phases.common.*; @@ -67,9 +68,13 @@ Class<Runnable> c = (Class<Runnable>) testCl.loadClass(name); Runnable r = c.newInstance(); ct = Long.MAX_VALUE; - for (int i = 0; i < 100000000; i++) { + // warmup + for (int i = 0; i < 100; i++) { r.run(); } + // compile + ResolvedJavaMethod method = getResolvedJavaMethod(c, "run"); + getCode(method); ct = 0; r.run(); } catch (Throwable e) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -29,7 +29,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Edges.Type; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -45,7 +44,7 @@ @NodeInfo static final class TestNode extends Node { - public static final NodeClass<TestNode> TYPE = NodeClass.get(TestNode.class); + public static final NodeClass<TestNode> TYPE = NodeClass.create(TestNode.class); @Input NodeInputList<ValueNode> itail; @Input ConstantNode i1; @Input FloatingNode i2; @@ -74,25 +73,25 @@ node.i1 = i1; node.i2 = i2; graph.add(node); - inputs = node.getNodeClass().getEdges(Type.Inputs); + inputs = node.getNodeClass().getInputEdges(); } /** * Checks that there are no checkcasts in the compiled version of - * {@link Edges#getNode(Node, int)}. + * {@link Edges#getNode(Node, long[], int)}. */ @Test public void test0() { - testMethod(getMethod("getNode", Node.class, int.class), inputs, node, 0); + testMethod(getMethod("getNode", Node.class, long[].class, int.class), null, node, inputs.getOffsets(), 0); } /** * Checks that there are no checkcasts in the compiled version of - * {@link Edges#getNodeList(Node, int)}. + * {@link Edges#getNodeList(Node, long[], int)}. */ @Test public void test1() { - testMethod(getMethod("getNodeList", Node.class, int.class), inputs, node, 2); + testMethod(getMethod("getNodeList", Node.class, long[].class, int.class), null, node, inputs.getOffsets(), 2); } /** @@ -117,8 +116,8 @@ ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); StructuredGraph g = parseProfiled(javaMethod, AllowAssumptions.NO); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase(true)).apply(g, context); - new CanonicalizerPhase(false).apply(g, context); + new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase()).apply(g, context); + new CanonicalizerPhase().apply(g, context); Assert.assertTrue(g.getNodes().filter(CheckCastNode.class).isEmpty()); }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -52,9 +52,9 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new InliningPhase(new CanonicalizerPhase()).apply(graph, context); Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); assertNotInGraph(graph, Invoke.class);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -403,7 +403,7 @@ HighTierContext context = new HighTierContext(getProviders(), null, null, OptimisticOptimizations.ALL); StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES); - new CanonicalizerPhase(false).apply(graph, context); + new CanonicalizerPhase().apply(graph, context); Assert.assertEquals(expectedWordCasts, graph.getNodes().filter(WordCastNode.class).count()); }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,7 +25,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.compiler.test.*; import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/APHotSpotSignature.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/APHotSpotSignature.java Tue Mar 10 21:26:02 2015 +0100 @@ -149,7 +149,7 @@ /** * Returns the kind from the character describing a primitive or void. - * + * * @param ch the character * @return the kind */
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Mar 10 21:26:02 2015 +0100 @@ -259,6 +259,7 @@ memoryRead.setStateAfter(n.stateAfter()); ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead); + n.stateAfter().replaceFirstInput(n, memoryRead); n.replaceAtUsages(readValue); graph.replaceFixedWithFixed(n, memoryRead); }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/EdgesSubstitutions.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/EdgesSubstitutions.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,22 +40,12 @@ public class EdgesSubstitutions { @MethodSubstitution - private static Node getNode(Node node, long offset) { + private static Node getNodeUnsafe(Node node, long offset) { return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class); } @MethodSubstitution - private static NodeList<?> getNodeList(Node node, long offset) { + private static NodeList<?> getNodeListUnsafe(Node node, long offset) { return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), NodeList.class); } - - @MethodSubstitution - private static void putNode(Node node, long offset, Node value) { - UnsafeStoreNode.store(node, offset, value, Kind.Object, LocationIdentity.ANY_LOCATION); - } - - @MethodSubstitution - private static void putNodeList(Node node, long offset, NodeList<?> value) { - UnsafeStoreNode.store(node, offset, value, Kind.Object, LocationIdentity.ANY_LOCATION); - } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Log.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Log.java Tue Mar 10 21:26:02 2015 +0100 @@ -80,7 +80,7 @@ /** * Prints a formatted string to the log stream. - * + * * @param format a C style printf format value that can contain at most one conversion specifier * (i.e., a sequence of characters starting with '%'). * @param value the value associated with the conversion specifier
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,6 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; @@ -264,7 +263,7 @@ StructuredGraph graph = UseSnippetGraphCache ? graphs.get(method) : null; if (graph == null) { - try (TimerCloseable a = SnippetPreparationTime.start()) { + try (DebugCloseable a = SnippetPreparationTime.start()) { FrameStateProcessing frameStateProcessing = method.getAnnotation(Snippet.class).removeAllFrameStates() ? FrameStateProcessing.Removal : FrameStateProcessing.CollapseFrameForSingleSideEffect; StructuredGraph newGraph = makeGraph(method, recursiveEntry, inliningPolicy(method), frameStateProcessing); @@ -290,7 +289,7 @@ // Do deferred intrinsification of node intrinsics nodeIntrinsificationPhase.apply(specializedSnippet); - new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers)); + new CanonicalizerPhase().apply(specializedSnippet, new PhaseContext(providers)); NodeIntrinsificationVerificationPhase.verify(specializedSnippet); } @@ -541,7 +540,7 @@ } int sideEffectCount = 0; assert (sideEffectCount = graph.getNodes().filter(e -> hasSideEffect(e)).count()) >= 0; - new ConvertDeoptimizeToGuardPhase().apply(graph); + new ConvertDeoptimizeToGuardPhase().apply(graph, null); assert sideEffectCount == graph.getNodes().filter(e -> hasSideEffect(e)).count() : "deleted side effecting node"; switch (frameStateProcessing) { @@ -630,7 +629,7 @@ afterParsing(graph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers)); + new CanonicalizerPhase().apply(graph, new PhaseContext(replacements.providers)); } } catch (Throwable e) { throw Debug.handle(e); @@ -662,7 +661,7 @@ */ protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) { if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(caller, new PhaseContext(replacements.providers)); + new CanonicalizerPhase().apply(caller, new PhaseContext(replacements.providers)); } } @@ -673,7 +672,7 @@ replacements.nodeIntrinsificationPhase.apply(graph); new DeadCodeEliminationPhase(Optional).apply(graph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers)); + new CanonicalizerPhase().apply(graph, new PhaseContext(replacements.providers)); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,7 +43,6 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; @@ -395,7 +394,7 @@ @NodeInfo static final class VarargsPlaceholderNode extends FloatingNode implements ArrayLengthProvider { - public static final NodeClass<VarargsPlaceholderNode> TYPE = NodeClass.get(VarargsPlaceholderNode.class); + public static final NodeClass<VarargsPlaceholderNode> TYPE = NodeClass.create(VarargsPlaceholderNode.class); protected final Varargs varargs; public VarargsPlaceholderNode(Varargs varargs, MetaAccessProvider metaAccess) { @@ -520,7 +519,7 @@ SnippetTemplate template = UseSnippetTemplateCache ? templates.get(args.cacheKey) : null; if (template == null) { SnippetTemplates.increment(); - try (TimerCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) { + try (DebugCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) { template = new SnippetTemplate(providers, snippetReflection, args); if (UseSnippetTemplateCache) { templates.put(args.cacheKey, template); @@ -671,8 +670,8 @@ if (loopBegin != null) { LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); Mark mark = snippetCopy.getMark(); - LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true)); - new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark); + LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase()); + new CanonicalizerPhase().applyIncremental(snippetCopy, phaseContext, mark); loop.deleteUnusedNodes(); } GraphUtil.removeFixedWithUnusedInputs(explodeLoop); @@ -687,7 +686,7 @@ } snippetCopy.setGuardsStage(guardsStage); try (Scope s = Debug.scope("LoweringSnippetTemplate", snippetCopy)) { - new LoweringPhase(new CanonicalizerPhase(true), args.cacheKey.loweringStage).apply(snippetCopy, phaseContext); + new LoweringPhase(new CanonicalizerPhase(), args.cacheKey.loweringStage).apply(snippetCopy, phaseContext); } catch (Throwable e) { throw Debug.handle(e); } @@ -721,7 +720,7 @@ assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders); - new FloatingReadPhase(false, true, false).apply(snippetCopy); + new FloatingReadPhase(false, true).apply(snippetCopy); MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode()); snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor); @@ -746,7 +745,7 @@ List<MemoryMapNode> memMaps = returnNodes.stream().map(n -> n.getMemoryMap()).collect(Collectors.toList()); ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes, null); this.returnNode = snippet.add(new ReturnNode(returnValue)); - MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps, false); + MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps); MemoryMapNode memoryMap = snippet.unique(new MemoryMapNode(mmap.getMap())); this.returnNode.setMemoryMap(memoryMap); for (MemoryMapNode mm : memMaps) { @@ -1097,7 +1096,7 @@ */ public Map<Node, Node> instantiate(MetaAccessProvider metaAccess, FixedNode replacee, UsageReplacer replacer, Arguments args) { assert assertSnippetKills(replacee); - try (TimerCloseable a = args.info.instantiationTimer.start(); TimerCloseable b = instantiationTimer.start()) { + try (DebugCloseable a = args.info.instantiationTimer.start(); DebugCloseable b = instantiationTimer.start()) { args.info.instantiationCounter.increment(); instantiationCounter.increment(); // Inline the snippet nodes, replacing parameters with the given args in the process @@ -1244,7 +1243,7 @@ */ public void instantiate(MetaAccessProvider metaAccess, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) { assert assertSnippetKills(replacee); - try (TimerCloseable a = args.info.instantiationTimer.start()) { + try (DebugCloseable a = args.info.instantiationTimer.start()) { args.info.instantiationCounter.increment(); instantiationCounter.increment();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess { - public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.get(ArrayEqualsNode.class); + public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class); /** {@link Kind} of the arrays to compare. */ protected final Kind kind; @@ -51,6 +51,8 @@ /** Length of both arrays. */ @Input ValueNode length; + @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess; + public ArrayEqualsNode(ValueNode array1, ValueNode array2, ValueNode length) { super(TYPE, StampFactory.forKind(Kind.Boolean)); // Ignore nullness in stamp equality test @@ -139,4 +141,13 @@ public LocationIdentity getLocationIdentity() { return NamedLocationIdentity.getArrayLocation(kind); } + + public MemoryNode getLastLocationAccess() { + return lastLocationAccess; + } + + public void setLastLocationAccess(MemoryNode lla) { + updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla)); + lastLocationAccess = lla; + } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class AssertionNode extends FixedWithNextNode implements Lowerable, Canonicalizable, LIRLowerable { - public static final NodeClass<AssertionNode> TYPE = NodeClass.get(AssertionNode.class); + public static final NodeClass<AssertionNode> TYPE = NodeClass.create(AssertionNode.class); @Input ValueNode value; protected final boolean compileTimeAssertion;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicArrayCopyNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicArrayCopyNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,7 +34,7 @@ @NodeInfo public abstract class BasicArrayCopyNode extends MacroStateSplitNode implements Virtualizable { - public static final NodeClass<BasicArrayCopyNode> TYPE = NodeClass.get(BasicArrayCopyNode.class); + public static final NodeClass<BasicArrayCopyNode> TYPE = NodeClass.create(BasicArrayCopyNode.class); public BasicArrayCopyNode(NodeClass<? extends BasicArrayCopyNode> c, Invoke invoke) { super(c, invoke);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public abstract class BasicObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider { - public static final NodeClass<BasicObjectCloneNode> TYPE = NodeClass.get(BasicObjectCloneNode.class); + public static final NodeClass<BasicObjectCloneNode> TYPE = NodeClass.create(BasicObjectCloneNode.class); protected BasicObjectCloneNode(NodeClass<? extends BasicObjectCloneNode> c, Invoke invoke) { super(c, invoke); @@ -64,7 +64,7 @@ /* * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an * exact type) and if it is a cloneable type. - * + * * If yes, then the exact type is returned, otherwise it returns null. */ protected static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class BitCountNode extends UnaryNode implements LIRLowerable { - public static final NodeClass<BitCountNode> TYPE = NodeClass.get(BitCountNode.class); + public static final NodeClass<BitCountNode> TYPE = NodeClass.create(BitCountNode.class); public BitCountNode(ValueNode value) { super(TYPE, StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class BitScanForwardNode extends UnaryNode implements LIRLowerable { - public static final NodeClass<BitScanForwardNode> TYPE = NodeClass.get(BitScanForwardNode.class); + public static final NodeClass<BitScanForwardNode> TYPE = NodeClass.create(BitScanForwardNode.class); public BitScanForwardNode(ValueNode value) { super(TYPE, StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class BitScanReverseNode extends UnaryNode implements LIRLowerable { - public static final NodeClass<BitScanReverseNode> TYPE = NodeClass.get(BitScanReverseNode.class); + public static final NodeClass<BitScanReverseNode> TYPE = NodeClass.create(BitScanReverseNode.class); public BitScanReverseNode(ValueNode value) { super(TYPE, StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DeferredPiNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DeferredPiNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -40,7 +40,7 @@ */ @NodeInfo public final class DeferredPiNode extends FloatingNode implements Canonicalizable { - public static final NodeClass<DeferredPiNode> TYPE = NodeClass.get(DeferredPiNode.class); + public static final NodeClass<DeferredPiNode> TYPE = NodeClass.create(DeferredPiNode.class); @Input ValueNode object; @Input ValueNode type;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable { - public static final NodeClass<DirectObjectStoreNode> TYPE = NodeClass.get(DirectObjectStoreNode.class); + public static final NodeClass<DirectObjectStoreNode> TYPE = NodeClass.create(DirectObjectStoreNode.class); @Input ValueNode object; @Input ValueNode value; @Input ValueNode offset;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class DirectReadNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<DirectReadNode> TYPE = NodeClass.get(DirectReadNode.class); + public static final NodeClass<DirectReadNode> TYPE = NodeClass.create(DirectReadNode.class); @Input protected ValueNode address; protected final Kind readKind;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class DirectStoreNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<DirectStoreNode> TYPE = NodeClass.get(DirectStoreNode.class); + public static final NodeClass<DirectStoreNode> TYPE = NodeClass.create(DirectStoreNode.class); @Input protected ValueNode address; @Input protected ValueNode value; protected final Kind kind;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ */ @NodeInfo public final class ExplodeLoopNode extends FixedWithNextNode { - public static final NodeClass<ExplodeLoopNode> TYPE = NodeClass.get(ExplodeLoopNode.class); + public static final NodeClass<ExplodeLoopNode> TYPE = NodeClass.create(ExplodeLoopNode.class); public ExplodeLoopNode() { super(TYPE, StampFactory.forVoid());
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class LoadSnippetVarargParameterNode extends FixedWithNextNode implements Canonicalizable { - public static final NodeClass<LoadSnippetVarargParameterNode> TYPE = NodeClass.get(LoadSnippetVarargParameterNode.class); + public static final NodeClass<LoadSnippetVarargParameterNode> TYPE = NodeClass.create(LoadSnippetVarargParameterNode.class); @Input ValueNode index; @Input NodeInputList<ParameterNode> parameters;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -59,7 +59,7 @@ @NodeInfo public abstract class MacroNode extends FixedWithNextNode implements Lowerable { - public static final NodeClass<MacroNode> TYPE = NodeClass.get(MacroNode.class); + public static final NodeClass<MacroNode> TYPE = NodeClass.create(MacroNode.class); @Input protected NodeInputList<ValueNode> arguments; protected final int bci; @@ -142,7 +142,7 @@ } } try (Scope s = Debug.scope("LoweringSnippetTemplate", replacementGraph)) { - new LoweringPhase(new CanonicalizerPhase(true), tool.getLoweringStage()).apply(replacementGraph, c); + new LoweringPhase(new CanonicalizerPhase(), tool.getLoweringStage()).apply(replacementGraph, c); } catch (Throwable e) { throw Debug.handle(e); } @@ -171,7 +171,7 @@ InliningUtil.inline(invoke, replacementGraph, false, null); Debug.dump(graph(), "After inlining replacement %s", replacementGraph); } else { - if (stateAfter() == null) { + if (invoke.stateAfter() == null) { throw new GraalInternalError("cannot lower to invoke without state: %s", this); } invoke.lower(tool);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public abstract class MacroStateSplitNode extends MacroNode implements StateSplit, MemoryCheckpoint.Single { - public static final NodeClass<MacroStateSplitNode> TYPE = NodeClass.get(MacroStateSplitNode.class); + public static final NodeClass<MacroStateSplitNode> TYPE = NodeClass.create(MacroStateSplitNode.class); @OptionalInput(InputType.State) protected FrameState stateAfter; public MacroStateSplitNode(NodeClass<? extends MacroStateSplitNode> c, Invoke invoke) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo public final class MathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable { - public static final NodeClass<MathIntrinsicNode> TYPE = NodeClass.get(MathIntrinsicNode.class); + public static final NodeClass<MathIntrinsicNode> TYPE = NodeClass.create(MathIntrinsicNode.class); protected final Operation operation; public enum Operation {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathPowNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathPowNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class MathPowNode extends MacroStateSplitNode implements Canonicalizable.Binary<ValueNode> { - public static final NodeClass<MathPowNode> TYPE = NodeClass.get(MathPowNode.class); + public static final NodeClass<MathPowNode> TYPE = NodeClass.create(MathPowNode.class); public MathPowNode(Invoke i) { super(TYPE, i);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class MemoryAnchorNode extends FixedWithNextNode implements LIRLowerable, MemoryNode, Canonicalizable { - public static final NodeClass<MemoryAnchorNode> TYPE = NodeClass.get(MemoryAnchorNode.class); + public static final NodeClass<MemoryAnchorNode> TYPE = NodeClass.create(MemoryAnchorNode.class); public MemoryAnchorNode() { super(TYPE, StampFactory.forVoid());
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public abstract class PureFunctionMacroNode extends MacroStateSplitNode implements Canonicalizable { - public static final NodeClass<PureFunctionMacroNode> TYPE = NodeClass.get(PureFunctionMacroNode.class); + public static final NodeClass<PureFunctionMacroNode> TYPE = NodeClass.create(PureFunctionMacroNode.class); protected PureFunctionMacroNode(NodeClass<? extends PureFunctionMacroNode> c, Invoke invoke) { super(c, invoke);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo(nameTemplate = "ReadRegister %{p#register}") public final class ReadRegisterNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<ReadRegisterNode> TYPE = NodeClass.get(ReadRegisterNode.class); + public static final NodeClass<ReadRegisterNode> TYPE = NodeClass.create(ReadRegisterNode.class); /** * The fixed register to access. */
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class ReverseBytesNode extends UnaryNode implements LIRLowerable { - public static final NodeClass<ReverseBytesNode> TYPE = NodeClass.get(ReverseBytesNode.class); + public static final NodeClass<ReverseBytesNode> TYPE = NodeClass.create(ReverseBytesNode.class); public ReverseBytesNode(ValueNode value) { super(TYPE, StampFactory.forKind(value.getKind()), value);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,7 +36,7 @@ @NodeInfo(nameTemplate = "WriteRegister %{p#register}") public final class WriteRegisterNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<WriteRegisterNode> TYPE = NodeClass.get(WriteRegisterNode.class); + public static final NodeClass<WriteRegisterNode> TYPE = NodeClass.create(WriteRegisterNode.class); /** * The fixed register to access. */
--- a/graal/com.oracle.graal.runtime/src/com/oracle/graal/runtime/RuntimeProvider.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.runtime/src/com/oracle/graal/runtime/RuntimeProvider.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ /** * Gets the backend for a given architecture. - * + * * @param arch a specific architecture class */ <T extends Architecture> Backend getBackend(Class<T> arch);
--- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,25 +22,23 @@ */ package com.oracle.graal.truffle.hotspot.sparc; -import com.oracle.graal.api.code.CallingConvention.Type; +import static com.oracle.graal.api.code.CallingConvention.Type.*; +import static com.oracle.graal.api.meta.Kind.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; +import static com.oracle.graal.sparc.SPARC.CPUFeature.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe; -import com.oracle.graal.asm.sparc.SPARCAssembler.CBcondx; -import com.oracle.graal.asm.sparc.SPARCAssembler.CC; -import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; -import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Jmp; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; 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.SPARC.CPUFeature; import com.oracle.graal.sparc.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.hotspot.*; @@ -56,23 +54,23 @@ @SuppressWarnings("hiding") SPARCMacroAssembler asm = (SPARCMacroAssembler) this.asm; try (SPARCScratchRegister scratch = SPARCScratchRegister.get()) { - Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, Kind.Object)[0]; + Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(JavaCall, Object)[0]; Register spillRegister = scratch.getRegister(); Label doProlog = new Label(); SPARCAddress codeBlobAddress = new SPARCAddress(thisRegister, getFieldOffset("address", InstalledCode.class)); SPARCAddress verifiedEntryPointAddress = new SPARCAddress(spillRegister, config.nmethodEntryOffset); - new Ldx(codeBlobAddress, spillRegister).emit(asm); - if (asm.hasFeature(CPUFeature.CBCOND)) { - new CBcondx(ConditionFlag.Equal, spillRegister, 0, doProlog).emit(asm); + asm.ldx(codeBlobAddress, spillRegister); + if (asm.hasFeature(CBCOND)) { + asm.cbcondx(Equal, spillRegister, 0, doProlog); } else { - new Cmp(spillRegister, 0).emit(asm); - new Bpe(CC.Xcc, doProlog).emit(asm); - new Nop().emit(asm); + asm.cmp(spillRegister, 0); + asm.bpcc(Equal, NOT_ANNUL, doProlog, Xcc, PREDICT_NOT_TAKEN); + asm.nop(); } - new Ldx(verifiedEntryPointAddress, spillRegister).emit(asm); // in delay slot - new Jmp(spillRegister).emit(asm); - new Nop().emit(asm); + asm.ldx(verifiedEntryPointAddress, spillRegister); // in delay slot + asm.jmp(spillRegister); + asm.nop(); asm.bind(doProlog); } }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 10 21:26:02 2015 +0100 @@ -137,6 +137,7 @@ compilationPolicy = new InterpreterOnlyCompilationPolicy(); } OptimizedCallTarget target = new OptimizedCallTarget(source, rootNode, this, compilationPolicy, new HotSpotSpeculationLog()); + rootNode.setCallTarget(target); callTargets.put(target, null); return target;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/BytecodeInterpreterPartialEvaluationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.test; + +import org.junit.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +public class BytecodeInterpreterPartialEvaluationTest extends PartialEvaluationTest { + + public static class Bytecode { + public static final byte CONST = 0; + public static final byte RETURN = 1; + public static final byte ADD = 2; + public static final byte IFZERO = 3; + public static final byte POP = 4; + public static final byte JMP = 5; + public static final byte DUP = 6; + } + + public static boolean TRACE = false; + + public static class Program extends RootNode { + private final String name; + @CompilationFinal private final byte[] bytecodes; + @CompilationFinal private final FrameSlot[] locals; + @CompilationFinal private final FrameSlot[] stack; + + public Program(String name, byte[] bytecodes, int maxLocals, int maxStack) { + this.name = name; + this.bytecodes = bytecodes; + locals = new FrameSlot[maxLocals]; + stack = new FrameSlot[maxStack]; + for (int i = 0; i < maxLocals; ++i) { + locals[i] = this.getFrameDescriptor().addFrameSlot("local" + i); + locals[i].setKind(FrameSlotKind.Int); + } + for (int i = 0; i < maxStack; ++i) { + stack[i] = this.getFrameDescriptor().addFrameSlot("stack" + i); + stack[i].setKind(FrameSlotKind.Int); + } + } + + protected void setInt(VirtualFrame frame, int stackIndex, int value) { + frame.setInt(stack[stackIndex], value); + } + + protected int getInt(VirtualFrame frame, int stackIndex) { + try { + return frame.getInt(stack[stackIndex]); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException("Error accessing stack slot " + stackIndex); + } + } + + @Override + public String toString() { + return name; + } + + public void trace(String format, Object... args) { + if (CompilerDirectives.inInterpreter() && TRACE) { + System.out.println(String.format(format, args)); + } + } + + @Override + @ExplodeLoop(merge = true) + public Object execute(VirtualFrame frame) { + trace("Start program"); + int topOfStack = -1; + int bci = 0; + while (true) { + CompilerAsserts.partialEvaluationConstant(bci); + byte bc = bytecodes[bci]; + byte value = 0; + switch (bc) { + case Bytecode.CONST: + value = bytecodes[bci + 1]; + trace("%d (%d): CONST %s", bci, topOfStack, value); + setInt(frame, ++topOfStack, value); + bci = bci + 2; + continue; + + case Bytecode.RETURN: + trace("%d (%d): RETURN", bci, topOfStack); + return getInt(frame, topOfStack); + + case Bytecode.ADD: { + int left = getInt(frame, topOfStack); + int right = getInt(frame, topOfStack - 1); + trace("%d (%d): ADD %d %d", bci, topOfStack, left, right); + setInt(frame, topOfStack - 1, left + right); + topOfStack--; + bci = bci + 1; + continue; + } + + case Bytecode.IFZERO: + trace("%d (%d): IFZERO", bci, topOfStack); + if (getInt(frame, topOfStack--) == 0) { + bci = bytecodes[bci + 1]; + continue; + } else { + bci = bci + 2; + continue; + } + + case Bytecode.POP: + trace("%d (%d): POP", bci, topOfStack); + topOfStack--; + bci++; + continue; + + case Bytecode.JMP: + trace("%d (%d): JMP", bci, topOfStack); + bci = bytecodes[bci + 1]; + continue; + + case Bytecode.DUP: + trace("%d (%d): DUP", bci, topOfStack); + setInt(frame, topOfStack + 1, getInt(frame, topOfStack)); + topOfStack++; + bci++; + continue; + } + } + } + } + + public static Object constant42() { + return 42; + } + + private static void assertReturns42(Program program) { + Assert.assertEquals(Integer.valueOf(42), Truffle.getRuntime().createCallTarget(program).call()); + } + + private void assertPartialEvalEqualsAndRunsCorrect(Program program) { + assertReturns42(program); + assertPartialEvalEquals("constant42", program); + } + + @Test + public void constReturnProgram() { + byte[] bytecodes = new byte[]{ + /* 0: */Bytecode.CONST, + /* 1: */42, + /* 2: */Bytecode.RETURN}; + assertPartialEvalEqualsAndRunsCorrect(new Program("constReturnProgram", bytecodes, 0, 2)); + } + + @Test + public void constAddProgram() { + byte[] bytecodes = new byte[]{ + /* 0: */Bytecode.CONST, + /* 1: */40, + /* 2: */Bytecode.CONST, + /* 3: */2, + /* 4: */Bytecode.ADD, + /* 5: */Bytecode.RETURN}; + assertPartialEvalEqualsAndRunsCorrect(new Program("constAddProgram", bytecodes, 0, 2)); + } + + @Test + public void simpleIfProgram() { + byte[] bytecodes = new byte[]{ + /* 0: */Bytecode.CONST, + /* 1: */40, + /* 2: */Bytecode.CONST, + /* 3: */1, + /* 4: */Bytecode.IFZERO, + /* 5: */8, + /* 6: */Bytecode.CONST, + /* 7: */42, + /* 8: */Bytecode.RETURN}; + assertPartialEvalEqualsAndRunsCorrect(new Program("simpleIfProgram", bytecodes, 0, 3)); + } + + @Test + public void ifAndPopProgram() { + byte[] bytecodes = new byte[]{ + /* 0: */Bytecode.CONST, + /* 1: */40, + /* 2: */Bytecode.CONST, + /* 3: */1, + /* 4: */Bytecode.IFZERO, + /* 5: */9, + /* 6: */Bytecode.POP, + /* 7: */Bytecode.CONST, + /* 8: */42, + /* 9: */Bytecode.RETURN}; + assertPartialEvalEqualsAndRunsCorrect(new Program("ifAndPopProgram", bytecodes, 0, 3)); + } + + @Test + public void simpleLoopProgram() { + byte[] bytecodes = new byte[]{ + /* 0: */Bytecode.CONST, + /* 1: */42, + /* 2: */Bytecode.CONST, + /* 3: */-12, + /* 4: */Bytecode.CONST, + /* 5: */1, + /* 6: */Bytecode.ADD, + /* 7: */Bytecode.DUP, + /* 8: */Bytecode.IFZERO, + /* 9: */12, + /* 10: */Bytecode.JMP, + /* 11: */4, + /* 12: */Bytecode.POP, + /* 13: */Bytecode.RETURN}; + assertPartialEvalEqualsAndRunsCorrect(new Program("simpleLoopProgram", bytecodes, 0, 3)); + } + + @Test + public void nestedLoopsProgram() { + byte[] bytecodes = new byte[]{ + /* 0: */Bytecode.CONST, + /* 1: */42, + /* 2: */Bytecode.CONST, + /* 3: */-2, + /* 4: */Bytecode.CONST, + /* 5: */1, + /* 6: */Bytecode.ADD, + /* 7: */Bytecode.DUP, + /* 8: */Bytecode.CONST, + /* 9: */-2, + /* 10: */Bytecode.CONST, + /* 11: */1, + /* 12: */Bytecode.ADD, + /* 13: */Bytecode.DUP, + /* 14: */Bytecode.IFZERO, + /* 15: */18, + /* 16: */Bytecode.JMP, + /* 17: */10, + /* 18: */Bytecode.POP, + /* 19: */Bytecode.IFZERO, + /* 20: */23, + /* 21: */Bytecode.JMP, + /* 22: */4, + /* 23: */Bytecode.POP, + /* 24: */Bytecode.RETURN}; + assertPartialEvalEqualsAndRunsCorrect(new Program("nestedLoopsProgram", bytecodes, 0, 6)); + } + + @Test(timeout = 1000) + public void manyIfsProgram() { + byte[] bytecodes = new byte[]{ + /* 0: */Bytecode.CONST, + /* 1: */40, + /* 2: */Bytecode.CONST, + /* 3: */1, + /* 4: */Bytecode.IFZERO, + /* 5: */8, + /* 6: */Bytecode.CONST, + /* 7: */1, + /* 8: */Bytecode.IFZERO, + /* 9: */12, + /* 10: */Bytecode.CONST, + /* 11: */1, + /* 12: */Bytecode.IFZERO, + /* 13: */16, + /* 14: */Bytecode.CONST, + /* 15: */1, + /* 16: */Bytecode.IFZERO, + /* 17: */20, + /* 18: */Bytecode.CONST, + /* 19: */1, + /* 20: */Bytecode.IFZERO, + /* 21: */24, + /* 22: */Bytecode.CONST, + /* 23: */1, + /* 24: */Bytecode.IFZERO, + /* 25: */28, + /* 26: */Bytecode.CONST, + /* 27: */1, + /* 28: */Bytecode.IFZERO, + /* 29: */32, + /* 30: */Bytecode.CONST, + /* 31: */1, + /* 32: */Bytecode.IFZERO, + /* 33: */36, + /* 34: */Bytecode.CONST, + /* 35: */1, + /* 36: */Bytecode.IFZERO, + /* 37: */40, + /* 38: */Bytecode.CONST, + /* 39: */1, + /* 40: */Bytecode.IFZERO, + /* 41: */44, + /* 42: */Bytecode.CONST, + /* 43: */42, + /* 44: */Bytecode.RETURN}; + assertPartialEvalEqualsAndRunsCorrect(new Program("manyIfsProgram", bytecodes, 0, 3)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/CompilerAssertsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.truffle.test.nodes.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; + +public class CompilerAssertsTest extends PartialEvaluationTest { + + public static class NeverPartOfCompilationTestNode extends AbstractTestNode { + + @Override + public int execute(VirtualFrame frame) { + CompilerAsserts.neverPartOfCompilation(); + return 0; + } + + } + + public static class CompilationConstantTestNode extends AbstractTestNode { + @Child private AbstractTestNode child; + + public CompilationConstantTestNode(AbstractTestNode child) { + this.child = child; + } + + @Override + public int execute(VirtualFrame frame) { + CompilerAsserts.compilationConstant(child.execute(frame)); + return 0; + } + + } + + @Test + public void neverPartOfCompilationTest() { + NeverPartOfCompilationTestNode result = new NeverPartOfCompilationTestNode(); + RootTestNode rootNode = new RootTestNode(new FrameDescriptor(), "neverPartOfCompilation", result); + try { + compileHelper("neverPartOfCompilation", rootNode, new Object[0]); + Assert.fail("Expected bailout exception due to never part of compilation"); + } catch (BailoutException e) { + // Bailout exception expected. + } + } + + @Test + public void compilationNonConstantTest() { + FrameDescriptor descriptor = new FrameDescriptor(); + CompilationConstantTestNode result = new CompilationConstantTestNode(new NonConstantTestNode(5)); + RootTestNode rootNode = new RootTestNode(descriptor, "compilationConstant", result); + try { + compileHelper("compilationConstant", rootNode, new Object[0]); + Assert.fail("Expected bailout exception because expression is not compilation constant"); + } catch (BailoutException e) { + // Bailout exception expected. + } + } + + @Test + public void compilationConstantTest() { + FrameDescriptor descriptor = new FrameDescriptor(); + CompilationConstantTestNode result = new CompilationConstantTestNode(new ConstantTestNode(5)); + RootTestNode rootNode = new RootTestNode(descriptor, "compilationConstant", result); + compileHelper("compilationConstant", rootNode, new Object[0]); + } +}
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -141,7 +141,7 @@ final int[] count = {1}; count[0] = 0; // Register a "prober" that will get applied when CallTarget gets created. - Probe.registerASTProber(new ASTProber() { + final ASTProber prober = new ASTProber() { @Override public void probeAST(Node node) { @@ -157,31 +157,92 @@ }); } - }); - final RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(root); + }; + Probe.registerASTProber(prober); + try { + final RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(root); + + // The CallTarget has one Probe, attached to the ConstantTestNode, ready to run + Assert.assertEquals(42, callTarget.call()); // Correct result + Assert.assertEquals(0, count[0]); // Didn't count anything + + // Add a counting instrument; this changes the "Probe state" and should cause a deopt + final Instrument countingInstrument = Instrument.create(new DefaultEventListener() { + + @Override + public void enter(Node node, VirtualFrame frame) { + count[0] = count[0] + 1; + } + }); + probe[0].attach(countingInstrument); + + Assert.assertEquals(42, callTarget.call()); // Correct result + Assert.assertEquals(1, count[0]); // Counted the first call - // The CallTarget has one Probe, attached to the ConstantTestNode, ready to run - Assert.assertEquals(42, callTarget.call()); // Correct result - Assert.assertEquals(0, count[0]); // Didn't count anything + // Remove the counting instrument; this changes the "Probe state" and should cause a + // deopt + countingInstrument.dispose(); + + Assert.assertEquals(42, callTarget.call()); // Correct result + Assert.assertEquals(1, count[0]); // Didn't count this time + } finally { + Probe.unregisterASTProber(prober); + } + + } - // Add a counting instrument; this changes the "Probe state" and should cause a deopt - final Instrument countingInstrument = Instrument.create(new DefaultEventListener() { + /** + * Experimental feature; not yet validated. + */ + @Test + public void specialOptInstrument() { + final FrameDescriptor fd = new FrameDescriptor(); + final AbstractTestNode result = new ConstantTestNode(42); + final RootTestNode root = new RootTestNode(fd, "constantValue", result); + final Probe[] probe = new Probe[1]; + final int[] count = {1}; + count[0] = 0; + // Register a "prober" that will get applied when CallTarget gets created. + final ASTProber prober = new ASTProber() { @Override - public void enter(Node node, VirtualFrame frame) { - count[0] = count[0] + 1; + public void probeAST(Node node) { + node.accept(new NodeVisitor() { + + @Override + public boolean visit(Node visitedNode) { + if (visitedNode instanceof ConstantTestNode) { + probe[0] = visitedNode.probe(); + } + return true; + } + }); } - }); - probe[0].attach(countingInstrument); + }; + Probe.registerASTProber(prober); + try { + final RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(root); - Assert.assertEquals(42, callTarget.call()); // Correct result - Assert.assertEquals(1, count[0]); // Counted the first call + // The CallTarget has one Probe, attached to the ConstantTestNode, ready to run + Assert.assertEquals(42, callTarget.call()); // Correct result + + final boolean[] isCurrentlyCompiled = {false}; + final Instrument optInstrument = Instrument.create(new Instrument.TruffleOptListener() { - // Remove the counting instrument; this changes the "Probe state" and should cause a deopt - countingInstrument.dispose(); + public void notifyIsCompiled(boolean isCompiled) { + isCurrentlyCompiled[0] = isCompiled; + } + }); + probe[0].attach(optInstrument); - Assert.assertEquals(42, callTarget.call()); // Correct result - Assert.assertEquals(1, count[0]); // Didn't count this time + Assert.assertEquals(42, callTarget.call()); // Correct result + Assert.assertFalse(isCurrentlyCompiled[0]); + + // TODO (mlvdv) compile, call again, and assert that isCurrentlyCompiled == true + + } finally { + Probe.unregisterASTProber(prober); + } } }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -100,7 +100,7 @@ frameState.replaceAtUsages(null); frameState.safeDelete(); } - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); + new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new DeadCodeEliminationPhase().apply(graph); }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,6 +24,7 @@ import org.junit.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.truffle.test.nodes.*; import com.oracle.truffle.api.frame.*; @@ -48,6 +49,32 @@ } @Test + public void neverPartOfCompilationTest() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode firstTree = new NeverPartOfCompilationTestNode(new ConstantTestNode(1), 2); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "neverPartOfCompilationTest", firstTree)); + + AbstractTestNode secondTree = new NeverPartOfCompilationTestNode(new ConstantTestNode(1), 1); + try { + assertPartialEvalEquals("constant42", new RootTestNode(fd, "neverPartOfCompilationTest", secondTree)); + Assert.fail("Expected verification error!"); + } catch (SourceStackTrace t) { + // Expected verification error occurred. + StackTraceElement[] trace = t.getStackTrace(); + Assert.assertEquals("com.oracle.truffle.api.nodes.RootNode.getFrameDescriptor(RootNode.java)", trace[0].toString()); + String secondString = trace[1].toString(); + Assert.assertEquals("com.oracle.graal.truffle.OptimizedCallTarget.callRoot(OptimizedCallTarget.java:" /* "259)" */, secondString.substring(0, secondString.length() - 4)); + } + } + + @Test + public void nestedLoopExplosion() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new AddTestNode(new NestedExplodedLoopTestNode(5), new ConstantTestNode(17)); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "nestedLoopExplosion", result)); + } + + @Test public void sequenceConstants() { FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new BlockTestNode(new AbstractTestNode[]{new ConstantTestNode(40), new ConstantTestNode(42)});
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/BlockTestNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/BlockTestNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @Children private final AbstractTestNode[] statements; - public BlockTestNode(AbstractTestNode[] statements) { + public BlockTestNode(AbstractTestNode... statements) { this.statements = statements; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NestedExplodedLoopTestNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.test.nodes; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +@NodeInfo +public class NestedExplodedLoopTestNode extends AbstractTestNode { + + private final int count; + + public NestedExplodedLoopTestNode(int count) { + this.count = count; + } + + @ExplodeLoop + @Override + public int execute(VirtualFrame frame) { + int result = 0; + for (int i = 0; i < count; ++i) { + for (int j = 0; j < count; ++j) { + result++; + } + } + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NeverPartOfCompilationTestNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 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.truffle.test.nodes; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; + +public class NeverPartOfCompilationTestNode extends AbstractTestNode { + + @Child private AbstractTestNode left; + private final int value; + + private static class ValueContainer { + int value; + } + + public NeverPartOfCompilationTestNode(AbstractTestNode left, int value) { + this.left = left; + this.value = value; + } + + @Override + public int execute(VirtualFrame frame) { + ValueContainer v = new ValueContainer(); + v.value = value; + if (v.value == left.execute(frame)) { + CompilerAsserts.neverPartOfCompilation(); + } + return 42; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NonConstantTestNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 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.truffle.test.nodes; + +import com.oracle.truffle.api.frame.*; + +public class NonConstantTestNode extends AbstractTestNode { + + private int value; + + public NonConstantTestNode(int value) { + this.value = value; + } + + @Override + public int execute(VirtualFrame frame) { + return value; + } +}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategy.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategy.java Tue Mar 10 21:26:02 2015 +0100 @@ -62,7 +62,7 @@ return false; } OptimizedCallTarget splitTarget = call.getCallTarget(); - int nodeCount = splitTarget.countNonTrivialNodes(false); + int nodeCount = splitTarget.countNonTrivialNodes(); if (nodeCount > TruffleCompilerOptions.TruffleSplittingMaxCalleeSize.getValue()) { return false; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategyNew.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategyNew.java Tue Mar 10 21:26:02 2015 +0100 @@ -55,7 +55,7 @@ if (TruffleCompilerOptions.TruffleSplittingAggressive.getValue()) { return true; } - int size = call.getCallTarget().countNonTrivialNodes(false); + int size = call.getCallTarget().countNonTrivialNodes(); if (size > TruffleCompilerOptions.TruffleSplittingMaxCalleeSize.getValue()) { return false; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Mar 10 21:26:02 2015 +0100 @@ -56,6 +56,7 @@ protected final CompilationPolicy compilationPolicy; private final OptimizedCallTarget sourceCallTarget; private final AtomicInteger callSitesKnown = new AtomicInteger(0); + private final ValueProfile exceptionProfile = ValueProfile.createClassProfile(); @CompilationFinal private Class<?>[] profiledArgumentTypes; @CompilationFinal private Assumption profiledArgumentTypesAssumption; @@ -70,6 +71,7 @@ private TruffleStamp argumentStamp = DefaultTruffleStamp.getInstance(); private TruffleInlining inlining; + private int cachedNonTrivialNodeCount = -1; /** * When this call target is inlined, the inlining {@link InstalledCode} registers this @@ -91,7 +93,6 @@ this.compilationPolicy = compilationPolicy; this.rootNode.adoptChildren(); this.rootNode.applyInstrumentation(); - this.rootNode.setCallTarget(this); this.uninitializedRootNode = sourceCallTarget == null ? cloneRootNode(rootNode) : sourceCallTarget.uninitializedRootNode; if (TruffleCallTargetProfiling.getValue()) { this.compilationProfile = new TraceCompilationProfile(); @@ -233,7 +234,18 @@ } protected Object doInvoke(Object[] args) { - return callBoundary(args); + try { + return callBoundary(args); + } catch (Throwable t) { + t = exceptionProfile.profile(t); + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else if (t instanceof Error) { + throw (Error) t; + } else { + throw new RuntimeException(t); + } + } } @TruffleCallBoundary @@ -287,6 +299,7 @@ if (isValid()) { this.runtime.invalidateInstalledCode(this, source, reason); } + cachedNonTrivialNodeCount = -1; } public TruffleInlining getInlining() { @@ -469,8 +482,17 @@ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false); } - public int countNonTrivialNodes(final boolean inlined) { - return (int) nodeStream(inlined).filter(e -> e != null && !e.getCost().isTrivial()).count(); + public final int countNonTrivialNodes() { + if (cachedNonTrivialNodeCount == -1) { + cachedNonTrivialNodeCount = calculateNonTrivialNodesImpl(); + } + return cachedNonTrivialNodeCount; + } + + private int calculateNonTrivialNodesImpl() { + NonTrivialNodeCountVisitor visitor = new NonTrivialNodeCountVisitor(); + getRootNode().accept(visitor); + return visitor.nodeCount; } public Map<String, Object> getDebugProperties() { @@ -506,4 +528,17 @@ return context.getCompilerOptions(); } + private static final class NonTrivialNodeCountVisitor implements NodeVisitor { + + public int nodeCount; + + public boolean visit(Node node) { + if (!node.getCost().isTrivial()) { + nodeCount++; + } + return true; + } + + } + }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 10 21:26:02 2015 +0100 @@ -85,7 +85,7 @@ public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { this.providers = providers; - this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); + this.canonicalizer = new CanonicalizerPhase(); this.snippetReflection = snippetReflection; this.truffleCache = truffleCache; this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); @@ -238,6 +238,14 @@ return method.getAnnotation(ExplodeLoop.class) != null; } + public boolean shouldMergeExplosions(ResolvedJavaMethod method) { + ExplodeLoop explodeLoop = method.getAnnotation(ExplodeLoop.class); + if (explodeLoop != null) { + return explodeLoop.merge(); + } + return false; + } + } @SuppressWarnings("unused") @@ -254,6 +262,9 @@ TruffleCompilerImpl.Optimizations, false).apply(graph); Debug.dump(graph, "After FastPE"); + // Perform deoptimize to guard conversion. + new ConvertDeoptimizeToGuardPhase().apply(graph, tierContext); + for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE)) { Class<? extends FixedWithNextNode> macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod()); if (macroSubstitution != null) { @@ -266,13 +277,14 @@ } } - // Perform dead code elimination. Dead nodes mainly come from parse time canonicalizations. - new DeadCodeEliminationPhase().apply(graph); + // Perform conditional elimination. + new DominatorConditionalEliminationPhase(false).apply(graph); + + canonicalizer.apply(graph, tierContext); // Do single partial escape and canonicalization pass. try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); - new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); } catch (Throwable t) { Debug.handle(t); } @@ -349,6 +361,13 @@ } } } + + if (!TruffleCompilerOptions.TruffleInlineAcrossTruffleBoundary.getValue()) { + // Do not inline across Truffle boundaries. + for (MethodCallTargetNode mct : graph.getNodes(MethodCallTargetNode.TYPE)) { + mct.invoke().setUseForInlining(false); + } + } } private void injectConstantCallTarget(final StructuredGraph graph, final OptimizedCallTarget constantCallTarget, PhaseContext baseContext) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -147,7 +147,7 @@ new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); // Convert deopt to guards. - new ConvertDeoptimizeToGuardPhase().apply(graph); + new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext); PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizer); @@ -175,7 +175,7 @@ } // Convert deopt to guards. - new ConvertDeoptimizeToGuardPhase().apply(graph); + new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext); new EarlyReadEliminationPhase(canonicalizer).apply(graph, phaseContext);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,14 +36,11 @@ import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.DebugMemUseTracker.Closeable; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; @@ -132,7 +129,7 @@ try { PhaseSuite<HighTierContext> graphBuilderSuite = createGraphBuilderSuite(); - try (TimerCloseable a = PartialEvaluationTime.start(); Closeable c = PartialEvaluationMemUse.start()) { + try (DebugCloseable a = PartialEvaluationTime.start(); DebugCloseable c = PartialEvaluationMemUse.start()) { graph = partialEvaluator.createGraph(compilable, AllowAssumptions.YES); } @@ -140,17 +137,11 @@ return; } - if (!TruffleCompilerOptions.TruffleInlineAcrossTruffleBoundary.getValue()) { - // Do not inline across Truffle boundaries. - for (MethodCallTargetNode mct : graph.getNodes(MethodCallTargetNode.TYPE)) { - mct.invoke().setUseForInlining(false); - } - } - compilationNotify.notifyCompilationTruffleTierFinished(compilable, graph); CompilationResult compilationResult = compileMethodHelper(graph, compilable.toString(), graphBuilderSuite, compilable.getSpeculationLog(), compilable); compilationNotify.notifyCompilationSuccess(compilable, graph, compilationResult); } catch (Throwable t) { + System.out.println("compilation failed!?"); compilationNotify.notifyCompilationFailed(compilable, graph, t); throw t; } @@ -164,7 +155,7 @@ } CompilationResult result = null; - try (TimerCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache()); Closeable c = CompilationMemUse.start()) { + try (DebugCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache()); DebugCloseable c = CompilationMemUse.start()) { CodeCacheProvider codeCache = providers.getCodeCache(); CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); CompilationResult compilationResult = new CompilationResult(name); @@ -197,7 +188,7 @@ result.setAssumptions(newAssumptions.toArray(new Assumption[newAssumptions.size()])); InstalledCode installedCode; - try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start(); Closeable c = CodeInstallationMemUse.start()) { + try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); DebugCloseable a = CodeInstallationTime.start(); DebugCloseable c = CodeInstallationMemUse.start()) { installedCode = providers.getCodeCache().addMethod(graph.method(), result, speculationLog, predefinedInstalledCode); } catch (Throwable e) { throw Debug.handle(e);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java Tue Mar 10 21:26:02 2015 +0100 @@ -43,7 +43,7 @@ } private static List<TruffleInliningDecision> createDecisions(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy, CompilerOptions options) { - int nodeCount = sourceTarget.countNonTrivialNodes(false); + int nodeCount = sourceTarget.countNonTrivialNodes(); List<TruffleInliningDecision> exploredCallSites = exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), nodeCount, policy); return decideInlining(exploredCallSites, policy, nodeCount, options); } @@ -66,7 +66,7 @@ List<TruffleInliningDecision> childCallSites = Collections.emptyList(); double frequency = calculateFrequency(parentTarget, callNode); - int nodeCount = callNode.getCurrentCallTarget().countNonTrivialNodes(false); + int nodeCount = callNode.getCurrentCallTarget().countNonTrivialNodes(); boolean recursive = isRecursiveStack(callStack); int deepNodeCount = nodeCount;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/AbstractDebugCompilationListener.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/AbstractDebugCompilationListener.java Tue Mar 10 21:26:02 2015 +0100 @@ -101,7 +101,7 @@ } public static void addASTSizeProperty(OptimizedCallTarget target, Map<String, Object> properties) { - int nodeCount = target.countNonTrivialNodes(false); + int nodeCount = target.countNonTrivialNodes(); int deepNodeCount = nodeCount; TruffleInlining inlining = target.getInlining(); if (inlining != null) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java Tue Mar 10 21:26:02 2015 +0100 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; import com.oracle.graal.truffle.*; @@ -39,7 +40,7 @@ @Override public void notifyCompilationFailed(OptimizedCallTarget target, StructuredGraph graph, Throwable t) { - if (isPermanentBailout(t)) { + if (isPermanentBailout(t) || GraalOptions.PrintBailout.getValue()) { Map<String, Object> properties = new LinkedHashMap<>(); properties.put("Reason", t.toString()); log(0, "opt fail", target.toString(), properties);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ @NodeInfo public final class AssumptionNode extends MacroNode implements Simplifiable { - public static final NodeClass<AssumptionNode> TYPE = NodeClass.get(AssumptionNode.class); + public static final NodeClass<AssumptionNode> TYPE = NodeClass.create(AssumptionNode.class); public AssumptionNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public final class BailoutNode extends MacroNode implements Canonicalizable { - public static final NodeClass<BailoutNode> TYPE = NodeClass.get(BailoutNode.class); + public static final NodeClass<BailoutNode> TYPE = NodeClass.create(BailoutNode.class); public BailoutNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IsCompilationConstantNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IsCompilationConstantNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class IsCompilationConstantNode extends FloatingNode implements Lowerable, Canonicalizable { - public static final NodeClass<IsCompilationConstantNode> TYPE = NodeClass.get(IsCompilationConstantNode.class); + public static final NodeClass<IsCompilationConstantNode> TYPE = NodeClass.create(IsCompilationConstantNode.class); @Input ValueNode value;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ */ @NodeInfo public final class IntegerAddExactNode extends AddNode implements IntegerExactArithmeticNode { - public static final NodeClass<IntegerAddExactNode> TYPE = NodeClass.get(IntegerAddExactNode.class); + public static final NodeClass<IntegerAddExactNode> TYPE = NodeClass.create(IntegerAddExactNode.class); public IntegerAddExactNode(ValueNode x, ValueNode y) { super(TYPE, x, y); @@ -53,35 +53,49 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode result = findSynonym(forX, forY); + if (result == null) { + return this; + } else { + return result; + } + } + + private static ValueNode findSynonym(ValueNode forX, ValueNode forY) { if (forX.isConstant() && !forY.isConstant()) { return new IntegerAddExactNode(forY, forX); } if (forX.isConstant()) { - return canonicalXconstant(forX, forY); + ConstantNode constantNode = canonicalXconstant(forX, forY); + if (constantNode != null) { + return constantNode; + } } else if (forY.isConstant()) { long c = forY.asJavaConstant().asLong(); if (c == 0) { return forX; } } - return this; + return null; } - private ValueNode canonicalXconstant(ValueNode forX, ValueNode forY) { + private static ConstantNode canonicalXconstant(ValueNode forX, ValueNode forY) { JavaConstant xConst = forX.asJavaConstant(); JavaConstant yConst = forY.asJavaConstant(); - assert xConst.getKind() == yConst.getKind(); - try { - if (xConst.getKind() == Kind.Int) { - return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt())); - } else { - assert xConst.getKind() == Kind.Long; - return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong())); + if (xConst != null && yConst != null) { + assert xConst.getKind() == yConst.getKind(); + try { + if (xConst.getKind() == Kind.Int) { + return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt())); + } else { + assert xConst.getKind() == Kind.Long; + return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong())); + } + } catch (ArithmeticException ex) { + // The operation will result in an overflow exception, so do not canonicalize. } - } catch (ArithmeticException ex) { - // The operation will result in an overflow exception, so do not canonicalize. } - return this; + return null; } @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode { - public static final NodeClass<IntegerAddExactSplitNode> TYPE = NodeClass.get(IntegerAddExactSplitNode.class); + public static final NodeClass<IntegerAddExactSplitNode> TYPE = NodeClass.create(IntegerAddExactSplitNode.class); public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { super(TYPE, stamp, x, y, next, overflowSuccessor);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,10 +32,10 @@ @NodeInfo public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRLowerable { - public static final NodeClass<IntegerExactArithmeticSplitNode> TYPE = NodeClass.get(IntegerExactArithmeticSplitNode.class); + public static final NodeClass<IntegerExactArithmeticSplitNode> TYPE = NodeClass.create(IntegerExactArithmeticSplitNode.class); + @Successor AbstractBeginNode next; @Successor AbstractBeginNode overflowSuccessor; - @Successor AbstractBeginNode next; @Input ValueNode x; @Input ValueNode y; @@ -48,6 +48,11 @@ } @Override + public AbstractBeginNode getPrimarySuccessor() { + return next; + } + + @Override public double probability(AbstractBeginNode successor) { return successor == next ? 1 : 0; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ */ @NodeInfo public final class IntegerMulExactNode extends MulNode implements IntegerExactArithmeticNode { - public static final NodeClass<IntegerMulExactNode> TYPE = NodeClass.get(IntegerMulExactNode.class); + public static final NodeClass<IntegerMulExactNode> TYPE = NodeClass.create(IntegerMulExactNode.class); public IntegerMulExactNode(ValueNode x, ValueNode y) { super(TYPE, x, y);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode { - public static final NodeClass<IntegerMulExactSplitNode> TYPE = NodeClass.get(IntegerMulExactSplitNode.class); + public static final NodeClass<IntegerMulExactSplitNode> TYPE = NodeClass.create(IntegerMulExactSplitNode.class); public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { super(TYPE, stamp, x, y, next, overflowSuccessor);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ @NodeInfo(shortName = "*H") public final class IntegerMulHighNode extends BinaryNode implements ArithmeticLIRLowerable { - public static final NodeClass<IntegerMulHighNode> TYPE = NodeClass.get(IntegerMulHighNode.class); + public static final NodeClass<IntegerMulHighNode> TYPE = NodeClass.create(IntegerMulHighNode.class); public IntegerMulHighNode(ValueNode x, ValueNode y) { this((IntegerStamp) x.stamp().unrestricted(), x, y);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ */ @NodeInfo public final class IntegerSubExactNode extends SubNode implements IntegerExactArithmeticNode { - public static final NodeClass<IntegerSubExactNode> TYPE = NodeClass.get(IntegerSubExactNode.class); + public static final NodeClass<IntegerSubExactNode> TYPE = NodeClass.create(IntegerSubExactNode.class); public IntegerSubExactNode(ValueNode x, ValueNode y) { super(TYPE, x, y);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode { - public static final NodeClass<IntegerSubExactSplitNode> TYPE = NodeClass.get(IntegerSubExactSplitNode.class); + public static final NodeClass<IntegerSubExactSplitNode> TYPE = NodeClass.create(IntegerSubExactSplitNode.class); public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { super(TYPE, stamp, x, y, next, overflowSuccessor);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo(shortName = "|*H|") public final class UnsignedMulHighNode extends BinaryNode implements ArithmeticLIRLowerable { - public static final NodeClass<UnsignedMulHighNode> TYPE = NodeClass.get(UnsignedMulHighNode.class); + public static final NodeClass<UnsignedMulHighNode> TYPE = NodeClass.create(UnsignedMulHighNode.class); public UnsignedMulHighNode(ValueNode x, ValueNode y) { this((IntegerStamp) x.stamp().unrestricted(), x, y);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 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.truffle.nodes.asserts; - -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; - -@NodeInfo -public final class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable { - - public static final NodeClass<CompilationConstantNode> TYPE = NodeClass.get(CompilationConstantNode.class); - - public CompilationConstantNode(Invoke invoke) { - super(TYPE, invoke, "The value could not be reduced to a compile time constant."); - assert arguments.size() == 1; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - if (arguments.get(0).isConstant()) { - return arguments.get(0); - } - return this; - } -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ @NodeInfo public final class NeverInlineMacroNode extends MacroStateSplitNode implements com.oracle.graal.graph.IterableNodeType { - public static final NodeClass<NeverInlineMacroNode> TYPE = NodeClass.get(NeverInlineMacroNode.class); + public static final NodeClass<NeverInlineMacroNode> TYPE = NodeClass.create(NeverInlineMacroNode.class); public NeverInlineMacroNode(Invoke invoke) { super(TYPE, invoke);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -22,29 +22,25 @@ */ package com.oracle.graal.truffle.nodes.asserts; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.replacements.nodes.*; @NodeInfo -public class NeverPartOfCompilationNode extends MacroStateSplitNode implements IterableNodeType { +public final class NeverPartOfCompilationNode extends FixedWithNextNode implements IterableNodeType { - public static final NodeClass<NeverPartOfCompilationNode> TYPE = NodeClass.get(NeverPartOfCompilationNode.class); + public static final NodeClass<NeverPartOfCompilationNode> TYPE = NodeClass.create(NeverPartOfCompilationNode.class); protected final String message; - public NeverPartOfCompilationNode(Invoke invoke) { - this(TYPE, invoke, "This code path should never be part of a compilation."); - } - - protected NeverPartOfCompilationNode(NodeClass<? extends NeverPartOfCompilationNode> c, Invoke invoke, String message) { - super(c, invoke); + public NeverPartOfCompilationNode(String message) { + super(TYPE, StampFactory.forVoid()); this.message = message; } - public final String getMessage() { - return message + " " + arguments.toString(); + public String getMessage() { + return message; } public static void verifyNotFoundIn(final StructuredGraph graph) { @@ -53,4 +49,7 @@ throw GraphUtil.approxSourceException(neverPartOfCompilationNode, exception); } } + + @NodeIntrinsic + public static native void apply(@ConstantNodeParameter String message); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/ForceMaterializeNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/ForceMaterializeNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,7 +30,7 @@ @NodeInfo public final class ForceMaterializeNode extends FixedWithNextNode implements LIRLowerable { - public static final NodeClass<ForceMaterializeNode> TYPE = NodeClass.get(ForceMaterializeNode.class); + public static final NodeClass<ForceMaterializeNode> TYPE = NodeClass.create(ForceMaterializeNode.class); @Input ValueNode object;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo(nameTemplate = "MaterializeFrame{p#frame/s}") public final class MaterializeFrameNode extends FixedWithNextNode implements IterableNodeType { - public static final NodeClass<MaterializeFrameNode> TYPE = NodeClass.get(MaterializeFrameNode.class); + public static final NodeClass<MaterializeFrameNode> TYPE = NodeClass.create(MaterializeFrameNode.class); @Input ValueNode frame; public MaterializeFrameNode(ValueNode frame) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -48,7 +48,7 @@ @NodeInfo public final class NewFrameNode extends FixedWithNextNode implements IterableNodeType, VirtualizableAllocation, Canonicalizable { - public static final NodeClass<NewFrameNode> TYPE = NodeClass.get(NewFrameNode.class); + public static final NodeClass<NewFrameNode> TYPE = NodeClass.create(NewFrameNode.class); @Input ValueNode descriptor; @Input ValueNode arguments; @@ -99,7 +99,7 @@ @NodeInfo public static final class VirtualOnlyInstanceNode extends VirtualInstanceNode { - public static final NodeClass<VirtualOnlyInstanceNode> TYPE = NodeClass.get(VirtualOnlyInstanceNode.class); + public static final NodeClass<VirtualOnlyInstanceNode> TYPE = NodeClass.create(VirtualOnlyInstanceNode.class); protected boolean allowMaterialization; public VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,15 +30,15 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.nodes.*; -import com.oracle.graal.truffle.nodes.asserts.*; /** * Macro node for CompilerDirectives#unsafeGetInt*. */ @NodeInfo -public final class CustomizedUnsafeLoadMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - public static final NodeClass<CustomizedUnsafeLoadMacroNode> TYPE = NodeClass.get(CustomizedUnsafeLoadMacroNode.class); +public final class CustomizedUnsafeLoadMacroNode extends MacroStateSplitNode implements Canonicalizable { + public static final NodeClass<CustomizedUnsafeLoadMacroNode> TYPE = NodeClass.create(CustomizedUnsafeLoadMacroNode.class); private static final int ARGUMENT_COUNT = 4; private static final int OBJECT_ARGUMENT_INDEX = 0; @@ -47,7 +47,7 @@ private static final int LOCATION_ARGUMENT_INDEX = 3; public CustomizedUnsafeLoadMacroNode(Invoke invoke) { - super(TYPE, invoke, "The location argument could not be resolved to a constant."); + super(TYPE, invoke); assert arguments.size() == ARGUMENT_COUNT; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,15 +28,15 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.nodes.*; -import com.oracle.graal.truffle.nodes.asserts.*; /** * Macro node for method CompilerDirectives#unsafePut*. */ @NodeInfo -public final class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable, StateSplit { - public static final NodeClass<CustomizedUnsafeStoreMacroNode> TYPE = NodeClass.get(CustomizedUnsafeStoreMacroNode.class); +public final class CustomizedUnsafeStoreMacroNode extends MacroStateSplitNode implements Canonicalizable, StateSplit { + public static final NodeClass<CustomizedUnsafeStoreMacroNode> TYPE = NodeClass.create(CustomizedUnsafeStoreMacroNode.class); private static final int ARGUMENT_COUNT = 4; private static final int OBJECT_ARGUMENT_INDEX = 0; private static final int OFFSET_ARGUMENT_INDEX = 1; @@ -44,7 +44,7 @@ private static final int LOCATION_ARGUMENT_INDEX = 3; public CustomizedUnsafeStoreMacroNode(Invoke invoke) { - super(TYPE, invoke, "The location argument could not be resolved to a constant."); + super(TYPE, invoke); assert arguments.size() == ARGUMENT_COUNT; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,15 +31,15 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.graal.replacements.nodes.*; /** * Macro node for method CompilerDirectives#unsafeCast. */ @NodeInfo -public final class UnsafeTypeCastMacroNode extends NeverPartOfCompilationNode implements Simplifiable { +public final class UnsafeTypeCastMacroNode extends MacroStateSplitNode implements Simplifiable { - public static final NodeClass<UnsafeTypeCastMacroNode> TYPE = NodeClass.get(UnsafeTypeCastMacroNode.class); + public static final NodeClass<UnsafeTypeCastMacroNode> TYPE = NodeClass.create(UnsafeTypeCastMacroNode.class); private static final int OBJECT_ARGUMENT_INDEX = 0; private static final int CLASS_ARGUMENT_INDEX = 1; private static final int CONDITION_ARGUMENT_INDEX = 2; @@ -47,7 +47,7 @@ private static final int ARGUMENT_COUNT = 4; public UnsafeTypeCastMacroNode(Invoke invoke) { - super(TYPE, invoke, "The class of the unsafe cast could not be reduced to a compile time constant."); + super(TYPE, invoke); assert arguments.size() == ARGUMENT_COUNT; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java Tue Mar 10 21:26:02 2015 +0100 @@ -23,43 +23,15 @@ package com.oracle.graal.truffle.substitutions; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.truffle.api.*; @ClassSubstitution(CompilerAsserts.class) public class CompilerAssertsSubstitutions { - @MacroSubstitution(macro = NeverPartOfCompilationNode.class, isStatic = true) - public static native void neverPartOfCompilation(); - - @MacroSubstitution(macro = NeverPartOfCompilationNode.class, isStatic = true) - public static native void neverPartOfCompilation(String message); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native boolean compilationConstant(boolean value); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native byte compilationConstant(byte value); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native char compilationConstant(char value); + @MethodSubstitution + public static void neverPartOfCompilation(@SuppressWarnings("unused") String message) { + NeverPartOfCompilationNode.apply("Never part of compilation"); + } - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native short compilationConstant(short value); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native int compilationConstant(int value); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native long compilationConstant(long value); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native float compilationConstant(float value); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native double compilationConstant(double value); - - @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true) - public static native Object compilationConstant(Object value); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,11 +26,11 @@ import java.util.concurrent.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; import com.oracle.graal.java.*; import com.oracle.graal.java.GraphBuilderPlugin.InvocationPlugin; import com.oracle.graal.java.InvocationPlugins.Registration; @@ -41,6 +41,7 @@ import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.nodes.*; import com.oracle.graal.truffle.nodes.arithmetic.*; +import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.graal.truffle.unsafe.*; import com.oracle.truffle.api.*; @@ -78,7 +79,7 @@ builder.getAssumptions().record(new AssumptionValidAssumption(assumption)); } } else { - throw new BailoutException("assumption could not be reduced to a constant"); + throw builder.bailout("assumption could not be reduced to a constant"); } return true; } @@ -87,42 +88,38 @@ public static void registerExactMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { Registration r = new Registration(plugins, metaAccess, ExactMath.class); - r.register2("addExact", Integer.TYPE, Integer.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Int.getStackKind(), builder.append(new IntegerAddExactNode(x, y))); - return true; - } - }); - r.register2("addExact", Long.TYPE, Long.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Long, builder.append(new IntegerAddExactNode(x, y))); - return true; - } - }); - r.register2("subtractExact", Integer.TYPE, Integer.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Int.getStackKind(), builder.append(new IntegerSubExactNode(x, y))); - return true; - } - }); - r.register2("subtractExact", Long.TYPE, Long.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Long, builder.append(new IntegerSubExactNode(x, y))); - return true; - } - }); - r.register2("multiplyExact", Integer.TYPE, Integer.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Int.getStackKind(), builder.append(new IntegerMulExactNode(x, y))); - return true; - } - }); - r.register2("multiplyExact", Long.TYPE, Long.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Long, builder.append(new IntegerMulExactNode(x, y))); - return true; - } - }); + for (Kind kind : new Kind[]{Kind.Int, Kind.Long}) { + r.register2("addExact", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerAddExactNode(x, y))); + return true; + } + }); + r.register2("subtractExact", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerSubExactNode(x, y))); + return true; + } + }); + r.register2("multiplyExact", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerMulExactNode(x, y))); + return true; + } + }); + r.register2("multiplyHigh", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerMulHighNode(x, y))); + return true; + } + }); + r.register2("multiplyHighUnsigned", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new UnsignedMulHighNode(x, y))); + return true; + } + }); + } } public static void registerCompilerDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { @@ -170,9 +167,9 @@ r.register1("bailout", String.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext builder, ValueNode message) { if (message.isConstant()) { - throw new BailoutException(message.asConstant().toValueString()); + throw builder.bailout(message.asConstant().toValueString()); } - throw new BailoutException("bailout (message is not compile-time constant, so no additional information is available)"); + throw builder.bailout("bailout (message is not compile-time constant, so no additional information is available)"); } }); r.register1("isCompilationConstant", Object.class, new InvocationPlugin() { @@ -191,6 +188,43 @@ return true; } }); + + r = new Registration(plugins, metaAccess, CompilerAsserts.class); + r.register1("partialEvaluationConstant", Object.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode value) { + ValueNode curValue = value; + if (curValue instanceof BoxNode) { + BoxNode boxNode = (BoxNode) curValue; + curValue = boxNode.getValue(); + } + if (curValue.isConstant()) { + return true; + } else { + StringBuilder sb = new StringBuilder(); + sb.append(curValue); + if (curValue instanceof ValuePhiNode) { + ValuePhiNode valuePhi = (ValuePhiNode) curValue; + sb.append(" ("); + for (Node n : valuePhi.inputs()) { + sb.append(n); + sb.append("; "); + } + sb.append(")"); + } + throw builder.bailout("Partial evaluation did not reduce value to a constant, is a regular compiler node: " + sb.toString()); + } + } + }); + r.register1("neverPartOfCompilation", String.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode message) { + if (message.isConstant()) { + String messageString = message.asConstant().toValueString(); + builder.append(new NeverPartOfCompilationNode(messageString)); + return true; + } + throw builder.bailout("message for never part of compilation is non-constant"); + } + }); } public static void registerOptimizedCallTargetPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,7 +33,7 @@ @NodeInfo public final class MaterializedObjectState extends EscapeObjectState implements Node.ValueNumberable { - public static final NodeClass<MaterializedObjectState> TYPE = NodeClass.get(MaterializedObjectState.class); + public static final NodeClass<MaterializedObjectState> TYPE = NodeClass.create(MaterializedObjectState.class); @Input ValueNode materializedValue; public ValueNode materializedValue() {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Tue Mar 10 21:26:02 2015 +0100 @@ -35,7 +35,7 @@ @NodeInfo public final class VirtualObjectState extends EscapeObjectState implements Node.ValueNumberable { - public static final NodeClass<VirtualObjectState> TYPE = NodeClass.get(VirtualObjectState.class); + public static final NodeClass<VirtualObjectState> TYPE = NodeClass.create(VirtualObjectState.class); @Input NodeInputList<ValueNode> values; public NodeInputList<ValueNode> values() {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,6 +32,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; @@ -111,6 +112,12 @@ }; ReentrantBlockIterator.apply(closure, cfg.getStartBlock()); assert VirtualUtil.assertNonReachable(graph, obsoleteNodes); + for (Node node : obsoleteNodes) { + if (node.isAlive()) { + node.replaceAtUsages(null); + GraphUtil.killWithUnusedFloatingInputs(node); + } + } } @Override
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Tue Mar 10 21:26:02 2015 +0100 @@ -130,23 +130,16 @@ * * @param node The fixed node that should be deleted. */ - public void deleteFixedNode(final FixedWithNextNode node) { + public void deleteNode(final Node node) { add("delete fixed node", (graph, obsoleteNodes) -> { - GraphUtil.unlinkFixedNode(node); - assert obsoleteNodes.add(node); + if (node instanceof FixedWithNextNode) { + GraphUtil.unlinkFixedNode((FixedWithNextNode) node); + } + obsoleteNodes.add(node); }); } /** - * Removes the given fixed node from the control flow. - * - * @param node The fixed node that should be deleted. - */ - public void unlinkFixedNode(final FixedWithNextNode node) { - add("unlink fixed node", graph -> GraphUtil.unlinkFixedNode(node)); - } - - /** * Replaces the given node at its usages without deleting it. If the current node is a fixed * node it will be disconnected from the control flow, so that it will be deleted by a * subsequent {@link DeadCodeEliminationPhase} @@ -165,11 +158,9 @@ } node.replaceAtUsages(replacement); if (node instanceof FixedWithNextNode) { - FixedNode next = ((FixedWithNextNode) node).next(); - ((FixedWithNextNode) node).setNext(null); - node.replaceAtPredecessor(next); - assert obsoleteNodes.add(node); + GraphUtil.unlinkFixedNode((FixedWithNextNode) node); } + obsoleteNodes.add(node); }); } @@ -181,6 +172,7 @@ * @param newInput The value to replace with. */ public void replaceFirstInput(final Node node, final Node oldInput, final Node newInput) { + assert node.isAlive() && oldInput.isAlive() && !newInput.isDeleted(); add("replace first input", new Effect() { @Override public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { @@ -194,13 +186,4 @@ } }); } - - /** - * Performs a custom action. - * - * @param action The action that should be performed when the effects are applied. - */ - public void customAction(final Runnable action) { - add("customAction", graph -> action.run()); - } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -65,7 +65,7 @@ Map<Invoke, Double> hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null; - InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase(true)); + InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase()); inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); inlining.apply(graph, context); progress |= inlining.getInliningCount() > 0; @@ -74,7 +74,7 @@ if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { canonicalizer.apply(graph, context); - new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context); + new IterativeConditionalEliminationPhase(canonicalizer, false).apply(graph, context); } if (!progress) { break;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Mar 10 21:26:02 2015 +0100 @@ -94,7 +94,7 @@ ValueNode value = getScalarAlias(store.value()); boolean result = false; if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { - effects.deleteFixedNode(store); + effects.deleteNode(store); result = true; } state.killReadCache(store.field());
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Mar 10 21:26:02 2015 +0100 @@ -649,6 +649,7 @@ if (uniqueVirtualObject) { // all inputs refer to the same object: just make the phi node an alias addAndMarkAlias(objStates[0].virtual, phi); + mergeEffects.deleteNode(phi); return false; } else { // all inputs are virtual: check if they're compatible and without identity @@ -680,6 +681,7 @@ if (compatible) { VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual); mergeEffects.addFloatingNode(virtual, "valueObjectNode"); + mergeEffects.deleteNode(phi); boolean materialized = mergeObjectStates(virtual, objStates, states); addAndMarkAlias(virtual, virtual);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Mar 10 21:26:02 2015 +0100 @@ -75,7 +75,7 @@ StoreFieldNode store = (StoreFieldNode) node; ValueNode value = getScalarAlias(store.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { - effects.deleteFixedNode(store); + effects.deleteNode(store); deleted = true; } state.killReadCache(store.field()); @@ -108,7 +108,7 @@ ValueNode value = getScalarAlias(write.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { - effects.deleteFixedNode(write); + effects.deleteNode(write); deleted = true; } processIdentity(state, write.location().getLocationIdentity()); @@ -141,7 +141,7 @@ ValueNode value = getScalarAlias(write.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { - effects.deleteFixedNode(write); + effects.deleteNode(write); deleted = true; } processIdentity(state, write.getLocationIdentity());
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Tue Mar 10 21:26:02 2015 +0100 @@ -62,7 +62,7 @@ } for (Node node : obsoleteNodes) { - if (node instanceof FixedNode) { + if (node instanceof FixedNode && !node.isDeleted()) { assert !flood.isMarked(node) : node; } } @@ -87,7 +87,7 @@ } boolean success = true; for (Node node : obsoleteNodes) { - if (flood.isMarked(node)) { + if (!node.isDeleted() && flood.isMarked(node)) { TTY.println("offending node path:"); Node current = node; TTY.print(current.toString()); @@ -109,12 +109,24 @@ return success; } - public static void trace(String format, Object... obj) { - if (TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { + public static void trace(String format, Object obj) { + if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { Debug.logv(format, obj); } } + public static void trace(String format, Object obj, Object obj2) { + if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { + Debug.logv(format, obj, obj2); + } + } + + public static void trace(String format, Object obj, Object obj2, Object obj3) { + if (Debug.isEnabled() && TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { + Debug.logv(format, obj, obj2, obj3); + } + } + public static boolean matches(StructuredGraph graph, String filter) { if (filter != null) { return matchesHelper(graph, filter);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -117,9 +117,7 @@ @Override public void replaceWithVirtual(VirtualObjectNode virtual) { closure.addAndMarkAlias(virtual, current); - if (current instanceof FixedWithNextNode) { - effects.deleteFixedNode((FixedWithNextNode) current); - } + effects.deleteNode(current); deleted = true; } @@ -132,7 +130,7 @@ @Override public void delete() { - effects.deleteFixedNode((FixedWithNextNode) current); + effects.deleteNode(current); deleted = true; }
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,7 +26,7 @@ /** * Returns a Signed whose value is {@code (this + val)}. - * + * * @param val value to be added to this Signed. * @return {@code this + val} */ @@ -34,7 +34,7 @@ /** * Returns a Signed whose value is {@code (this - val)}. - * + * * @param val value to be subtracted from this Signed. * @return {@code this - val} */ @@ -42,7 +42,7 @@ /** * Returns a Signed whose value is {@code (this * val)}. - * + * * @param val value to be multiplied by this Signed. * @return {@code this * val} */ @@ -50,7 +50,7 @@ /** * Returns a Signed whose value is {@code (this / val)}. - * + * * @param val value by which this Signed is to be divided. * @return {@code this / val} */ @@ -58,7 +58,7 @@ /** * Returns a Signed whose value is {@code (this % val)}. - * + * * @param val value by which this Signed is to be divided, and the remainder computed. * @return {@code this % val} */ @@ -66,7 +66,7 @@ /** * Returns a Signed whose value is {@code (this << n)}. - * + * * @param n shift distance, in bits. * @return {@code this << n} */ @@ -74,7 +74,7 @@ /** * Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed. - * + * * @param n shift distance, in bits. * @return {@code this >> n} */ @@ -83,7 +83,7 @@ /** * Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed * if and only if this and val are both negative.) - * + * * @param val value to be AND'ed with this Signed. * @return {@code this & val} */ @@ -92,7 +92,7 @@ /** * Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed * if and only if either this or val is negative.) - * + * * @param val value to be OR'ed with this Signed. * @return {@code this | val} */ @@ -101,7 +101,7 @@ /** * Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed * if and only if exactly one of this and val are negative.) - * + * * @param val value to be XOR'ed with this Signed. * @return {@code this ^ val} */ @@ -110,14 +110,14 @@ /** * Returns a Signed whose value is {@code (~this)}. (This method returns a negative value if and * only if this Signed is non-negative.) - * + * * @return {@code ~this} */ Signed not(); /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this == val} */ @@ -125,7 +125,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this != val} */ @@ -133,7 +133,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this < val} */ @@ -141,7 +141,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this <= val} */ @@ -149,7 +149,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this > val} */ @@ -157,7 +157,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this >= val} */ @@ -165,7 +165,7 @@ /** * Returns a Signed whose value is {@code (this + val)}. - * + * * @param val value to be added to this Signed. * @return {@code this + val} */ @@ -173,7 +173,7 @@ /** * Returns a Signed whose value is {@code (this - val)}. - * + * * @param val value to be subtracted from this Signed. * @return {@code this - val} */ @@ -181,7 +181,7 @@ /** * Returns a Signed whose value is {@code (this * val)}. - * + * * @param val value to be multiplied by this Signed. * @return {@code this * val} */ @@ -189,7 +189,7 @@ /** * Returns a Signed whose value is {@code (this / val)}. - * + * * @param val value by which this Signed is to be divided. * @return {@code this / val} */ @@ -197,7 +197,7 @@ /** * Returns a Signed whose value is {@code (this % val)}. - * + * * @param val value by which this Signed is to be divided, and the remainder computed. * @return {@code this % val} */ @@ -205,7 +205,7 @@ /** * Returns a Signed whose value is {@code (this << n)}. - * + * * @param n shift distance, in bits. * @return {@code this << n} */ @@ -213,7 +213,7 @@ /** * Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed. - * + * * @param n shift distance, in bits. * @return {@code this >> n} */ @@ -222,7 +222,7 @@ /** * Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed * if and only if this and val are both negative.) - * + * * @param val value to be AND'ed with this Signed. * @return {@code this & val} */ @@ -231,7 +231,7 @@ /** * Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed * if and only if either this or val is negative.) - * + * * @param val value to be OR'ed with this Signed. * @return {@code this | val} */ @@ -240,7 +240,7 @@ /** * Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed * if and only if exactly one of this and val are negative.) - * + * * @param val value to be XOR'ed with this Signed. * @return {@code this ^ val} */ @@ -248,7 +248,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this == val} */ @@ -256,7 +256,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this != val} */ @@ -264,7 +264,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this < val} */ @@ -272,7 +272,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this <= val} */ @@ -280,7 +280,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this > val} */ @@ -288,7 +288,7 @@ /** * Compares this Signed with the specified value. - * + * * @param val value to which this Signed is to be compared. * @return {@code this >= val} */
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,7 +26,7 @@ /** * Returns a Unsigned whose value is {@code (this + val)}. - * + * * @param val value to be added to this Unsigned. * @return {@code this + val} */ @@ -34,7 +34,7 @@ /** * Returns a Unsigned whose value is {@code (this - val)}. - * + * * @param val value to be subtracted from this Unsigned. * @return {@code this - val} */ @@ -42,7 +42,7 @@ /** * Returns a Unsigned whose value is {@code (this * val)}. - * + * * @param val value to be multiplied by this Unsigned. * @return {@code this * val} */ @@ -50,7 +50,7 @@ /** * Returns a Unsigned whose value is {@code (this / val)}. - * + * * @param val value by which this Unsigned is to be divided. * @return {@code this / val} */ @@ -58,7 +58,7 @@ /** * Returns a Unsigned whose value is {@code (this % val)}. - * + * * @param val value by which this Unsigned is to be divided, and the remainder computed. * @return {@code this % val} */ @@ -66,7 +66,7 @@ /** * Returns a Unsigned whose value is {@code (this << n)}. - * + * * @param n shift distance, in bits. * @return {@code this << n} */ @@ -74,7 +74,7 @@ /** * Returns a Unsigned whose value is {@code (this >>> n)}. No sign extension is performed. - * + * * @param n shift distance, in bits. * @return {@code this >> n} */ @@ -82,7 +82,7 @@ /** * Returns a Unsigned whose value is {@code (this & val)}. - * + * * @param val value to be AND'ed with this Unsigned. * @return {@code this & val} */ @@ -90,7 +90,7 @@ /** * Returns a Unsigned whose value is {@code (this | val)}. - * + * * @param val value to be OR'ed with this Unsigned. * @return {@code this | val} */ @@ -98,7 +98,7 @@ /** * Returns a Unsigned whose value is {@code (this ^ val)}. - * + * * @param val value to be XOR'ed with this Unsigned. * @return {@code this ^ val} */ @@ -106,14 +106,14 @@ /** * Returns a Unsigned whose value is {@code (~this)}. - * + * * @return {@code ~this} */ Unsigned not(); /** * Compares this Unsigned with the specified value. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this == val} */ @@ -121,7 +121,7 @@ /** * Compares this Unsigned with the specified value. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this != val} */ @@ -129,7 +129,7 @@ /** * Compares this Unsigned with the specified value. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this < val} */ @@ -137,7 +137,7 @@ /** * Compares this Unsigned with the specified value. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this <= val} */ @@ -145,7 +145,7 @@ /** * Compares this Unsigned with the specified value. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this > val} */ @@ -153,7 +153,7 @@ /** * Compares this Unsigned with the specified value. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this >= val} */ @@ -164,7 +164,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to be added to this Unsigned. * @return {@code this + val} */ @@ -175,7 +175,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to be subtracted from this Unsigned. * @return {@code this - val} */ @@ -186,7 +186,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to be multiplied by this Unsigned. * @return {@code this * val} */ @@ -197,7 +197,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value by which this Unsigned is to be divided. * @return {@code this / val} */ @@ -208,7 +208,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value by which this Unsigned is to be divided, and the remainder computed. * @return {@code this % val} */ @@ -219,7 +219,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param n shift distance, in bits. * @return {@code this << n} */ @@ -230,7 +230,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param n shift distance, in bits. * @return {@code this >> n} */ @@ -241,7 +241,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to be AND'ed with this Unsigned. * @return {@code this & val} */ @@ -252,7 +252,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to be OR'ed with this Unsigned. * @return {@code this | val} */ @@ -263,7 +263,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to be XOR'ed with this Unsigned. * @return {@code this ^ val} */ @@ -274,7 +274,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this == val} */ @@ -285,7 +285,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this != val} */ @@ -296,7 +296,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this < val} */ @@ -307,7 +307,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this <= val} */ @@ -318,7 +318,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this > val} */ @@ -329,7 +329,7 @@ * <p> * Note that the right operand is a signed value, while the operation is performed unsigned. * Therefore, the result is only well-defined for positive right operands. - * + * * @param val value to which this Unsigned is to be compared. * @return {@code this >= val} */
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -45,7 +45,7 @@ */ @NodeInfo public final class SnippetLocationNode extends LocationNode implements Canonicalizable { - public static final NodeClass<SnippetLocationNode> TYPE = NodeClass.get(SnippetLocationNode.class); + public static final NodeClass<SnippetLocationNode> TYPE = NodeClass.create(SnippetLocationNode.class); protected final SnippetReflectionProvider snippetReflection;
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ @NodeInfo public final class WordCastNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable { - public static final NodeClass<WordCastNode> TYPE = NodeClass.get(WordCastNode.class); + public static final NodeClass<WordCastNode> TYPE = NodeClass.create(WordCastNode.class); @Input ValueNode input; public static WordCastNode wordToObject(ValueNode input, Kind wordKind) {
--- a/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionPointer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionPointer.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,14 +33,14 @@ /** * Returns the name of the function. - * + * * @return name of the function */ String getName(); /** * Returns the raw function pointer value. - * + * * @return raw function pointer value */ long getRawValue();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MergeSpecializationsTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.dsl.test; + +import static com.oracle.truffle.api.dsl.test.TestHelper.*; +import static org.junit.Assert.*; + +import java.util.*; +import java.util.concurrent.*; + +import org.junit.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.internal.*; +import com.oracle.truffle.api.dsl.test.MergeSpecializationsTestFactory.TestCachedNodeFactory; +import com.oracle.truffle.api.dsl.test.MergeSpecializationsTestFactory.TestNodeFactory; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; +import com.oracle.truffle.api.nodes.*; + +public class MergeSpecializationsTest { + + private static final int THREADS = 50; + + @NodeChild + @SuppressWarnings("unused") + abstract static class TestNode extends ValueNode { + + @Specialization + int s1(int a) { + return 1; + } + + @Specialization + int s2(long a) { + return 2; + } + + @Specialization + int s3(double a) { + return 3; + } + } + + @NodeChild + @SuppressWarnings("unused") + abstract static class TestCachedNode extends ValueNode { + + @Specialization(guards = "a == cachedA", limit = "3") + int s1(int a, @Cached("a") int cachedA) { + return 1; + } + + @Specialization + int s2(long a) { + return 2; + } + + @Specialization + int s3(double a) { + return 3; + } + } + + @Test + public void testMultithreadedMergeInOrder() { + multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3); + } + + @Test + public void testMultithreadedMergeReverse() { + multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1.0, 1L << 32, 1), 3, 2, 1); + } + + @Test + public void testMultithreadedMergeCachedInOrder() { + multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3); + } + + @Test + public void testMultithreadedMergeCachedTwoEntries() { + multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 1.0), 1, 1, 3); + } + + @Test + public void testMultithreadedMergeCachedThreeEntries() { + multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 3), 1, 1, 1); + } + + private static <T extends ValueNode> void multithreadedMerge(NodeFactory<T> factory, final Executions executions, int... order) { + assertEquals(3, order.length); + final TestRootNode<T> node = createRoot(factory); + + final CountDownLatch threadsStarted = new CountDownLatch(THREADS); + + final CountDownLatch beforeFirst = new CountDownLatch(1); + final CountDownLatch executedFirst = new CountDownLatch(THREADS); + + final CountDownLatch beforeSecond = new CountDownLatch(1); + final CountDownLatch executedSecond = new CountDownLatch(THREADS); + + final CountDownLatch beforeThird = new CountDownLatch(1); + final CountDownLatch executedThird = new CountDownLatch(THREADS); + + Thread[] threads = new Thread[THREADS]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(new Runnable() { + public void run() { + threadsStarted.countDown(); + + MergeSpecializationsTest.await(beforeFirst); + executeWith(node, executions.firstValue); + executedFirst.countDown(); + + MergeSpecializationsTest.await(beforeSecond); + executeWith(node, executions.secondValue); + executedSecond.countDown(); + + MergeSpecializationsTest.await(beforeThird); + executeWith(node, executions.thirdValue); + executedThird.countDown(); + } + }); + threads[i].start(); + } + + final SpecializedNode gen = (SpecializedNode) node.getNode(); + + final SpecializationNode start0 = gen.getSpecializationNode(); + assertEquals("UninitializedNode_", start0.getClass().getSimpleName()); + + await(threadsStarted); + beforeFirst.countDown(); + await(executedFirst); + + final SpecializationNode start1 = gen.getSpecializationNode(); + assertEquals("S" + order[0] + "Node_", start1.getClass().getSimpleName()); + assertEquals("UninitializedNode_", nthChild(1, start1).getClass().getSimpleName()); + + beforeSecond.countDown(); + await(executedSecond); + + final SpecializationNode start2 = gen.getSpecializationNode(); + Arrays.sort(order, 0, 2); + assertEquals("PolymorphicNode_", start2.getClass().getSimpleName()); + assertEquals("S" + order[0] + "Node_", nthChild(1, start2).getClass().getSimpleName()); + assertEquals("S" + order[1] + "Node_", nthChild(2, start2).getClass().getSimpleName()); + assertEquals("UninitializedNode_", nthChild(3, start2).getClass().getSimpleName()); + + beforeThird.countDown(); + await(executedThird); + + final SpecializationNode start3 = gen.getSpecializationNode(); + Arrays.sort(order); + assertEquals("PolymorphicNode_", start3.getClass().getSimpleName()); + assertEquals("S" + order[0] + "Node_", nthChild(1, start3).getClass().getSimpleName()); + assertEquals("S" + order[1] + "Node_", nthChild(2, start3).getClass().getSimpleName()); + assertEquals("S" + order[2] + "Node_", nthChild(3, start3).getClass().getSimpleName()); + assertEquals("UninitializedNode_", nthChild(4, start3).getClass().getSimpleName()); + + for (Thread thread : threads) { + try { + thread.join(); + } catch (InterruptedException e) { + fail("interrupted"); + } + } + } + + private static class Executions { + public final Object firstValue; + public final Object secondValue; + public final Object thirdValue; + + public Executions(Object firstValue, Object secondValue, Object thirdValue) { + this.firstValue = firstValue; + this.secondValue = secondValue; + this.thirdValue = thirdValue; + } + } + + private static void await(final CountDownLatch latch) { + try { + latch.await(); + } catch (InterruptedException e) { + fail("interrupted"); + } + } + + private static Node firstChild(Node node) { + return node.getChildren().iterator().next(); + } + + private static Node nthChild(int n, Node node) { + if (n == 0) { + return node; + } else { + return nthChild(n - 1, firstChild(node)); + } + } +}
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Implies.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Implies.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ /** * Experimental API. - * + * * @deprecated annotation has no effect anymore. */ @Retention(RetentionPolicy.CLASS)
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java Tue Mar 10 21:26:02 2015 +0100 @@ -37,7 +37,7 @@ * concrete type is found first when searching the list sequentially for the type of a given generic * value. * </p> - * + * * <p> * Each {@link #value()} is represented as a java type. A type can specify two annotations: * {@link TypeCheck} and {@link TypeCast}. The {@link TypeCheck} checks whether a given generic @@ -51,30 +51,30 @@ * accept also {@link Integer} values, implicitly converting them to {@link Double} . This example * points out how we express implicit type conversions. * </p> - * + * * <p> * <b>Example:</b> The {@link TypeSystem} contains the types {@link Boolean}, {@link Integer}, and * {@link Double}. The type {@link Object} is always used implicitly as the generic type represent * all values. - * + * * <pre> - * + * * {@literal @}TypeSystem(types = {boolean.class, int.class, double.class}) * public abstract class ExampleTypeSystem { - * + * * {@literal @}TypeCheck * public boolean isInteger(Object value) { * return value instanceof Integer || value instanceof Double; * } - * + * * {@literal @}TypeCast * public double asInteger(Object value) { * return ((Number)value).doubleValue(); * } * } * </pre> - * - * + * + * * @see TypeCast * @see TypeCheck */
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystemReference.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystemReference.java Tue Mar 10 21:26:02 2015 +0100 @@ -31,7 +31,7 @@ /** * References a {@link TypeSystem} on a node. Must be applied on a {@link Node} class. At least one * {@link TypeSystem} must be referenced in a {@link Node}'s type hierarchy. - * + * * @see TypeSystem * @see Node */
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/RewriteEvent.java Tue Mar 03 14:20:58 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright (c) 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.truffle.api.dsl.internal; - -import com.oracle.truffle.api.nodes.*; - -/** - * Lazy rewrite event that implements {@link CharSequence} to be provided as message in - * {@link Node#replace(Node, CharSequence)}. - */ -abstract class RewriteEvent implements CharSequence { - - private final Node source; - private final String reason; - private String message; - - private RewriteEvent(Node source, String reason) { - this.source = source; - this.reason = reason; - } - - public int length() { - return getMessage().length(); - } - - public char charAt(int index) { - return getMessage().charAt(index); - } - - public CharSequence subSequence(int start, int end) { - return getMessage().subSequence(start, end); - } - - @Override - public String toString() { - return getMessage(); - } - - private String getMessage() { - if (message == null) { - message = createMessage(); - } - return message; - } - - private String createMessage() { - StringBuilder builder = new StringBuilder(); - builder.append(source); - builder.append(" "); - builder.append(reason); - Object[] values = getValues(); - if (values.length > 0) { - builder.append(" with parameters ("); - String sep = ""; - for (Object value : values) { - builder.append(sep); - if (value == null) { - builder.append("null"); - } else { - builder.append(value).append(" (").append(value.getClass().getSimpleName()).append(")"); - } - - sep = ", "; - } - builder.append(")"); - } - return builder.toString(); - } - - public abstract Object[] getValues(); - - static final class RewriteEvent0 extends RewriteEvent { - - private static final Object[] EMPTY = new Object[0]; - - public RewriteEvent0(Node source, String reason) { - super(source, reason); - } - - @Override - public Object[] getValues() { - return EMPTY; - } - - } - - static final class RewriteEvent1 extends RewriteEvent { - - private final Object o1; - - public RewriteEvent1(Node source, String reason, Object o1) { - super(source, reason); - this.o1 = o1; - } - - @Override - public Object[] getValues() { - return new Object[]{o1}; - } - - } - - static final class RewriteEvent2 extends RewriteEvent { - - private final Object o1; - private final Object o2; - - public RewriteEvent2(Node source, String reason, Object o1, Object o2) { - super(source, reason); - this.o1 = o1; - this.o2 = o2; - } - - @Override - public Object[] getValues() { - return new Object[]{o1, o2}; - } - - } - - static final class RewriteEvent3 extends RewriteEvent { - - private final Object o1; - private final Object o2; - private final Object o3; - - public RewriteEvent3(Node source, String reason, Object o1, Object o2, Object o3) { - super(source, reason); - this.o1 = o1; - this.o2 = o2; - this.o3 = o3; - } - - @Override - public Object[] getValues() { - return new Object[]{o1, o2, o3}; - } - - } - - static final class RewriteEvent4 extends RewriteEvent { - - private final Object o1; - private final Object o2; - private final Object o3; - private final Object o4; - - public RewriteEvent4(Node source, String reason, Object o1, Object o2, Object o3, Object o4) { - super(source, reason); - this.o1 = o1; - this.o2 = o2; - this.o3 = o3; - this.o4 = o4; - } - - @Override - public Object[] getValues() { - return new Object[]{o1, o2, o3, o4}; - } - - } - - static final class RewriteEventN extends RewriteEvent { - - private final Object[] args; - - public RewriteEventN(Node source, String reason, Object... args) { - super(source, reason); - this.args = args; - } - - @Override - public Object[] getValues() { - return args; - } - - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SlowPathEvent.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,227 @@ +/* + * Copyright (c) 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.dsl.internal; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Lazy rewrite event that implements {@link CharSequence} to be provided as message in + * {@link Node#replace(Node, CharSequence)}. + */ +abstract class SlowPathEvent implements CharSequence { + + protected final SpecializationNode source; + protected final String reason; + protected final Frame frame; + private String message; + + SlowPathEvent(SpecializationNode source, String reason, Frame frame) { + this.source = source; + this.reason = reason; + this.frame = frame; + } + + public int length() { + return getMessage().length(); + } + + public char charAt(int index) { + return getMessage().charAt(index); + } + + public CharSequence subSequence(int start, int end) { + return getMessage().subSequence(start, end); + } + + @Override + public String toString() { + return getMessage(); + } + + private String getMessage() { + if (message == null) { + message = createMessage(); + } + return message; + } + + private String createMessage() { + StringBuilder builder = new StringBuilder(); + builder.append(source); + builder.append(" "); + builder.append(reason); + Object[] values = getValues(); + if (values.length > 0) { + builder.append(" with parameters ("); + String sep = ""; + for (Object value : values) { + builder.append(sep); + if (value == null) { + builder.append("null"); + } else { + builder.append(value).append(" (").append(value.getClass().getSimpleName()).append(")"); + } + + sep = ", "; + } + builder.append(")"); + } + return builder.toString(); + } + + public abstract Object[] getValues(); + + static class SlowPathEvent0 extends SlowPathEvent { + + private static final Object[] EMPTY = new Object[0]; + + public SlowPathEvent0(SpecializationNode source, String reason, Frame frame) { + super(source, reason, frame); + } + + @Override + public final Object[] getValues() { + return EMPTY; + } + + } + + static class SlowPathEvent1 extends SlowPathEvent { + + protected final Object o1; + + public SlowPathEvent1(SpecializationNode source, String reason, Frame frame, Object o1) { + super(source, reason, frame); + this.o1 = o1; + } + + @Override + public final Object[] getValues() { + return new Object[]{o1}; + } + + } + + static class SlowPathEvent2 extends SlowPathEvent { + + protected final Object o1; + protected final Object o2; + + public SlowPathEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) { + super(source, reason, frame); + this.o1 = o1; + this.o2 = o2; + } + + @Override + public final Object[] getValues() { + return new Object[]{o1, o2}; + } + + } + + static class SlowPathEvent3 extends SlowPathEvent { + + protected final Object o1; + protected final Object o2; + protected final Object o3; + + public SlowPathEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) { + super(source, reason, frame); + this.o1 = o1; + this.o2 = o2; + this.o3 = o3; + } + + @Override + public final Object[] getValues() { + return new Object[]{o1, o2, o3}; + } + + } + + static class SlowPathEvent4 extends SlowPathEvent { + + protected final Object o1; + protected final Object o2; + protected final Object o3; + protected final Object o4; + + public SlowPathEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { + super(source, reason, frame); + this.o1 = o1; + this.o2 = o2; + this.o3 = o3; + this.o4 = o4; + } + + @Override + public final Object[] getValues() { + return new Object[]{o1, o2, o3, o4}; + } + + } + + static class SlowPathEvent5 extends SlowPathEvent { + + protected final Object o1; + protected final Object o2; + protected final Object o3; + protected final Object o4; + protected final Object o5; + + public SlowPathEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + super(source, reason, frame); + this.o1 = o1; + this.o2 = o2; + this.o3 = o3; + this.o4 = o4; + this.o5 = o5; + } + + @Override + public final Object[] getValues() { + return new Object[]{o1, o2, o3, o4, o5}; + } + + } + + static class SlowPathEventN extends SlowPathEvent { + + protected final Object[] args; + + public SlowPathEventN(SpecializationNode source, String reason, Frame frame, Object... args) { + super(source, reason, frame); + this.args = args; + } + + @Override + public final Object[] getValues() { + return args; + } + + } +}
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,12 +30,13 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.dsl.internal.RewriteEvent.RewriteEvent0; -import com.oracle.truffle.api.dsl.internal.RewriteEvent.RewriteEvent1; -import com.oracle.truffle.api.dsl.internal.RewriteEvent.RewriteEvent2; -import com.oracle.truffle.api.dsl.internal.RewriteEvent.RewriteEvent3; -import com.oracle.truffle.api.dsl.internal.RewriteEvent.RewriteEvent4; -import com.oracle.truffle.api.dsl.internal.RewriteEvent.RewriteEventN; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent0; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent1; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent2; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent3; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent4; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent5; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEventN; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; @@ -44,13 +45,13 @@ /** * Internal implementation dependent base class for generated specialized nodes. */ +@NodeInfo(cost = NodeCost.NONE) @SuppressWarnings("unused") -@NodeInfo(cost = NodeCost.NONE) public abstract class SpecializationNode extends Node { @Child protected SpecializationNode next; - private final int index; + final int index; public SpecializationNode() { this(-1); @@ -92,10 +93,9 @@ } } - protected final SpecializationNode polymorphicMerge(SpecializationNode newNode) { - SpecializationNode merged = next.merge(newNode); - if (merged == newNode && !isSame(newNode) && count() <= 2) { - return removeSame(new RewriteEvent0(findRoot(), "merged polymorphic to monomorphic")); + protected final SpecializationNode polymorphicMerge(SpecializationNode newNode, SpecializationNode merged) { + if (merged == newNode && count() <= 2) { + return removeSame(new SlowPathEvent0(this, "merged polymorphic to monomorphic", null)); } return merged; } @@ -114,15 +114,85 @@ protected abstract Node[] getSuppliedChildren(); - protected SpecializationNode merge(SpecializationNode newNode) { - if (this.isSame(newNode)) { + protected SpecializationNode merge(SpecializationNode newNode, Frame frame) { + if (isIdentical(newNode, frame)) { + return this; + } + return next != null ? next.merge(newNode, frame) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1) { + if (isIdentical(newNode, frame, o1)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2) { + if (isIdentical(newNode, frame, o1, o2)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1, o2) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3) { + if (isIdentical(newNode, frame, o1, o2, o3)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1, o2, o3) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4) { + if (isIdentical(newNode, frame, o1, o2, o3, o4)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1, o2, o3, o4) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + if (isIdentical(newNode, frame, o1, o2, o3, o4, o5)) { return this; } - return next != null ? next.merge(newNode) : newNode; + return next != null ? next.merge(newNode, frame, o1, o2, o3, o4, o5) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object... args) { + if (isIdentical(newNode, frame, args)) { + return this; + } + return next != null ? next.merge(newNode, frame, args) : newNode; + } + + protected boolean isSame(SpecializationNode other) { + return getClass() == other.getClass(); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame) { + return isSame(newNode); } - protected SpecializationNode mergeNoSame(SpecializationNode newNode) { - return next != null ? next.merge(newNode) : newNode; + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object... args) { + return isSame(newNode); } protected final int countSame(SpecializationNode node) { @@ -150,10 +220,6 @@ return index; } - protected boolean isSame(SpecializationNode other) { - return getClass() == other.getClass(); - } - private int count() { return next != null ? next.count() + 1 : 1; } @@ -226,19 +292,23 @@ return findStart().getParent(); } - private SpecializationNode removeSameImpl(SpecializationNode toRemove, CharSequence reason) { - SpecializationNode start = findStart(); + private SpecializedNode findSpecializedNode() { + return (SpecializedNode) findEnd().findStart().getParent(); + } + + private static SpecializationNode removeSameImpl(SpecializationNode toRemove, CharSequence reason) { + SpecializationNode start = toRemove.findStart(); SpecializationNode current = start; while (current != null) { if (current.isSame(toRemove)) { - current.replace(current.next, reason); + NodeUtil.nonAtomicReplace(current, current.next, reason); if (current == start) { start = start.next; } } current = current.next; } - return findEnd().findStart(); + return toRemove.findEnd().findStart(); } public Object acceptAndExecute(Frame frame) { @@ -314,7 +384,7 @@ if (nextSpecialization == null) { return unsupported(frame); } - return insertSpecialization(nextSpecialization, new RewriteEvent0(findRoot(), "inserted new specialization")).acceptAndExecute(frame); + return atomic(new InsertionEvent0(this, "insert new specialization", frame, nextSpecialization)).acceptAndExecute(frame); } protected final Object uninitialized(Frame frame, Object o1) { @@ -326,7 +396,7 @@ if (nextSpecialization == null) { return unsupported(frame, o1); } - return insertSpecialization(nextSpecialization, new RewriteEvent1(findRoot(), "inserted new specialization", o1)).acceptAndExecute(frame, o1); + return atomic(new InsertionEvent1(this, "insert new specialization", frame, o1, nextSpecialization)).acceptAndExecute(frame, o1); } protected final Object uninitialized(Frame frame, Object o1, Object o2) { @@ -338,7 +408,7 @@ if (nextSpecialization == null) { return unsupported(frame, o1, o2); } - return insertSpecialization(nextSpecialization, new RewriteEvent2(findRoot(), "inserted new specialization", o1, o2)).acceptAndExecute(frame, o1, o2); + return atomic(new InsertionEvent2(this, "insert new specialization", frame, o1, o2, nextSpecialization)).acceptAndExecute(frame, o1, o2); } protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3) { @@ -350,7 +420,7 @@ if (nextSpecialization == null) { return unsupported(frame, o1, o2, o3); } - return insertSpecialization(nextSpecialization, new RewriteEvent3(findRoot(), "inserted new specialization", o1, o2, o3)).acceptAndExecute(frame, o1, o2, o3); + return atomic(new InsertionEvent3(this, "insert new specialization", frame, o1, o2, o3, nextSpecialization)).acceptAndExecute(frame, o1, o2, o3); } protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4) { @@ -362,7 +432,7 @@ if (nextSpecialization == null) { return unsupported(frame, o1, o2, o3, o4); } - return insertSpecialization(nextSpecialization, new RewriteEvent4(findRoot(), "inserts new specialization", o1, o2, o3, o4)).acceptAndExecute(frame, o1, o2, o3, o4); + return atomic(new InsertionEvent4(this, "insert new specialization", frame, o1, o2, o3, o4, nextSpecialization)).acceptAndExecute(frame, o1, o2, o3, o4); } protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { @@ -374,7 +444,7 @@ if (nextSpecialization == null) { unsupported(frame, o1, o2, o3, o4, o5); } - return insertSpecialization(nextSpecialization, new RewriteEventN(findRoot(), "inserts new specialization", o1, o2, o3, o4, o5)).acceptAndExecute(frame, o1, o2, o3, o4, o5); + return atomic(new InsertionEvent5(this, "insert new specialization", frame, o1, o2, o3, o4, o5, nextSpecialization)).acceptAndExecute(frame, o1, o2, o3, o4, o5); } protected final Object uninitialized(Frame frame, Object... args) { @@ -386,39 +456,35 @@ if (nextSpecialization == null) { unsupported(frame, args); } - return insertSpecialization(nextSpecialization, new RewriteEventN(findRoot(), "inserts new specialization", args)).acceptAndExecute(frame, args); - } - - private boolean needsPolymorphic() { - return findStart().count() == 2; + return atomic(new InsertionEventN(this, "insert new specialization", frame, args, nextSpecialization)).acceptAndExecute(frame, args); } protected final Object remove(String reason, Frame frame) { - return removeSame(new RewriteEvent0(findRoot(), reason)).acceptAndExecute(frame); + return atomic(new RemoveEvent0(this, reason, frame)).acceptAndExecute(frame); } protected final Object remove(String reason, Frame frame, Object o1) { - return removeSame(new RewriteEvent1(findRoot(), reason, o1)).acceptAndExecute(frame, o1); + return atomic(new RemoveEvent1(this, reason, frame, o1)).acceptAndExecute(frame, o1); } protected final Object remove(String reason, Frame frame, Object o1, Object o2) { - return removeSame(new RewriteEvent2(findRoot(), reason, o1, o2)).acceptAndExecute(frame, o1, o2); + return atomic(new RemoveEvent2(this, reason, frame, o1, o2)).acceptAndExecute(frame, o1, o2); } protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3) { - return removeSame(new RewriteEvent3(findRoot(), reason, o1, o2, o3)).acceptAndExecute(frame, o1, o2, o3); + return atomic(new RemoveEvent3(this, reason, frame, o1, o2, o3)).acceptAndExecute(frame, o1, o2, o3); } protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { - return removeSame(new RewriteEvent4(findRoot(), reason, o1, o2, o3, o4)).acceptAndExecute(frame, o1, o2, o3, o4); + return atomic(new RemoveEvent4(this, reason, frame, o1, o2, o3, o4)).acceptAndExecute(frame, o1, o2, o3, o4); } protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { - return removeSame(new RewriteEventN(findRoot(), reason, o1, o2, o3, o4, o5)).acceptAndExecute(frame, o1, o2, o3, o4, o5); + return atomic(new RemoveEvent5(this, reason, frame, o1, o2, o3, o4, o5)).acceptAndExecute(frame, o1, o2, o3, o4, o5); } protected final Object remove(String reason, Frame frame, Object... args) { - return removeSame(new RewriteEventN(findRoot(), reason, args)).acceptAndExecute(frame, args); + return atomic(new RemoveEventN(this, reason, frame, args)).acceptAndExecute(frame, args); } protected Object unsupported(Frame frame) { @@ -449,51 +515,27 @@ throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), args); } - private SpecializationNode insertSpecialization(final SpecializationNode generated, final CharSequence message) { - return atomic(new Callable<SpecializationNode>() { - public SpecializationNode call() { - return insert(generated, message); - } - }); - } - - private SpecializationNode insert(final SpecializationNode generated, CharSequence message) { - SpecializationNode start = findStart(); - if (start == this) { - // fast path for first insert - return insertBefore(this, generated, message); - } else { - return slowSortedInsert(start, generated, message); - } - } - - private static <T> SpecializationNode slowSortedInsert(SpecializationNode start, final SpecializationNode generated, final CharSequence message) { - final SpecializationNode merged = start.merge(generated); + static SpecializationNode insertSorted(SpecializationNode start, final SpecializationNode generated, final CharSequence message, final SpecializationNode merged) { if (merged == generated) { // new node if (start.count() == 2) { - insertBefore(start, start.createPolymorphic(), "insert polymorphic"); + insertAt(start, start.createPolymorphic(), "insert polymorphic"); } - SpecializationNode insertBefore = findInsertBeforeNode(generated.index, start); - return insertBefore(insertBefore, generated, message); + SpecializationNode current = start; + while (current != null && current.index < generated.index) { + current = current.next; + } + return insertAt(current, generated, message); } else { // existing node - merged.replace(merged, new RewriteEvent0(merged.findRoot(), "merged specialization")); return start; } } - private static SpecializationNode findInsertBeforeNode(int generatedIndex, SpecializationNode start) { - SpecializationNode current = start; - while (current != null && current.index < generatedIndex) { - current = current.next; - } - return current; - } - - private static <T> SpecializationNode insertBefore(SpecializationNode node, SpecializationNode insertBefore, CharSequence message) { + static <T> SpecializationNode insertAt(SpecializationNode node, SpecializationNode insertBefore, CharSequence reason) { insertBefore.next = node; - return node.replace(insertBefore, message); + // always guaranteed to be executed inside of an atomic block + return NodeUtil.nonAtomicReplace(node, insertBefore, reason); } @Override @@ -545,7 +587,6 @@ b.append(")"); } - // utilities for generated code protected static void check(Assumption assumption) throws InvalidAssumptionException { if (assumption != null) { assumption.check(); @@ -580,4 +621,226 @@ return true; } + private static final class InsertionEvent0 extends SlowPathEvent0 implements Callable<SpecializationNode> { + + private final SpecializationNode next; + + public InsertionEvent0(SpecializationNode source, String reason, Frame frame, SpecializationNode next) { + super(source, reason, frame); + this.next = next; + } + + public SpecializationNode call() throws Exception { + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame)); + } + } + + } + + private static final class InsertionEvent1 extends SlowPathEvent1 implements Callable<SpecializationNode> { + + private final SpecializationNode next; + + public InsertionEvent1(SpecializationNode source, String reason, Frame frame, Object o1, SpecializationNode next) { + super(source, reason, frame, o1); + this.next = next; + } + + public SpecializationNode call() throws Exception { + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1)); + } + } + + } + + private static final class InsertionEvent2 extends SlowPathEvent2 implements Callable<SpecializationNode> { + + private final SpecializationNode next; + + public InsertionEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, SpecializationNode next) { + super(source, reason, frame, o1, o2); + this.next = next; + } + + public SpecializationNode call() throws Exception { + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2)); + } + } + + } + + private static final class InsertionEvent3 extends SlowPathEvent3 implements Callable<SpecializationNode> { + + private final SpecializationNode next; + + public InsertionEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, SpecializationNode next) { + super(source, reason, frame, o1, o2, o3); + this.next = next; + } + + public SpecializationNode call() throws Exception { + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3)); + } + } + + } + + private static final class InsertionEvent4 extends SlowPathEvent4 implements Callable<SpecializationNode> { + + private final SpecializationNode next; + + public InsertionEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, SpecializationNode next) { + super(source, reason, frame, o1, o2, o3, o4); + this.next = next; + } + + public SpecializationNode call() throws Exception { + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3, o4)); + } + } + + } + + private static final class InsertionEvent5 extends SlowPathEvent5 implements Callable<SpecializationNode> { + + private final SpecializationNode next; + + public InsertionEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5, SpecializationNode next) { + super(source, reason, frame, o1, o2, o3, o4, o5); + this.next = next; + } + + public SpecializationNode call() throws Exception { + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3, o4, o5)); + } + } + + } + + private static final class InsertionEventN extends SlowPathEventN implements Callable<SpecializationNode> { + + private final SpecializationNode next; + + public InsertionEventN(SpecializationNode source, String reason, Frame frame, Object[] args, SpecializationNode next) { + super(source, reason, frame, args); + this.next = next; + } + + public SpecializationNode call() throws Exception { + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, args)); + } + } + } + + private static final class RemoveEvent0 extends SlowPathEvent0 implements Callable<SpecializationNode> { + + public RemoveEvent0(SpecializationNode source, String reason, Frame frame) { + super(source, reason, frame); + } + + public SpecializationNode call() throws Exception { + return removeSameImpl(source, this); + } + + } + + private static final class RemoveEvent1 extends SlowPathEvent1 implements Callable<SpecializationNode> { + + public RemoveEvent1(SpecializationNode source, String reason, Frame frame, Object o1) { + super(source, reason, frame, o1); + } + + public SpecializationNode call() throws Exception { + return removeSameImpl(source, this); + } + + } + + private static final class RemoveEvent2 extends SlowPathEvent2 implements Callable<SpecializationNode> { + + public RemoveEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) { + super(source, reason, frame, o1, o2); + } + + public SpecializationNode call() throws Exception { + return removeSameImpl(source, this); + } + + } + + private static final class RemoveEvent3 extends SlowPathEvent3 implements Callable<SpecializationNode> { + + public RemoveEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) { + super(source, reason, frame, o1, o2, o3); + } + + public SpecializationNode call() throws Exception { + return removeSameImpl(source, this); + } + + } + + private static final class RemoveEvent4 extends SlowPathEvent4 implements Callable<SpecializationNode> { + + public RemoveEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { + super(source, reason, frame, o1, o2, o3, o4); + } + + public SpecializationNode call() throws Exception { + return removeSameImpl(source, this); + } + + } + + private static final class RemoveEvent5 extends SlowPathEvent5 implements Callable<SpecializationNode> { + + public RemoveEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + super(source, reason, frame, o1, o2, o3, o4, o5); + } + + public SpecializationNode call() throws Exception { + return removeSameImpl(source, this); + } + + } + + private static final class RemoveEventN extends SlowPathEventN implements Callable<SpecializationNode> { + + public RemoveEventN(SpecializationNode source, String reason, Frame frame, Object[] args) { + super(source, reason, frame, args); + } + + public SpecializationNode call() throws Exception { + return removeSameImpl(source, this); + } + } + }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/OnAdoptTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/OnAdoptTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,13 +30,13 @@ /** * <h3>Inserting Extra Nodes into the AST Transparently</h3> - * + * * <p> * The {@link Node} class provides a callback that is invoked whenever a node is adopted in an AST * by insertion or replacement. Node classes can override the {@code onAdopt()} method to run extra * functionality upon adoption. * </p> - * + * * <p> * This test demonstrates how node instances of a specific class can be automatically wrapped in * extra nodes when they are inserted into the AST.
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,19 +34,19 @@ /** * <h3>Replacing Nodes at Run Time</h3> - * + * * <p> * The structure of the Truffle tree can be changed at run time by replacing nodes using the * {@link Node#replace(Node)} method. This method will automatically change the child pointer in the * parent of the node and replace it with a pointer to the new node. * </p> - * + * * <p> * Replacing nodes is a costly operation, so it should not happen too often. The convention is that * the implementation of the Truffle nodes should ensure that there are maximal a small (and * constant) number of node replacements per Truffle node. * </p> - * + * * <p> * The next part of the Truffle API introduction is at {@link com.oracle.truffle.api.test.CallTest}. * </p>
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -439,7 +439,7 @@ } private abstract class TestLanguageNode extends Node { - public abstract Object execute(VirtualFrame frame); + public abstract Object execute(VirtualFrame vFrame); @Override public boolean isInstrumentable() { @@ -492,17 +492,17 @@ } @Override - public Object execute(VirtualFrame frame) { - probeNode.enter(child, frame); + public Object execute(VirtualFrame vFrame) { + probeNode.enter(child, vFrame); Object result; try { - result = child.execute(frame); - probeNode.returnValue(child, frame, result); + result = child.execute(vFrame); + probeNode.returnValue(child, vFrame, result); } catch (KillException e) { throw (e); } catch (Exception e) { - probeNode.returnExceptional(child, frame, e); + probeNode.returnExceptional(child, vFrame, e); throw (e); } @@ -521,7 +521,7 @@ } @Override - public Object execute(VirtualFrame frame) { + public Object execute(VirtualFrame vFrame) { return new Integer(this.value); } } @@ -539,8 +539,8 @@ } @Override - public Object execute(VirtualFrame frame) { - return new Integer(((Integer) leftChild.execute(frame)).intValue() + ((Integer) rightChild.execute(frame)).intValue()); + public Object execute(VirtualFrame vFrame) { + return new Integer(((Integer) leftChild.execute(vFrame)).intValue() + ((Integer) rightChild.execute(vFrame)).intValue()); } } @@ -563,8 +563,8 @@ } @Override - public Object execute(VirtualFrame frame) { - return body.execute(frame); + public Object execute(VirtualFrame vFrame) { + return body.execute(vFrame); } @Override @@ -591,12 +591,12 @@ instrument = Instrument.create(new SimpleEventListener() { @Override - public void enter(Node node, VirtualFrame frame) { + public void enter(Node node, VirtualFrame vFrame) { enterCount++; } @Override - public void returnAny(Node node, VirtualFrame frame) { + public void returnAny(Node node, VirtualFrame vFrame) { leaveCount++; } }, "Instrumentation Test Counter"); @@ -695,7 +695,7 @@ probe.attach(Instrument.create(new SimpleEventListener() { @Override - public void enter(Node node, VirtualFrame frame) { + public void enter(Node node, VirtualFrame vFrame) { count++; } }, "Instrumentation Test MultiCounter"));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.test.source; + +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.truffle.api.source.*; + +public class SourceTest { + + @Test + public void sourceTagTest() { + + // Private tag + final SourceTag testTag = new SourceTag() { + + public String name() { + return null; + } + + public String getDescription() { + return null; + } + }; + + // No sources exist with the private tag + assertEquals(Source.findSourcesTaggedAs(testTag).size(), 0); + + // Create a new source + final Source source = Source.fromText("test1 source", "test1 source"); + + // Initially has only the default tag + assertEquals(source.getSourceTags().size(), 1); + + assertTrue(source.getSourceTags().contains(StandardSourceTag.FROM_LITERAL)); + assertTrue(source.isTaggedAs(StandardSourceTag.FROM_LITERAL)); + assertTrue(Source.findSourcesTaggedAs(StandardSourceTag.FROM_LITERAL).contains(source)); + + assertFalse(source.isTaggedAs(testTag)); + assertEquals(Source.findSourcesTaggedAs(testTag).size(), 0); + + // Add a private tag + source.tagAs(testTag); + + // Now there are exactly two tags + assertEquals(source.getSourceTags().size(), 2); + + assertTrue(source.getSourceTags().contains(StandardSourceTag.FROM_LITERAL)); + assertTrue(source.isTaggedAs(StandardSourceTag.FROM_LITERAL)); + assertTrue(Source.findSourcesTaggedAs(StandardSourceTag.FROM_LITERAL).contains(source)); + + assertTrue(source.getSourceTags().contains(testTag)); + assertTrue(source.isTaggedAs(testTag)); + assertEquals(Source.findSourcesTaggedAs(testTag).size(), 1); + assertTrue(Source.findSourcesTaggedAs(testTag).contains(source)); + + // Add the private tag again + source.tagAs(testTag); + + // Nothing has changed + assertEquals(source.getSourceTags().size(), 2); + + assertTrue(source.getSourceTags().contains(StandardSourceTag.FROM_LITERAL)); + assertTrue(source.isTaggedAs(StandardSourceTag.FROM_LITERAL)); + assertTrue(Source.findSourcesTaggedAs(StandardSourceTag.FROM_LITERAL).contains(source)); + + assertTrue(source.getSourceTags().contains(testTag)); + assertTrue(source.isTaggedAs(testTag)); + assertEquals(Source.findSourcesTaggedAs(testTag).size(), 1); + assertTrue(Source.findSourcesTaggedAs(testTag).contains(source)); + } + + @Test + public void sourceListenerTest() { + + // Private tag + final SourceTag testTag = new SourceTag() { + + public String name() { + return null; + } + + public String getDescription() { + return null; + } + }; + + final int[] newSourceEvents = {0}; + final Source[] newSource = {null}; + + final int[] newTagEvents = {0}; + final Source[] taggedSource = {null}; + final SourceTag[] newTag = {null}; + + Source.addSourceListener(new SourceListener() { + + public void sourceCreated(Source source) { + newSourceEvents[0] = newSourceEvents[0] + 1; + newSource[0] = source; + } + + public void sourceTaggedAs(Source source, SourceTag tag) { + newTagEvents[0] = newTagEvents[0] + 1; + taggedSource[0] = source; + newTag[0] = tag; + } + }); + + // New source has a default tag applied. + // Get one event for the new source, another one when it gets tagged + final Source source = Source.fromText("testSource", "testSource"); + assertEquals(newSourceEvents[0], 1); + assertEquals(newSource[0], source); + assertEquals(newTagEvents[0], 1); + assertEquals(taggedSource[0], source); + assertEquals(newTag[0], StandardSourceTag.FROM_LITERAL); + + // reset + newSource[0] = null; + taggedSource[0] = null; + newTag[0] = null; + + // Add a tag; only get one event (the new tag) + source.tagAs(testTag); + assertEquals(newSourceEvents[0], 1); + assertEquals(newSource[0], null); + assertEquals(newTagEvents[0], 2); + assertEquals(taggedSource[0], source); + assertEquals(newTag[0], testTag); + + // Add the same tag; no events, and nothing changes. + source.tagAs(testTag); + assertEquals(newSourceEvents[0], 1); + assertEquals(newSource[0], null); + assertEquals(newTagEvents[0], 2); + assertEquals(taggedSource[0], source); + assertEquals(newTag[0], testTag); + + } +}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,6 @@ * */ public class CompilerAsserts { - /** * Assertion that this code position should never be reached during compilation. It can be used * for exceptional code paths or rare code paths that should never be included in a compilation @@ -40,98 +39,37 @@ * directive. */ public static void neverPartOfCompilation() { - } - - public static void neverPartOfCompilation(@SuppressWarnings("unused") String message) { - } - - /** - * Assertion that the corresponding value is reduced to a constant during compilation. - * - * @param value the value that must be constant during compilation - * @return the value given as parameter - */ - public static boolean compilationConstant(boolean value) { - return value; + neverPartOfCompilation(""); } /** - * Assertion that the corresponding value is reduced to a constant during compilation. + * Assertion that this code position should never be reached during compilation. It can be used + * for exceptional code paths or rare code paths that should never be included in a compilation + * unit. See {@link CompilerDirectives#transferToInterpreter()} for the corresponding compiler + * directive. * - * @param value the value that must be constant during compilation - * @return the value given as parameter + * @param message text associated with the bailout exception */ - public static byte compilationConstant(byte value) { - return value; - } - - /** - * Assertion that the corresponding value is reduced to a constant during compilation. - * - * @param value the value that must be constant during compilation - * @return the value given as parameter - */ - public static char compilationConstant(char value) { - return value; + public static void neverPartOfCompilation(String message) { } /** * Assertion that the corresponding value is reduced to a constant during compilation. * * @param value the value that must be constant during compilation - * @return the value given as parameter */ - public static short compilationConstant(short value) { - return value; - } - - /** - * Assertion that the corresponding value is reduced to a constant during compilation. - * - * @param value the value that must be constant during compilation - * @return the value given as parameter - */ - public static int compilationConstant(int value) { - return value; - } - - /** - * Assertion that the corresponding value is reduced to a constant during compilation. - * - * @param value the value that must be constant during compilation - * @return the value given as parameter - */ - public static long compilationConstant(long value) { - return value; + public static <T> void compilationConstant(Object value) { + if (!CompilerDirectives.isCompilationConstant(value)) { + neverPartOfCompilation("Value is not compilation constant"); + } } /** - * Assertion that the corresponding value is reduced to a constant during compilation. - * - * @param value the value that must be constant during compilation - * @return the value given as parameter - */ - public static float compilationConstant(float value) { - return value; - } - - /** - * Assertion that the corresponding value is reduced to a constant during compilation. + * Assertion that the corresponding value is reduced to a constant during the initial partial + * evaluation phase. * * @param value the value that must be constant during compilation - * @return the value given as parameter */ - public static double compilationConstant(double value) { - return value; - } - - /** - * Assertion that the corresponding value is reduced to a constant during compilation. - * - * @param value the value that must be constant during compilation - * @return the value given as parameter - */ - public static Object compilationConstant(Object value) { - return value; + public static <T> void partialEvaluationConstant(Object value) { } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Tue Mar 10 21:26:02 2015 +0100 @@ -80,33 +80,20 @@ /** * Returns a boolean indicating whether or not a given value is seen as constant in optimized * code. If this method is called in the interpreter this method will always return - * <code>false</code>. This API may be used in combination with {@link #inCompiledCode()} to - * implement compilation constant assertions in the following way: - * - * <pre> - * <code> - * void assertCompilationConstant(Object value) { - * if (inCompiledCode()) { - * if (!isCompilationConstant(value)) { - * throw new AssertionError("Given value is not constant"); - * } - * } - * } - * </code> - * </pre> + * <code>true</code>. * * Note that optimizations that a compiler will apply to code that is conditional on * <code>isCompilationConstant</code> may be limited. For this reason * <code>isCompilationConstant</code> is not recommended for use to select between alternate * implementations of functionality depending on whether a value is constant. Instead, it is - * intended for use as a diagnostic mechanism, such as illustrated above. + * intended for use as a diagnostic mechanism. * * @param value * @return {@code true} when given value is seen as compilation constant, {@code false} if not * compilation constant. */ public static boolean isCompilationConstant(Object value) { - return false; + return CompilerDirectives.inInterpreter(); } /**
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Tue Mar 10 21:26:02 2015 +0100 @@ -28,7 +28,7 @@ /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). - * + * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getObject(FrameSlot) @@ -44,7 +44,7 @@ /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). - * + * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getByte(FrameSlot) @@ -60,7 +60,7 @@ /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). - * + * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getBoolean(FrameSlot) @@ -76,7 +76,7 @@ /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). - * + * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getInt(FrameSlot) @@ -92,7 +92,7 @@ /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). - * + * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getLong(FrameSlot) @@ -108,7 +108,7 @@ /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). - * + * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getDouble(FrameSlot) @@ -124,7 +124,7 @@ /** * Read a frame slot that is guaranteed to be of the desired kind (either previously checked by * a guard or statically known). - * + * * @param frameSlot the slot of the variable * @throws IllegalStateException if the slot kind does not match * @see Frame#getFloat(FrameSlot)
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,11 +36,10 @@ private final RootNode rootNode; - public DefaultCallTarget(RootNode function) { + protected DefaultCallTarget(RootNode function) { this.rootNode = function; this.rootNode.adoptChildren(); this.rootNode.applyInstrumentation(); - this.rootNode.setCallTarget(this); } @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Tue Mar 10 21:26:02 2015 +0100 @@ -55,6 +55,7 @@ @Override public RootCallTarget createCallTarget(RootNode rootNode) { DefaultCallTarget target = new DefaultCallTarget(rootNode); + rootNode.setCallTarget(target); callTargets.put(target, null); return target; }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,13 +24,15 @@ */ package com.oracle.truffle.api.instrument; +import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.impl.*; import com.oracle.truffle.api.nodes.*; // TODO (mlvdv) migrate some of this to external documentation. +// TODO (mlvdv) move all this to a factory implemented in .impl (together with Probe), +// then break out some of the nested classes into package privates. /** * A dynamically added/removed binding between a {@link Probe}, which provides notification of * {@linkplain TruffleEventListener execution events} taking place at a {@link Node} in a Guest @@ -44,8 +46,8 @@ * <li>Create an Instrument via factory method {@link Instrument#create(TruffleEventListener)}.</li> * <li>"Attach" the Instrument to a Probe via {@link Probe#attach(Instrument)}, at which point event * notifications begin to arrive at the listener.</li> - * <li>When no longer needed, "detach" the Instrument via {@link Instrument#dispose()}, at which - * point event notifications to the listener cease, and the Instrument becomes unusable.</li> + * <li>When no longer needed, "detach" the Instrument via {@link TruffleEventInstrument#dispose()}, + * at which point event notifications to the listener cease, and the Instrument becomes unusable.</li> * </ol> * <p> * <h4>Options for creating listeners:</h4> @@ -123,8 +125,8 @@ * error to attempt attaching a previously attached instrument.</li> * <li>Attaching an instrument modifies every existing clone of the AST to which it is being * attached, which can trigger deoptimization.</li> - * <li>The method {@link Instrument#dispose()} makes an instrument inactive by removing it from the - * Probe to which it was attached and rendering it permanently inert.</li> + * <li>The method {@link TruffleEventInstrument#dispose()} makes an instrument inactive by removing + * it from the Probe to which it was attached and rendering it permanently inert.</li> * <li>Disposal removes the implementation of an instrument from all ASTs to which it was attached, * which can trigger deoptimization.</li> * </ul> @@ -142,7 +144,7 @@ * @see Probe * @see TruffleEventListener */ -public final class Instrument { +public abstract class Instrument { /** * Creates an instrument that will route execution events to a listener. @@ -152,25 +154,23 @@ * @return a new instrument, ready for attachment at a probe */ public static Instrument create(TruffleEventListener listener, String instrumentInfo) { - return new Instrument(listener, instrumentInfo); + return new TruffleEventInstrument(listener, instrumentInfo); } /** * Creates an instrument that will route execution events to a listener. */ public static Instrument create(TruffleEventListener listener) { - return new Instrument(listener, null); + return new TruffleEventInstrument(listener, null); } + // TODO (mlvdv) experimental /** - * Tool-supplied listener for events. + * For implementation testing. */ - private final TruffleEventListener toolEventListener; - - /** - * Optional documentation, mainly for debugging. - */ - private final String instrumentInfo; + public static Instrument create(TruffleOptListener listener) { + return new TruffleOptInstrument(listener, null); + } /** * Has this instrument been disposed? stays true once set. @@ -179,8 +179,12 @@ private Probe probe = null; - private Instrument(TruffleEventListener listener, String instrumentInfo) { - this.toolEventListener = listener; + /** + * Optional documentation, mainly for debugging. + */ + private final String instrumentInfo; + + private Instrument(String instrumentInfo) { this.instrumentInfo = instrumentInfo; } @@ -216,35 +220,176 @@ return isDisposed; } - InstrumentNode addToChain(InstrumentNode nextNode) { - return new InstrumentNode(nextNode); - } + abstract InstrumentNode addToChain(InstrumentNode nextNode); /** * Removes this instrument from an instrument chain. */ - InstrumentNode removeFromChain(InstrumentNode instrumentNode) { - boolean found = false; - if (instrumentNode != null) { - if (instrumentNode.getInstrument() == this) { - // Found the match at the head of the chain - return instrumentNode.nextInstrument; + abstract InstrumentNode removeFromChain(InstrumentNode instrumentNode); + + private static final class TruffleEventInstrument extends Instrument { + + /** + * Tool-supplied listener for events. + */ + private final TruffleEventListener toolEventListener; + + private TruffleEventInstrument(TruffleEventListener listener, String instrumentInfo) { + super(instrumentInfo); + this.toolEventListener = listener; + } + + @Override + InstrumentNode addToChain(InstrumentNode nextNode) { + return new TruffleEventInstrumentNode(nextNode); + } + + @Override + InstrumentNode removeFromChain(InstrumentNode instrumentNode) { + boolean found = false; + if (instrumentNode != null) { + if (instrumentNode.getInstrument() == this) { + // Found the match at the head of the chain + return instrumentNode.nextInstrument; + } + // Match not at the head of the chain; remove it. + found = instrumentNode.removeFromChain(TruffleEventInstrument.this); + } + if (!found) { + throw new IllegalStateException("Couldn't find instrument node to remove: " + this); + } + return instrumentNode; + } + + @NodeInfo(cost = NodeCost.NONE) + private final class TruffleEventInstrumentNode extends InstrumentNode { + + private TruffleEventInstrumentNode(InstrumentNode nextNode) { + super(nextNode); + } + + public void enter(Node node, VirtualFrame vFrame) { + TruffleEventInstrument.this.toolEventListener.enter(node, vFrame); + if (nextInstrument != null) { + nextInstrument.enter(node, vFrame); + } + } + + public void returnVoid(Node node, VirtualFrame vFrame) { + TruffleEventInstrument.this.toolEventListener.returnVoid(node, vFrame); + if (nextInstrument != null) { + nextInstrument.returnVoid(node, vFrame); + } + } + + public void returnValue(Node node, VirtualFrame vFrame, Object result) { + TruffleEventInstrument.this.toolEventListener.returnValue(node, vFrame, result); + if (nextInstrument != null) { + nextInstrument.returnValue(node, vFrame, result); + } + } + + public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { + TruffleEventInstrument.this.toolEventListener.returnExceptional(node, vFrame, exception); + if (nextInstrument != null) { + nextInstrument.returnExceptional(node, vFrame, exception); + } + } + + public String instrumentationInfo() { + final String info = getInstrumentInfo(); + return info != null ? info : toolEventListener.getClass().getSimpleName(); } - // Match not at the head of the chain; remove it. - found = instrumentNode.removeFromChain(Instrument.this); + } + + } + + public interface TruffleOptListener { + void notifyIsCompiled(boolean isCompiled); + } + + private static final class TruffleOptInstrument extends Instrument { + + private final TruffleOptListener toolOptListener; + + private TruffleOptInstrument(TruffleOptListener listener, String instrumentInfo) { + super(instrumentInfo); + this.toolOptListener = listener; + } + + @Override + InstrumentNode addToChain(InstrumentNode nextNode) { + return new TruffleOptInstrumentNode(nextNode); + } + + @Override + InstrumentNode removeFromChain(InstrumentNode instrumentNode) { + boolean found = false; + if (instrumentNode != null) { + if (instrumentNode.getInstrument() == this) { + // Found the match at the head of the chain + return instrumentNode.nextInstrument; + } + // Match not at the head of the chain; remove it. + found = instrumentNode.removeFromChain(TruffleOptInstrument.this); + } + if (!found) { + throw new IllegalStateException("Couldn't find instrument node to remove: " + this); + } + return instrumentNode; } - if (!found) { - throw new IllegalStateException("Couldn't find instrument node to remove: " + this); + + @NodeInfo(cost = NodeCost.NONE) + private final class TruffleOptInstrumentNode extends InstrumentNode { + + private boolean isCompiled; + + private TruffleOptInstrumentNode(InstrumentNode nextNode) { + super(nextNode); + this.isCompiled = CompilerDirectives.inCompiledCode(); + } + + public void enter(Node node, VirtualFrame vFrame) { + if (this.isCompiled != CompilerDirectives.inCompiledCode()) { + this.isCompiled = CompilerDirectives.inCompiledCode(); + TruffleOptInstrument.this.toolOptListener.notifyIsCompiled(this.isCompiled); + } + if (nextInstrument != null) { + nextInstrument.enter(node, vFrame); + } + } + + public void returnVoid(Node node, VirtualFrame vFrame) { + if (nextInstrument != null) { + nextInstrument.returnVoid(node, vFrame); + } + } + + public void returnValue(Node node, VirtualFrame vFrame, Object result) { + if (nextInstrument != null) { + nextInstrument.returnValue(node, vFrame, result); + } + } + + public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { + if (nextInstrument != null) { + nextInstrument.returnExceptional(node, vFrame, exception); + } + } + + public String instrumentationInfo() { + final String info = getInstrumentInfo(); + return info != null ? info : toolOptListener.getClass().getSimpleName(); + } } - return instrumentNode; + } @NodeInfo(cost = NodeCost.NONE) - final class InstrumentNode extends Node implements TruffleEventListener, InstrumentationNode { + abstract class InstrumentNode extends Node implements TruffleEventListener, InstrumentationNode { + @Child protected InstrumentNode nextInstrument; - @Child private InstrumentNode nextInstrument; - - private InstrumentNode(InstrumentNode nextNode) { + protected InstrumentNode(InstrumentNode nextNode) { this.nextInstrument = nextNode; } @@ -286,40 +431,10 @@ return nextInstrument.removeFromChain(instrument); } - public void enter(Node node, VirtualFrame frame) { - Instrument.this.toolEventListener.enter(node, frame); - if (nextInstrument != null) { - nextInstrument.enter(node, frame); - } - } - - public void returnVoid(Node node, VirtualFrame frame) { - Instrument.this.toolEventListener.returnVoid(node, frame); - if (nextInstrument != null) { - nextInstrument.returnVoid(node, frame); - } + protected String getInstrumentInfo() { + return Instrument.this.instrumentInfo; } - public void returnValue(Node node, VirtualFrame frame, Object result) { - Instrument.this.toolEventListener.returnValue(node, frame, result); - if (nextInstrument != null) { - nextInstrument.returnValue(node, frame, result); - } - } - - public void returnExceptional(Node node, VirtualFrame frame, Exception exception) { - Instrument.this.toolEventListener.returnExceptional(node, frame, exception); - if (nextInstrument != null) { - nextInstrument.returnExceptional(node, frame, exception); - } - } - - public String instrumentationInfo() { - if (Instrument.this.instrumentInfo != null) { - return Instrument.this.instrumentInfo; - } - return toolEventListener.getClass().getSimpleName(); - } } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Tue Mar 10 21:26:02 2015 +0100 @@ -69,6 +69,7 @@ * @see Instrument * @see ASTProber * @see ProbeListener + * @see SyntaxTag */ public final class Probe implements SyntaxTagged { @@ -183,6 +184,7 @@ * @param newTagTrap The {@link SyntaxTagTrap} to set. */ public static void setTagTrap(SyntaxTagTrap newTagTrap) { + tagTrap = newTagTrap; for (WeakReference<Probe> ref : probes) { final Probe probe = ref.get(); if (probe != null) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardSyntaxTag.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardSyntaxTag.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -30,9 +30,7 @@ * <p> * The need for alternative sets of tags is likely to arise, perhaps for other families of languages * (for example for mostly expression-oriented languages) or even for specific languages. - * <p> - * <strong>Disclaimer:</strong> experimental interface under development. - * + * * @see Probe */ public enum StandardSyntaxTag implements SyntaxTag {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTag.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTag.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -34,8 +34,6 @@ * and should not be visible to guest language programmers. Nodes may also have more than one tag, * for example a variable assignment that is also a statement. Finally, the assignment of tags to * nodes could depending on the use-case of whatever tool is using them. - * <p> - * <strong>Disclaimer:</strong> experimental interface under development. * * @see Probe * @see StandardSyntaxTag
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -29,6 +29,8 @@ /** * A trap that can be set to interrupt execution at probed nodes carrying a specific tag. + * + * @see Probe */ public abstract class SyntaxTagTrap {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagged.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagged.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ /** * Information about a guest language program element in a Truffle AST that can be marked as * belonging to 0 or more {@linkplain SyntaxTag tags}. - * <p> - * <strong>Disclaimer:</strong> experimental interface under development. */ public interface SyntaxTagged {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TruffleEventListener.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TruffleEventListener.java Tue Mar 10 21:26:02 2015 +0100 @@ -36,22 +36,22 @@ /** * Receive notification that an AST node's execute method is about to be called. */ - void enter(Node node, VirtualFrame frame); + void enter(Node node, VirtualFrame vFrame); /** * Receive notification that an AST Node's {@code void}-valued execute method has just returned. */ - void returnVoid(Node node, VirtualFrame frame); + void returnVoid(Node node, VirtualFrame vFrame); /** * Receive notification that an AST Node'sexecute method has just returned a value (boxed if * primitive). */ - void returnValue(Node node, VirtualFrame frame, Object result); + void returnValue(Node node, VirtualFrame vFrame, Object result); /** * Receive notification that an AST Node's execute method has just thrown an exception. */ - void returnExceptional(Node node, VirtualFrame frame, Exception exception); + void returnExceptional(Node node, VirtualFrame vFrame, Exception exception); }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -60,9 +60,12 @@ String displayCallTargetName(CallTarget callTarget); /** - * Converts a value in the guest language to a display string. + * Converts a value in the guest language to a display string. If + * + * @param trim if {@code > 0}, them limit size of String to either the value of trim or the + * number of characters in the first line, whichever is lower. */ - String displayValue(ExecutionContext context, Object value); + String displayValue(ExecutionContext context, Object value, int trim); /** * Converts a slot identifier in the guest language to a display string.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultEventListener.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultEventListener.java Tue Mar 10 21:26:02 2015 +0100 @@ -34,16 +34,16 @@ */ public class DefaultEventListener implements TruffleEventListener { - public void enter(Node node, VirtualFrame frame) { + public void enter(Node node, VirtualFrame vFrame) { } - public void returnVoid(Node node, VirtualFrame frame) { + public void returnVoid(Node node, VirtualFrame vFrame) { } - public void returnValue(Node node, VirtualFrame frame, Object result) { + public void returnValue(Node node, VirtualFrame vFrame, Object result) { } - public void returnExceptional(Node node, VirtualFrame frame, Exception exception) { + public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -70,12 +70,34 @@ return callTarget.toString(); } - public String displayValue(ExecutionContext context, Object value) { - return value.toString(); + public String displayValue(ExecutionContext context, Object value, int trim) { + return trim(value.toString(), trim); } public String displayIdentifier(FrameSlot slot) { return slot.getIdentifier().toString(); } + /** + * Trims text if {@code trim > 0} to the shorter of {@code trim} or the length of the first line + * of test. Identity if {@code trim <= 0}. + */ + protected String trim(String text, int trim) { + if (trim == 0) { + return text; + } + final String[] lines = text.split("\n"); + String result = lines[0]; + if (lines.length == 1) { + if (result.length() <= trim) { + return result; + } + if (trim <= 3) { + return result.substring(0, Math.min(result.length() - 1, trim - 1)); + } else { + return result.substring(0, trim - 4) + "..."; + } + } + return (result.length() < trim - 3 ? result : result.substring(0, trim - 4)) + "..."; + } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SimpleEventListener.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SimpleEventListener.java Tue Mar 10 21:26:02 2015 +0100 @@ -38,7 +38,7 @@ */ public abstract class SimpleEventListener implements TruffleEventListener { - public void enter(Node node, VirtualFrame frame) { + public void enter(Node node, VirtualFrame vFrame) { } /** @@ -46,21 +46,21 @@ * means: with or without a return value (ignored) or via exception (ignored). * * @param node - * @param frame + * @param vFrame */ - public void returnAny(Node node, VirtualFrame frame) { + public void returnAny(Node node, VirtualFrame vFrame) { } - public final void returnVoid(Node node, VirtualFrame frame) { - returnAny(node, frame); + public final void returnVoid(Node node, VirtualFrame vFrame) { + returnAny(node, vFrame); } - public final void returnValue(Node node, VirtualFrame frame, Object result) { - returnAny(node, frame); + public final void returnValue(Node node, VirtualFrame vFrame, Object result) { + returnAny(node, vFrame); } - public final void returnExceptional(Node node, VirtualFrame frame, Exception e) { - returnAny(node, frame); + public final void returnExceptional(Node node, VirtualFrame vFrame, Exception e) { + returnAny(node, vFrame); } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ExplodeLoop.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/ExplodeLoop.java Tue Mar 10 21:26:02 2015 +0100 @@ -33,4 +33,5 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ExplodeLoop { + boolean merge() default false; }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Mar 10 21:26:02 2015 +0100 @@ -41,7 +41,6 @@ public abstract class Node implements NodeInterface, Cloneable { @CompilationFinal private Node parent; - @CompilationFinal private SourceSection sourceSection; /** @@ -268,7 +267,7 @@ return replace(newNode, ""); } - private void replaceHelper(Node newNode, CharSequence reason) { + final void replaceHelper(Node newNode, CharSequence reason) { CompilerAsserts.neverPartOfCompilation(); if (this.getParent() == null) { throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent."); @@ -573,11 +572,7 @@ public final void atomic(Runnable closure) { RootNode rootNode = getRootNode(); - if (rootNode != null) { - synchronized (rootNode) { - closure.run(); - } - } else { + synchronized (rootNode != null ? rootNode : GIL) { closure.run(); } } @@ -585,14 +580,10 @@ public final <T> T atomic(Callable<T> closure) { try { RootNode rootNode = getRootNode(); - if (rootNode != null) { - synchronized (rootNode) { - return closure.call(); - } - } else { + synchronized (rootNode != null ? rootNode : GIL) { return closure.call(); } - } catch (RuntimeException e) { + } catch (RuntimeException | Error e) { throw e; } catch (Exception e) { throw new RuntimeException(e); @@ -625,4 +616,6 @@ } return ""; } + + private static final Object GIL = new Object(); }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Mar 10 21:26:02 2015 +0100 @@ -597,6 +597,11 @@ return nodes; } + public static <T extends Node> T nonAtomicReplace(Node oldNode, T newNode, CharSequence reason) { + oldNode.replaceHelper(newNode, reason); + return newNode; + } + public static boolean replaceChild(Node parent, Node oldChild, Node newChild) { NodeClass nodeClass = NodeClass.get(parent.getClass()); @@ -696,6 +701,42 @@ return false; } + /** + * Executes a closure for every non-null child of the parent node. + * + * @return {@code true} if all children were visited, {@code false} otherwise + */ + public static boolean forEachChild(Node parent, NodeVisitor visitor) { + Objects.requireNonNull(visitor); + NodeClass parentNodeClass = NodeClass.get(parent.getClass()); + + for (NodeField field : parentNodeClass.getChildFields()) { + Object child = field.getObject(parent); + if (child != null) { + if (!visitor.visit((Node) child)) { + return false; + } + } + } + + for (NodeField field : parentNodeClass.getChildrenFields()) { + Object arrayObject = field.getObject(parent); + if (arrayObject != null) { + Object[] array = (Object[]) arrayObject; + for (int i = 0; i < array.length; i++) { + Object child = array[i]; + if (child != null) { + if (!visitor.visit((Node) child)) { + return false; + } + } + } + } + } + + return true; + } + /** Returns all declared fields in the class hierarchy. */ private static Field[] getAllFields(Class<? extends Object> clazz) { Field[] declaredFields = clazz.getDeclaredFields();
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeVisitor.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeVisitor.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ /** * This visitor method is called for every node in the tree. Its return value determines if the * children of this node should be excluded in the iteration. - * + * * @param node the node that is currently visited * @return {@code true} if the children should be visited too, {@code false} otherwise */
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -72,7 +72,7 @@ * language specific implementations may want to return <code>true</code> here to indicate that * gathering call site specific profiling information might make sense for this {@link RootNode} * . - * + * * @return <code>true</code> if cloning is allowed else <code>false</code>. */ public boolean isCloningAllowed() { @@ -91,7 +91,7 @@ /** * Executes this function using the specified frame and returns the result value. - * + * * @param frame the frame of the currently executing guest language method * @return the value of the execution */ @@ -114,14 +114,14 @@ * the correct <code>ExecutionContext</code> to be determined for a <code>RootNode</code> (and * so also for a {@link RootCallTarget} and a {@link FrameInstance} obtained from the call * stack) without prior knowledge of the language it has come from. - * + * * Used for instance to determine the language of a <code>RootNode<code>: - * + * * <pre> * <code> * rootNode.getExecutionContext().getLanguageShortName(); * </code> </pre> - * + * * Returns <code>null</code> by default. */ public ExecutionContext getExecutionContext() { @@ -151,7 +151,7 @@ * <p> * Implementations should ensure that instrumentation is never applied more than once to an AST, * as this is not guaranteed to be error-free. - * + * * @see Probe#registerASTProber(com.oracle.truffle.api.instrument.ASTProber) */ public void applyInstrumentation() {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ /** * Creates the exception with the alternative result that cannot be represented as a value of * the return type. - * + * * @param result the alternative result */ public UnexpectedResultException(Object result) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/SerializerConstantPool.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/SerializerConstantPool.java Tue Mar 10 21:26:02 2015 +0100 @@ -39,7 +39,7 @@ * additional types that are necessary to serialize a truffle AST for a specific truffle * implementation. If a type is not supported by this constant pool implementation a * {@link UnsupportedConstantPoolTypeException} should be thrown. - * + * * @param clazz the {@link Class} of the value * @param value the value to be stored. Must be at least a subclass of the given clazz. * @return the constant pool index @@ -54,7 +54,7 @@ * are necessary to serialize a truffle AST for a specific truffle implementation. If a type is * not supported by this constant pool implementation a * {@link UnsupportedConstantPoolTypeException} should be thrown. - * + * * @param clazz the {@link Class} of the value in the constant pool. * @param cpi the previously returned index * @return the value stored inside the constant pool @@ -66,7 +66,7 @@ /** * Stores a Class instance in the constant pool and returns the constant pool index. - * + * * @param value the class to store * @return the new or existing constant pool index of the Class */ @@ -74,7 +74,7 @@ /** * Returns the {@link Class} instance to the given constant pool index. - * + * * @param cpi the constant pool index * @return stored value * @throws IllegalArgumentException if the constant pool indes is invalid. @@ -83,7 +83,7 @@ /** * Stores an int value in the constant pool and returns the constant pool index. - * + * * @param value the value to store * @return the new or existing constant pool index of the value */ @@ -91,7 +91,7 @@ /** * Returns the stored int value to the given constant pool index from the constant pool. - * + * * @param cpi the constant pool index * @return stored value * @throws IllegalArgumentException if the constant pool index is invalid. @@ -100,7 +100,7 @@ /** * Stores a long value in the constant pool and returns the constant pool index. - * + * * @param value the value to store * @return the new or existing constant pool index of the value */ @@ -108,7 +108,7 @@ /** * Returns the stored long value to the given constant pool index from the constant pool. - * + * * @param cpi the constant pool index * @return the stored value * @throws IllegalArgumentException if the constant pool index is invalid. @@ -117,7 +117,7 @@ /** * Stores a double value in the constant pool and returns the constant pool index. - * + * * @param value the value to store * @return the new or existing constant pool index of the value */ @@ -125,7 +125,7 @@ /** * Returns the stored double value to the given constant pool index from the constant pool. - * + * * @param cpi the constant pool index * @return the stored value * @throws IllegalArgumentException if the constant pool index is invalid. @@ -134,7 +134,7 @@ /** * Stores a float value in the constant pool and returns the constant pool index. - * + * * @param value the value to store * @return the new or existing constant pool index of the value */ @@ -142,7 +142,7 @@ /** * Returns the stored float value to the given constant pool index from the constant pool. - * + * * @param cpi the constant pool index * @return the stored value * @throws IllegalArgumentException if the constant pool index is invalid.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/NullSourceSection.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/NullSourceSection.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -73,6 +73,14 @@ throw new UnsupportedOperationException(this.toString()); } + public int getEndLine() { + throw new UnsupportedOperationException(this.toString()); + } + + public int getEndColumn() { + throw new UnsupportedOperationException(this.toString()); + } + public final int getCharIndex() { throw new UnsupportedOperationException(this.toString()); } @@ -101,5 +109,4 @@ public String toString() { return getShortDescription(); } - }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,6 +29,8 @@ import java.net.*; import java.util.*; +import com.oracle.truffle.api.instrument.*; + /** * Representation of a guest language source code unit and its contents. Sources originate in * several ways: @@ -66,17 +68,28 @@ * <li>Any access to file contents via the cache will result in a timestamp check and possible cache * reload.</li> * </ol> + * <p> + * + * @see SourceTag + * @see SourceListener */ public abstract class Source { // TODO (mlvdv) consider canonicalizing and reusing SourceSection instances // TOOD (mlvdv) connect SourceSections into a spatial tree for fast geometric lookup + /** + * All Sources that have been created. + */ + private static final List<WeakReference<Source>> allSources = new ArrayList<>(); + // Files and pseudo files are indexed. private static final Map<String, WeakReference<Source>> filePathToSource = new Hashtable<>(); private static boolean fileCacheEnabled = true; + private static final List<SourceListener> sourceListeners = new ArrayList<>(); + /** * Gets the canonical representation of a source file, whose contents will be read lazily and * then cached. @@ -106,6 +119,7 @@ if (reset) { source.reset(); } + notifyNewSource(source).tagAs(StandardSourceTag.FROM_FILE); return source; } @@ -122,6 +136,36 @@ } /** + * Gets the canonical representation of a source file, whose contents have already been read and + * need not be read again. It is confirmed that the file resolves to a file name, so it can be + * indexed by canonical path. It is not confirmed that the text supplied agrees with the file's + * contents or even whether the file is readable. + * + * @param chars textual source code already read from the file + * @param fileName + * @return canonical representation of the file's contents. + * @throws IOException if the file cannot be found + */ + public static Source fromFileName(CharSequence chars, String fileName) throws IOException { + + final WeakReference<Source> nameRef = filePathToSource.get(fileName); + Source source = nameRef == null ? null : nameRef.get(); + if (source == null) { + final File file = new File(fileName); + // We are going to trust that the fileName is readable. + final String path = file.getCanonicalPath(); + final WeakReference<Source> pathRef = filePathToSource.get(path); + source = pathRef == null ? null : pathRef.get(); + if (source == null) { + source = new FileSource(file, fileName, path, chars); + filePathToSource.put(path, new WeakReference<>(source)); + } + } + notifyNewSource(source).tagAs(StandardSourceTag.FROM_FILE); + return source; + } + + /** * Creates a non-canonical source from literal text. If an already created literal source must * be retrievable by name, use {@link #asPseudoFile(CharSequence, String)}. * @@ -131,7 +175,9 @@ */ public static Source fromText(CharSequence chars, String description) { assert chars != null; - return new LiteralSource(description, chars.toString()); + final LiteralSource source = new LiteralSource(description, chars.toString()); + notifyNewSource(source).tagAs(StandardSourceTag.FROM_LITERAL); + return source; } /** @@ -143,7 +189,9 @@ * @throws IOException if reading fails */ public static Source fromURL(URL url, String description) throws IOException { - return URLSource.get(url, description); + final URLSource source = URLSource.get(url, description); + notifyNewSource(source).tagAs(StandardSourceTag.FROM_URL); + return source; } /** @@ -155,7 +203,9 @@ * @throws IOException if reading fails */ public static Source fromReader(Reader reader, String description) throws IOException { - return new LiteralSource(description, read(reader)); + final LiteralSource source = new LiteralSource(description, read(reader)); + notifyNewSource(source).tagAs(StandardSourceTag.FROM_READER); + return source; } /** @@ -186,7 +236,9 @@ * @return a newly created, non-indexed source representation */ public static Source fromBytes(byte[] bytes, int byteIndex, int length, String description, BytesDecoder decoder) { - return new BytesSource(description, bytes, byteIndex, length, decoder); + final BytesSource source = new BytesSource(description, bytes, byteIndex, length, decoder); + notifyNewSource(source).tagAs(StandardSourceTag.FROM_BYTES); + return source; } /** @@ -200,6 +252,7 @@ public static Source asPseudoFile(CharSequence chars, String pseudoFileName) { final Source source = new LiteralSource(pseudoFileName, chars.toString()); filePathToSource.put(pseudoFileName, new WeakReference<>(source)); + notifyNewSource(source).tagAs(StandardSourceTag.FROM_LITERAL); return source; } @@ -212,6 +265,48 @@ fileCacheEnabled = enabled; } + /** + * Returns all {@link Source}s holding a particular {@link SyntaxTag}, or the whole collection + * of Sources if the specified tag is {@code null}. + * + * @return A collection of Sources containing the given tag. + */ + public static Collection<Source> findSourcesTaggedAs(SourceTag tag) { + final List<Source> taggedSources = new ArrayList<>(); + for (WeakReference<Source> ref : allSources) { + Source source = ref.get(); + if (source != null) { + if (tag == null || source.isTaggedAs(tag)) { + taggedSources.add(ref.get()); + } + } + } + return taggedSources; + } + + /** + * Adds a {@link SourceListener} to receive events. + */ + public static void addSourceListener(SourceListener listener) { + assert listener != null; + sourceListeners.add(listener); + } + + /** + * Removes a {@link SourceListener}. Ignored if listener not found. + */ + public static void removeSourceListener(SourceListener listener) { + sourceListeners.remove(listener); + } + + private static Source notifyNewSource(Source source) { + allSources.add(new WeakReference<>(source)); + for (SourceListener listener : sourceListeners) { + listener.sourceCreated(source); + } + return source; + } + private static String read(Reader reader) throws IOException { final BufferedReader bufferedReader = new BufferedReader(reader); final StringBuilder builder = new StringBuilder(); @@ -228,6 +323,8 @@ return builder.toString(); } + private final ArrayList<SourceTag> tags = new ArrayList<>(); + Source() { } @@ -235,6 +332,32 @@ protected abstract void reset(); + public final boolean isTaggedAs(SourceTag tag) { + assert tag != null; + return tags.contains(tag); + } + + public final Collection<SourceTag> getSourceTags() { + return Collections.unmodifiableCollection(tags); + } + + /** + * Adds a {@linkplain SourceTag tag} to the set of tags associated with this {@link Source}; + * {@code no-op} if already in the set. + * + * @return this + */ + public final Source tagAs(SourceTag tag) { + assert tag != null; + if (!tags.contains(tag)) { + tags.add(tag); + for (SourceListener listener : sourceListeners) { + listener.sourceTaggedAs(this, tag); + } + } + return this; + } + /** * Returns the name of this resource holding a guest language program. An example would be the * name of a guest language source code file. @@ -275,10 +398,20 @@ } /** - * Return the complete text of the code. + * Gets the number of characters in the source. + */ + public final int getLength() { + return checkTextMap().length(); + } + + /** + * Returns the complete text of the code. */ public abstract String getCode(); + /** + * Returns a subsection of the code test. + */ public String getCode(int charIndex, int charLength) { return getCode().substring(charIndex, charIndex + charLength); } @@ -542,9 +675,16 @@ private long timeStamp; // timestamp of the cache in the file system public FileSource(File file, String name, String path) { + this(file, name, path, null); + } + + public FileSource(File file, String name, String path, CharSequence chars) { this.file = file.getAbsoluteFile(); this.name = name; this.path = path; + if (chars != null) { + this.code = chars.toString(); + } } @Override @@ -812,6 +952,14 @@ return startColumn; } + public int getEndLine() { + return source.getLineNumber(charIndex + charLength - 1); + } + + public int getEndColumn() { + return source.getColumnNumber(charIndex + charLength - 1); + } + @Override public int getCharIndex() { return charIndex; @@ -900,7 +1048,6 @@ } return true; } - } private static final class LineLocationImpl implements LineLocation { @@ -1090,6 +1237,13 @@ } /** + * The number of characters in the mapped text. + */ + public int length() { + return textLength; + } + + /** * The number of lines in the text; if characters appear after the final newline, then they * also count as a line, even though not newline-terminated. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceListener.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.source; + +/** + * An observer of events related to {@link Source}s: creating and tagging. + */ +public interface SourceListener { + + /** + * Notifies that a new {@link Source} has just been created. + */ + void sourceCreated(Source source); + + /** + * Notifies that a {@link SourceTag} has been newly added to the set of tags associated with a + * {@link Source} via {@link Source#tagAs(SourceTag)}. + * <p> + * The {@linkplain SourceTag tags} at a {@link Source} are a <em>set</em>; this notification + * will only be delivered the first time a particular {@linkplain SourceTag tag} is added at a + * {@link Source}. + * + * @param source where a tag has been added + * @param tag the tag that has been newly added (subsequent additions of the tag are + * unreported). + */ + void sourceTaggedAs(Source source, SourceTag tag); + +}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceSection.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceSection.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -66,6 +66,20 @@ int getStartColumn(); /** + * Returns 1-based line number of the last character in this section (inclusive). + * + * @return the starting line number + */ + int getEndLine(); + + /** + * Returns the 1-based column number of the last character in this section (inclusive). + * + * @return the starting column number + */ + int getEndColumn(); + + /** * Returns the 0-based index of the first character in this section. * * @return the starting character index
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/SourceTag.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.source; + +/** + * Categorical information (best implemented as enums} about particular sources of Guest Language + * code that can be useful to configure behavior of both the language runtime and external tools. + * These might include {@linkplain StandardSourceTag standard tags} noting, for example, whether the + * source was read from a file and whether it should be considered library code. + * <p> + * An untagged {@link Source} should by default be considered application code. + * <p> + * The need for additional tags is likely to arise, in some cases because of issue specific to a + * Guest Language, but also for help configuring the behavior of particular tools. + * + * @see Source + * @see StandardSourceTag + */ +public interface SourceTag { + + /** + * Human-friendly name of a category of code sources, e.g. "file", or "library". + * + */ + String name(); + + /** + * Criteria and example uses for the tag. + */ + String getDescription(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/StandardSourceTag.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.source; + +/** + * A general set of "properties" or "categories" that might be usefully attached to a particular + * source of code, both for use by the language runtime and by external tools. This set of tags + * includes some intended to be applied by default by {@link Source} factory methods or other + * services built into the Truffle platform. + * <p> + * The need for additional tags is likely to arise, in some cases because of issue specific to a + * Guest Language, but also for help configuring the behavior of particular tools. + * + * @see Source + */ +public enum StandardSourceTag implements SourceTag { + + /** + * Builtin. + */ + BUILTIN("builtin", "implementation of language builtins"), + + /** + * From bytes. + */ + FROM_BYTES("bytes", "read from bytes"), + + /** + * Read from a file. + */ + FROM_FILE("file", "read from a file"), + + /** + * From literal text. + */ + FROM_LITERAL("literal", "from literal text"), + + /** + * From a {@linkplain java.io.Reader Reader}. + */ + FROM_READER("reader", "read from a Java Reader"), + + /** + * Read from a URL. + */ + FROM_URL("URL", "read from a URL"), + + /** + * Treat as LIBRARY code. + */ + LIBRARY("library", "library code"); + + private final String name; + private final String description; + + private StandardSourceTag(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + +}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/CoverageTracker.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/CoverageTracker.java Tue Mar 10 21:26:02 2015 +0100 @@ -27,13 +27,11 @@ import java.io.*; import java.util.*; import java.util.Map.Entry; -import java.util.concurrent.atomic.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.instrument.impl.*; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.source.*; /** @@ -160,7 +158,7 @@ curSource = source; curLineTable = new Long[source.getLineCount()]; } - curLineTable[lineNo - 1] = entry.getValue().count.longValue(); + curLineTable[lineNo - 1] = entry.getValue().count; } if (curSource != null) { result.put(curSource, curLineTable); @@ -206,7 +204,7 @@ while (curLineNo < lineNo) { displayLine(out, null, curSource, curLineNo++); } - displayLine(out, entry.getValue().count, curSource, curLineNo++); + displayLine(out, entry.getValue(), curSource, curLineNo++); } if (curSource != null) { while (curLineNo <= curSource.getLineCount()) { @@ -215,11 +213,11 @@ } } - private static void displayLine(PrintStream out, AtomicLong value, Source source, int lineNo) { - if (value == null) { + private static void displayLine(PrintStream out, CoverageRecord record, Source source, int lineNo) { + if (record == null) { out.format("%14s", " "); } else { - out.format("(%12d)", value.longValue()); + out.format("(%12d)", record.count); } out.format(" %3d: ", lineNo); out.println(source.getCode(lineNo)); @@ -227,33 +225,25 @@ /** * A listener for events at each instrumented AST location. This listener counts - * "execution calls" to the instrumented node and is <em>stateful</em>. State in listeners must - * be considered carefully since ASTs, along with all instrumentation (including event listener - * such as this) are routinely cloned by the Truffle runtime. AST cloning is <em>shallow</em> - * (for non- {@link Child} nodes), so in this case the actual count <em>is shared</em> among all - * the clones; the count is also held in a table indexed by source line. - * <p> - * In contrast, a primitive field would <em>not</em> be shared among clones and resulting counts - * would not be accurate. + * "execution calls" to the instrumented node. */ - private final class CoverageEventListener extends DefaultEventListener { + private final class CoverageRecord extends DefaultEventListener { - /** - * Shared by all clones of the associated instrument and by the table of counters for the - * line. - */ - private final AtomicLong count; + private final SourceSection srcSection; // The text of the code being counted + private Instrument instrument; // The attached Instrument, in case need to remove. + private long count = 0; - CoverageEventListener(AtomicLong count) { - this.count = count; + CoverageRecord(SourceSection srcSection) { + this.srcSection = srcSection; } @Override - public void enter(Node node, VirtualFrame frame) { + public void enter(Node node, VirtualFrame vFrame) { if (isEnabled()) { - count.getAndIncrement(); + count++; } } + } private static final class LineLocationEntryComparator implements Comparator<Entry<LineLocation, CoverageRecord>> { @@ -282,35 +272,23 @@ if (record != null) { // Another node starts on same line; count only the first (textually) if (srcSection.getCharIndex() > record.srcSection.getCharIndex()) { - // Record already in place, corresponds to code earlier on line + // Existing record, corresponds to code earlier on line return; } else { - // Record already in place, corresponds to later code; replace it + // Existing record, corresponds to code at a later position; replace it record.instrument.dispose(); } } - final AtomicLong count = new AtomicLong(); - final CoverageEventListener eventListener = new CoverageEventListener(count); - final Instrument instrument = Instrument.create(eventListener, CoverageTracker.class.getSimpleName()); + + final CoverageRecord coverage = new CoverageRecord(srcSection); + final Instrument instrument = Instrument.create(coverage, CoverageTracker.class.getSimpleName()); + coverage.instrument = instrument; instruments.add(instrument); probe.attach(instrument); - coverageMap.put(lineLocation, new CoverageRecord(srcSection, instrument, count)); + coverageMap.put(lineLocation, coverage); } } } } - private class CoverageRecord { - - final SourceSection srcSection; // The text of the code being counted - final Instrument instrument; // The attached Instrument, in case need to remove. - final AtomicLong count; - - CoverageRecord(SourceSection srcSection, Instrument instrument, AtomicLong count) { - this.srcSection = srcSection; - this.instrument = instrument; - this.count = count; - } - } - }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/LineToProbesMap.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/LineToProbesMap.java Tue Mar 10 21:26:02 2015 +0100 @@ -32,7 +32,7 @@ import com.oracle.truffle.api.source.*; /** - * An {@link InstrumentationTool} that builds a map of every {@Probe} attached to some AST, + * An {@link InstrumentationTool} that builds a map of every {@link Probe} attached to some AST, * indexed by {@link Source} and line number. */ public final class LineToProbesMap extends InstrumentationTool {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/NodeExecCounter.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/NodeExecCounter.java Tue Mar 10 21:26:02 2015 +0100 @@ -97,7 +97,7 @@ */ private final TruffleEventListener eventListener = new DefaultEventListener() { @Override - public void enter(Node node, VirtualFrame frame) { + public void enter(Node node, VirtualFrame vFrame) { if (isEnabled()) { final Class<?> nodeClass = node.getClass(); /*
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java Tue Mar 10 21:26:02 2015 +0100 @@ -30,24 +30,24 @@ /** * Abstract utility class to speculate on conditions. Condition profiles are intended to be used as * part of if conditions. - * + * * Example usage: - * + * * <pre> * private final ConditionProfile zero = ConditionProfile.createBinaryProfile(); - * + * * int value = ...; * if (zero.profile(value == 0)) { * return 0; * } else { * return value; * } - * + * * </pre> - * + * * All instances of {@code ConditionProfile} (and subclasses) must be held in {@code final} fields * for compiler optimizations to take effect. - * + * * @see #createCountingProfile() * @see #createBinaryProfile() */ @@ -62,7 +62,7 @@ * true and false. This information is reported to the underlying optimization system using * {@link CompilerDirectives#injectBranchProbability(double, boolean)}. Condition profiles are * intended to be used as part of if conditions. - * + * * @see ConditionProfile * @see #createBinaryProfile() */ @@ -73,7 +73,7 @@ /** * Returns a {@link ConditionProfile} that speculates on conditions to be never true or to be * never false. Condition profiles are intended to be used as part of if conditions. - * + * * @see ConditionProfile * @see ConditionProfile#createCountingProfile() */
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CyclicAssumption.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CyclicAssumption.java Tue Mar 10 21:26:02 2015 +0100 @@ -24,6 +24,8 @@ */ package com.oracle.truffle.api.utilities; +import java.util.concurrent.atomic.*; + import com.oracle.truffle.api.*; /** @@ -36,23 +38,21 @@ public class CyclicAssumption { private final String name; - private Assumption assumption; + private final AtomicReference<Assumption> assumption; public CyclicAssumption(String name) { this.name = name; - invalidate(); + this.assumption = new AtomicReference<>(Truffle.getRuntime().createAssumption(name)); } public void invalidate() { - if (assumption != null) { - assumption.invalidate(); - } - - assumption = Truffle.getRuntime().createAssumption(name); + Assumption newAssumption = Truffle.getRuntime().createAssumption(name); + Assumption oldAssumption = assumption.getAndSet(newAssumption); + oldAssumption.invalidate(); } public Assumption getAssumption() { - return assumption; + return assumption.get(); } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Tue Mar 10 21:26:02 2015 +0100 @@ -51,25 +51,26 @@ @SuppressWarnings("unchecked") @Override public Object profile(Object value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Byte && value instanceof Byte && (byte) cachedValue == (byte) value) { - return cachedValue; - } else if (cachedValue instanceof Short && value instanceof Short && (short) cachedValue == (short) value) { - return cachedValue; - } else if (cachedValue instanceof Integer && value instanceof Integer && (int) cachedValue == (int) value) { - return cachedValue; - } else if (cachedValue instanceof Long && value instanceof Long && (long) cachedValue == (long) value) { - return cachedValue; - } else if (cachedValue instanceof Float && value instanceof Float && exactCompare((float) cachedValue, (float) value)) { - return cachedValue; - } else if (cachedValue instanceof Double && value instanceof Double && exactCompare((double) cachedValue, (double) value)) { - return cachedValue; - } else if (cachedValue instanceof Boolean && value instanceof Boolean && (boolean) cachedValue == (boolean) value) { - return cachedValue; - } else if (cachedValue instanceof Character && value instanceof Character && (char) cachedValue == (char) value) { - return cachedValue; - } else if (cachedValue == value) { - return cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Byte && value instanceof Byte && (byte) snapshot == (byte) value) { + return snapshot; + } else if (snapshot instanceof Short && value instanceof Short && (short) snapshot == (short) value) { + return snapshot; + } else if (snapshot instanceof Integer && value instanceof Integer && (int) snapshot == (int) value) { + return snapshot; + } else if (snapshot instanceof Long && value instanceof Long && (long) snapshot == (long) value) { + return snapshot; + } else if (snapshot instanceof Float && value instanceof Float && exactCompare((float) snapshot, (float) value)) { + return snapshot; + } else if (snapshot instanceof Double && value instanceof Double && exactCompare((double) snapshot, (double) value)) { + return snapshot; + } else if (snapshot instanceof Boolean && value instanceof Boolean && (boolean) snapshot == (boolean) value) { + return snapshot; + } else if (snapshot instanceof Character && value instanceof Character && (char) snapshot == (char) value) { + return snapshot; + } else if (snapshot == value) { + return snapshot; } else { cacheMiss(value); } @@ -78,9 +79,10 @@ } public byte profile(byte value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Byte && (byte) cachedValue == value) { - return (byte) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Byte && (byte) snapshot == value) { + return (byte) snapshot; } else { cacheMiss(value); } @@ -89,9 +91,10 @@ } public short profile(short value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Short && (short) cachedValue == value) { - return (short) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Short && (short) snapshot == value) { + return (short) snapshot; } else { cacheMiss(value); } @@ -100,9 +103,10 @@ } public int profile(int value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Integer && (int) cachedValue == value) { - return (int) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Integer && (int) snapshot == value) { + return (int) snapshot; } else { cacheMiss(value); } @@ -111,9 +115,10 @@ } public long profile(long value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Long && (long) cachedValue == value) { - return (long) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Long && (long) snapshot == value) { + return (long) snapshot; } else { cacheMiss(value); } @@ -122,9 +127,10 @@ } public float profile(float value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Float && exactCompare((float) cachedValue, value)) { - return (float) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Float && exactCompare((float) snapshot, value)) { + return (float) snapshot; } else { cacheMiss(value); } @@ -133,9 +139,10 @@ } public double profile(double value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Double && exactCompare((double) cachedValue, value)) { - return (double) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Double && exactCompare((double) snapshot, value)) { + return (double) snapshot; } else { cacheMiss(value); } @@ -144,9 +151,10 @@ } public boolean profile(boolean value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Boolean && (boolean) cachedValue == value) { - return (boolean) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Boolean && (boolean) snapshot == value) { + return (boolean) snapshot; } else { cacheMiss(value); } @@ -155,9 +163,10 @@ } public char profile(char value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Character && (char) cachedValue == value) { - return (char) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Character && (char) snapshot == value) { + return (char) snapshot; } else { cacheMiss(value); } @@ -166,11 +175,11 @@ } public boolean isGeneric() { - return getCachedValue() == GENERIC; + return cachedValue == GENERIC; } public boolean isUninitialized() { - return getCachedValue() == UNINITIALIZED; + return cachedValue == UNINITIALIZED; } public Object getCachedValue() { @@ -183,6 +192,7 @@ } private void cacheMiss(Object value) { + // TODO should we try to handle this more atomically? CompilerDirectives.transferToInterpreterAndInvalidate(); if (cachedValue == UNINITIALIZED) { cachedValue = value; @@ -208,17 +218,18 @@ } private String formatValue() { - if (cachedValue == null) { + Object snapshot = this.cachedValue; + if (snapshot == null) { return "null"; - } else if (cachedValue == UNINITIALIZED) { + } else if (snapshot == UNINITIALIZED) { return "uninitialized"; - } else if (cachedValue == GENERIC) { + } else if (snapshot == GENERIC) { return "generic"; - } else if (cachedValue instanceof Byte || cachedValue instanceof Short || cachedValue instanceof Integer || cachedValue instanceof Long || cachedValue instanceof Float || - cachedValue instanceof Double || cachedValue instanceof Boolean || cachedValue instanceof Character) { - return String.format("%s=%s", cachedValue.getClass().getSimpleName(), cachedValue); + } else if (snapshot instanceof Byte || snapshot instanceof Short || snapshot instanceof Integer || snapshot instanceof Long || snapshot instanceof Float || snapshot instanceof Double || + snapshot instanceof Boolean || snapshot instanceof Character) { + return String.format("%s=%s", snapshot.getClass().getSimpleName(), snapshot); } else { - return String.format("%s@%x", cachedValue.getClass().getSimpleName(), Objects.hash(cachedValue)); + return String.format("%s@%x", snapshot.getClass().getSimpleName(), Objects.hash(snapshot)); } } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java Tue Mar 10 21:26:02 2015 +0100 @@ -26,18 +26,18 @@ /** * Utility class to speculate on certain properties of values. - * + * * Example usage: - * + * * <pre> * private final ValueProfile classProfile = ValueProfile.createClassProfile(); - * + * * return classProfile.profile(value); * </pre> - * + * * All instances of {@code ValueProfile} (and subclasses) must be held in {@code final} fields for * compiler optimizations to take effect. - * + * * @see #createPrimitiveProfile() * @see #createIdentityProfile() * @see #createClassProfile()
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java Tue Mar 10 21:26:02 2015 +0100 @@ -447,6 +447,7 @@ clazz.addOptional(createSpecializationCreateMethod(specialization, constructor)); clazz.addOptional(createMergeMethod(specialization)); clazz.addOptional(createIsSameMethod(specialization)); + clazz.addOptional(createIsIdenticalMethod(specialization)); TypeData returnType = specialization.getReturnType().getTypeSystemType(); int signatureSize = specialization.getSignatureSize(); @@ -493,6 +494,36 @@ return executable; } + private Element createIsIdenticalMethod(SpecializationData specialization) { + boolean cacheBoundGuard = specialization.hasMultipleInstances(); + if (!cacheBoundGuard) { + return null; + } + + LocalContext currentLocals = LocalContext.load(this, node.getSignatureSize(), varArgsThreshold); + currentLocals.loadFastPathState(specialization); + + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "isIdentical"); + method.addParameter(new CodeVariableElement(getType(SpecializationNode.class), "other")); + currentLocals.addParametersTo(method, FRAME_VALUE); + method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); + final CodeTreeBuilder builder = method.createBuilder(); + + SpecializationGroup group = SpecializationGroup.create(specialization); + SpecializationBody executionFactory = new SpecializationBody(true, false) { + @Override + public CodeTree createBody(SpecializationData s, LocalContext values) { + return builder.create().returnTrue().build(); + } + }; + + builder.startIf().string("isSame(other)").end().startBlock(); + builder.tree(createGuardAndCast(group, typeSystem.getGenericTypeData(), currentLocals, executionFactory)); + builder.end(); + builder.returnFalse(); + return method; + } + private CodeExecutableElement createIsSameMethod(SpecializationData specialization) { if (!specialization.isSpecialized() || !options.implicitCastOptimization().isDuplicateTail()) { return null; @@ -532,18 +563,29 @@ } private Element createMergeMethod(SpecializationData specialization) { - boolean cacheBoundGuard = specialization.hasMultipleInstances(); - if (specialization.getExcludedBy().isEmpty() && !specialization.isPolymorphic() && !cacheBoundGuard) { + if (specialization.getExcludedBy().isEmpty() && !specialization.isPolymorphic()) { return null; } TypeMirror specializationNodeType = getType(SpecializationNode.class); + LocalContext currentLocals = LocalContext.load(this, node.getSignatureSize(), varArgsThreshold); + CodeExecutableElement executable = new CodeExecutableElement(modifiers(PUBLIC), specializationNodeType, "merge"); executable.addParameter(new CodeVariableElement(specializationNodeType, "newNode")); + currentLocals.addParametersTo(executable, FRAME_VALUE); executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class))); CodeTreeBuilder builder = executable.createBuilder(); if (specialization.isPolymorphic()) { - builder.statement("return polymorphicMerge(newNode)"); + builder.startReturn(); + builder.startCall("polymorphicMerge"); + builder.string("newNode"); + builder.startCall("super", "merge"); + builder.string("newNode"); + currentLocals.addReferencesTo(builder, FRAME_VALUE); + builder.end(); + builder.end(); + builder.end(); + } else { boolean elseIf = false; for (SpecializationData containedSpecialization : specialization.getExcludedBy()) { @@ -554,11 +596,12 @@ builder.statement("removeSame(\"Contained by " + containedSpecialization.createReferenceName() + "\")"); builder.end(); } - if (cacheBoundGuard) { - builder.statement("return super.mergeNoSame(newNode)"); - } else { - builder.statement("return super.merge(newNode)"); - } + builder.startReturn(); + builder.startCall("super", "merge"); + builder.string("newNode"); + currentLocals.addReferencesTo(builder, FRAME_VALUE); + builder.end(); + builder.end(); } return executable; @@ -638,18 +681,15 @@ CodeTreeBuilder builder = method.createBuilder(); SpecializationGroup group = createSpecializationGroups(); - CodeTree execution = createGuardAndCast(group, genericType, locals, new SpecializationExecution() { - public CodeTree createExecute(SpecializationData specialization, LocalContext values) { + CodeTree execution = createGuardAndCast(group, genericType, locals, new SpecializationBody(false, false) { + @Override + public CodeTree createBody(SpecializationData specialization, LocalContext values) { CodeTypeElement generatedType = specializationClasses.get(specialization); if (generatedType == null) { throw new AssertionError("No generated type for " + specialization); } return createSlowPathExecute(specialization, values); } - - public boolean isFastPath() { - return false; - } }); builder.tree(execution); @@ -867,18 +907,27 @@ locals.addReferencesTo(executeBuilder); executeBuilder.end(); + boolean hasExecutedUnexpected = executedType != null && !executedType.isGeneric() && !executedType.isVoid(); + CodeTreeBuilder contentBuilder = builder.create(); contentBuilder.startReturn(); - contentBuilder.tree(TypeSystemCodeGenerator.expect(executedType, returnType, executeBuilder.build())); + if (!hasExecutedUnexpected && !execType.hasUnexpectedValue(context)) { + if (executedType == null || executedType.needsCastTo(returnType)) { + contentBuilder.cast(returnType.getPrimitiveType(), executeBuilder.build()); + } else { + contentBuilder.tree(executeBuilder.build()); + } + } else { + contentBuilder.tree(TypeSystemCodeGenerator.expect(executedType, returnType, executeBuilder.build())); + } contentBuilder.end(); // try catch assert if unexpected value is not expected CodeTree content = contentBuilder.build(); - if (!execType.hasUnexpectedValue(context) && !returnType.isGeneric() && !returnType.isVoid()) { + if (!execType.hasUnexpectedValue(context) && hasExecutedUnexpected) { content = wrapTryCatchUnexpected(content); } builder.tree(content); } - return method; } @@ -1078,7 +1127,7 @@ String varName = name + specialization.getIndex(); TypeMirror type = assumption.getExpression().getResolvedType(); builder.declaration(type, varName, assumptions); - currentValues.set(name, new LocalVariable(null, type, varName, null)); + currentValues.set(name, new LocalVariable(null, type, varName, null, null)); } builder.startIf(); @@ -1244,8 +1293,11 @@ for (Parameter p : specialization.getSignatureParameters()) { CodeVariableElement var = createImplicitProfileParameter(p.getSpecification().getExecution(), p.getTypeSystemType()); if (var != null) { - // we need the original name here - builder.tree(LocalVariable.fromParameter(p).createReference()); + LocalVariable variable = currentValues.get(p.getLocalName()); + if (variable == null) { + throw new AssertionError("Could not bind cached value " + p.getLocalName() + ": " + currentValues); + } + builder.tree(variable.original().createReference()); } } for (CacheExpression cache : specialization.getCaches()) { @@ -1513,14 +1565,11 @@ } else { final TypeData finalType = type; SpecializationGroup group = SpecializationGroup.create(specialization); - SpecializationExecution executionFactory = new SpecializationExecution() { - public CodeTree createExecute(SpecializationData s, LocalContext values) { + SpecializationBody executionFactory = new SpecializationBody(true, true) { + @Override + public CodeTree createBody(SpecializationData s, LocalContext values) { return createFastPathExecute(builder, finalType, s, values); } - - public boolean isFastPath() { - return true; - } }; builder.tree(createGuardAndCast(group, type, currentLocals, executionFactory)); if (hasFallthrough(group, type, originalValues, true, null) || group.getSpecialization().isFallback()) { @@ -1609,11 +1658,11 @@ return builder.build(); } - private CodeTree createGuardAndCast(SpecializationGroup group, TypeData forType, LocalContext currentValues, SpecializationExecution execution) { + private CodeTree createGuardAndCast(SpecializationGroup group, TypeData forType, LocalContext currentValues, SpecializationBody execution) { CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); Set<TypeGuard> castGuards; - if (execution.isFastPath()) { + if (execution.needsCastedValues()) { castGuards = null; // cast all } else { castGuards = new HashSet<>(); @@ -1667,7 +1716,7 @@ builder.tree(createGuardAndCast(child, forType, currentValues.copy(), execution)); } if (specialization != null) { - builder.tree(execution.createExecute(specialization, currentValues)); + builder.tree(execution.createBody(specialization, currentValues)); } } builder.end(ifCount); @@ -2195,7 +2244,7 @@ } private CodeTree[] createTypeCheckAndLocals(SpecializationData specialization, List<TypeGuard> typeGuards, Set<TypeGuard> castGuards, LocalContext currentValues, - SpecializationExecution specializationExecution) { + SpecializationBody specializationExecution) { CodeTreeBuilder checksBuilder = CodeTreeBuilder.createBuilder(); CodeTreeBuilder localsBuilder = CodeTreeBuilder.createBuilder(); for (TypeGuard typeGuard : typeGuards) { @@ -2282,7 +2331,7 @@ String varName = name + specialization.getIndex(); TypeMirror type = cache.getParameter().getType(); builder.declaration(type, varName, initializer); - currentValues.set(name, new LocalVariable(null, type, varName, null)); + currentValues.set(name, new LocalVariable(null, type, varName, null, null)); } public static final class LocalContext { @@ -2298,13 +2347,13 @@ for (CacheExpression cache : specialization.getCaches()) { Parameter cacheParameter = cache.getParameter(); String name = cacheParameter.getVariableElement().getSimpleName().toString(); - set(cacheParameter.getLocalName(), new LocalVariable(cacheParameter.getTypeSystemType(), cacheParameter.getType(), name, CodeTreeBuilder.singleString("this." + name))); + set(cacheParameter.getLocalName(), new LocalVariable(cacheParameter.getTypeSystemType(), cacheParameter.getType(), name, CodeTreeBuilder.singleString("this." + name), null)); } for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { String name = assumptionName(assumption); TypeMirror type = assumption.getExpression().getResolvedType(); - set(name, new LocalVariable(null, type, name, CodeTreeBuilder.singleString("this." + name))); + set(name, new LocalVariable(null, type, name, CodeTreeBuilder.singleString("this." + name), null)); } } @@ -2336,11 +2385,11 @@ @SuppressWarnings("static-method") public LocalVariable createValue(NodeExecutionData execution, TypeData type) { - return new LocalVariable(type, type.getPrimitiveType(), valueName(execution), null); + return new LocalVariable(type, type.getPrimitiveType(), valueName(execution), null, null); } public LocalVariable createShortCircuitValue(NodeExecutionData execution) { - return new LocalVariable(factory.typeSystem.getBooleanType(), factory.getType(boolean.class), shortCircuitName(execution), null); + return new LocalVariable(factory.typeSystem.getBooleanType(), factory.getType(boolean.class), shortCircuitName(execution), null, null); } private static String valueName(NodeExecutionData execution) { @@ -2411,11 +2460,11 @@ } private void loadValues(int evaluatedArguments, int varargsThreshold) { - values.put(FRAME_VALUE, new LocalVariable(null, factory.getType(Frame.class), FRAME_VALUE, null)); + values.put(FRAME_VALUE, new LocalVariable(null, factory.getType(Frame.class), FRAME_VALUE, null, null)); for (NodeFieldData field : factory.node.getFields()) { String fieldName = fieldValueName(field); - values.put(fieldName, new LocalVariable(null, field.getType(), fieldName, factory.accessParent(field.getName()))); + values.put(fieldName, new LocalVariable(null, field.getType(), fieldName, factory.accessParent(field.getName()), null)); } boolean varargs = needsVarargs(false, varargsThreshold); @@ -2430,13 +2479,13 @@ if (varargs) { shortCircuit = shortCircuit.accessWith(createReadVarargs(i)); } - values.put(shortCircuit.getName(), shortCircuit); + values.put(shortCircuit.getName(), shortCircuit.makeOriginal()); } LocalVariable value = createValue(execution, factory.genericType); if (varargs) { value = value.accessWith(createReadVarargs(i)); } - values.put(value.getName(), value); + values.put(value.getName(), value.makeOriginal()); } } @@ -2519,6 +2568,7 @@ private final TypeMirror typeMirror; private final CodeTree accessorTree; private final String name; + private final LocalVariable previous; public static LocalVariable fromParameter(Parameter parameter) { NodeExecutionData execution = parameter.getSpecification().getExecution(); @@ -2528,15 +2578,16 @@ } else { name = createName(execution); } - return new LocalVariable(parameter.getTypeSystemType(), parameter.getType(), name, null); + return new LocalVariable(parameter.getTypeSystemType(), parameter.getType(), name, null, null); } - private LocalVariable(TypeData type, TypeMirror typeMirror, String name, CodeTree accessorTree) { + private LocalVariable(TypeData type, TypeMirror typeMirror, String name, CodeTree accessorTree, LocalVariable previous) { Objects.requireNonNull(typeMirror); this.typeMirror = typeMirror; this.accessorTree = accessorTree; this.type = type; this.name = name; + this.previous = previous; } public TypeData getType() { @@ -2583,19 +2634,31 @@ } public LocalVariable newType(TypeData newType) { - return new LocalVariable(newType, newType.getPrimitiveType(), name, accessorTree); + return new LocalVariable(newType, newType.getPrimitiveType(), name, accessorTree, this); } public LocalVariable newType(TypeMirror newType) { - return new LocalVariable(type, newType, name, accessorTree); + return new LocalVariable(type, newType, name, accessorTree, this); } public LocalVariable accessWith(CodeTree tree) { - return new LocalVariable(type, typeMirror, name, tree); + return new LocalVariable(type, typeMirror, name, tree, this); } public LocalVariable nextName() { - return new LocalVariable(type, typeMirror, createNextName(name), accessorTree); + return new LocalVariable(type, typeMirror, createNextName(name), accessorTree, this); + } + + public LocalVariable makeOriginal() { + return new LocalVariable(type, typeMirror, name, accessorTree, null); + } + + public LocalVariable original() { + LocalVariable variable = this; + while (variable.previous != null) { + variable = variable.previous; + } + return variable; } public LocalVariable makeGeneric() { @@ -2609,11 +2672,25 @@ } - private interface SpecializationExecution { - - boolean isFastPath(); - - CodeTree createExecute(SpecializationData specialization, LocalContext currentValues); + private abstract class SpecializationBody { + + private final boolean fastPath; + private final boolean needsCastedValues; + + public SpecializationBody(boolean fastPath, boolean needsCastedValues) { + this.fastPath = fastPath; + this.needsCastedValues = needsCastedValues; + } + + public final boolean isFastPath() { + return fastPath; + } + + public final boolean needsCastedValues() { + return needsCastedValues; + } + + public abstract CodeTree createBody(SpecializationData specialization, LocalContext currentValues); }
--- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -275,8 +275,7 @@ */ @Override @TruffleBoundary - public final Property getProperty(Object key) { - // return this.propertyMap.get(propertyName); + public Property getProperty(Object key) { PropertyMap current = this.propertyMap; while (current.getLastProperty() != null) { if (current.getLastProperty().getKey().equals(key)) { @@ -284,7 +283,6 @@ } current = current.getParentMap(); } - return null; } @@ -355,9 +353,9 @@ */ private ShapeImpl addPropertyInternal(Property prop) { CompilerAsserts.neverPartOfCompilation(); - assert prop.isShadow() || !(this.hasProperty(prop.getKey())) : "duplicate property"; - assert !getPropertyListInternal(false).contains(prop); - // invalidatePropertyAssumption(prop.getName()); + assert prop.isShadow() || !(this.hasProperty(prop.getKey())) : "duplicate property " + prop.getKey(); + // assertion caused performance issues on e.g. testv8 regress-619.js + // assert !getPropertyListInternal(false).contains(prop); AddPropertyTransition addTransition = new AddPropertyTransition(prop); ShapeImpl cachedShape = queryTransition(addTransition); @@ -655,7 +653,7 @@ newShape = newShape.applyTransition(previous, true); } - getTransitionMapForWrite().put(transition, newShape); + addIndirectTransition(transition, newShape); return newShape; } else { return null; @@ -901,7 +899,7 @@ private Property[] createPropertiesArray() { propertyListAllocCount.inc(); Property[] propertiesArray = new Property[getPropertyCount()]; - List<Property> ownProperties = getPropertyList(ALL); + List<Property> ownProperties = getPropertyList(); assert ownProperties.size() == getPropertyCount(); for (int i = 0; i < getPropertyCount(); i++) { propertiesArray[i] = ownProperties.get(i); @@ -1101,7 +1099,7 @@ /** * Match all filter. */ - public static final Pred<Property> ALL = new Pred<Property>() { + private static final Pred<Property> ALL = new Pred<Property>() { public boolean test(Property t) { return true; }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -73,11 +73,11 @@ } @Override - public String displayValue(ExecutionContext context, Object value) { + public String displayValue(ExecutionContext context, Object value, int trim) { if (value == SLNull.SINGLETON) { return "null"; } - return value.toString(); + return trim(value.toString(), trim); } @Override
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -84,58 +84,58 @@ } @Override - public Object executeGeneric(VirtualFrame frame) { + public Object executeGeneric(VirtualFrame vFrame) { - probeNode.enter(child, frame); + probeNode.enter(child, vFrame); Object result; try { - result = child.executeGeneric(frame); - probeNode.returnValue(child, frame, result); + result = child.executeGeneric(vFrame); + probeNode.returnValue(child, vFrame, result); } catch (Exception e) { - probeNode.returnExceptional(child, frame, e); + probeNode.returnExceptional(child, vFrame, e); throw (e); } return result; } @Override - public long executeLong(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectLong(executeGeneric(frame)); + public long executeLong(VirtualFrame vFrame) throws UnexpectedResultException { + return SLTypesGen.expectLong(executeGeneric(vFrame)); } @Override - public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectBigInteger(executeGeneric(frame)); + public BigInteger executeBigInteger(VirtualFrame vFrame) throws UnexpectedResultException { + return SLTypesGen.expectBigInteger(executeGeneric(vFrame)); } @Override - public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectBoolean(executeGeneric(frame)); + public boolean executeBoolean(VirtualFrame vFrame) throws UnexpectedResultException { + return SLTypesGen.expectBoolean(executeGeneric(vFrame)); } @Override - public String executeString(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectString(executeGeneric(frame)); + public String executeString(VirtualFrame vFrame) throws UnexpectedResultException { + return SLTypesGen.expectString(executeGeneric(vFrame)); } @Override - public SLFunction executeFunction(VirtualFrame frame) throws UnexpectedResultException { - probeNode.enter(child, frame); + public SLFunction executeFunction(VirtualFrame vFrame) throws UnexpectedResultException { + probeNode.enter(child, vFrame); SLFunction result; try { - result = child.executeFunction(frame); - probeNode.returnValue(child, frame, result); + result = child.executeFunction(vFrame); + probeNode.returnValue(child, vFrame, result); } catch (Exception e) { - probeNode.returnExceptional(child, frame, e); + probeNode.returnExceptional(child, vFrame, e); throw (e); } return result; } @Override - public SLNull executeNull(VirtualFrame frame) throws UnexpectedResultException { - return SLTypesGen.expectSLNull(executeGeneric(frame)); + public SLNull executeNull(VirtualFrame vFrame) throws UnexpectedResultException { + return SLTypesGen.expectSLNull(executeGeneric(vFrame)); } }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java Tue Mar 03 14:20:58 2015 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java Tue Mar 10 21:26:02 2015 +0100 @@ -78,16 +78,16 @@ } @Override - public void executeVoid(VirtualFrame frame) { - probeNode.enter(child, frame); + public void executeVoid(VirtualFrame vFrame) { + probeNode.enter(child, vFrame); try { - child.executeVoid(frame); - probeNode.returnVoid(child, frame); + child.executeVoid(vFrame); + probeNode.returnVoid(child, vFrame); } catch (KillException e) { throw (e); } catch (Exception e) { - probeNode.returnExceptional(child, frame, e); + probeNode.returnExceptional(child, vFrame, e); throw (e); } }
--- a/mx/mx_graal.py Tue Mar 03 14:20:58 2015 +0100 +++ b/mx/mx_graal.py Tue Mar 10 21:26:02 2015 +0100 @@ -940,8 +940,7 @@ # This removes the need to unzip the *.diz files before debugging in gdb setMakeVar('ZIP_DEBUGINFO_FILES', '0', env=env) - # Clear these 2 variables as having them set can cause very confusing build problems - env.pop('LD_LIBRARY_PATH', None) + # Clear this variable as having it set can cause very confusing build problems env.pop('CLASSPATH', None) # Issue an env prefix that can be used to run the make on the command line @@ -2107,6 +2106,8 @@ flavor = 'intel' if 'att' in args: flavor = 'att' + if mx.get_arch() == "sparcv9": + flavor = "sparcv9" lib = mx.add_lib_suffix('hsdis-' + mx.get_arch()) path = join(_graal_home, 'lib', lib) @@ -2116,6 +2117,7 @@ 'intel/hsdis-amd64.dll' : '6a388372cdd5fe905c1a26ced614334e405d1f30', 'intel/hsdis-amd64.so' : '844ed9ffed64fe9599638f29a8450c50140e3192', 'intel/hsdis-amd64.dylib' : 'fdb13ef0d7d23d93dacaae9c98837bea0d4fc5a2', + 'sparcv9/hsdis-sparcv9.so': '5f79c312b3dcc55bad551dbb710b11f0048a4ce7', } flavoredLib = flavor + "/" + lib
--- a/src/cpu/x86/vm/compiledIC_x86.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/cpu/x86/vm/compiledIC_x86.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -135,10 +135,15 @@ NativeMovConstReg* method_holder = nativeMovConstReg_at(stub); NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); - assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(), +#ifdef ASSERT + // read the value once + intptr_t data = method_holder->data(); + address destination = jump->jump_destination(); + assert(data == 0 || data == (intptr_t)callee(), "a) MT-unsafe modification of inline cache"); - assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry, + assert(destination == (address)-1 || destination == entry, "b) MT-unsafe modification of inline cache"); +#endif // Update stub. method_holder->set_data((intptr_t)callee());
--- a/src/share/vm/classfile/systemDictionary.hpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Mar 10 21:26:02 2015 +0100 @@ -198,7 +198,6 @@ GRAAL_ONLY(do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Graal)) \ GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, Graal)) \ GRAAL_ONLY(do_klass(HotSpotResolvedObjectTypeImpl_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl, Graal)) \ - GRAAL_ONLY(do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Graal)) \ GRAAL_ONLY(do_klass(HotSpotCompressedNullConstant_klass, com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant, Graal)) \ GRAAL_ONLY(do_klass(HotSpotObjectConstantImpl_klass, com_oracle_graal_hotspot_meta_HotSpotObjectConstantImpl, Graal)) \ GRAAL_ONLY(do_klass(HotSpotMetaspaceConstantImpl_klass, com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstantImpl, Graal)) \ @@ -227,6 +226,7 @@ GRAAL_ONLY(do_klass(RegisterValue_klass, com_oracle_graal_api_code_RegisterValue, Graal)) \ GRAAL_ONLY(do_klass(RegisterCategory_klass, com_oracle_graal_api_code_Register_RegisterCategory, Graal)) \ GRAAL_ONLY(do_klass(StackSlot_klass, com_oracle_graal_api_code_StackSlot, Graal)) \ + GRAAL_ONLY(do_klass(StackLockValue_klass, com_oracle_graal_api_code_StackLockValue, Graal)) \ GRAAL_ONLY(do_klass(VirtualObject_klass, com_oracle_graal_api_code_VirtualObject, Graal)) \ GRAAL_ONLY(do_klass(SpeculationLog_klass, com_oracle_graal_api_code_SpeculationLog, Graal)) \ GRAAL_ONLY(do_klass(JavaConstant_klass, com_oracle_graal_api_meta_JavaConstant, Graal)) \
--- a/src/share/vm/classfile/vmSymbols.hpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Mar 10 21:26:02 2015 +0100 @@ -305,7 +305,6 @@ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant, "com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotObjectConstantImpl, "com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstantImpl,"com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl")) \ @@ -343,6 +342,7 @@ GRAAL_ONLY(template(com_oracle_graal_api_code_RegisterValue, "com/oracle/graal/api/code/RegisterValue")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_Register_RegisterCategory, "com/oracle/graal/api/code/Register$RegisterCategory")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_StackSlot, "com/oracle/graal/api/code/StackSlot")) \ + GRAAL_ONLY(template(com_oracle_graal_api_code_StackLockValue, "com/oracle/graal/api/code/StackLockValue")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_VirtualObject, "com/oracle/graal/api/code/VirtualObject")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_RegisterSaveLayout, "com/oracle/graal/api/code/RegisterSaveLayout")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_InvalidInstalledCodeException, "com/oracle/graal/api/code/InvalidInstalledCodeException")) \
--- a/src/share/vm/code/debugInfo.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/code/debugInfo.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -52,7 +52,7 @@ #ifdef ASSERT assert(_obj_pool != NULL, "object pool does not exist"); for (int i = _obj_pool->length() - 1; i >= 0; i--) { - assert(((ObjectValue*) _obj_pool->at(i))->id() != id, "should not be read twice"); + assert(_obj_pool->at(i)->as_ObjectValue()->id() != id, "should not be read twice"); } #endif ObjectValue* result = new ObjectValue(id); @@ -66,7 +66,7 @@ int id = read_int(); assert(_obj_pool != NULL, "object pool does not exist"); for (int i = _obj_pool->length() - 1; i >= 0; i--) { - ObjectValue* ov = (ObjectValue*) _obj_pool->at(i); + ObjectValue* ov = _obj_pool->at(i)->as_ObjectValue(); if (ov->id() == id) { return ov; }
--- a/src/share/vm/code/debugInfo.hpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/code/debugInfo.hpp Tue Mar 10 21:26:02 2015 +0100 @@ -41,6 +41,7 @@ // - ConstantValue describes a constant class ConstantOopReadValue; +class ObjectValue; class ScopeValue: public ResourceObj { public: @@ -58,6 +59,11 @@ return (ConstantOopReadValue*) this; } + ObjectValue* as_ObjectValue() { + assert(is_object(), "must be"); + return (ObjectValue*)this; + } + // Serialization of debugging information virtual void write_on(DebugInfoWriteStream* stream) = 0; static ScopeValue* read_from(DebugInfoReadStream* stream);
--- a/src/share/vm/code/debugInfoRec.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/code/debugInfoRec.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -392,7 +392,7 @@ PcDesc* last_pd = &_pcs[_pcs_length-1]; if (objects != NULL) { for (int i = objects->length() - 1; i >= 0; i--) { - ((ObjectValue*) objects->at(i))->set_visited(false); + objects->at(i)->as_ObjectValue()->set_visited(false); } } int offset = serialize_scope_values(objects);
--- a/src/share/vm/code/nmethod.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/code/nmethod.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -856,7 +856,8 @@ CodeCache::commit(this); } - if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { + bool printnmethods = PrintNMethods || PrintNMethodsAtLevel == _comp_level; + if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { ttyLocker ttyl; // keep the following output all in one block // This output goes directly to the tty, not the compiler log. // To enable tools to match it up with the compilation activity, @@ -870,7 +871,7 @@ // print the header part first print(); // then print the requested information - if (PrintNMethods) { + if (printnmethods) { print_code(); } if (PrintRelocations) { @@ -1014,7 +1015,7 @@ " entry points must be same for static methods and vice versa"); } - bool printnmethods = PrintNMethods + bool printnmethods = PrintNMethods || PrintNMethodsAtLevel == _comp_level || CompilerOracle::should_print(_method) || CompilerOracle::has_option_string(_method, "PrintNMethods"); if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { @@ -1105,13 +1106,13 @@ oop_maps()->print(); } } - if (PrintDebugInfo) { + if (PrintDebugInfo || CompilerOracle::has_option_string(_method, "PrintDebugInfo")) { print_scopes(); } - if (PrintRelocations) { + if (PrintRelocations || CompilerOracle::has_option_string(_method, "PrintRelocations")) { print_relocations(); } - if (PrintDependencies) { + if (PrintDependencies || CompilerOracle::has_option_string(_method, "PrintDependencies")) { print_dependencies(); } if (PrintExceptionHandlers) { @@ -2749,7 +2750,10 @@ continue; ScopeDesc* sd = scope_desc_at(p->real_pc(this)); - sd->print_on(tty, p); + while (sd != NULL) { + sd->print_on(tty, p); + sd = sd->sender(); + } } }
--- a/src/share/vm/code/scopeDesc.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/code/scopeDesc.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -230,7 +230,7 @@ if (NOT_GRAAL(DoEscapeAnalysis &&) is_top() && _objects != NULL) { tty->print_cr("Objects"); for (int i = 0; i < _objects->length(); i++) { - ObjectValue* sv = (ObjectValue*) _objects->at(i); + ObjectValue* sv = _objects->at(i)->as_ObjectValue(); tty->print(" - %d: ", sv->id()); sv->print_fields_on(tty); tty->cr();
--- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -212,6 +212,7 @@ oop lirKind = AbstractValue::lirKind(value); oop platformKind = LIRKind::platformKind(lirKind); jint referenceMask = LIRKind::referenceMask(lirKind); + assert(referenceMask != -1, "derived pointers are not allowed"); assert(referenceMask == 0 || referenceMask == 1, "unexpected referenceMask"); bool reference = referenceMask == 1; @@ -365,19 +366,19 @@ } MonitorValue* CodeInstaller::get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, OopRecorder* oop_recorder) { - guarantee(value->is_a(HotSpotMonitorValue::klass()), "Monitors must be of type MonitorValue"); + guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type MonitorValue"); ScopeValue* second = NULL; - ScopeValue* owner_value = get_scope_value(HotSpotMonitorValue::owner(value), total_frame_size, objects, second, oop_recorder); + ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), total_frame_size, objects, second, oop_recorder); assert(second == NULL, "monitor cannot occupy two stack slots"); - ScopeValue* lock_data_value = get_scope_value(HotSpotMonitorValue::slot(value), total_frame_size, objects, second, oop_recorder); + ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), total_frame_size, objects, second, oop_recorder); assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); assert(lock_data_value->is_location(), "invalid monitor location"); Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); bool eliminated = false; - if (HotSpotMonitorValue::eliminated(value)) { + if (StackLockValue::eliminated(value)) { eliminated = true; } @@ -660,9 +661,8 @@ if (context != subtype) { assert(context->is_abstract(), ""); _dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype); - } else { - _dependencies->assert_leaf_type(subtype); } + _dependencies->assert_leaf_type(subtype); } void CodeInstaller::assumption_ConcreteMethod(Handle assumption) {
--- a/src/share/vm/graal/graalJavaAccess.hpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Mar 10 21:26:02 2015 +0100 @@ -169,7 +169,7 @@ typeArrayOop_field(BitSet, words, "[J") \ end_class \ start_class(BytecodeFrame) \ - objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/JavaValue;") \ + objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/Value;") \ int_field(BytecodeFrame, numLocals) \ int_field(BytecodeFrame, numStack) \ int_field(BytecodeFrame, numLocks) \ @@ -241,12 +241,12 @@ start_class(VirtualObject) \ int_field(VirtualObject, id) \ oop_field(VirtualObject, type, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \ - objArrayOop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/JavaValue;") \ + objArrayOop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/Value;") \ end_class \ - start_class(HotSpotMonitorValue) \ - oop_field(HotSpotMonitorValue, owner, "Lcom/oracle/graal/api/meta/JavaValue;") \ - oop_field(HotSpotMonitorValue, slot, "Lcom/oracle/graal/api/code/StackSlotValue;") \ - boolean_field(HotSpotMonitorValue, eliminated) \ + start_class(StackLockValue) \ + oop_field(StackLockValue, owner, "Lcom/oracle/graal/api/meta/Value;") \ + oop_field(StackLockValue, slot, "Lcom/oracle/graal/api/code/StackSlotValue;") \ + boolean_field(StackLockValue, eliminated) \ end_class \ start_class(SpeculationLog) \ oop_field(SpeculationLog, lastFailed, "Ljava/lang/Object;") \
--- a/src/share/vm/graal/vmStructs_graal.hpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/graal/vmStructs_graal.hpp Tue Mar 10 21:26:02 2015 +0100 @@ -39,6 +39,7 @@ nonstatic_field(GraalEnv, _jvmti_can_hotswap_or_post_breakpoint, bool) \ #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type) \ + declare_toplevel_type(GraalEnv) \ #define VM_INT_CONSTANTS_GRAAL(declare_constant, declare_preprocessor_constant) \ declare_constant(Deoptimization::Reason_unreached0) \
--- a/src/share/vm/runtime/deoptimization.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -1405,6 +1405,7 @@ ScopeDesc* trap_scope = cvf->scope(); if (TraceDeoptimization) { + ttyLocker ttyl; tty->print_cr(" bci=%d pc=" INTPTR_FORMAT ", relative_pc=%d, method=%s" GRAAL_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string() #ifdef GRAAL , debug_id
--- a/src/share/vm/runtime/globals.hpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/runtime/globals.hpp Tue Mar 10 21:26:02 2015 +0100 @@ -993,6 +993,9 @@ diagnostic(bool, PrintNMethods, false, \ "Print assembly code for nmethods when generated") \ \ + diagnostic(intx, PrintNMethodsAtLevel, -1, \ + "Only print code for nmethods at the given compilation level") \ + \ diagnostic(bool, PrintNativeNMethods, false, \ "Print assembly code for native nmethods when generated") \ \
--- a/src/share/vm/runtime/vframe.cpp Tue Mar 03 14:20:58 2015 +0100 +++ b/src/share/vm/runtime/vframe.cpp Tue Mar 10 21:26:02 2015 +0100 @@ -274,7 +274,7 @@ // Get oopmap describing oops and int for current bci InterpreterOopMap oop_mask; if ((TraceDeoptimization && Verbose) GRAAL_ONLY( || PrintDeoptimizationDetails)) { - methodHandle m_h(thread(), method()); + methodHandle m_h(Thread::current(), method()); OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); } else { method()->mask_for(bci(), &oop_mask);