<commit_before>//
// Mark On statements/blocks as "fast" (no communication, small, etc.)
//
// The comm layer can provide a "fast" option, for example, run within
//  the handler (rather than creating a new task).
//

#include "astutil.h"
#include "expr.h"
#include "passes.h"
#ifdef DEBUG
#include "stmt.h"
#endif

//
// Return true if this primitive function is safe for fast on optimization
// (e.g., no communication, no sync/single accesses)
//
static bool
isFastPrimitive(CallExpr *call) {
  INT_ASSERT(call->primitive);
  // Check primitives for communication
  switch (call->primitive->tag) {
  case PRIM_UNKNOWN:
    // TODO: Return true for PRIM_UNKNOWNs that are side-effect free
    return false;

  case PRIM_NOOP:
  case PRIM_REF_TO_STRING:
  case PRIM_RETURN:
  case PRIM_UNARY_MINUS:
  case PRIM_UNARY_PLUS:
  case PRIM_UNARY_NOT:
  case PRIM_UNARY_LNOT:
  case PRIM_ADD:
  case PRIM_SUBTRACT:
  case PRIM_MULT:
  case PRIM_DIV:
  case PRIM_MOD:
  case PRIM_LSH:
  case PRIM_RSH:
  case PRIM_EQUAL:
  case PRIM_NOTEQUAL:
  case PRIM_LESSOREQUAL:
  case PRIM_GREATEROREQUAL:
  case PRIM_LESS:
  case PRIM_GREATER:
  case PRIM_AND:
  case PRIM_OR:
  case PRIM_XOR:
  case PRIM_POW:
  case PRIM_MIN:
  case PRIM_MAX:

  case PRIM_GET_MEMBER:
  case PRIM_GET_SVEC_MEMBER:
  case PRIM_GET_PRIV_CLASS:
  case PRIM_NEW_PRIV_CLASS:
  case PRIM_NUM_PRIV_CLASSES:

  case PRIM_CHECK_NIL:
  case PRIM_GET_REAL:
  case PRIM_GET_IMAG:

  case PRIM_ADDR_OF:
  case PRIM_LOCAL_CHECK:

  case PRIM_INIT_FIELDS:
  case PRIM_PTR_EQUAL:
  case PRIM_PTR_NOTEQUAL:
  case PRIM_CAST:
  case PRIM_GET_ITERATOR_RETURN:

  case PRIM_BLOCK_LOCAL:

  case PRIM_LOCALE_ID:
  case PRIM_IS_HERE:
  case PRIM_NODE_ID:
  case PRIM_ON_LOCALE_NUM:
  case PRIM_GET_SERIAL:
  case PRIM_SET_SERIAL:
  case PRIM_TASK_SET_LOCALE:
  case PRIM_TASK_GET_LOCALE:
  case PRIM_TASK_SET_HERE:
  case PRIM_TASK_GET_HERE:

  case PRIM_STRING_COPY:

  case PRIM_NEXT_UINT32:
  case PRIM_GET_USER_LINE:
  case PRIM_GET_USER_FILE:

#ifdef DEBUG
    printf(" *** OK (default): %s\n", call->primitive->name);
#endif
    return true;

  case PRIM_MOVE:
    if (call->get(1)->typeInfo() == dtVoid) {
#ifdef DEBUG
      printf(" *** OK (PRIM_MOVE 0): %s\n", call->primitive->name);
#endif
      return true;
    }
    if (!isCallExpr(call->get(2))) {
      if (!(call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE) &&
            !call->get(2)->typeInfo()->symbol->hasFlag(FLAG_WIDE) &&
            !call->get(2)->typeInfo()->symbol->hasFlag(FLAG_REF)))
#ifdef DEBUG
        printf(" *** OK (PRIM_MOVE 1): %s\n", call->primitive->name);
#endif
        return true;
    } else {
#ifdef DEBUG
      printf(" *** OK (PRIM_MOVE 3): %s\n", call->primitive->name);
#endif
      return true;
    }
    break;

// I think these can always return true. <hilde><commit_msg>Note that we may be too optimistic in our fast-on optimization.(Work item for later resolution.)<commit_after>//
// Mark On statements/blocks as "fast" (no communication, small, etc.)
//
// The comm layer can provide a "fast" option, for example, run within
//  the handler (rather than creating a new task).
//

#include "astutil.h"
#include "expr.h"
#include "passes.h"
#ifdef DEBUG
#include "stmt.h"
#endif

//
// Return true if this primitive function is safe for fast on optimization
// (e.g., no communication, no sync/single accesses)
//
static bool
isFastPrimitive(CallExpr *call) {
  INT_ASSERT(call->primitive);
  // Check primitives for communication
  switch (call->primitive->tag) {
  case PRIM_UNKNOWN:
    // TODO: Return true for PRIM_UNKNOWNs that are side-effect free
    return false;

  case PRIM_NOOP:
  case PRIM_REF_TO_STRING:
  case PRIM_RETURN:
  case PRIM_UNARY_MINUS:
  case PRIM_UNARY_PLUS:
  case PRIM_UNARY_NOT:
  case PRIM_UNARY_LNOT:
  case PRIM_ADD:
  case PRIM_SUBTRACT:
  case PRIM_MULT:
  case PRIM_DIV:
  case PRIM_MOD:
  case PRIM_LSH:
  case PRIM_RSH:
  case PRIM_EQUAL:
  case PRIM_NOTEQUAL:
  case PRIM_LESSOREQUAL:
  case PRIM_GREATEROREQUAL:
  case PRIM_LESS:
  case PRIM_GREATER:
  case PRIM_AND:
  case PRIM_OR:
  case PRIM_XOR:
  case PRIM_POW:
  case PRIM_MIN:
  case PRIM_MAX:

  case PRIM_GET_MEMBER:
  case PRIM_GET_SVEC_MEMBER:
  case PRIM_GET_PRIV_CLASS:
  case PRIM_NEW_PRIV_CLASS:
  case PRIM_NUM_PRIV_CLASSES:

  case PRIM_CHECK_NIL:
  case PRIM_GET_REAL:
  case PRIM_GET_IMAG:

  case PRIM_ADDR_OF:
  case PRIM_LOCAL_CHECK:

  case PRIM_INIT_FIELDS:
  case PRIM_PTR_EQUAL:
  case PRIM_PTR_NOTEQUAL:
  case PRIM_CAST:
  case PRIM_GET_ITERATOR_RETURN:

  case PRIM_BLOCK_LOCAL:

  case PRIM_LOCALE_ID:
  case PRIM_IS_HERE:
  case PRIM_NODE_ID:
  case PRIM_ON_LOCALE_NUM:
  case PRIM_GET_SERIAL:
  case PRIM_SET_SERIAL:
  case PRIM_TASK_SET_LOCALE:
  case PRIM_TASK_GET_LOCALE:
  case PRIM_TASK_SET_HERE:
  case PRIM_TASK_GET_HERE:

  case PRIM_STRING_COPY:

  case PRIM_NEXT_UINT32:
  case PRIM_GET_USER_LINE:
  case PRIM_GET_USER_FILE:

#ifdef DEBUG
    printf(" *** OK (default): %s\n", call->primitive->name);
#endif
    return true;

  case PRIM_MOVE:
    if (call->get(1)->typeInfo() == dtVoid) {
#ifdef DEBUG
      printf(" *** OK (PRIM_MOVE 0): %s\n", call->primitive->name);
#endif
      // TODO: The rhs is evaluated for its side effects, so 
      // we should not return true here.  We should recurse on the rhs instead,
      // in case that expression contains a "slow" call.
      return true;
    }
    if (!isCallExpr(call->get(2))) {
      if (!(call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE) &&
            !call->get(2)->typeInfo()->symbol->hasFlag(FLAG_WIDE) &&
            !call->get(2)->typeInfo()->symbol->hasFlag(FLAG_REF)))
#ifdef DEBUG
        printf(" *** OK (PRIM_MOVE 1): %s\n", call->primitive->name);
#endif
        return true;
    } else {
#ifdef DEBUG
      printf(" *** OK (PRIM_MOVE 3): %s\n", call->primitive->name);
#endif
      return true;
    }
    break;

// I think these can always return true. <hilde>
{'fraction_non_alphanumeric': 0.10893760539629005, 'fraction_numerical': 0.003372681281618887, 'mean_word_length': 3.63359375, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3096754', 'n_tokens_mistral': 2307, 'n_tokens_neox': 2273, 'n_words': 562}