From c8e09acc1927e4f1a28c48caec8b094d3f6291a8 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Thu, 3 Dec 2015 19:02:13 +0100
Subject: [PATCH] various performance fixes

---
 .../builtin/base/IsMethodsDispatchOn.java     | 10 ++--
 .../truffle/r/nodes/builtin/base/Setwd.java   | 20 ++++----
 .../truffle/r/nodes/builtin/base/Sprintf.java |  1 -
 .../truffle/r/nodes/builtin/base/Substr.java  | 27 +++++-----
 .../r/nodes/builtin/base/Tabulate.java        | 49 ++++++++++---------
 .../truffle/r/nodes/builtin/base/TempDir.java |  7 +--
 .../truffle/r/nodes/builtin/base/ToLower.java | 12 ++---
 .../truffle/r/nodes/builtin/base/ToUpper.java | 14 +++---
 .../r/nodes/builtin/base/Transpose.java       |  4 --
 .../truffle/r/nodes/builtin/base/Unlist.java  |  2 -
 .../r/nodes/builtin/base/UpdateDiag.java      | 33 +++++++------
 .../r/nodes/builtin/base/UpperTri.java        | 38 +++++++-------
 .../r/nodes/builtin/base/WhichFunctions.java  |  3 --
 13 files changed, 110 insertions(+), 110 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsMethodsDispatchOn.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsMethodsDispatchOn.java
index 3eacbc3f2f..696112bcf6 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsMethodsDispatchOn.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsMethodsDispatchOn.java
@@ -22,10 +22,11 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.r.nodes.builtin.*;
-import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RBuiltin;
+import com.oracle.truffle.r.runtime.RBuiltinKind;
+import com.oracle.truffle.r.runtime.RRuntime;
 
 @RBuiltin(name = ".isMethodsDispatchOn", kind = RBuiltinKind.PRIMITIVE, parameterNames = {})
 public abstract class IsMethodsDispatchOn extends RBuiltinNode {
@@ -33,7 +34,6 @@ public abstract class IsMethodsDispatchOn extends RBuiltinNode {
     private static boolean on;
 
     @Specialization
-    @TruffleBoundary
     protected byte doIsMethodsDispatchOn() {
         controlVisibility();
         return RRuntime.asLogical(on);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Setwd.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Setwd.java
index 1c964cf1ca..7bd1b49680 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Setwd.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Setwd.java
@@ -22,34 +22,32 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.utilities.*;
+import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.RInvisibleBuiltinNode;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.model.*;
+import com.oracle.truffle.r.runtime.RBuiltin;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
-import static com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL;
-
 @RBuiltin(name = "setwd", kind = INTERNAL, parameterNames = "path")
 public abstract class Setwd extends RInvisibleBuiltinNode {
 
-    private final BranchProfile errorProfile = BranchProfile.create();
-
     @Specialization
     @TruffleBoundary
     protected Object setwd(RAbstractStringVector path) {
         controlVisibility();
         if (path.getLength() == 0) {
-            errorProfile.enter();
             throw RError.error(this, RError.Message.CHAR_ARGUMENT);
         }
         String owd = RFFIFactory.getRFFI().getBaseRFFI().getwd();
         String nwd = Utils.tildeExpand(path.getDataAt(0));
         int rc = RFFIFactory.getRFFI().getBaseRFFI().setwd(nwd);
         if (rc != 0) {
-            errorProfile.enter();
             throw RError.error(this, RError.Message.CANNOT_CHANGE_DIRECTORY);
         } else {
             String nwdAbs = RFFIFactory.getRFFI().getBaseRFFI().getwd();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java
index 047fb8b796..eba2fea85e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java
@@ -44,7 +44,6 @@ public abstract class Sprintf extends RBuiltinNode {
     @Child private Sprintf sprintfRecursive;
 
     @Specialization
-    @TruffleBoundary
     protected String sprintf(String fmt, @SuppressWarnings("unused") RMissing x) {
         controlVisibility();
         return fmt;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java
index ff7debd90e..12201a59c6 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java
@@ -22,17 +22,23 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
+import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL;
 
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.r.nodes.builtin.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-import com.oracle.truffle.r.runtime.data.model.*;
-import com.oracle.truffle.r.runtime.ops.na.*;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.utilities.BranchProfile;
+import com.oracle.truffle.api.utilities.ConditionProfile;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RBuiltin;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RStringVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
 @RBuiltin(name = "substr", kind = INTERNAL, parameterNames = {"x", "start", "stop"})
 public abstract class Substr extends RBuiltinNode {
@@ -49,7 +55,6 @@ public abstract class Substr extends RBuiltinNode {
 
     @SuppressWarnings("unused")
     @Specialization(guards = {"!emptyArg(arg)", "wrongParams(start, stop)"})
-    @TruffleBoundary
     protected RNull substrWrongParams(RAbstractStringVector arg, RAbstractIntVector start, RAbstractIntVector stop) {
         RInternalError.shouldNotReachHere();
         return RNull.instance; // dummy
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
index 1fa1a74c43..3c07784737 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
@@ -10,29 +10,42 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.r.nodes.builtin.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-import com.oracle.truffle.r.runtime.data.model.*;
-
-import static com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.utilities.BranchProfile;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.profile.CountedLoopConditionProfile;
+import com.oracle.truffle.r.runtime.RBuiltin;
+import com.oracle.truffle.r.runtime.RBuiltinKind;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.RFactor;
+import com.oracle.truffle.r.runtime.data.RIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 
 @RBuiltin(name = "tabulate", kind = RBuiltinKind.INTERNAL, parameterNames = {"bin", "nbins"})
 public abstract class Tabulate extends RBuiltinNode {
 
+    private final BranchProfile errorProfile = BranchProfile.create();
+    private final CountedLoopConditionProfile loopProfile = CountedLoopConditionProfile.create();
+
     @Override
     protected void createCasts(CastBuilder casts) {
         casts.toInteger(1);
     }
 
-    @Specialization(guards = {"isValidNBin(nBins)"})
-    @TruffleBoundary
+    @Specialization
     public RIntVector tabulate(RAbstractIntVector bin, int nBins) {
         controlVisibility();
+        if (RRuntime.isNA(nBins) || nBins < 0) {
+            errorProfile.enter();
+            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "nbin");
+        }
         int[] ans = new int[nBins];
-        for (int i = 0; i < bin.getLength(); i++) {
+        loopProfile.profileLength(bin.getLength());
+        for (int i = 0; loopProfile.inject(i < bin.getLength()); i++) {
             int currentEl = bin.getDataAt(i);
             if (!RRuntime.isNA(currentEl) && currentEl > 0 && currentEl <= nBins) {
                 ans[currentEl - 1]++;
@@ -41,23 +54,15 @@ public abstract class Tabulate extends RBuiltinNode {
         return RDataFactory.createIntVector(ans, RDataFactory.COMPLETE_VECTOR);
     }
 
-    @Specialization(guards = {"isValidNBin(nBins)"})
-    @TruffleBoundary
+    @Specialization
     public RIntVector tabulate(RFactor bin, int nBins) {
         return tabulate(bin.getVector(), nBins);
     }
 
     @SuppressWarnings("unused")
-    @Specialization
+    @Fallback
+    @TruffleBoundary
     public RIntVector tabulate(Object bin, int nBins) {
-        CompilerDirectives.transferToInterpreter();
         throw RError.error(this, RError.Message.INVALID_INPUT);
     }
-
-    protected boolean isValidNBin(int nBins) {
-        if (RRuntime.isNA(nBins) || nBins < 0) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "nbin");
-        }
-        return true;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TempDir.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TempDir.java
index 449598ed3f..075497373d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TempDir.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TempDir.java
@@ -22,22 +22,19 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL;
+
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RBuiltin;
 import com.oracle.truffle.r.runtime.TempPathName;
 
-import static com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL;
-
 @RBuiltin(name = "tempdir", kind = INTERNAL, parameterNames = {})
 public abstract class TempDir extends RBuiltinNode {
 
     @Specialization
-    @TruffleBoundary
     protected Object tempdir() {
         controlVisibility();
         return TempPathName.tempDirPath();
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java
index d10f2a3a99..609207e62a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java
@@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.r.nodes.builtin.*;
+import com.oracle.truffle.r.nodes.profile.CountedLoopConditionProfile;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -42,20 +43,19 @@ public abstract class ToLower extends RBuiltinNode {
     }
 
     @Specialization
-    @TruffleBoundary
-    protected RStringVector toLower(RAbstractStringVector vector) {
+    protected RStringVector toLower(RAbstractStringVector vector, //
+                    @Cached("create()") CountedLoopConditionProfile loopProfile) {
         controlVisibility();
         String[] stringVector = new String[vector.getLength()];
-        for (int i = 0; i < vector.getLength(); i++) {
+        loopProfile.profileLength(vector.getLength());
+        for (int i = 0; loopProfile.inject(i < vector.getLength()); i++) {
             stringVector[i] = toLower(vector.getDataAt(i));
         }
         return RDataFactory.createStringVector(stringVector, vector.isComplete());
     }
 
-    @SuppressWarnings("unused")
     @Specialization
-    @TruffleBoundary
-    protected RStringVector tolower(RNull empty) {
+    protected RStringVector tolower(@SuppressWarnings("unused") RNull empty) {
         controlVisibility();
         return RDataFactory.createStringVector(0);
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java
index 88ad73094e..b9df54b012 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.r.nodes.builtin.*;
+import com.oracle.truffle.r.nodes.profile.CountedLoopConditionProfile;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 
@@ -41,11 +42,12 @@ public abstract class ToUpper extends RBuiltinNode {
     }
 
     @Specialization
-    @TruffleBoundary
-    protected RStringVector toUpper(RStringVector vector) {
+    protected RStringVector toUpper(RStringVector vector, //
+                    @Cached("create()") CountedLoopConditionProfile loopProfile) {
         controlVisibility();
         String[] stringVector = new String[vector.getLength()];
-        for (int i = 0; i < vector.getLength(); i++) {
+        loopProfile.profileLength(vector.getLength());
+        for (int i = 0; loopProfile.inject(i < vector.getLength()); i++) {
             stringVector[i] = toUpper(vector.getDataAt(i));
         }
         RStringVector res = RDataFactory.createStringVector(stringVector, vector.isComplete());
@@ -53,10 +55,8 @@ public abstract class ToUpper extends RBuiltinNode {
         return res;
     }
 
-    @SuppressWarnings("unused")
     @Specialization
-    @TruffleBoundary
-    protected RStringVector toupper(RNull empty) {
+    protected RStringVector toupper(@SuppressWarnings("unused") RNull empty) {
         controlVisibility();
         return RDataFactory.createStringVector(0);
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java
index ef679f6ec0..0eb9e9639f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java
@@ -33,28 +33,24 @@ public abstract class Transpose extends RBuiltinNode {
     public abstract Object execute(Object o);
 
     @Specialization
-    @TruffleBoundary
     protected RNull transpose(RNull value) {
         controlVisibility();
         return value;
     }
 
     @Specialization
-    @TruffleBoundary
     protected int transpose(int value) {
         controlVisibility();
         return value;
     }
 
     @Specialization
-    @TruffleBoundary
     protected double transpose(double value) {
         controlVisibility();
         return value;
     }
 
     @Specialization
-    @TruffleBoundary
     protected byte transpose(byte value) {
         controlVisibility();
         return value;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java
index ae39a1702f..53d0398c53 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java
@@ -115,7 +115,6 @@ public abstract class Unlist extends RBuiltinNode {
 
     @SuppressWarnings("unused")
     @Specialization
-    @TruffleBoundary
     protected RNull unlist(RNull vector, byte recursive, byte useNames) {
         controlVisibility();
         return RNull.instance;
@@ -123,7 +122,6 @@ public abstract class Unlist extends RBuiltinNode {
 
     @SuppressWarnings("unused")
     @Specialization(guards = "!isVectorList(vector)")
-    @TruffleBoundary
     protected RAbstractVector unlistVector(RAbstractVector vector, byte recursive, byte useNames) {
         controlVisibility();
         return vector;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java
index 6e32b51975..c364609bac 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java
@@ -22,17 +22,22 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
+import static com.oracle.truffle.r.runtime.RBuiltinKind.SUBSTITUTE;
 
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.r.nodes.builtin.*;
-import com.oracle.truffle.r.nodes.unary.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-import com.oracle.truffle.r.runtime.data.model.*;
-import com.oracle.truffle.r.runtime.ops.na.*;
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.RInvisibleBuiltinNode;
+import com.oracle.truffle.r.nodes.unary.CastDoubleNode;
+import com.oracle.truffle.r.nodes.unary.CastDoubleNodeGen;
+import com.oracle.truffle.r.runtime.RBuiltin;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
+import com.oracle.truffle.r.runtime.data.RDoubleVector;
+import com.oracle.truffle.r.runtime.data.RIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
 @RBuiltin(name = "diag<-", kind = SUBSTITUTE, parameterNames = {"x", ""})
 // 2nd parameter is "value", but should not be matched against, so "")
@@ -70,8 +75,7 @@ public abstract class UpdateDiag extends RInvisibleBuiltinNode {
     }
 
     @Specialization(guards = {"isMatrix(vector)", "correctReplacementLength(vector, valueVector)"})
-    @TruffleBoundary
-    protected RAbstractIntVector updateDiag(RIntVector vector, RAbstractIntVector valueVector) {
+    protected RAbstractIntVector updateDiag(RAbstractIntVector vector, RAbstractIntVector valueVector) {
         controlVisibility();
         RIntVector resultVector = (RIntVector) vector.materializeNonShared();
         int nrow = resultVector.getDimensions()[0];
@@ -86,8 +90,7 @@ public abstract class UpdateDiag extends RInvisibleBuiltinNode {
     }
 
     @Specialization(guards = {"isMatrix(vector)", "correctReplacementLength(vector, valueVector)"})
-    @TruffleBoundary
-    protected RAbstractDoubleVector updateDiag(RDoubleVector vector, RAbstractDoubleVector valueVector) {
+    protected RAbstractDoubleVector updateDiag(RAbstractDoubleVector vector, RAbstractDoubleVector valueVector) {
         controlVisibility();
         RDoubleVector resultVector = (RDoubleVector) vector.materializeNonShared();
         int size = Math.min(resultVector.getDimensions()[0], resultVector.getDimensions()[1]);
@@ -102,7 +105,7 @@ public abstract class UpdateDiag extends RInvisibleBuiltinNode {
     }
 
     @Specialization(guards = {"isMatrix(vector)", "correctReplacementLength(vector, valueVector)"})
-    protected RAbstractDoubleVector updateDiag(RIntVector vector, RAbstractDoubleVector valueVector) {
+    protected RAbstractDoubleVector updateDiag(RAbstractIntVector vector, RAbstractDoubleVector valueVector) {
         controlVisibility();
         initCastDoubleNode();
         RDoubleVector resultVector = (RDoubleVector) castDouble.executeDouble(vector);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpperTri.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpperTri.java
index 9846654e59..2b9b5f97ea 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpperTri.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpperTri.java
@@ -22,17 +22,19 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.runtime.RBuiltinKind.SUBSTITUTE;
+
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.utilities.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RBuiltin;
+import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
-import static com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import static com.oracle.truffle.r.runtime.RBuiltinKind.SUBSTITUTE;
-
 @RBuiltin(name = "upper.tri", kind = SUBSTITUTE, parameterNames = {"x", "diag"})
 // TODO Implement in R
 public abstract class UpperTri extends RBuiltinNode {
@@ -42,36 +44,36 @@ public abstract class UpperTri extends RBuiltinNode {
         return new Object[]{RMissing.instance, RRuntime.LOGICAL_FALSE};
     }
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.firstBoolean(1);
+    }
+
     @Specialization
-    @TruffleBoundary
-    protected RLogicalVector upperTri(RAbstractVector vector, byte diag) {
+    protected RLogicalVector upperTri(RAbstractVector vector, boolean diag, //
+                    @Cached("createBinaryProfile()") ConditionProfile nullDimensionsProfile, //
+                    @Cached("createBinaryProfile()") ConditionProfile nonSquareProfile) {
         controlVisibility();
-        int[] dim = preprocessDim(vector);
+        int[] dim = vector.getDimensions();
+        if (nullDimensionsProfile.profile(dim == null)) {
+            dim = new int[]{vector.getLength(), 1};
+        }
         int size = Math.min(dim[0], dim[1]);
         int nrow = dim[0];
         int length = vector.getLength();
         byte[] result = new byte[length];
         for (int i = 0; i < size; i++) {
-            int cmp = diag == RRuntime.LOGICAL_TRUE ? i + 1 : i;
+            int cmp = diag ? i + 1 : i;
             for (int j = 0; j < cmp; j++) {
                 int index = i * nrow + j;
                 result[index] = RRuntime.LOGICAL_TRUE;
             }
         }
-        if (dim[0] < dim[1]) {
+        if (nonSquareProfile.profile(dim[0] < dim[1])) {
             for (int i = size * size; i < length; i++) {
                 result[i] = RRuntime.LOGICAL_TRUE;
             }
         }
         return RDataFactory.createLogicalVector(result, true, dim);
     }
-
-    @TruffleBoundary
-    private static int[] preprocessDim(RAbstractVector vector) {
-        int[] dim = vector.getDimensions();
-        if (dim == null) {
-            return new int[]{vector.getLength(), 1};
-        }
-        return dim;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java
index 854dde38e7..9e4c6d981a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java
@@ -101,7 +101,6 @@ public class WhichFunctions {
         }
 
         @Specialization
-        @TruffleBoundary
         protected int which(RAbstractDoubleVector x) {
             controlVisibility();
             double max = x.getDataAt(0);
@@ -126,7 +125,6 @@ public class WhichFunctions {
         }
 
         @Specialization
-        @TruffleBoundary
         protected int which(RAbstractDoubleVector x) {
             controlVisibility();
             double minimum = x.getDataAt(0);
@@ -139,6 +137,5 @@ public class WhichFunctions {
             }
             return minIndex + 1;
         }
-
     }
 }
-- 
GitLab