From ff75637c454f017b6cba719150c6a63fdf9fc442 Mon Sep 17 00:00:00 2001
From: Adam Welc <adam.welc@oracle.com>
Date: Mon, 23 Mar 2015 09:56:21 -0700
Subject: [PATCH] Backed out changeset 0f217709eb72 to fix performance
 regression.

---
 .../truffle/r/nodes/RTruffleVisitor.java      | 73 ++++++++++---------
 .../r/nodes/access/WriteVariableNode.java     | 20 ++---
 2 files changed, 49 insertions(+), 44 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java
index 3ec710818f..bf244c9228 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java
@@ -355,9 +355,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         return new RNode[5];
     }
 
-    private static final String varSymbol = "*tmp*";
-
-    private static String constructReplacementPrefix(RNode[] seq, RNode rhs, RNode replacementArg, WriteVariableNode.Mode rhsWriteMode) {
+    private static String constructReplacementPrefix(RNode[] seq, RNode rhs, RNode replacementArg, WriteVariableNode.Mode rhsWriteMode, String tmpSymbol) {
         //@formatter:off
         // store a - need to use temporary, otherwise there is a failure in case multiple calls to
         // the replacement form are chained:
@@ -365,8 +363,8 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         //@formatter:on
         final String rhsSymbol = new Object().toString();
 
-        WriteVariableNode rhsAssign = WriteVariableNode.create(rhsSymbol.toString(), rhs, false, false, rhsWriteMode);
-        WriteVariableNode varAssign = WriteVariableNode.create(varSymbol, replacementArg, false, false, WriteVariableNode.Mode.TEMP);
+        WriteVariableNode rhsAssign = WriteVariableNode.create(rhsSymbol, rhs, false, false, rhsWriteMode);
+        WriteVariableNode varAssign = WriteVariableNode.create(tmpSymbol, replacementArg, false, false, WriteVariableNode.Mode.INVISIBLE);
 
         seq[0] = rhsAssign;
         seq[1] = varAssign;
@@ -374,9 +372,9 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         return rhsSymbol;
     }
 
-    private static ReplacementNode constructReplacementSuffix(RNode[] seq, RNode assignFromTemp, Object rhsSymbol, SourceSection source) {
+    private static ReplacementNode constructReplacementSuffix(RNode[] seq, RNode assignFromTemp, Object tmpSymbol, Object rhsSymbol, SourceSection source) {
         // remove var and rhs, returning rhs' value
-        RemoveAndAnswerNode rmVar = RemoveAndAnswerNode.create(varSymbol);
+        RemoveAndAnswerNode rmVar = RemoveAndAnswerNode.create(tmpSymbol);
         RemoveAndAnswerNode rmRhs = RemoveAndAnswerNode.create(rhsSymbol);
 
         // assemble
@@ -440,17 +438,18 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
             SimpleAccessVariable varAST = (SimpleAccessVariable) a.getVector();
             String vSymbol = varAST.getVariable();
 
+            final String tmpSymbol = new Object().toString();
             RNode[] seq = createReplacementSequence();
             ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             String rhsSymbolString = RRuntime.toString(rhsSymbol);
             RNode rhsAccess = ReadVariableNode.create(rhsSymbolString, false);
-            RNode tmpVarAccess = ReadVariableNode.create(varSymbol, false);
+            RNode tmpVarAccess = ReadVariableNode.create(tmpSymbol, false);
 
             CoerceVector coerceVector = CoerceVectorNodeGen.create(null, null, null);
             RNode updateOp = createPositions(a.getArguments(), argLength, a.isSubset(), null, tmpVarAccess, rhsAccess, coerceVector, true);
-            RNode assignFromTemp = WriteVariableNode.create(vSymbol, updateOp, false, isSuper, WriteVariableNode.Mode.TEMP);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, source);
+            RNode assignFromTemp = WriteVariableNode.create(vSymbol, updateOp, false, isSuper);
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, source);
         } else if (a.getVector() instanceof AccessVector) {
             // assign value to the outermost dimension and then the result (recursively) to
             // appropriate position in the lower dimension
@@ -459,15 +458,16 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
             AccessVector vecAST = (AccessVector) a.getVector();
             SimpleAccessVariable varAST = getVectorVariable(vecAST);
             RNode[] seq = new RNode[3];
+            final String tmpSymbol = new Object().toString();
             String rhsSymbol;
             if (varAST != null) {
                 String vSymbol = varAST.getVariable();
 
                 ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
 
             } else {
-                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             }
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
             CoerceVector coerceVector = CoerceVectorNodeGen.create(null, null, null);
@@ -479,12 +479,13 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
 
             RNode[] seq = new RNode[3];
             String rhsSymbol;
+            final String tmpSymbol = new Object().toString();
             if (varAST != null) {
                 String vSymbol = varAST.getVariable();
                 ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             } else {
-                rhsSymbol = constructReplacementPrefix(seq, rhs, accessAST.getLhs().accept(this), WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, accessAST.getLhs().accept(this), WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             }
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
 
@@ -515,10 +516,10 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         return WriteVariableNode.create(n.getSource(), n.getVariable(), expression, false, n.isSuper());
     }
 
-    private RCallNode prepareReplacementCall(FunctionCall f, List<ArgNode> args, String rhsSymbol, boolean simpleReplacement) {
+    private RCallNode prepareReplacementCall(FunctionCall f, List<ArgNode> args, String tmpSymbol, String rhsSymbol, boolean simpleReplacement) {
         // massage arguments to replacement function call (replace v with tmp, append a)
         List<ArgNode> rfArgs = new ArrayList<>();
-        rfArgs.add(ArgNode.create(null, null, AccessVariable.create(null, varSymbol, false)));
+        rfArgs.add(ArgNode.create(null, null, AccessVariable.create(null, tmpSymbol, false)));
         if (args.size() > 1) {
             for (int i = 1; i < args.size(); ++i) {
                 rfArgs.add(args.get(i));
@@ -555,33 +556,34 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         FunctionCall f = replacement.getReplacementFunctionCall();
         List<ArgNode> args = f.getArguments();
         ASTNode val = args.get(0).getValue();
+        final String tmpSymbol = new Object().toString();
         if (val instanceof SimpleAccessVariable) {
             SimpleAccessVariable callArg = (SimpleAccessVariable) val;
             String vSymbol = callArg.getVariable();
             RNode[] seq = createReplacementSequence();
             ReadVariableNode replacementCallArg = createReplacementForVariableUsing(callArg, vSymbol, replacement);
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementCallArg, WriteVariableNode.Mode.COPY);
-            RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, true);
-            RNode assignFromTemp = WriteVariableNode.create(vSymbol, replacementCall, false, replacement.isSuper(), WriteVariableNode.Mode.TEMP);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, replacement.getSource());
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementCallArg, WriteVariableNode.Mode.COPY, tmpSymbol);
+            RNode replacementCall = prepareReplacementCall(f, args, tmpSymbol, rhsSymbol, true);
+            RNode assignFromTemp = WriteVariableNode.create(vSymbol, replacementCall, false, replacement.isSuper(), WriteVariableNode.Mode.INVISIBLE);
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, replacement.getSource());
         } else if (val instanceof AccessVector) {
             AccessVector callArgAst = (AccessVector) val;
             RNode replacementArg = callArgAst.accept(this);
             RNode[] seq = createReplacementSequence();
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY);
-            RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, false);
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY, tmpSymbol);
+            RNode replacementCall = prepareReplacementCall(f, args, tmpSymbol, rhsSymbol, false);
             // see AssignVariable.writeVector (number of args must match)
             callArgAst.getArguments().add(ArgNode.create(rhsAst.getSource(), "value", rhsAst));
             RNode assignFromTemp = createVectorUpdate(callArgAst, replacementCall, replacement.isSuper(), replacement.getSource(), false);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, replacement.getSource());
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, replacement.getSource());
         } else {
             FieldAccess callArgAst = (FieldAccess) val;
             RNode replacementArg = callArgAst.accept(this);
             RNode[] seq = createReplacementSequence();
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY);
-            RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, false);
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY, tmpSymbol);
+            RNode replacementCall = prepareReplacementCall(f, args, tmpSymbol, rhsSymbol, false);
             RNode assignFromTemp = createFieldUpdate(callArgAst, replacementCall, replacement.isSuper(), replacement.getSource());
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, replacement.getSource());
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, replacement.getSource());
         }
     }
 
@@ -670,25 +672,27 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
 
             RNode[] seq = createReplacementSequence();
             ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+            final String tmpSymbol = new Object().toString();
+            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             String rhsSymbolString = RRuntime.toString(rhsSymbol);
             RNode rhsAccess = ReadVariableNode.create(rhsSymbolString, false);
-            RNode tmpVarAccess = ReadVariableNode.create(varSymbol, false);
+            RNode tmpVarAccess = ReadVariableNode.create(tmpSymbol, false);
             UpdateFieldNode ufn = UpdateFieldNodeGen.create(tmpVarAccess, rhsAccess, a.getFieldName());
-            RNode assignFromTemp = WriteVariableNode.create(vSymbol, ufn, false, isSuper, WriteVariableNode.Mode.TEMP);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, source);
+            RNode assignFromTemp = WriteVariableNode.create(vSymbol, ufn, false, isSuper, WriteVariableNode.Mode.INVISIBLE);
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, source);
         } else if (a.getLhs() instanceof AccessVector) {
             AccessVector vecAST = (AccessVector) a.getLhs();
             SimpleAccessVariable varAST = getVectorVariable(vecAST);
             RNode[] seq = new RNode[3];
+            final String tmpSymbol = new Object().toString();
             String rhsSymbol;
             if (varAST != null) {
                 String vSymbol = varAST.getVariable();
 
                 ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             } else {
-                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             }
 
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
@@ -705,7 +709,8 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
             String vSymbol = varAST.getVariable();
             RNode[] seq = new RNode[3];
             ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+            final String tmpSymbol = new Object().toString();
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
             UpdateFieldNode ufn = UpdateFieldNodeGen.create(accessAST.accept(this), rhsAccess, a.getFieldName());
             return constructRecursiveFieldUpdateSuffix(seq, ufn, accessAST, source, isSuper);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
index 40ec9b1990..61f6bcb6e0 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
@@ -51,8 +51,7 @@ public abstract class WriteVariableNode extends RNode implements VisibilityContr
 
         REGULAR,
         COPY,
-        INVISIBLE,
-        TEMP
+        INVISIBLE
     }
 
     public abstract boolean isArgWrite();
@@ -94,8 +93,14 @@ public abstract class WriteVariableNode extends RNode implements VisibilityContr
     protected final Object shareObjectValue(Frame frame, FrameSlot frameSlot, Object value, Mode mode, boolean isSuper) {
         Object newValue = value;
         if (!isArgWrite()) {
-            // for the meaning of INVISIBLE mode see the comment preceding the current method
-            if (mode != Mode.INVISIBLE && !isCurrentProfile.profile(isCurrentValue(frame, frameSlot, value))) {
+            // for the meaning of INVISIBLE mode see the comment preceding the current method;
+            // also change state when assigning to the enclosing frame as there must
+            // be a distinction between variables with the same name defined in
+            // different scopes, for example to correctly support:
+            // x<-1:3; f<-function() { x[2]<-10; x[2]<<-100; x[2]<-1000 }; f()
+            // or
+            // x<-c(1); f<-function() { x[[1]]<<-x[[1]] + 1; x }; a<-f(); b<-f(); c(a,b)
+            if ((mode != Mode.INVISIBLE || isSuper) && !isCurrentProfile.profile(isCurrentValue(frame, frameSlot, value))) {
                 if (isShareableProfile.profile(value instanceof RShareable)) {
                     RShareable rShareable = (RShareable) value;
                     if (isTemporaryProfile.profile(rShareable.isTemporary())) {
@@ -115,12 +120,7 @@ public abstract class WriteVariableNode extends RNode implements VisibilityContr
                         if (mode == Mode.COPY) {
                             RShareable shareableCopy = rShareable.copy();
                             newValue = shareableCopy;
-                        } else if (mode != Mode.TEMP || isSuper) {
-                            // mark shared when assigning to the enclosing frame as there must
-                            // be a distinction between variables with the same name defined in
-                            // different scopes, for example to correctly support:
-                            // x<-1:3; f<-function() { x[2]<-10; x[2]<<-100; x[2]<-1000 } ; f()
-
+                        } else {
                             rShareable.makeShared();
                         }
                     }
-- 
GitLab