From 3a94886d6f0d8b91eafb9f5607f4fee994741be0 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Fri, 11 Nov 2016 15:56:48 +0100
Subject: [PATCH] do not re-evaluate rhs upon fallback to generic in special
 replacement

---
 .../r/nodes/control/ReplacementNode.java       | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
index 7f0c00efc7..4e872f4a0b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
@@ -237,21 +237,21 @@ abstract class ReplacementNode extends OperatorNode {
 
         @Override
         public Object execute(VirtualFrame frame) {
+            Object rhsValue = rhs.execute(frame);
+            storeRhs.execute(frame, rhsValue);
             try {
-                Object rhsValue = rhs.execute(frame);
-                storeRhs.execute(frame, rhsValue);
                 // Note: the very last call is the actual assignment, e.g. [[<-, if this call's
                 // argument is shared, it bails out. Moreover, if that call's argument is not
                 // shared, it could not be extracted from a shared container (list), so we should be
                 // OK with not calling any other update function and just update the value directly.
                 replaceCall.execute(frame);
-                removeRhs.execute(frame);
-                visibility.execute(frame, false);
-                return rhsValue;
             } catch (FullCallNeededException | RecursiveSpecialBailout e) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                return replace(createGenericReplacement(getLazySourceSection(), operator, target, lhs, rhs, calls, targetVarName, isSuper, tempNamesStartIndex)).execute(frame);
+                return replace(createGenericReplacement(getLazySourceSection(), operator, target, lhs, rhs, calls, targetVarName, isSuper, tempNamesStartIndex)).execute(frame, rhsValue);
             }
+            removeRhs.execute(frame);
+            visibility.execute(frame, false);
+            return rhsValue;
         }
 
         @Override
@@ -292,7 +292,11 @@ abstract class ReplacementNode extends OperatorNode {
         @Override
         @ExplodeLoop
         public Object execute(VirtualFrame frame) {
-            Object rhsValue = rhs.execute(frame);
+            return execute(frame, rhs.execute(frame));
+        }
+
+        @ExplodeLoop
+        public Object execute(VirtualFrame frame, Object rhsValue) {
             storeRhs.execute(frame, rhsValue);
             targetTmpWrite.execute(frame, target.execute(frame));
             for (RNode update : updates) {
-- 
GitLab