From e2c4f3110907ca617b11aa79f113b0d8a338c570 Mon Sep 17 00:00:00 2001
From: Florian Angerer <florian.angerer@oracle.com>
Date: Fri, 25 Aug 2017 12:21:20 +0200
Subject: [PATCH] Split evaluateArgs into version with and w/o explode loop.

---
 .../truffle/r/nodes/function/PromiseNode.java | 34 ++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
index b2d5ebe471..c3a0a12254 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
@@ -521,8 +521,40 @@ public abstract class PromiseNode extends RNode {
             }
         }
 
-        @ExplodeLoop
         private int evaluateArguments(VirtualFrame frame, Object[] evaluatedArgs) {
+            if (evaluatedArgs.length <= 32) {
+                return evaluateArgumentsExplode(frame, evaluatedArgs);
+            }
+            return evaluateArgumentsLoop(frame, evaluatedArgs);
+        }
+
+        @ExplodeLoop
+        private int evaluateArgumentsExplode(VirtualFrame frame, Object[] evaluatedArgs) {
+            int size = 0;
+            boolean containsVarargs = false;
+            for (int i = 0; i < varargs.length; i++) {
+                Object argValue = varargs[i].execute(frame);
+                if (argsValueAndNamesProfile.profile(argValue instanceof RArgsValuesAndNames)) {
+                    containsVarargs = true;
+                    size += ((RArgsValuesAndNames) argValue).getLength();
+                    evaluatedArgs[i] = argValue;
+                } else {
+                    size++;
+                    evaluatedArgs[i] = promiseCheckHelper.checkEvaluate(frame, argValue);
+                }
+                if (evaluatedArgs[i] == null) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    throw RInternalError.shouldNotReachHere("evaluated argument must not be null");
+                }
+            }
+            if (containsVarargProfile.profile(containsVarargs)) {
+                return size;
+            } else {
+                return -1;
+            }
+        }
+
+        private int evaluateArgumentsLoop(VirtualFrame frame, Object[] evaluatedArgs) {
             int size = 0;
             boolean containsVarargs = false;
             for (int i = 0; i < varargs.length; i++) {
-- 
GitLab