From f10cac2bf913ca7d7635ca4100aaf1bdad7272b6 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Fri, 9 Feb 2018 15:10:02 +0100
Subject: [PATCH] better profiling in various S4- and call-related places

---
 .../truffle/r/nodes/function/GetCallerFrameNode.java     | 9 ++++++++-
 .../truffle/r/nodes/function/PromiseHelperNode.java      | 7 ++++---
 .../r/nodes/function/call/CallRFunctionBaseNode.java     | 4 +++-
 .../oracle/truffle/r/nodes/objects/ExecuteMethod.java    | 6 +++++-
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetCallerFrameNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetCallerFrameNode.java
index fde5609e43..d90108207a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetCallerFrameNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetCallerFrameNode.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.function;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.Frame;
@@ -54,7 +55,13 @@ public final class GetCallerFrameNode extends RBaseNode {
             return (MaterializedFrame) callerFrameObject;
         }
         if (callerFrameObject instanceof CallerFrameClosure) {
-            closureProfile.enter();
+            if (slowPathInitialized) {
+                closureProfile.enter();
+            } else {
+                // don't initialize the profile at the first call
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                slowPathInitialized = true;
+            }
             CallerFrameClosure closure = (CallerFrameClosure) callerFrameObject;
             RCaller parent = RArguments.getCall(frame);
             MaterializedFrame slowPathFrame = notifyCallers(closure, parent);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java
index 2438587909..8e23d7679d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java
@@ -158,14 +158,14 @@ public final class PromiseHelperNode extends RBaseNode {
         }
 
         int state = optStateProfile.profile(promise.getState());
-        if (PromiseState.isExplicit(state)) {
+        if (isExplicitProfile.profile(PromiseState.isExplicit(state))) {
             CompilerDirectives.transferToInterpreter();
             // reset profiles, this is very likely a one-time event
             isEvaluatedProfile = ConditionProfile.createBinaryProfile();
             optStateProfile = PrimitiveValueProfile.createEqualityProfile();
             return evaluateSlowPath(frame, promise);
         }
-        if (PromiseState.isDefaultOpt(state)) {
+        if (isDefaultOptProfile.profile(PromiseState.isDefaultOpt(state))) {
             return generateValueDefault(frame, promise);
         } else {
             return generateValueNonDefault(frame, state, (EagerPromise) promise);
@@ -320,7 +320,7 @@ public final class PromiseHelperNode extends RBaseNode {
      * <code>null</code>
      */
     public void materialize(RPromise promise) {
-        if (isDefaultOptProfile.profile(!PromiseState.isDefaultOpt(promise.getState()))) {
+        if (!isDefaultOptProfile.profile(PromiseState.isDefaultOpt(promise.getState()))) {
             EagerPromise eager = (EagerPromise) promise;
             eager.materialize();
         }
@@ -364,6 +364,7 @@ public final class PromiseHelperNode extends RBaseNode {
     private final ValueProfile valueProfile = ValueProfile.createClassProfile();
 
     // Eager
+    private final ConditionProfile isExplicitProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isDefaultOptProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isDeoptimizedProfile = ConditionProfile.createBinaryProfile();
     private final ValueProfile eagerValueProfile = ValueProfile.createClassProfile();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionBaseNode.java
index 10aee1f08c..ab87ece2ba 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionBaseNode.java
@@ -28,12 +28,14 @@ import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.CallerFrameClosure;
 
 public abstract class CallRFunctionBaseNode extends Node {
 
     protected final Assumption needsNoCallerFrame = Truffle.getRuntime().createAssumption("no caller frame");
     protected final CallerFrameClosure invalidateNoCallerFrame = new InvalidateNoCallerFrame(needsNoCallerFrame);
+    private final ConditionProfile topLevelProfile = ConditionProfile.createBinaryProfile();
     private static final CallerFrameClosure DUMMY = new DummyCallerFrameClosure();
 
     public boolean setNeedsCallerFrame() {
@@ -62,7 +64,7 @@ public abstract class CallRFunctionBaseNode extends Node {
         } else {
             if (callerFrame != null) {
                 return callerFrame;
-            } else if (topLevel) {
+            } else if (topLevelProfile.profile(topLevel)) {
                 return DUMMY;
             }
             return curFrame.materialize();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/ExecuteMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/ExecuteMethod.java
index baf6272c4f..d61af375d2 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/ExecuteMethod.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/ExecuteMethod.java
@@ -14,6 +14,7 @@ package com.oracle.truffle.r.nodes.objects;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.function.CallMatcherNode;
@@ -37,12 +38,15 @@ final class ExecuteMethod extends RBaseNode {
     @Child private CollectArgumentsNode collectArgs;
     @Child private CallMatcherNode callMatcher;
 
+    private final ValueProfile functionProfile = ValueProfile.createClassProfile();
+    private final ValueProfile signatureProfile = ValueProfile.createIdentityProfile();
+
     public Object executeObject(VirtualFrame frame, RFunction fdef, String fname) {
         if (collectArgs == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             collectArgs = insert(CollectArgumentsNodeGen.create());
         }
-        ArgumentsSignature signature = RArguments.getSignature(frame);
+        ArgumentsSignature signature = signatureProfile.profile(RArguments.getSignature(frame, functionProfile));
 
         // Collect arguments; we cannot use the arguments of the original call because there might
         // be overriding default arguments.
-- 
GitLab