diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java index 920f33a652d25854fd3e1f341e68ba6e4d7966df..0431b88c2d7884d2095f7bf821e6398afff913c9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java @@ -25,10 +25,11 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.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.r.nodes.builtin.RInvisibleBuiltinNode; +import com.oracle.truffle.r.nodes.function.opt.ReuseNonSharedNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; -import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.RNull; @@ -39,34 +40,27 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @RBuiltin(name = "dim<-", kind = PRIMITIVE, parameterNames = {"x", "value"}) public abstract class UpdateDim extends RInvisibleBuiltinNode { - @Child private CastIntegerNode castInteger; - - private RAbstractIntVector castInteger(RAbstractVector vector) { - if (castInteger == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castInteger = insert(CastIntegerNodeGen.create(true, false, false)); - } - return (RAbstractIntVector) castInteger.execute(vector); - } + @Child private ReuseNonSharedNode reuse = ReuseNonSharedNode.create(); @Specialization protected RAbstractVector updateDim(RAbstractVector vector, @SuppressWarnings("unused") RNull dimensions) { controlVisibility(); - RVector result = (RVector) vector.getNonShared(); + RVector result = ((RAbstractVector) reuse.execute(vector)).materialize(); result.resetDimensions(null); return result; } @Specialization - protected RAbstractVector updateDim(RAbstractVector vector, RAbstractVector dimensions) { + protected RAbstractVector updateDim(RAbstractVector vector, RAbstractVector dimensions, // + @Cached("createPreserveNames()") CastIntegerNode castInteger) { controlVisibility(); if (dimensions.getLength() == 0) { CompilerDirectives.transferToInterpreter(); throw RError.error(this, RError.Message.LENGTH_ZERO_DIM_INVALID); } - int[] dimsData = castInteger(dimensions).materialize().getDataCopy(); + int[] dimsData = ((RAbstractIntVector) castInteger.execute(dimensions)).materialize().getDataCopy(); RVector.verifyDimensions(vector.getLength(), dimsData, this); - RVector result = (RVector) vector.getNonShared(); + RVector result = ((RAbstractVector) reuse.execute(vector)).materialize(); result.resetDimensions(dimsData); return result; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ReuseNonSharedNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ReuseNonSharedNode.java new file mode 100644 index 0000000000000000000000000000000000000000..70aa1febcc3f89bd62a47e8a2adedf89b42c399a --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ReuseNonSharedNode.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016, 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.function.opt; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.runtime.data.RShareable; +import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage; + +public abstract class ReuseNonSharedNode extends Node { + + public static ReuseNonSharedNode create() { + return ReuseNonSharedNodeGen.create(); + } + + public abstract Object execute(Object value); + + @Specialization + protected RShareable getStorage(RSharingAttributeStorage value, // + @Cached("createBinaryProfile()") ConditionProfile isSharedProfile, // + @Cached("createBinaryProfile()") ConditionProfile isTemporaryProfile, // + @Cached("createClassProfile()") ValueProfile copyProfile) { + if (isSharedProfile.profile(value.isShared())) { + RShareable res = copyProfile.profile(value).copy(); + assert res.isTemporary(); + res.incRefCount(); + return res; + } + if (isTemporaryProfile.profile(value.isTemporary())) { + value.incRefCount(); + } + return value; + } + + @Specialization(contains = "getStorage") + protected static RShareable getRShareable(RShareable value, // + @Cached("createBinaryProfile()") ConditionProfile isSharedProfile, // + @Cached("createBinaryProfile()") ConditionProfile isTemporaryProfile) { + if (isSharedProfile.profile(value.isShared())) { + RShareable res = value.copy(); + assert res.isTemporary(); + res.incRefCount(); + return res; + } + if (isTemporaryProfile.profile(value.isTemporary())) { + value.incRefCount(); + } + return value; + } + + protected static boolean isRShareable(Object value) { + return value instanceof RShareable; + } + + @Specialization(guards = "!isRShareable(value)") + protected static Object getNonShareable(Object value) { + return value; + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java index 7b15cf7fede1479f5f3718de78a5bbf3983a8978..617d540e4023f0f517cc36627f4d69d645515f8f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java @@ -224,4 +224,8 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { public static CastIntegerNode createNonPreserving() { return CastIntegerNodeGen.create(false, false, false); } + + public static CastIntegerNode createPreserveNames() { + return CastIntegerNodeGen.create(false, false, false); + } }