Mercurial > hg > graal-compiler
changeset 14997:5e4ae8709830
Use typed illegal stamps and use IllegalStamp only for conflicting primitive types.
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -66,6 +66,11 @@ } @Override + public Stamp illegal() { + return new NarrowOopStamp((ObjectStamp) super.illegal(), encoding); + } + + @Override public Kind getStackKind() { return Kind.Object; } @@ -88,11 +93,8 @@ if (this == otherStamp) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.meet(this); - } if (!isCompatible(otherStamp)) { - return StampFactory.illegal(Kind.Illegal); + return StampFactory.illegal(); } return new NarrowOopStamp((ObjectStamp) super.meet(otherStamp), encoding); } @@ -102,9 +104,6 @@ if (this == otherStamp) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.join(this); - } if (!isCompatible(otherStamp)) { return StampFactory.illegal(Kind.Illegal); }
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java Fri Apr 04 15:57:41 2014 +0200 @@ -103,8 +103,9 @@ @Test public void testJoin6() { Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class)); - Stamp allwaysNull = StampFactory.alwaysNull(); - Stamp join = join(allwaysNull, dExactNonNull); + Stamp alwaysNull = StampFactory.alwaysNull(); + Stamp join = join(alwaysNull, dExactNonNull); + Assert.assertFalse(join.isLegal()); Assert.assertFalse(ObjectStamp.isObjectNonNull(join)); Assert.assertFalse(ObjectStamp.isObjectAlwaysNull(join)); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -38,7 +38,6 @@ protected FloatStamp(int bits, double lowerBound, double upperBound, boolean nonNaN) { super(bits); - assert (!nonNaN && Double.isNaN(lowerBound) && Double.isNaN(upperBound)) || lowerBound <= upperBound; this.lowerBound = lowerBound; this.upperBound = upperBound; this.nonNaN = nonNaN; @@ -50,6 +49,16 @@ } @Override + public Stamp illegal() { + return new FloatStamp(getBits(), Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, true); + } + + @Override + public boolean isLegal() { + return lowerBound <= upperBound || !nonNaN; + } + + @Override public Kind getStackKind() { if (getBits() > 32) { return Kind.Double; @@ -124,9 +133,6 @@ if (otherStamp == this) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.meet(this); - } if (!(otherStamp instanceof FloatStamp)) { return StampFactory.illegal(Kind.Illegal); } @@ -149,9 +155,6 @@ if (otherStamp == this) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.join(this); - } if (!(otherStamp instanceof FloatStamp)) { return StampFactory.illegal(Kind.Illegal); } @@ -164,8 +167,6 @@ return this; } else if (joinLowerBound == other.lowerBound && joinUpperBound == other.upperBound && joinNonNaN == other.nonNaN) { return other; - } else if (joinLowerBound > joinUpperBound) { - return illegal(); } else { return new FloatStamp(getBits(), joinLowerBound, joinUpperBound, joinNonNaN); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -61,7 +61,7 @@ @Override public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { - throw GraalInternalError.shouldNotReachHere(type + " stamp has not Java type"); + throw GraalInternalError.shouldNotReachHere(type + " stamp has no Java type"); } @Override @@ -76,22 +76,16 @@ @Override public Stamp meet(Stamp other) { - if (other instanceof IllegalStamp) { - return other.join(this); - } if (!(other instanceof GenericStamp) || ((GenericStamp) other).type != type) { - return StampFactory.illegal(Kind.Illegal); + return illegal(); } return this; } @Override public Stamp join(Stamp other) { - if (other instanceof IllegalStamp) { - return other.join(this); - } if (!(other instanceof GenericStamp) || ((GenericStamp) other).type != type) { - return StampFactory.illegal(Kind.Illegal); + return illegal(); } return this; } @@ -126,4 +120,14 @@ } return true; } + + @Override + public Stamp illegal() { + return IllegalStamp.getInstance(); + } + + @Override + public boolean isLegal() { + return true; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -29,22 +29,14 @@ /** * This stamp represents the illegal type. Values with this type can not exist at run time. */ -public final class IllegalStamp extends PrimitiveStamp { - - private final Kind kind; +public final class IllegalStamp extends Stamp { - public IllegalStamp(Kind kind) { - super(0); - this.kind = kind; - } - - public Kind kind() { - return kind; + private IllegalStamp() { } @Override public Kind getStackKind() { - return kind; + return Kind.Illegal; } @Override @@ -64,12 +56,12 @@ @Override public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { - return null; + throw GraalInternalError.shouldNotReachHere("illegal stamp has no Java type"); } @Override public Stamp meet(Stamp other) { - return other; + return this; } @Override @@ -79,19 +71,22 @@ @Override public boolean isCompatible(Stamp stamp) { - if (this == stamp) { - return true; - } - if (stamp instanceof IllegalStamp) { - IllegalStamp other = (IllegalStamp) stamp; - return kind == other.kind; - } else { - return stamp.isCompatible(this); - } + return false; } @Override public String toString() { return "ILLEGAL"; } + + @Override + public boolean isLegal() { + return false; + } + + private static IllegalStamp instance = new IllegalStamp(); + + static IllegalStamp getInstance() { + return instance; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -31,7 +31,7 @@ /** * Describes the possible values of a {@link ValueNode} that produces an int or long result. - * + * * The description consists of (inclusive) lower and upper bounds and up (may be set) and down * (always set) bit-masks. */ @@ -51,13 +51,10 @@ this.upperBound = upperBound; this.downMask = downMask; this.upMask = upMask; - assert lowerBound <= upperBound : this; assert lowerBound >= defaultMinValue(bits, unsigned) : this; assert upperBound <= defaultMaxValue(bits, unsigned) : this; assert (downMask & defaultMask(bits)) == downMask : this; assert (upMask & defaultMask(bits)) == upMask : this; - assert (lowerBound & downMask) == downMask : this; - assert (upperBound & downMask) == downMask : this; } @Override @@ -66,6 +63,20 @@ } @Override + public Stamp illegal() { + return new IntegerStamp(getBits(), unsigned, defaultMaxValue(getBits(), unsigned), defaultMinValue(getBits(), unsigned), defaultMask(getBits()), 0); + } + + @Override + public boolean isLegal() { + if (unsigned) { + return Long.compareUnsigned(lowerBound, upperBound) <= 0; + } else { + return lowerBound <= upperBound; + } + } + + @Override public Kind getStackKind() { if (getBits() > 32) { return Kind.Long; @@ -211,9 +222,6 @@ if (otherStamp == this) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.meet(this); - } if (!(otherStamp instanceof IntegerStamp)) { return StampFactory.illegal(Kind.Illegal); } @@ -226,9 +234,6 @@ if (otherStamp == this) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.join(this); - } if (!(otherStamp instanceof IntegerStamp)) { return StampFactory.illegal(Kind.Illegal); } @@ -310,7 +315,7 @@ /** * Checks if the 2 stamps represent values of the same sign. Returns true if the two stamps are * both positive of null or if they are both strictly negative - * + * * @return true if the two stamps are both positive of null or if they are both strictly * negative */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -37,7 +37,6 @@ private final boolean alwaysNull; public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { - assert !exactType || (type != null && (isConcreteType(type))); this.type = type; this.exactType = exactType; this.nonNull = nonNull; @@ -50,6 +49,16 @@ } @Override + public Stamp illegal() { + return new ObjectStamp(null, true, true, false); + } + + @Override + public boolean isLegal() { + return !exactType || (type != null && (isConcreteType(type))); + } + + @Override public Kind getStackKind() { return Kind.Object; } @@ -96,9 +105,6 @@ if (this == otherStamp) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.meet(this); - } if (!(otherStamp instanceof ObjectStamp)) { return StampFactory.illegal(Kind.Illegal); } @@ -119,7 +125,11 @@ meetAlwaysNull = other.alwaysNull; } else { meetType = meetTypes(type(), other.type()); - meetExactType = Objects.equals(meetType, type) && Objects.equals(meetType, other.type) && exactType && other.exactType; + meetExactType = exactType && other.exactType; + if (meetExactType && type != null && other.type != null) { + // meeting two valid exact types may result in a non-exact type + meetExactType = Objects.equals(meetType, type) && Objects.equals(meetType, other.type); + } meetNonNull = nonNull && other.nonNull; meetAlwaysNull = false; } @@ -146,9 +156,6 @@ if (other instanceof ObjectStamp) { return true; } - if (other instanceof IllegalStamp) { - return ((IllegalStamp) other).kind() == Kind.Object; - } return false; } @@ -158,12 +165,12 @@ * where both types are not obviously related, the cast operation will prefer the type of the * {@code to} stamp. This is necessary as long as ObjectStamps are not able to accurately * represent intersection types. - * + * * For example when joining the {@link RandomAccess} type with the {@link AbstractList} type, * without intersection types, this would result in the most generic type ({@link Object} ). For * this reason, in some cases a {@code castTo} operation is preferable in order to keep at least * the {@link AbstractList} type. - * + * * @param to the stamp this stamp should be casted to * @return This stamp casted to the {@code to} stamp */ @@ -175,13 +182,16 @@ if (this == otherStamp) { return this; } - if (otherStamp instanceof IllegalStamp) { - return otherStamp.join(this); - } if (!(otherStamp instanceof ObjectStamp)) { return StampFactory.illegal(Kind.Illegal); } ObjectStamp other = (ObjectStamp) otherStamp; + if (!isLegal()) { + return this; + } else if (!other.isLegal()) { + return other; + } + ResolvedJavaType joinType; boolean joinAlwaysNull = alwaysNull || other.alwaysNull; boolean joinNonNull = nonNull || other.nonNull; @@ -291,7 +301,7 @@ } public static boolean isObjectAlwaysNull(Stamp stamp) { - return (stamp instanceof ObjectStamp && ((ObjectStamp) stamp).alwaysNull()); + return (stamp instanceof ObjectStamp && ((ObjectStamp) stamp).isLegal() && ((ObjectStamp) stamp).alwaysNull()); } public static boolean isObjectNonNull(ValueNode node) { @@ -299,7 +309,7 @@ } public static boolean isObjectNonNull(Stamp stamp) { - return (stamp instanceof ObjectStamp && ((ObjectStamp) stamp).nonNull()); + return stamp instanceof ObjectStamp && ((ObjectStamp) stamp).isLegal() && ((ObjectStamp) stamp).nonNull(); } public static ResolvedJavaType typeOrNull(ValueNode node) { @@ -323,14 +333,4 @@ } return false; } - - public static boolean isObject(Stamp stamp) { - if (stamp instanceof ObjectStamp) { - return true; - } else if (stamp instanceof IllegalStamp) { - return ((IllegalStamp) stamp).kind() == Kind.Object; - } else { - return false; - } - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -41,7 +41,7 @@ public abstract ResolvedJavaType javaType(MetaAccessProvider metaAccess); public boolean alwaysDistinct(Stamp other) { - return join(other) instanceof IllegalStamp; + return !join(other).isLegal(); } /** @@ -76,15 +76,17 @@ /** * Returns a stamp of the same kind, but allowing the full value range of the kind. + * + * {@link #unrestricted()} is the neutral element of the {@link #join(Stamp)} operation. */ public abstract Stamp unrestricted(); /** - * Returns an illegal stamp that has the same kind, but no valid values. + * Returns a stamp of the same kind, but with no allowed values. + * + * {@link #illegal()} is the neutral element of the {@link #meet(Stamp)} operation. */ - public Stamp illegal() { - return StampFactory.illegal(getStackKind()); - } + public abstract Stamp illegal(); /** * Test whether two stamps have the same base type. @@ -92,6 +94,11 @@ public abstract boolean isCompatible(Stamp other); /** + * Test whether this stamp has legal values. + */ + public abstract boolean isLegal(); + + /** * If this stamp represents a single value, the methods returns this single value. It returns * null otherwise. *
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Fri Apr 04 15:57:41 2014 +0200 @@ -73,8 +73,13 @@ setCache(Kind.Object, objectStamp); setCache(Kind.Void, VoidStamp.getInstance()); + for (Kind k : Kind.values()) { - illegalStampCache[k.ordinal()] = new IllegalStamp(k); + if (stampCache[k.ordinal()] != null) { + illegalStampCache[k.ordinal()] = stampCache[k.ordinal()].illegal(); + } else { + illegalStampCache[k.ordinal()] = IllegalStamp.getInstance(); + } } } @@ -122,6 +127,10 @@ return positiveInt; } + public static Stamp illegal() { + return illegal(Kind.Illegal); + } + public static Stamp illegal(Kind kind) { return illegalStampCache[kind.ordinal()]; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Fri Apr 04 15:57:41 2014 +0200 @@ -32,23 +32,6 @@ */ public class StampTool { - private static Kind joinKind(Kind a, Kind b) { - if (a == b) { - return a; - } - return Kind.Illegal; - } - - /** - * Create an {@link IllegalStamp} from two incompatible input stamps, joining the kind of the - * input stamps if possible. - */ - private static Stamp joinIllegal(Stamp a, Stamp b) { - IllegalStamp ia = (IllegalStamp) a.illegal(); - IllegalStamp ib = (IllegalStamp) b.illegal(); - return StampFactory.illegal(joinKind(ia.kind(), ib.kind())); - } - public static Stamp negate(Stamp stamp) { if (stamp instanceof IntegerStamp) { IntegerStamp integerStamp = (IntegerStamp) stamp; @@ -93,7 +76,7 @@ if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { return add((IntegerStamp) stamp1, (IntegerStamp) stamp2); } - return joinIllegal(stamp1, stamp2); + return StampFactory.illegal(); } private static long carryBits(long x, long y) { @@ -108,7 +91,7 @@ if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { return div((IntegerStamp) stamp1, (IntegerStamp) stamp2); } - return joinIllegal(stamp1, stamp2); + return StampFactory.illegal(); } public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) { @@ -223,7 +206,7 @@ if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { return and((IntegerStamp) stamp1, (IntegerStamp) stamp2); } - return joinIllegal(stamp1, stamp2); + return StampFactory.illegal(); } public static Stamp and(IntegerStamp stamp1, IntegerStamp stamp2) { @@ -235,7 +218,7 @@ if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { return or((IntegerStamp) stamp1, (IntegerStamp) stamp2); } - return joinIllegal(stamp1, stamp2); + return StampFactory.illegal(); } public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) { @@ -247,7 +230,7 @@ if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { return xor((IntegerStamp) stamp1, (IntegerStamp) stamp2); } - return joinIllegal(stamp1, stamp2); + return StampFactory.illegal(); } public static Stamp xor(IntegerStamp stamp1, IntegerStamp stamp2) { @@ -465,7 +448,7 @@ /** * Compute the stamp resulting from the unsigned comparison being true. - * + * * @return null if it's can't be true or it nothing useful can be encoded. */ public static Stamp unsignedCompare(Stamp stamp, Stamp stamp2) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/VoidStamp.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/VoidStamp.java Fri Apr 04 15:57:41 2014 +0200 @@ -91,6 +91,17 @@ return this == stamp; } + @Override + public Stamp illegal() { + // there is no illegal void stamp + return this; + } + + @Override + public boolean isLegal() { + return true; + } + private static VoidStamp instance = new VoidStamp(); static VoidStamp getInstance() {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java Mon Apr 07 10:40:37 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java Fri Apr 04 15:57:41 2014 +0200 @@ -49,8 +49,8 @@ for (Node n : graph.getNodes()) { if (n instanceof ValuePhiNode || n instanceof ValueAndStampProxy) { ValueNode node = (ValueNode) n; - if (ObjectStamp.isObject(node.stamp())) { - assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis"; + if (node.stamp() instanceof ObjectStamp) { + assert node.stamp().isLegal() : "We assume all Phi and Proxy stamps are legal before the analysis"; node.setStamp(node.stamp().illegal()); } } @@ -68,7 +68,7 @@ for (Node n : graph.getNodes()) { if (n instanceof ValueNode) { ValueNode node = (ValueNode) n; - if (ObjectStamp.isObject(node.stamp())) { + if (node.stamp() instanceof ObjectStamp) { stampChanged |= node.inferStamp(); } }