Skip to content
Snippets Groups Projects
Commit 57b9f278 authored by Adam Welc's avatar Adam Welc
Browse files

Rewritten conversion builtins to avoid copy on identity conversion.

parent 43e0c404
Branches
No related tags found
No related merge requests found
Showing
with 77 additions and 49 deletions
......@@ -28,6 +28,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.runtime.RDeparse;
......@@ -42,6 +43,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
@RBuiltin(name = "as.character", kind = PRIMITIVE, parameterNames = {"x", "..."}, dispatch = INTERNAL_GENERIC, behavior = PURE)
public abstract class AsCharacter extends RBuiltinNode {
private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
@Override
protected void createCasts(CastBuilder casts) {
casts.arg("x").mapIf(instanceOf(RAbstractListVector.class).not(), asStringVector());
......@@ -54,7 +57,11 @@ public abstract class AsCharacter extends RBuiltinNode {
@Specialization
protected RAbstractStringVector asCharacter(RAbstractStringVector v) {
return v;
if (noAttributes.profile(v.getAttributes() == null)) {
return v;
} else {
return (RAbstractStringVector) v.copyDropAttributes();
}
}
@Specialization
......
......@@ -26,6 +26,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
......@@ -36,6 +37,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
@RBuiltin(name = "as.complex", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
public abstract class AsComplex extends RBuiltinNode {
private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
@Override
protected void createCasts(CastBuilder casts) {
casts.arg("x").asComplexVector();
......@@ -48,7 +51,11 @@ public abstract class AsComplex extends RBuiltinNode {
@Specialization
protected RAbstractComplexVector asComplex(RAbstractComplexVector v) {
return v;
if (noAttributes.profile(v.getAttributes() == null)) {
return v;
} else {
return (RAbstractComplexVector) v.copyDropAttributes();
}
}
}
......@@ -26,6 +26,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
......@@ -36,6 +37,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
@RBuiltin(name = "as.double", aliases = {"as.numeric"}, kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
public abstract class AsDouble extends RBuiltinNode {
private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
@Override
protected void createCasts(CastBuilder casts) {
casts.arg("x").asDoubleVector();
......@@ -48,6 +51,10 @@ public abstract class AsDouble extends RBuiltinNode {
@Specialization
protected RAbstractDoubleVector asDouble(RAbstractDoubleVector v) {
return v;
if (noAttributes.profile(v.getAttributes() == null)) {
return v;
} else {
return (RAbstractDoubleVector) v.copyDropAttributes();
}
}
}
......@@ -26,6 +26,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
......@@ -37,6 +38,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
@RBuiltin(name = "as.integer", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
public abstract class AsInteger extends RBuiltinNode {
private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
@Override
protected void createCasts(CastBuilder casts) {
casts.arg("x").asIntegerVector();
......@@ -49,7 +52,11 @@ public abstract class AsInteger extends RBuiltinNode {
@Specialization
protected RAbstractIntVector asInteger(RAbstractIntVector v) {
return v;
if (noAttributes.profile(v.getAttributes() == null)) {
return v;
} else {
return (RAbstractIntVector) v.copyDropAttributes();
}
}
@Specialization
......
......@@ -26,6 +26,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
......@@ -36,6 +37,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
@RBuiltin(name = "as.logical", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
public abstract class AsLogical extends RBuiltinNode {
private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
@Override
protected void createCasts(CastBuilder casts) {
casts.arg("x").asLogicalVector();
......@@ -48,6 +51,10 @@ public abstract class AsLogical extends RBuiltinNode {
@Specialization
protected RAbstractLogicalVector asLogicaleger(RAbstractLogicalVector v) {
return v;
if (noAttributes.profile(v.getAttributes() == null)) {
return v;
} else {
return (RAbstractLogicalVector) v.copyDropAttributes();
}
}
}
......@@ -26,6 +26,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
......@@ -36,6 +37,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
@RBuiltin(name = "as.raw", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
public abstract class AsRaw extends RBuiltinNode {
private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
@Override
protected void createCasts(CastBuilder casts) {
casts.arg("x").asRawVector();
......@@ -48,6 +51,10 @@ public abstract class AsRaw extends RBuiltinNode {
@Specialization
protected RAbstractRawVector asRaw(RAbstractRawVector v) {
return v;
if (noAttributes.profile(v.getAttributes() == null)) {
return v;
} else {
return (RAbstractRawVector) v.copyDropAttributes();
}
}
}
......@@ -34,6 +34,7 @@ import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
......@@ -57,6 +58,7 @@ import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.RType;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
import com.oracle.truffle.r.runtime.data.RAttributable;
import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
import com.oracle.truffle.r.runtime.data.RComplex;
import com.oracle.truffle.r.runtime.data.RDataFactory;
......@@ -118,41 +120,54 @@ public abstract class AsVector extends RBuiltinNode {
public abstract Object execute(Object x, String mode);
private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
private final BranchProfile hasAttributes = BranchProfile.create();
private Object dropAttributesIfNeeded(Object o) {
Object res = o;
if (res instanceof RAttributable && ((RAttributable) res).getAttributes() != null) {
// the assertion should hold because of how cast works and it's only used for
// vectors (as per as.vector docs)
assert res instanceof RAbstractVector;
hasAttributes.enter();
res = ((RAbstractVector) res).copyDropAttributes();
}
return res;
}
@Specialization(guards = "castToString(mode)")
protected Object asVectorString(Object x, @SuppressWarnings("unused") String mode, //
@Cached("createNonPreserving()") CastStringNode cast) {
return cast.execute(x);
return dropAttributesIfNeeded(cast.execute(x));
}
@Specialization(guards = "castToInt(x, mode)")
protected Object asVectorInt(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
@Cached("createNonPreserving()") CastIntegerNode cast) {
return cast.execute(x);
return dropAttributesIfNeeded(cast.execute(x));
}
@Specialization(guards = "castToDouble(x, mode)")
protected Object asVectorDouble(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
@Cached("createNonPreserving()") CastDoubleNode cast) {
return cast.execute(x);
return dropAttributesIfNeeded(cast.execute(x));
}
@Specialization(guards = "castToComplex(x, mode)")
protected Object asVectorComplex(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
@Cached("createNonPreserving()") CastComplexNode cast) {
return cast.execute(x);
return dropAttributesIfNeeded(cast.execute(x));
}
@Specialization(guards = "castToLogical(x, mode)")
protected Object asVectorLogical(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
@Cached("createNonPreserving()") CastLogicalNode cast) {
return cast.execute(x);
return dropAttributesIfNeeded(cast.execute(x));
}
@Specialization(guards = "castToRaw(x, mode)")
protected Object asVectorRaw(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
@Cached("createNonPreserving()") CastRawNode cast) {
return cast.execute(x);
return dropAttributesIfNeeded(cast.execute(x));
}
protected static CastListNode createListCast() {
......
......@@ -77,7 +77,7 @@ public abstract class Paste extends RBuiltinNode {
} else if (ret == RNull.instance) {
return RDataFactory.createEmptyStringVector();
} else {
return (RStringVector) ret;
return (RStringVector) ((RStringVector) ret).copyDropAttributes();
}
}
......
......@@ -69,7 +69,7 @@ public abstract class UpdateNames extends RBuiltinNode {
if (newNames instanceof String) {
stringVector = RDataFactory.createStringVector((String) newNames);
} else {
stringVector = (RStringVector) ((RAbstractVector) newNames).materialize();
stringVector = (RStringVector) ((RAbstractVector) newNames).materialize().copyDropAttributes();
}
RAbstractContainer result = (RAbstractContainer) container.getNonShared();
if (stringVector.getLength() < result.getLength()) {
......
......@@ -60,15 +60,6 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
return recursiveCastDouble.executeDouble(o);
}
private RDoubleVector createResultVector(RAbstractVector operand, double[] ddata) {
RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), getPreservedDimensions(operand), getPreservedNames(operand));
preserveDimensionNames(operand, ret);
if (preserveAttributes()) {
ret.copyRegAttributesFrom(operand);
}
return ret;
}
private RDoubleVector vectorCopy(RAbstractContainer operand, double[] data, boolean isComplete) {
RDoubleVector ret = RDataFactory.createDoubleVector(data, isComplete, getPreservedDimensions(operand), getPreservedNames(operand));
preserveDimensionNames(operand, ret);
......@@ -152,7 +143,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
warningBranch.enter();
RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
}
return createResultVector(operand, ddata);
return vectorCopy(operand, ddata, naCheck.neverSeenNA());
}
@Specialization
......@@ -162,11 +153,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
@Specialization
protected RDoubleVector doDoubleVector(RDoubleVector operand) {
if (preserveAttributes() && preserveDimensions() && preserveNames()) {
return operand;
} else {
return vectorCopy(operand, operand.getDataCopy(), operand.isComplete());
}
return operand;
}
@Specialization
......
......@@ -62,11 +62,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
@Specialization
protected RIntVector doIntVector(RIntVector operand) {
if (preserveAttributes() && preserveDimensions() && preserveNames()) {
return operand;
} else {
return vectorCopy(operand, operand.getDataCopy(), operand.isComplete());
}
return operand;
}
@Specialization
......
......@@ -103,11 +103,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
@Specialization
protected RLogicalVector doLogicalVector(RLogicalVector operand) {
if (preserveAttributes() && preserveDimensions() && preserveNames()) {
return operand;
} else {
return vectorCopy(operand, operand.getDataCopy(), operand.isComplete());
}
return operand;
}
@Specialization(guards = "!isFactor(operand)")
......
......@@ -288,11 +288,7 @@ public abstract class CastRawNode extends CastBaseNode {
@Specialization
protected RRawVector doRawVector(RRawVector operand) {
if (preserveAttributes() && preserveDimensions() && preserveNames()) {
return operand;
} else {
return vectorCopy(operand, operand.getDataCopy());
}
return operand;
}
@Specialization
......
......@@ -61,11 +61,7 @@ public abstract class CastStringNode extends CastStringBaseNode {
@Specialization
protected RStringVector doStringVector(RStringVector vector) {
if (preserveAttributes() && preserveDimensions() && preserveNames()) {
return vector;
} else {
return vectorCopy(vector, vector.getDataCopy());
}
return vector;
}
@Specialization
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment