From 0494c21189a14d0b0e339accfef4ac72cff9300d Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Fri, 22 Sep 2017 12:32:35 +0200 Subject: [PATCH] VectorIterator: reduce instance-of checks, make sure interface calls are inlined --- .../r/runtime/data/nodes/VectorIterator.java | 94 ++++++++++++------- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java index 4ba40b6598..c1820176a6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data.nodes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -45,15 +46,16 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.nodes.GetNextNodeGen.GetNextGenericNodeGen; import com.oracle.truffle.r.runtime.data.nodes.VectorIterator.IteratorData; abstract class VectorIteratorNodeAdapter extends Node { - public static boolean hasNoNativeMemoryData(RAbstractVector vector) { - return !(vector instanceof RVector<?>) || !((RVector<?>) vector).hasNativeMemoryData(); + public static boolean hasNoNativeMemoryData(RAbstractVector vector, Class<? extends RAbstractVector> vecClass) { + return !(RVector.class.isAssignableFrom(vecClass)) || !((RVector<?>) vecClass.cast(vector)).hasNativeMemoryData(); } - public static boolean isRVector(RAbstractVector vector) { - return vector instanceof RVector<?>; + public static boolean isRVector(Class<? extends RAbstractVector> vecClass) { + return RVector.class.isAssignableFrom(vecClass); } } @@ -65,11 +67,11 @@ abstract class GetIteratorNode extends VectorIteratorNodeAdapter { return new IteratorData<>(vector.getNativeMirror(), vector.getLength()); } - @Specialization(guards = {"hasNoNativeMemoryData(vector)", "vectorClass == vector.getClass()"}) + @Specialization(guards = {"vectorClass == vector.getClass()", "hasNoNativeMemoryData(vector, vectorClass)"}, limit = "10") protected IteratorData<?> generic(RAbstractVector vector, @Cached("vector.getClass()") Class<? extends RAbstractVector> vectorClass) { RAbstractVector profiledVec = vectorClass.cast(vector); - return new IteratorData<>(profiledVec.getInternalStore(), vector.getLength()); + return new IteratorData<>(profiledVec.getInternalStore(), profiledVec.getLength()); } @Fallback @@ -106,7 +108,7 @@ abstract class HasNextNode extends VectorIteratorNodeAdapter { return iter.index < ((String[]) iter.store).length; } - @Specialization(guards = {"!isRVector(vector)", "vectorClass == vector.getClass()"}) + @Specialization(guards = {"vectorClass == vector.getClass()", "!isRVector(vectorClass)"}, limit = "10") protected boolean generic(RAbstractVector vector, IteratorData<?> iter, @Cached("vector.getClass()") Class<? extends RAbstractVector> vectorClass) { RAbstractVector profiledVec = vectorClass.cast(vector); @@ -183,40 +185,62 @@ abstract class GetNextNode extends VectorIteratorNodeAdapter { throw RInternalError.unimplemented("string vectors backed by native memory"); } - @Specialization(guards = "!isRVector(vector)") - protected int intVectorGeneric(RAbstractIntVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Int getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + @Child private GetNextGenericNode getNextGenericNode; - @Specialization(guards = "!isRVector(vector)") - protected double doubleVectorGeneric(RAbstractDoubleVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Double getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); + @Fallback + protected Object doGeneric(RAbstractVector vector, IteratorData<?> iter) { + // we use fallback and extra node so that we do not have to explicitly check that the vector is not + // RVector, DSL generates fallback guard that compares the class with the all RVector subclasses + // used in the specializations above, "vector instanceof RVector" would not be a leaf-check. + if (getNextGenericNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getNextGenericNode = insert(GetNextGenericNode.create()); + } + return getNextGenericNode.execute(vector, iter); } - @Specialization(guards = "!isRVector(vector)") - protected String stringVectorGeneric(RAbstractStringVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.String getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + static abstract class GetNextGenericNode extends Node { + public abstract Object execute(RAbstractVector vector, IteratorData<?> iter); - @Specialization(guards = "!isRVector(vector)") - protected byte rawVectorGeneric(RAbstractRawVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Raw getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + public static GetNextGenericNode create() { + return GetNextGenericNodeGen.create(); + } - @Specialization(guards = "!isRVector(vector)") - protected byte logicalVectorGeneric(RAbstractLogicalVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Logical getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); - } + @Specialization + protected int intVectorGeneric(RAbstractIntVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Int getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } - @Specialization(guards = "!isRVector(vector)") - protected RComplex complexVectorGeneric(RAbstractComplexVector vector, IteratorData<?> iter, - @Cached("create()") GetDataAt.Complex getDataAtNode) { - return getDataAtNode.get(vector, iter.store, iter.index); + @Specialization + protected double doubleVectorGeneric(RAbstractDoubleVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Double getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected String stringVectorGeneric(RAbstractStringVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.String getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected byte rawVectorGeneric(RAbstractRawVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Raw getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected byte logicalVectorGeneric(RAbstractLogicalVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Logical getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization + protected RComplex complexVectorGeneric(RAbstractComplexVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Complex getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } } } -- GitLab