diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java index 1cfa2b74dfa57ff0db9fdb43852431bc135a9491..9094f3e34ff8d521a8ec586a20f0686e6d561c10 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java @@ -19,6 +19,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; @@ -48,9 +49,10 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { protected RDoubleVector cdist(RAbstractDoubleVector x, @SuppressWarnings("unused") int method, RList list, double p, @SuppressWarnings("unused") @Cached("method") int cachedMethod, @Cached("getMethod(method)") Method methodObj, @Cached("create()") SetAttributeNode setAttrNode, - @Cached("create()") SetClassAttributeNode setClassAttrNode) { - int nr = RRuntime.nrows(x); - int nc = RRuntime.ncols(x); + @Cached("create()") SetClassAttributeNode setClassAttrNode, + @Cached("create()") GetDimAttributeNode getDimNode) { + int nr = getDimNode.nrows(x); + int nc = getDimNode.ncols(x); int n = nr * (nr - 1) / 2; /* avoid int overflow for N ~ 50,000 */ double[] ans = new double[n]; RDoubleVector xm = x.materialize(); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java index 1aff0091ef52ff496d09f462d7c2a1fd8db2e4dd..5080206bbed26ecd787667839af2adae4bfe9f3f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java @@ -22,6 +22,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -76,6 +77,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { private final BranchProfile error = BranchProfile.create(); private final BranchProfile warning = BranchProfile.create(); + @Child private GetDimAttributeNode getDimsNode = GetDimAttributeNode.create(); + private final LoopConditionProfile loopLength = LoopConditionProfile.createCountingProfile(); public RDoubleVector corcov(RDoubleVector x, RDoubleVector y, @SuppressWarnings("unused") int method, boolean iskendall, RBaseNode invokingNode) throws RError { @@ -175,14 +178,14 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { return ans; } - private static int ncols(RDoubleVector x) { + private int ncols(RDoubleVector x) { assert x.isMatrix(); - return x.getDimensions()[1]; + return getDimsNode.getDimensions(x)[1]; } - private static int nrows(RDoubleVector x) { + private int nrows(RDoubleVector x) { assert x.isMatrix(); - return x.getDimensions()[0]; + return getDimsNode.getDimensions(x)[0]; } private void complete1(int n, int ncx, RDoubleVector x, RIntVector ind, boolean naFail) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java index 2887c8f67d5837b4fe5f76b91940f39a199ac373..9517ffa7525c57410a9d4ff43420c87c7a132d08 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java @@ -10,7 +10,9 @@ */ package com.oracle.truffle.r.library.stats; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; @@ -29,7 +31,7 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { } @Specialization - protected RIntVector cutree(RAbstractIntVector mergeIn, RAbstractIntVector whichIn) { + protected RIntVector cutree(RAbstractIntVector mergeIn, RAbstractIntVector whichIn, @Cached("create()") GetDimAttributeNode getDimNode) { RIntVector merge = mergeIn.materialize(); RIntVector which = whichIn.materialize(); int whichLen = which.getLength(); @@ -43,7 +45,7 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { int mm = 0; boolean foundJ; - int n = RRuntime.nrows(merge) + 1; + int n = getDimNode.nrows(merge) + 1; /* * The C code uses 1-based indices for the next three arrays and so set the int * value * behind the actual start of the array. To keep the logic equivalent, we call adj(k) on the diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java index 01a1f747831be975f900f91e34525d9d0cc6dd20..dd00fde2ef4e339fade9bf637eb08acc76c452d5 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java @@ -10,7 +10,9 @@ */ package com.oracle.truffle.r.library.stats; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; @@ -25,9 +27,9 @@ public abstract class DoubleCentre extends RExternalBuiltinNode.Arg1 { } @Specialization - protected RDoubleVector doubleCentre(RAbstractDoubleVector aVecAbs) { + protected RDoubleVector doubleCentre(RAbstractDoubleVector aVecAbs, @Cached("create()") GetDimAttributeNode getDimNode) { RDoubleVector aVec = aVecAbs.materialize(); - int n = RRuntime.nrows(aVec); + int n = getDimNode.nrows(aVec); double[] a = aVec.getDataWithoutCopying(); // does not copy for (int i = 0; i < n; i++) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java index 472fdc3f53b299f573acac83050b028769cddef2..ed643cb629ef06cd93cc76696597613684206b0f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java @@ -23,6 +23,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -61,10 +62,11 @@ public abstract class APerm extends RBuiltinNode { } @Specialization - protected RAbstractVector aPerm(RAbstractVector vector, @SuppressWarnings("unused") RNull permVector, byte resize) { + protected RAbstractVector aPerm(RAbstractVector vector, @SuppressWarnings("unused") RNull permVector, byte resize, + @Cached("create()") GetDimAttributeNode getDimsNode) { checkErrorConditions(vector); - int[] dim = vector.getDimensions(); + int[] dim = getDimsNode.getDimensions(vector); final int diml = dim.length; RVector<?> result = vector.createEmptySameType(vector.getLength(), vector.isComplete()); @@ -101,10 +103,11 @@ public abstract class APerm extends RBuiltinNode { } @Specialization - protected RAbstractVector aPerm(RAbstractVector vector, RAbstractIntVector permVector, byte resize) { + protected RAbstractVector aPerm(RAbstractVector vector, RAbstractIntVector permVector, byte resize, + @Cached("create()") GetDimAttributeNode getDimsNode) { checkErrorConditions(vector); - int[] dim = vector.getDimensions(); + int[] dim = getDimsNode.getDimensions(vector); int[] perm = getPermute(dim, permVector); int[] posV = new int[dim.length]; @@ -126,7 +129,8 @@ public abstract class APerm extends RBuiltinNode { @Specialization protected RAbstractVector aPerm(RAbstractVector vector, RAbstractStringVector permVector, byte resize, - @Cached("create()") RAttributeProfiles dimNamesProfile) { + @Cached("create()") RAttributeProfiles dimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimsNode) { RList dimNames = vector.getDimNames(dimNamesProfile); if (dimNames == null) { // TODO: this error is reported after IS_OF_WRONG_LENGTH in GnuR @@ -146,7 +150,7 @@ public abstract class APerm extends RBuiltinNode { } // Note: if this turns out to be slow, we can cache the permutation - return aPerm(vector, RDataFactory.createIntVector(perm, true), resize); + return aPerm(vector, RDataFactory.createIntVector(perm, true), resize, getDimsNode); } private static int[] getReverse(int[] dim) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java index 8fc0691a76e82d5d36fbb142623805bb51e7f335..7532f080c19d0b86026bed5a456fa030199eae76 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java @@ -36,6 +36,7 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.RASTUtils; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode; @@ -95,6 +96,7 @@ public abstract class Bind extends RBaseNode { @Child private CastToVectorNode castVector; @Child private UseMethodInternalNode dcn; @Child private CastLogicalNode castLogical; + @Child private GetDimAttributeNode getDimsNode; private final BindType type; @@ -122,6 +124,14 @@ public abstract class Bind extends RBaseNode { this.type = type; } + protected int[] getVectorDimensions(RAbstractVector v) { + if (getDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimsNode = insert(GetDimAttributeNode.create()); + } + return getDimsNode.getDimensions(v); + } + protected RAbstractVector castVector(Object value) { if (castVector == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -275,7 +285,7 @@ public abstract class Bind extends RBaseNode { if (vecDimNames != null) { firstDimNames = vecDimNames.getDataAt(dimInd); } - } else if (!vec.isArray() || vec.getDimensions().length == 1) { + } else if (!vec.isArray() || getVectorDimensions(vec).length == 1) { RStringVector names = vec.getNames(attrProfiles); firstDimNames = names == null ? RNull.instance : names; } else { @@ -319,7 +329,7 @@ public abstract class Bind extends RBaseNode { dimNamesArray[ind++] = RRuntime.NAMES_ATTR_EMPTY_VALUE; } return -ind; - } else if (!vec.isArray() || vec.getDimensions().length == 1) { + } else if (!vec.isArray() || getVectorDimensions(vec).length == 1) { if (argNames == null) { if (deparseLevel == 0) { dimNamesArray[ind++] = RRuntime.NAMES_ATTR_EMPTY_VALUE; @@ -377,7 +387,7 @@ public abstract class Bind extends RBaseNode { } protected int[] getDimensions(RAbstractVector vector) { - int[] dimensions = vector.getDimensions(); + int[] dimensions = getVectorDimensions(vector); if (dimensions == null || dimensions.length != 2) { return type == BindType.cbind ? new int[]{vector.getLength(), 1} : new int[]{1, vector.getLength()}; } else { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java index 3aefffb5f6b5d7a8e3bc4f27c5d4f058c0e13fd1..e59eb2809cc9c0ab9488e9fc92da42880af3a5b0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java @@ -27,7 +27,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -62,21 +64,26 @@ public abstract class Crossprod extends RBuiltinNode { } @Specialization(guards = {"x.isMatrix()", "y.isMatrix()"}) - protected RDoubleVector crossprod(RAbstractDoubleVector x, RAbstractDoubleVector y) { - int xRows = x.getDimensions()[0]; - int xCols = x.getDimensions()[1]; - int yRows = y.getDimensions()[0]; - int yCols = y.getDimensions()[1]; + protected RDoubleVector crossprod(RAbstractDoubleVector x, RAbstractDoubleVector y, + @Cached("create()") GetDimAttributeNode getXDimsNode, + @Cached("create()") GetDimAttributeNode getYDimsNode) { + int[] xDims = getXDimsNode.getDimensions(x); + int[] yDims = getYDimsNode.getDimensions(y); + int xRows = xDims[0]; + int xCols = xDims[1]; + int yRows = yDims[0]; + int yCols = yDims[1]; return matMult.doubleMatrixMultiply(x, y, xCols, xRows, yRows, yCols, xRows, 1, 1, yRows, false); } - private static RDoubleVector mirror(RDoubleVector result) { + private static RDoubleVector mirror(RDoubleVector result, GetDimAttributeNode getResultDimsNode) { /* * Mirroring the result is not only good for performance, but it is also required to produce * the same result as GNUR. */ - assert result.isMatrix() && result.getDimensions()[0] == result.getDimensions()[1]; - int size = result.getDimensions()[0]; + int[] resultDims = getResultDimsNode.getDimensions(result); + assert result.isMatrix() && resultDims[0] == resultDims[1]; + int size = resultDims[0]; double[] data = result.getDataWithoutCopying(); for (int row = 0; row < size; row++) { int destIndex = row * size + row + 1; @@ -96,10 +103,12 @@ public abstract class Crossprod extends RBuiltinNode { } @Specialization(guards = "x.isMatrix()") - protected RDoubleVector crossprodDoubleMatrix(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y) { - int xRows = x.getDimensions()[0]; - int xCols = x.getDimensions()[1]; - return mirror(matMult.doubleMatrixMultiply(x, x, xCols, xRows, xRows, xCols, xRows, 1, 1, xRows, true)); + protected RDoubleVector crossprodDoubleMatrix(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y, + @Cached("create()") GetDimAttributeNode getDimsNode, @Cached("create()") GetDimAttributeNode getResultDimsNode) { + int[] xDims = getDimsNode.getDimensions(x); + int xRows = xDims[0]; + int xCols = xDims[1]; + return mirror(matMult.doubleMatrixMultiply(x, x, xCols, xRows, xRows, xCols, xRows, 1, 1, xRows, true), getResultDimsNode); } @Specialization diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java index be4d0db5ec9a83264b3daeaf3390b780184ef2eb..95cb519bd8e14fe633c8a23426a03118a603379e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java @@ -29,6 +29,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -40,9 +41,11 @@ public abstract class Dim extends RBuiltinNode { @Specialization protected Object dim(RAbstractContainer container, // - @Cached("createBinaryProfile()") ConditionProfile hasDimensionsProfile) { - if (hasDimensionsProfile.profile(container.hasDimensions())) { - return RDataFactory.createIntVector(container.getDimensions(), RDataFactory.COMPLETE_VECTOR); + @Cached("createBinaryProfile()") ConditionProfile hasDimensionsProfile, + @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(container); + if (hasDimensionsProfile.profile(dims != null && dims.length > 0)) { + return RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR); } else { return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java index 43cfb6a97d7bde5e346af117e8b0e2762f640d5d..e31f75656d5eb43a0ca4d37666f818a7de86e739 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java @@ -25,9 +25,11 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; @@ -47,8 +49,8 @@ public abstract class Drop extends RBuiltinNode { private final ConditionProfile noDimNamesProfile = ConditionProfile.createBinaryProfile(); @Specialization - protected RAbstractVector doDrop(RAbstractVector x) { - int[] dims = x.getDimensions(); + protected RAbstractVector doDrop(RAbstractVector x, @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(x); if (nullDimensions.profile(dims == null)) { return x; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java index 984935f3b56ac9def0cdc4c4fcc437aafa1d79a3..13dc1bcad62fb47e61c0beebf0f6e1a5cf7a9f2c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java @@ -28,9 +28,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -74,12 +76,12 @@ public abstract class IsNA extends RBuiltinNode { } @Specialization - protected RLogicalVector isNA(RAbstractIntVector vector) { + protected RLogicalVector isNA(RAbstractIntVector vector, @Cached("create()") GetDimAttributeNode getDimsNode) { byte[] resultVector = new byte[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { resultVector[i] = RRuntime.asLogical(RRuntime.isNA(vector.getDataAt(i))); } - return createResult(resultVector, vector); + return createResult(resultVector, vector, getDimsNode); } @Specialization @@ -88,22 +90,22 @@ public abstract class IsNA extends RBuiltinNode { } @Specialization - protected RLogicalVector isNA(RAbstractDoubleVector vector) { + protected RLogicalVector isNA(RAbstractDoubleVector vector, @Cached("create()") GetDimAttributeNode getDimsNode) { byte[] resultVector = new byte[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { resultVector[i] = RRuntime.asLogical(RRuntime.isNAorNaN(vector.getDataAt(i))); } - return createResult(resultVector, vector); + return createResult(resultVector, vector, getDimsNode); } @Specialization - protected RLogicalVector isNA(RComplexVector vector) { + protected RLogicalVector isNA(RComplexVector vector, @Cached("create()") GetDimAttributeNode getDimsNode) { byte[] resultVector = new byte[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { RComplex complex = vector.getDataAt(i); resultVector[i] = RRuntime.asLogical(RRuntime.isNA(complex)); } - return createResult(resultVector, vector); + return createResult(resultVector, vector, getDimsNode); } @Specialization @@ -112,12 +114,12 @@ public abstract class IsNA extends RBuiltinNode { } @Specialization - protected RLogicalVector isNA(RStringVector vector) { + protected RLogicalVector isNA(RStringVector vector, @Cached("create()") GetDimAttributeNode getDimsNode) { byte[] resultVector = new byte[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { resultVector[i] = RRuntime.asLogical(RRuntime.isNA(vector.getDataAt(i))); } - return createResult(resultVector, vector); + return createResult(resultVector, vector, getDimsNode); } @Specialization @@ -152,12 +154,12 @@ public abstract class IsNA extends RBuiltinNode { } @Specialization - protected RLogicalVector isNA(RLogicalVector vector) { + protected RLogicalVector isNA(RLogicalVector vector, @Cached("create()") GetDimAttributeNode getDimsNode) { byte[] resultVector = new byte[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { resultVector[i] = (RRuntime.isNA(vector.getDataAt(i)) ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE); } - return createResult(resultVector, vector); + return createResult(resultVector, vector, getDimsNode); } @Specialization @@ -171,12 +173,12 @@ public abstract class IsNA extends RBuiltinNode { } @Specialization - protected RLogicalVector isNA(RRawVector vector) { + protected RLogicalVector isNA(RRawVector vector, @Cached("create()") GetDimAttributeNode getDimsNode) { byte[] resultVector = new byte[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { resultVector[i] = RRuntime.LOGICAL_FALSE; } - return createResult(resultVector, vector); + return createResult(resultVector, vector, getDimsNode); } @Specialization @@ -193,8 +195,8 @@ public abstract class IsNA extends RBuiltinNode { return RRuntime.LOGICAL_FALSE; } - private RLogicalVector createResult(byte[] data, RAbstractVector originalVector) { - RLogicalVector result = RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR, originalVector.getDimensions(), originalVector.getNames(attrProfiles)); + private RLogicalVector createResult(byte[] data, RAbstractVector originalVector, GetDimAttributeNode getDimsNode) { + RLogicalVector result = RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR, getDimsNode.getDimensions(originalVector), originalVector.getNames(attrProfiles)); RList dimNames = originalVector.getDimNames(attrProfiles); if (nullDimNamesProfile.profile(dimNames != null)) { result.setDimNames(dimNames); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java index 45b9ae431e3b2dc55480c1af8cf867d546772e07..81003390bcf0aaede7fb48b504a4cb2146a7f844 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java @@ -28,10 +28,12 @@ import java.util.function.Function; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; @@ -96,8 +98,8 @@ public class LaFunctions { private final ConditionProfile hasComplexValues = ConditionProfile.createBinaryProfile(); @Specialization - protected Object doRg(RDoubleVector matrix, boolean onlyValues) { - int[] dims = matrix.getDimensions(); + protected Object doRg(RDoubleVector matrix, boolean onlyValues, @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(matrix); // copy array component of matrix as Lapack destroys it int n = dims[0]; double[] a = matrix.getDataCopy(); @@ -190,8 +192,8 @@ public class LaFunctions { @RBuiltin(name = "La_rs", kind = INTERNAL, parameterNames = {"matrix", "onlyValues"}, behavior = PURE) public abstract static class Rs extends RsgAdapter { @Specialization - protected Object doRs(RDoubleVector matrix, boolean onlyValues) { - int[] dims = matrix.getDimensions(); + protected Object doRs(RDoubleVector matrix, boolean onlyValues, @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(matrix); int n = dims[0]; char jobv = onlyValues ? 'N' : 'V'; char uplo = 'L'; @@ -257,13 +259,13 @@ public class LaFunctions { } @Specialization - protected RList doQr(RAbstractDoubleVector aIn) { + protected RList doQr(RAbstractDoubleVector aIn, @Cached("create()") GetDimAttributeNode getDimsNode) { // This implementation is sufficient for B25 matcal-5. if (!(aIn instanceof RDoubleVector)) { RError.nyi(this, "non-real vectors not supported (yet)"); } RDoubleVector daIn = (RDoubleVector) aIn; - int[] dims = daIn.getDimensions(); + int[] dims = getDimsNode.getDimensions(daIn); // copy array component of matrix as Lapack destroys it int n = dims[0]; int m = dims[1]; @@ -312,7 +314,9 @@ public class LaFunctions { } @Specialization - protected RDoubleVector doQrCoefReal(RList qIn, RDoubleVector bIn) { + protected RDoubleVector doQrCoefReal(RList qIn, RDoubleVector bIn, + @Cached("create()") GetDimAttributeNode getBDimsNode, + @Cached("create()") GetDimAttributeNode getQDimsNode) { // If bIn was coerced this extra copy is unnecessary RDoubleVector b = (RDoubleVector) bIn.copy(); @@ -321,8 +325,8 @@ public class LaFunctions { RDoubleVector tau = (RDoubleVector) qIn.getDataAt(2); int k = tau.getLength(); - int[] bDims = bIn.getDimensions(); - int[] qrDims = qr.getDimensions(); + int[] bDims = getBDimsNode.getDimensions(bIn); + int[] qrDims = getQDimsNode.getDimensions(qr); int n = qrDims[0]; if (bDims[0] != n) { errorProfile.enter(); @@ -387,9 +391,10 @@ public class LaFunctions { } @Specialization - protected RList doDetGeReal(RDoubleVector aIn, boolean useLog) { + protected RList doDetGeReal(RDoubleVector aIn, boolean useLog, + @Cached("create()") GetDimAttributeNode getDimsNode) { RDoubleVector a = (RDoubleVector) aIn.copy(); - int[] aDims = aIn.getDimensions(); + int[] aDims = getDimsNode.getDimensions(aIn); int n = aDims[0]; int[] ipiv = new int[n]; double modulus = 0; @@ -475,9 +480,10 @@ public class LaFunctions { } @Specialization - protected RDoubleVector doDetGeReal(RDoubleVector aIn, boolean piv, double tol) { + protected RDoubleVector doDetGeReal(RDoubleVector aIn, boolean piv, double tol, + @Cached("create()") GetDimAttributeNode getDimsNode) { RDoubleVector a = (RDoubleVector) aIn.copy(); - int[] aDims = aIn.getDimensions(); + int[] aDims = getDimsNode.getDimensions(aIn); int n = aDims[0]; int m = aDims[1]; double[] aData = a.getDataWithoutCopying(); @@ -546,8 +552,10 @@ public class LaFunctions { } @Specialization - protected RDoubleVector laSolve(RAbstractVector a, RDoubleVector bin, double tol) { - int[] aDims = a.getDimensions(); + protected RDoubleVector laSolve(RAbstractVector a, RDoubleVector bin, double tol, + @Cached("create()") GetDimAttributeNode getADimsNode, + @Cached("create()") GetDimAttributeNode getBinDimsNode) { + int[] aDims = getADimsNode.getDimensions(a); int n = aDims[0]; if (n == 0) { throw RError.error(this, RError.Message.GENERIC, "'a' is 0-diml"); @@ -561,7 +569,7 @@ public class LaFunctions { double[] bData; RDoubleVector b; if (bin.isMatrix()) { - int[] bDims = bin.getDimensions(); + int[] bDims = getBinDimsNode.getDimensions(bin); p = bDims[1]; if (p == 0) { throw RError.error(this, RError.Message.GENERIC, "no right-hand side in 'b'"); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java index 8532659c5be0afa030c0bac1a55a0e52f9406904..d408b9a4d0e03fbc59dabe28e63bc21d273ff854 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.UnaryArithmeticBuiltinNode; @@ -80,7 +81,8 @@ public class LogFunctions { @Specialization protected RDoubleVector log(RAbstractIntVector vector, double base, @Cached("create()") CopyOfRegAttributesNode copyAttrsNode, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") RAttributeProfiles attrProfiles, + @Cached("create()") GetDimAttributeNode getDimsNode) { double[] resultVector = new double[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { int inputValue = vector.getDataAt(i); @@ -90,13 +92,14 @@ public class LogFunctions { } resultVector[i] = result; } - return createResult(vector, resultVector, base, copyAttrsNode, attrProfiles); + return createResult(vector, resultVector, base, copyAttrsNode, attrProfiles, getDimsNode); } @Specialization protected RDoubleVector log(RAbstractDoubleVector vector, double base, @Cached("create()") CopyOfRegAttributesNode copyAttrsNode, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") RAttributeProfiles attrProfiles, + @Cached("create()") GetDimAttributeNode getDimsNode) { double[] doubleVector = new double[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { double value = vector.getDataAt(i); @@ -105,7 +108,7 @@ public class LogFunctions { } doubleVector[i] = value; } - return createResult(vector, doubleVector, base, copyAttrsNode, attrProfiles); + return createResult(vector, doubleVector, base, copyAttrsNode, attrProfiles, getDimsNode); } private double logb(double x, double base) { @@ -121,8 +124,9 @@ public class LogFunctions { return Math.log(x) / Math.log(base); } - private static RDoubleVector createResult(RAbstractVector source, double[] resultData, double base, CopyOfRegAttributesNode copyAttrsNode, RAttributeProfiles attrProfiles) { - RDoubleVector result = RDataFactory.createDoubleVector(resultData, source.isComplete() && !RRuntime.isNA(base), source.getDimensions(), source.getNames(attrProfiles)); + private static RDoubleVector createResult(RAbstractVector source, double[] resultData, double base, CopyOfRegAttributesNode copyAttrsNode, RAttributeProfiles attrProfiles, + GetDimAttributeNode getDimsNode) { + RDoubleVector result = RDataFactory.createDoubleVector(resultData, source.isComplete() && !RRuntime.isNA(base), getDimsNode.getDimensions(source), source.getNames(attrProfiles)); copyAttrsNode.execute(source, result); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java index c7a5ea146e47895dba8a926822b61db083c8c696..359655123762e0281c039706e26d6481b4346e28 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java @@ -34,6 +34,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.binary.BinaryMapArithmeticFunctionNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -75,6 +76,9 @@ public abstract class MatMult extends RBuiltinNode { private final RAttributeProfiles bDimAttributeProfile = RAttributeProfiles.create(); private final ConditionProfile noDimAttributes = ConditionProfile.createBinaryProfile(); + @Child protected GetDimAttributeNode getADimsNode = GetDimAttributeNode.create(); + @Child protected GetDimAttributeNode getBDimsNode = GetDimAttributeNode.create(); + protected abstract Object executeObject(Object a, Object b); private final NACheck na; @@ -88,24 +92,26 @@ public abstract class MatMult extends RBuiltinNode { return MatMultNodeGen.create(true); } - @Specialization(guards = "bothZeroDim(a, b)") + @Specialization(guards = "bothZeroDim(a, b, getADimsNode, getBDimsNode)") protected RDoubleVector both0Dim(RAbstractDoubleVector a, RAbstractDoubleVector b) { - int r = b.getDimensions()[1]; - int c = a.getDimensions()[0]; + int r = getBDimsNode.getDimensions(b)[1]; + int c = getADimsNode.getDimensions(a)[0]; RDoubleVector result = RDataFactory.createDoubleVector(r * c); result.setDimensions(new int[]{r, c}); return result; } - @Specialization(guards = "hasZeroDim(a)") + @Specialization(guards = "hasZeroDim(a, getADimsNode)") protected RAbstractVector left0Dim(RAbstractVector a, RAbstractVector b) { - int[] dim = a.getDimensions()[0] == 0 ? new int[]{0, b.getDimensions()[1]} : new int[]{b.getDimensions()[0], 0}; + int[] aDim = getADimsNode.getDimensions(a); + int[] dim = aDim[0] == 0 ? new int[]{0, getBDimsNode.getDimensions(b)[1]} : new int[]{getBDimsNode.getDimensions(b)[0], 0}; return a.copyWithNewDimensions(dim); } - @Specialization(guards = "hasZeroDim(b)") + @Specialization(guards = "hasZeroDim(b, getBDimsNode)") protected RAbstractVector right0Dim(RAbstractVector a, RAbstractVector b) { - int[] dim = b.getDimensions()[0] == 0 ? new int[]{0, a.getDimensions()[1]} : new int[]{a.getDimensions()[0], 0}; + int[] bDim = getBDimsNode.getDimensions(b); + int[] dim = bDim[0] == 0 ? new int[]{0, getADimsNode.getDimensions(a)[1]} : new int[]{getADimsNode.getDimensions(a)[0], 0}; return b.copyWithNewDimensions(dim); } @@ -268,12 +274,13 @@ public abstract class MatMult extends RBuiltinNode { @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - int[] aDimensions = a.getDimensions(); - int[] bDimensions = b.getDimensions(); + int[] aDimensions = getADimsNode.getDimensions(a); + int[] bDimensions = getBDimsNode.getDimensions(b); return doubleMatrixMultiply(a, b, aDimensions[0], aDimensions[1], bDimensions[0], bDimensions[1]); } else { - int aRows = a.getDimensions()[0]; - int aCols = a.getDimensions()[1]; + int[] aDim = getADimsNode.getDimensions(a); + int aRows = aDim[0]; + int aCols = aDim[1]; int bRows; int bCols; if (lengthEquals.profile(aCols == b.getLength())) { @@ -287,8 +294,9 @@ public abstract class MatMult extends RBuiltinNode { } } else { if (bIsMatrix.profile(b.isMatrix())) { - int bRows = b.getDimensions()[0]; - int bCols = b.getDimensions()[1]; + int[] bDim = getBDimsNode.getDimensions(b); + int bRows = bDim[0]; + int bCols = bDim[1]; int aRows; int aCols; if (lengthEquals.profile(bRows == a.getLength())) { @@ -328,14 +336,16 @@ public abstract class MatMult extends RBuiltinNode { @Cached("createBinaryProfile()") ConditionProfile bIsMatrix) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - final int aCols = a.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + int[] bDim = getBDimsNode.getDimensions(b); + final int aCols = aDim[1]; + final int bRows = bDim[0]; if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); } - final int aRows = a.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + final int aRows = aDim[0]; + final int bCols = bDim[1]; double[] result = new double[(aRows * bCols) << 1]; na.enable(a); na.enable(b); @@ -353,8 +363,9 @@ public abstract class MatMult extends RBuiltinNode { } return RDataFactory.createComplexVector(result, na.neverSeenNA(), new int[]{aRows, bCols}); } else { - final int aCols = a.getDimensions()[1]; - final int aRows = a.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + final int aCols = aDim[1]; + final int aRows = aDim[0]; if (aCols != 1 && aCols != b.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -388,8 +399,9 @@ public abstract class MatMult extends RBuiltinNode { } } else { if (bIsMatrix.profile(b.isMatrix())) { - final int bRows = b.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + int[] bDim = getBDimsNode.getDimensions(b); + final int bRows = bDim[0]; + final int bCols = bDim[1]; if (bRows != 1 && bRows != a.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -445,14 +457,16 @@ public abstract class MatMult extends RBuiltinNode { @Cached("createBinaryProfile()") ConditionProfile bIsMatrix) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - final int aCols = a.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + int[] bDim = getBDimsNode.getDimensions(b); + final int aCols = aDim[1]; + final int bRows = bDim[0]; if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); } - final int aRows = a.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + final int aRows = aDim[0]; + final int bCols = bDim[1]; int[] result = new int[aRows * bCols]; na.enable(a); na.enable(b); @@ -468,8 +482,9 @@ public abstract class MatMult extends RBuiltinNode { } return RDataFactory.createIntVector(result, na.neverSeenNA(), new int[]{aRows, bCols}); } else { - final int aCols = a.getDimensions()[1]; - final int aRows = a.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + final int aCols = aDim[1]; + final int aRows = aDim[0]; if (aCols != 1 && aCols != b.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -500,9 +515,10 @@ public abstract class MatMult extends RBuiltinNode { } } } else { + int[] bDim = getBDimsNode.getDimensions(b); if (bIsMatrix.profile(b.isMatrix())) { - final int bCols = b.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + final int bCols = bDim[1]; + final int bRows = bDim[0]; if (bRows != 1 && bRows != a.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -660,15 +676,16 @@ public abstract class MatMult extends RBuiltinNode { // guards - protected static boolean bothZeroDim(RAbstractVector a, RAbstractVector b) { - return hasZeroDim(a) && hasZeroDim(b); + protected static boolean bothZeroDim(RAbstractVector a, RAbstractVector b, GetDimAttributeNode getADimsNode, GetDimAttributeNode getBDimsNode) { + return hasZeroDim(a, getADimsNode) && hasZeroDim(b, getBDimsNode); } - protected static boolean hasZeroDim(RAbstractVector v) { - if (!v.hasDimensions()) { + protected static boolean hasZeroDim(RAbstractVector v, GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(v); + if (dims == null || dims.length == 0) { return false; } - for (int d : v.getDimensions()) { + for (int d : dims) { if (d == 0) { return true; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java index 1f0a0a0deb44b0cb65f736923ed39858c624ab8f..cb00025437bdadb08565c25e66bc32b2503a204a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java @@ -33,6 +33,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; @@ -68,7 +69,8 @@ public abstract class NChar extends RBuiltinNode { protected RIntVector ncharInt(RAbstractIntVector vector, String type, boolean allowNA, boolean keepNA, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @Cached("create()") RAttributeProfiles attrProfiles, - @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode) { int len = vector.getLength(); int[] result = new int[len]; loopProfile.profileCounted(len); @@ -80,7 +82,7 @@ public abstract class NChar extends RBuiltinNode { result[i] = (int) (Math.log10(x) + 1); // not the fastest one } } - RIntVector resultVector = RDataFactory.createIntVector(result, true, vector.getDimensions(), vector.getNames(attrProfiles)); + RIntVector resultVector = RDataFactory.createIntVector(result, true, getDimNode.getDimensions(vector), vector.getNames(attrProfiles)); RList dimNames = vector.getDimNames(attrProfiles); if (nullDimNamesProfile.profile(dimNames != null)) { resultVector.setDimNames(dimNames); @@ -93,14 +95,15 @@ public abstract class NChar extends RBuiltinNode { protected RIntVector nchar(RAbstractStringVector vector, String type, boolean allowNA, boolean keepNA, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @Cached("create()") RAttributeProfiles attrProfiles, - @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode) { int len = vector.getLength(); int[] result = new int[len]; loopProfile.profileCounted(len); for (int i = 0; loopProfile.inject(i < len); i++) { result[i] = vector.getDataAt(i).length(); } - RIntVector resultVector = RDataFactory.createIntVector(result, true, vector.getDimensions(), vector.getNames(attrProfiles)); + RIntVector resultVector = RDataFactory.createIntVector(result, true, getDimNode.getDimensions(vector), vector.getNames(attrProfiles)); RList dimNames = vector.getDimNames(attrProfiles); if (nullDimNamesProfile.profile(dimNames != null)) { resultVector.setDimNames(dimNames); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java index 0313cad4b98aec16177b01b33fe7021ffa3fa6ee..443a5505f5bc37089c8b11fb7562b3be52736cf9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java @@ -30,9 +30,11 @@ import java.util.function.BiFunction; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNodeGen; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; @@ -55,6 +57,7 @@ public abstract class ToLowerOrUpper { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Child private CopyOfRegAttributesNode copyAttributes = CopyOfRegAttributesNodeGen.create(); + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); private StringMapNode() { // nothing to do @@ -82,7 +85,7 @@ public abstract class ToLowerOrUpper { String value = vector.getDataAt(i); stringVector[i] = elementFunction(value, i, function); } - RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), vector.getDimensions(), vector.getNames(attrProfiles)); + RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), getDimNode.getDimensions(vector), vector.getNames(attrProfiles)); copyAttributes.execute(vector, result); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java index b5ee7967ce49f2b74af6722eca32380187520043..ace3e951b770935861cfca0502a8f5fcaeac013b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; @@ -116,9 +117,10 @@ public abstract class UpdateDimNames extends RBuiltinNode { @Specialization(guards = "list.getLength() > 0") protected RAbstractContainer updateDimnames(RAbstractContainer container, RList list, // - @Cached("createDimNames()") SetFixedAttributeNode attrSetter) { + @Cached("createDimNames()") SetFixedAttributeNode attrSetter, + @Cached("create()") GetDimAttributeNode getDimNode) { RAbstractContainer result = (RAbstractContainer) container.getNonShared(); - setDimNames(result, convertToListOfStrings(list), attrSetter); + setDimNames(result, convertToListOfStrings(list), attrSetter, getDimNode); return result; } @@ -128,11 +130,11 @@ public abstract class UpdateDimNames extends RBuiltinNode { throw RError.error(this, RError.Message.DIMNAMES_LIST); } - private void setDimNames(RAbstractContainer container, RList newDimNames, SetFixedAttributeNode attrSetter) { + private void setDimNames(RAbstractContainer container, RList newDimNames, SetFixedAttributeNode attrSetter, GetDimAttributeNode getDimNode) { assert newDimNames != null; if (isRVectorProfile.profile(container instanceof RVector)) { RVector<?> vector = (RVector<?>) container; - int[] dimensions = vector.getDimensions(); + int[] dimensions = getDimNode.getDimensions(vector); if (dimensions == null) { CompilerDirectives.transferToInterpreter(); throw RError.error(this, RError.Message.DIMNAMES_NONARRAY); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java index 7c9ae20b0b01c46ebfc2fb1f4fe44946c839c083..e63b42dd1195018bf6b83324ff0ca72ef2dcdfb1 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java @@ -11,6 +11,7 @@ */ package com.oracle.truffle.r.nodes.builtin.base.foreign; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -29,6 +30,8 @@ public final class Dqrdc2 extends RExternalBuiltinNode { private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE; private static final RStringVector DQRDC2_NAMES = RDataFactory.createStringVector(new String[]{"qr", E, E, E, E, "rank", "qraux", "pivot", E}, RDataFactory.COMPLETE_VECTOR); + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); + @Override public RList call(RArgsValuesAndNames args) { Object[] argValues = args.getArguments(); @@ -49,7 +52,7 @@ public final class Dqrdc2 extends RExternalBuiltinNode { rApplRFFINode.dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.materialize().getDataCopy()); // @formatter:off Object[] data = new Object[]{ - RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, xVec.getDimensions()), + RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, getDimNode.getDimensions(xVec)), argValues[1], argValues[2], argValues[3], argValues[4], RDataFactory.createIntVector(rank, RDataFactory.COMPLETE_VECTOR), RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR), diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java index 31db4963325002d4c9ddb1db5826bcefc7247f2a..b4bf5517d216c83e638f04f7e139142fa7278a16 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java @@ -11,8 +11,10 @@ */ package com.oracle.truffle.r.nodes.builtin.base.foreign; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; @@ -36,15 +38,16 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { // TODO: handle more argument types (this is sufficient to run the b25 benchmarks) @Specialization - public Object execute(RAbstractComplexVector zVec, boolean inverse) { + public Object execute(RAbstractComplexVector zVec, boolean inverse, @Cached("create()") GetDimAttributeNode getDimNode) { double[] z = zVec.materialize().getDataTemp(); int inv = inverse ? 2 : -2; + int[] d = getDimNode.getDimensions(zVec); @SuppressWarnings("unused") int retCode = 7; if (zVecLgt1.profile(zVec.getLength() > 1)) { int[] maxf = new int[1]; int[] maxp = new int[1]; - if (noDims.profile(zVec.getDimensions() == null)) { + if (noDims.profile(d == null)) { int n = zVec.getLength(); fftNode.executeFactor(n, maxf, maxp); if (maxf[0] == 0) { @@ -57,7 +60,6 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { } else { int maxmaxf = 1; int maxmaxp = 1; - int[] d = zVec.getDimensions(); int ndims = d.length; /* do whole loop just for error checking and maxmax[fp] .. */ for (int i = 0; i < ndims; i++) { @@ -91,6 +93,6 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { } } } - return RDataFactory.createComplexVector(z, zVec.isComplete(), zVec.getDimensions()); + return RDataFactory.createComplexVector(z, zVec.isComplete(), d); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java index 2622dfc83ebb23d9920416d187264533e4ce06fe..ddd61957c7c5e09b7df428161eff08cd00e3ace4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java @@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.access.vector; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; @@ -60,6 +61,8 @@ abstract class CachedVectorNode extends RBaseNode { // if this is non-null, the node needs to throw the error whenever it is executed @CompilationFinal protected Runnable error; + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); + CachedVectorNode(ElementAccessMode mode, RTypedValue vector, Object[] positions, boolean recursive) { this.mode = mode; this.vectorType = vector.getRType(); @@ -151,14 +154,13 @@ abstract class CachedVectorNode extends RBaseNode { } } - @SuppressWarnings("static-method") protected final int[] loadVectorDimensions(RAbstractContainer vector) { // N.B. (stepan) this method used to be instance method and have special handling for // RDataFrame, which was removed and any test case, which would require this special // handling was not found (see TestBuiltin_extract_dataframe for tests used and further // explanation). This method and note will remain here for a while in case this behavior // crops up somewhere - return vector.getDimensions(); + return getDimNode.getDimensions(vector); } public ElementAccessMode getMode() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java index 5ec428e5feefa3341125319e430de02631d25336..9dffa7e5111fdd7459b8c5f77352b2daa85eed54 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.vector.PositionCheckNodeFactory.Mat2indsubNodeGen; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.control.RLengthNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -110,6 +111,8 @@ abstract class PositionCheckNode extends Node { } @Child private Mat2indsubNode mat2indsub; + @Child private GetDimAttributeNode getVectorDimsNode; + @Child private GetDimAttributeNode getVectorPosDimsNode; public final Object execute(PositionProfile profile, RAbstractContainer vector, int[] vectorDimensions, int vectorLength, Object position) { Object castPosition = castNode.execute(positionClass.cast(position)); @@ -124,12 +127,20 @@ abstract class PositionCheckNode extends Node { } if (mode.isSubset() && numDimensions == 1) { - int[] vectorDim = vector.getDimensions(); + if (getVectorDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getVectorDimsNode = insert(GetDimAttributeNode.create()); + } + int[] vectorDim = getVectorDimsNode.getDimensions(vector); if (nullDimensionsProfile.profile(vectorDim != null) && vectorDim.length == 2) { if (vector instanceof RAbstractVector && ((RAbstractVector) vector).isArray()) { if (castPosition instanceof RAbstractVector) { + if (getVectorPosDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getVectorPosDimsNode = insert(GetDimAttributeNode.create()); + } RAbstractVector vectorPosition = (RAbstractVector) castPosition; - int[] posDim = vectorPosition.getDimensions(); + int[] posDim = getVectorPosDimsNode.getDimensions(vectorPosition); if (posDim != null && posDim.length == 2 && posDim[1] == vectorDim.length) { if (castPosition instanceof RAbstractIntVector || castPosition instanceof RAbstractDoubleVector) { if (mat2indsub == null) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java index 31b4442825912ce16498bf016335ff54bb7eec2d..088dcd2711c487ae188cc1119e8d3236ec366253 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java @@ -28,6 +28,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -50,6 +51,8 @@ public abstract class CopyAttributesNode extends RBaseNode { protected final RAttributeProfiles attrLeftProfiles = RAttributeProfiles.create(); protected final RAttributeProfiles attrRightProfiles = RAttributeProfiles.create(); + @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + protected CopyAttributesNode(boolean copyAllAttributes) { this.copyAllAttributes = copyAllAttributes; } @@ -61,7 +64,7 @@ public abstract class CopyAttributesNode extends RBaseNode { public abstract RAbstractVector execute(RAbstractVector target, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength); protected boolean containsMetadata(RAbstractVector vector, RAttributeProfiles attrProfiles) { - return vector instanceof RVector && vector.hasDimensions() || (copyAllAttributes && vector.getAttributes() != null) || vector.getDimNames(attrProfiles) != null || + return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || vector.getDimNames(attrProfiles) != null || vector.getNames(attrProfiles) != null; } @@ -124,7 +127,9 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("create()") BranchProfile noDimensions, @Cached("createBinaryProfile()") ConditionProfile hasNamesLeft, @Cached("createBinaryProfile()") ConditionProfile hasNamesRight, - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode) { if (LOG) { log("copyAttributes: =="); countEquals++; @@ -139,9 +144,9 @@ public abstract class CopyAttributesNode extends RBaseNode { } } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null) { - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null) { noDimensions.enter(); DynamicObject attributes = result.getAttributes(); @@ -206,7 +211,9 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createBinaryProfile()") ConditionProfile hasNames, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode) { if (LOG) { log("copyAttributes: <"); countSmaller++; @@ -217,10 +224,10 @@ public abstract class CopyAttributesNode extends RBaseNode { copyOfReg.execute(right, result); } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null || (newDimensions.length == 2 && newDimensions[0] == 1 && newDimensions[1] == 1)) { // 1-element matrix should be treated as 1-element vector - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null || (newDimensions.length == 2 && newDimensions[0] == 1 && newDimensions[1] == 1)) { // 1-element matrix should be treated as 1-element vector noDimensions.enter(); @@ -260,7 +267,9 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createBinaryProfile()") ConditionProfile hasNames, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode) { if (LOG) { log("copyAttributes: >"); countLarger++; @@ -269,9 +278,9 @@ public abstract class CopyAttributesNode extends RBaseNode { if (copyAllAttributes && result != left) { copyOfReg.execute(left, result); } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null) { - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null) { noDimensions.enter(); if (left != result) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java index 24910e4e0a6b6326c8df97dd4f00a2813aa208cf..f4e6a5bd94306f9f3ebda9a665631a5a737c25cb 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; @@ -55,15 +56,15 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { return GetFixedAttributeNode.create(RRuntime.NAMES_ATTR_KEY); } - public static GetFixedAttributeNode createDim() { - return GetFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY); + public static GetDimAttributeNode createDim() { + return GetDimAttributeNode.create(); } public static GetFixedAttributeNode createClass() { return GetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); } - public abstract Object execute(Object attrs); + public abstract Object execute(Object attr); protected boolean hasProperty(Shape shape) { return shape.hasProperty(name); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java new file mode 100644 index 0000000000000000000000000000000000000000..fa44bfdcc6bb57d5fe39759889ac9fce390411f4 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, 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.r.nodes.attributes; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.object.Location; +import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributable; + +/** + * This node is responsible for determining the existence of the predefined (fixed) attribute. It + * accepts both {@link DynamicObject} and {@link RAttributable} instances as the first argument. If + * the first argument is {@link RAttributable} and its attributes are initialized, the recursive + * instance of this class is used to determine the existence from the attributes. + */ +public abstract class HasFixedAttributeNode extends FixedAttributeAccessNode { + + @Child private HasFixedAttributeNode recursive; + + protected HasFixedAttributeNode(String name) { + super(name); + } + + public static HasFixedAttributeNode create(String name) { + return HasFixedAttributeNodeGen.create(name); + } + + public static HasFixedAttributeNode createDim() { + return HasFixedAttributeNodeGen.create(RRuntime.DIM_ATTR_KEY); + } + + public abstract boolean execute(Object attr); + + protected boolean hasProperty(Shape shape) { + return shape.hasProperty(name); + } + + @Specialization(limit = "3", // + guards = {"shapeCheck(shape, attrs)"}, // + assumptions = {"shape.getValidAssumption()"}) + @SuppressWarnings("unused") + protected boolean hasAttrCached(DynamicObject attrs, + @Cached("lookupShape(attrs)") Shape shape, + @Cached("lookupLocation(shape, name)") Location location) { + return location != null; + } + + @Specialization(contains = "hasAttrCached") + @TruffleBoundary + protected boolean hasAttrFallback(DynamicObject attrs) { + return attrs.containsKey(name); + } + + @Specialization + protected boolean hasAttrFromAttributable(RAttributable x, + @Cached("create()") BranchProfile attrNullProfile) { + DynamicObject attributes = x.getAttributes(); + if (attributes == null) { + attrNullProfile.enter(); + return false; + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + + return recursive.execute(attributes); + } + +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java index b50ffbabe5201a036732c5f9b3e2c786c9ad7278..95f995a5481e993130e435e63cb367d8c5df0a15 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java @@ -94,6 +94,25 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { } } + @Specialization(limit = "3", // + guards = {"shapeCheck(oldShape, attrs)", "oldLocation == null"}, // + assumptions = {"oldShape.getValidAssumption()", "newShape.getValidAssumption()"}) + protected static void setNewAttrCached(DynamicObject attrs, Object value, + @Cached("lookupShape(attrs)") Shape oldShape, + @SuppressWarnings("unused") @Cached("lookupLocation(oldShape, name)") Location oldLocation, + @Cached("defineProperty(oldShape, name, value)") Shape newShape, + @Cached("lookupLocation(newShape, name)") Location newLocation) { + try { + newLocation.set(attrs, value, oldShape, newShape); + } catch (IncompatibleLocationException ex) { + RInternalError.reportError(ex); + } + } + + protected static Shape defineProperty(Shape oldShape, Object name, Object value) { + return oldShape.defineProperty(name, value, 0); + } + @Specialization(contains = "setAttrCached") @TruffleBoundary protected void setFallback(DynamicObject attrs, Object value) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java index 3fe2f477a3a9bfa22e850272a8af3375d65ee3d4..1670540a7913dd1d94d54460cd34cc30230631cf 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -29,10 +29,12 @@ import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.GetDimAttributeNodeGen; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; @@ -215,7 +217,8 @@ public final class SpecialAttributesFunctions { @Specialization protected void setOneDimInContainer(RAbstractContainer x, Integer dim, @Cached("createClassProfile()") ValueProfile contClassProfile) { RAbstractContainer xProfiled = contClassProfile.profile(x); - xProfiled.setDimensions(new int[]{dim}); + // xProfiled.setDimensions(new int[]{dim}); + xProfiled.setAttr(RRuntime.DIM_ATTR_KEY, new int[]{dim}); } @Specialization @@ -226,6 +229,60 @@ public final class SpecialAttributesFunctions { } + public abstract static class GetDimAttributeNode extends GetFixedAttributeNode { + + private final ConditionProfile nullDimsProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile nonEmptyDimsProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile twoDimsOrMoreProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile isContainerProfile = ConditionProfile.createBinaryProfile(); + + protected GetDimAttributeNode() { + super(RRuntime.DIM_ATTR_KEY); + } + + public static GetDimAttributeNode create() { + return GetDimAttributeNodeGen.create(); + } + + public final int[] getDimensions(Object x) { + RIntVector dims = (RIntVector) execute(x); + return nullDimsProfile.profile(dims == null) ? null : dims.getInternalStore(); + } + + public int nrows(Object x) { + if (isContainerProfile.profile(x instanceof RAbstractContainer)) { + RAbstractContainer xa = (RAbstractContainer) x; + int[] dims = getDimensions(xa); + if (nonEmptyDimsProfile.profile(dims != null && dims.length > 0)) { + return dims[0]; + } else { + return xa.getLength(); + } + } else { + throw RError.error(RError.SHOW_CALLER2, RError.Message.OBJECT_NOT_MATRIX); + } + } + + public int ncols(Object x) { + if (isContainerProfile.profile(x instanceof RAbstractContainer)) { + RAbstractContainer xa = (RAbstractContainer) x; + int[] dims = getDimensions(xa); + if (nonEmptyDimsProfile.profile(dims != null && dims.length > 0)) { + if (twoDimsOrMoreProfile.profile(dims.length >= 2)) { + return dims[1]; + } else { + return 1; + } + } else { + return 1; + } + } else { + throw RError.error(RError.SHOW_CALLER2, RError.Message.OBJECT_NOT_MATRIX); + } + } + + } + public abstract static class SetDimNamesAttributeNode extends SetSpecialAttributeNode { public static SetDimNamesAttributeNode create() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java index fe2840463b46335b24eabe2075bab1007f50e33f..f695e4d9ee8677e1381cd9fed2a70f505e2fda3f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java @@ -24,8 +24,10 @@ package com.oracle.truffle.r.nodes.attributes; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -49,6 +51,8 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { protected final RAttributeProfiles attrSourceProfiles = RAttributeProfiles.create(); + @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + protected UnaryCopyAttributesNode(boolean copyAllAttributes) { this.copyAllAttributes = copyAllAttributes; } @@ -60,7 +64,7 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { public abstract RAbstractVector execute(RAbstractVector target, RAbstractVector left); protected boolean containsMetadata(RAbstractVector vector, RAttributeProfiles attrProfiles) { - return vector instanceof RVector && vector.hasDimensions() || (copyAllAttributes && vector.getAttributes() != null) || vector.getNames(attrProfiles) != null || + return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || vector.getNames(attrProfiles) != null || vector.getDimNames(attrProfiles) != null; } @@ -87,14 +91,15 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { @Cached("createDimNames()") SetFixedAttributeNode putDimNames, // @Cached("createBinaryProfile()") ConditionProfile noDimensions, // @Cached("createBinaryProfile()") ConditionProfile hasNamesSource, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getDimsNode) { RVector<?> result = target.materialize(); if (copyAllAttributes) { copyOfReg.execute(source, result); } - int[] newDimensions = source.getDimensions(); + int[] newDimensions = getDimsNode.getDimensions(source); if (noDimensions.profile(newDimensions == null)) { DynamicObject attributes = result.getAttributes(); if (attributes != null) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java index bb33f7c87e692865c85bb056adbd3b6cb32987b2..532ba2036fc54681ce27bf60de25cc590429e5cd 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java @@ -25,10 +25,13 @@ package com.oracle.truffle.r.nodes.primitive; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNodeGen; +import com.oracle.truffle.r.nodes.attributes.HasFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNodeFactory.VectorMapBinaryInternalNodeGen; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -63,6 +66,10 @@ public final class BinaryMapNode extends RBaseNode { @Child private VectorMapBinaryInternalNode vectorNode; @Child private BinaryMapFunctionNode function; @Child private CopyAttributesNode copyAttributes; + @Child private GetDimAttributeNode getLeftDimNode = GetDimAttributeNode.create(); + @Child private GetDimAttributeNode getRightDimNode = GetDimAttributeNode.create(); + @Child protected HasFixedAttributeNode hasLeftDimNode = HasFixedAttributeNode.createDim(); + @Child protected HasFixedAttributeNode hasRightDimNode = HasFixedAttributeNode.createDim(); // profiles private final Class<? extends RAbstractVector> leftClass; @@ -142,9 +149,9 @@ public final class BinaryMapNode extends RBaseNode { } } - private static boolean differentDimensions(RAbstractVector left, RAbstractVector right) { - int[] leftDimensions = left.getDimensions(); - int[] rightDimensions = right.getDimensions(); + private boolean differentDimensions(RAbstractVector left, RAbstractVector right) { + int[] leftDimensions = getLeftDimNode.getDimensions(left); + int[] rightDimensions = getRightDimNode.getDimensions(right); int leftLength = leftDimensions.length; int rightLength = rightDimensions.length; if (leftLength != rightLength) { @@ -227,7 +234,7 @@ public final class BinaryMapNode extends RBaseNode { } private Object applyVectorized(RAbstractVector left, RAbstractVector leftCast, int leftLength, RAbstractVector right, RAbstractVector rightCast, int rightLength) { - if (mayContainMetadata && (dimensionsProfile.profile(left.hasDimensions() && right.hasDimensions()))) { + if (mayContainMetadata && (dimensionsProfile.profile(hasLeftDimNode.execute(left) && hasRightDimNode.execute(right)))) { if (differentDimensions(left, right)) { CompilerDirectives.transferToInterpreter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARRAYS); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java index bb49fe7f101598457022b1d5854d3b0901d8de16..df9aea109de8925484edd31bcfc2ecb3b21b9746 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java @@ -22,12 +22,16 @@ */ package com.oracle.truffle.r.nodes.primitive; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.HasFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.primitive.UnaryMapNodeFactory.MapUnaryVectorInternalNodeGen; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RInternalError; @@ -50,6 +54,7 @@ public final class UnaryMapNode extends RBaseNode { @Child private UnaryMapFunctionNode scalarNode; @Child private MapUnaryVectorInternalNode vectorNode; + @Child private GetDimAttributeNode getDimNode; // profiles private final Class<? extends RAbstractVector> operandClass; @@ -170,7 +175,13 @@ public final class UnaryMapNode extends RBaseNode { if (containsMetadata(operand) && operand != target) { hasAttributesProfile.enter(); result = result.materialize(); - copyAttributesInternal((RVector<?>) result, operand); + + if (getDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNode = insert(GetDimAttributeNode.create()); + } + + copyAttributesInternal((RVector<?>) result, operand, getDimNode.getDimensions(operand)); } return result; } @@ -178,16 +189,18 @@ public final class UnaryMapNode extends RBaseNode { private final ConditionProfile hasDimensionsProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile hasNamesProfile = ConditionProfile.createBinaryProfile(); + @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + private boolean containsMetadata(RAbstractVector vector) { return vector instanceof RVector && - (hasDimensionsProfile.profile(vector.hasDimensions()) || vector.getAttributes() != null || hasNamesProfile.profile(vector.getNames(attrProfiles) != null) || + (hasDimensionsProfile.profile(hasDimNode.execute(vector)) || vector.getAttributes() != null || hasNamesProfile.profile(vector.getNames(attrProfiles) != null) || vector.getDimNames(attrProfiles) != null); } @TruffleBoundary - private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource) { + private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource, int[] dims) { result.copyRegAttributesFrom(attributeSource); - result.setDimensions(attributeSource.getDimensions()); + result.setDimensions(dims); result.copyNamesFrom(attrProfiles, attributeSource); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java index e9b89627095e03cd06329d0eee7a0082a7ea2ab5..32b42ad68dcd797bd8f41902392963e6c28c7565 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java @@ -22,11 +22,14 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.runtime.NullProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; @@ -47,6 +50,7 @@ public abstract class CastBaseNode extends CastNode { private final NullProfile hasDimensionsProfile = NullProfile.create(); private final NullProfile hasNamesProfile = NullProfile.create(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetDimAttributeNode getDimNode; private final boolean preserveNames; private final boolean preserveDimensions; @@ -79,7 +83,11 @@ public abstract class CastBaseNode extends CastNode { protected int[] getPreservedDimensions(RAbstractContainer operand) { if (preserveDimensions()) { - return hasDimensionsProfile.profile(operand.getDimensions()); + if (getDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNode = insert(GetDimAttributeNode.create()); + } + return hasDimensionsProfile.profile(getDimNode.getDimensions(operand)); } else { return null; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java index 06c7279cc4862b2d689fc5b9a5f460de77367ad5..5d952237fb70f7e3aad9089653ce63df02ad65b3 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java @@ -28,9 +28,6 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.api.object.Location; -import com.oracle.truffle.api.object.Property; -import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; @@ -62,8 +59,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement private static final RStringVector implicitClassHeaderMatrix = RDataFactory.createStringVector(new String[]{RType.Matrix.getName()}, true); protected boolean complete; // "complete" means: does not contain NAs - private Shape attrShape; - private Location dimensionsLoc; protected RStringVector names; private RList dimNames; // cache rownames for data frames as they are accessed at every data frame access @@ -96,34 +91,14 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement initAttributes(RAttributesLayout.createDim(RDataFactory.createIntVector(dimensions, true))); } } - updateLocationsFromAttrs(); - } - - private void updateLocationsFromAttrs() { - if (attributes == null) { - attrShape = null; - dimensionsLoc = null; - } else if (attributes.getShape() != attrShape) { - attrShape = attributes.getShape(); - Property prop = attrShape.getProperty(RRuntime.DIM_ATTR_KEY); - if (prop == null) { - dimensionsLoc = null; - } else { - dimensionsLoc = prop.getLocation(); - } - // TODO: the same for the other special attributes - } } private int[] getDimensionsFromAttrs() { - // Sync the shape - updateLocationsFromAttrs(); - - if (dimensionsLoc == null) { + if (attributes == null) { return null; } else { - RIntVector dims = (RIntVector) dimensionsLoc.get(attributes); - return dims.getInternalStore(); + RIntVector dims = (RIntVector) attributes.get(RRuntime.DIM_ATTR_KEY); + return dims == null ? null : dims.getInternalStore(); } } @@ -507,9 +482,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final boolean hasDimensions() { // Sync the shape - updateLocationsFromAttrs(); - - return dimensionsLoc != null; + return attributes == null ? false : attributes.containsKey(RRuntime.DIM_ATTR_KEY); } @Override