<commit_before>#ifdef ENABLE_LLVM

#include "llvm/inline.hpp"
#include "llvm/jit_context.hpp"

// We use the i64 and i32 versions here. We do the bounds checking
// manually later on, because using i63 / i31 is buggy in LLVM, also
// see http://llvm.org/bugs/show_bug.cgi?id=13991
#ifdef IS_X8664
#define MUL_WITH_OVERFLOW "llvm.smul.with.overflow.i64"
#else
#define MUL_WITH_OVERFLOW "llvm.smul.with.overflow.i32"
#endif

namespace rubinius {

  enum MathOperation {
    cAdd, cSub, cMultiply, cDivide, cMod,
    cEqual, cLessThan, cLessThanEqual, cGreaterThan, cGreaterThanEqual
  };

  struct InlinePrimitive {
    JITOperations& ops;
    Inliner& i;
    CompiledCode* compiled_code;
    Class* klass;

    InlinePrimitive(JITOperations& _ops, Inliner& _i, CompiledCode* _code,
                    Class* _klass)
      : ops(_ops)
      , i(_i)
      , compiled_code(_code)
      , klass(_klass)
    {}

    void log(const char* name) {
      if(ops.state()->config().jit_inline_debug) {
        i.context().inline_log("inlining")
          << ops.state()->enclosure_name(compiled_code)
          << "#"
          << ops.state()->symbol_debug_str(compiled_code->name())
          << " into "
          << ops.state()->symbol_debug_str(ops.method_name())
          << ". primitive " << name << "\n";
      }
    }

    void tuple_at() {
      log("tuple_at");
      i.context().enter_inline();

      Value* rec = i.recv();

      // bool is_tuple = recv->flags & mask;

      Value* cmp = ops.check_type_bits(rec, rubinius::Tuple::type);

      BasicBlock* is_tuple = ops.new_block("is_tuple");
      BasicBlock* access =   ops.new_block("tuple_at");
      BasicBlock* is_other = i.failure();

      ops.create_conditional_branch(is_tuple, is_other, cmp);

      ops.set_block(is_tuple);

      Value* index_val = i.arg(0);

      Value* fix_cmp = ops.check_if_fixnum(index_val);
      // Check that index is not over the end of the Tuple

      Value* tup = ops.upcast(rec, "Tuple");

      Value* index = ops.fixnum_to_native(index_val);
      Value* full_size = ops.get_tuple_size(tup);
      Value* size_cmp = ops.create_less_than(index, full_size, "is_in_bounds");

      // Combine fix_cmp and size_cmp to validate entry into access code
      Value* access_cmp = ops.create_and(fix_cmp, size_cmp, "access_cmp");
      ops.create_conditional_branch(access, is_other, access_cmp);

      ops.set_block(access);

      Value* idx[] = {
        ConstantInt::get(ops.state()->Int32Ty, 0),
        ConstantInt::get(ops.state()->Int32Ty, offset::tuple_field),
        index
      };

      Value* gep = ops.create_gep(tup, idx, 3, "field_pos");

      i.exception_safe();
      i.set_result(ops.create_load(gep, "tuple_at"));

      i.context().leave_inline();
    }

    void tuple_put() {
      log("tuple_put");
      i.context().enter_inline();

      Value* rec = i.recv();

      Value* cmp = ops.check_type_bits(rec, rubinius::Tuple::type);

      BasicBlock* is_tuple = ops.new_block("is_tuple");
      BasicBlock* access =   ops.new_block("tuple_put");
      BasicBlock* is_other = i.failure();

      ops.create_conditional_branch(is_tuple, is_other, cmp);

      ops.set_block(is_tuple);

      Value* index_val = i.arg(0);
      Value* fix_cmp = ops.check_if_fixnum(index_val);

      Value* tup = ops.upcast(rec, "Tuple");
<commit_msg>Use check_is_tuple instead of specify type bits<commit_after>#ifdef ENABLE_LLVM

#include "llvm/inline.hpp"
#include "llvm/jit_context.hpp"

// We use the i64 and i32 versions here. We do the bounds checking
// manually later on, because using i63 / i31 is buggy in LLVM, also
// see http://llvm.org/bugs/show_bug.cgi?id=13991
#ifdef IS_X8664
#define MUL_WITH_OVERFLOW "llvm.smul.with.overflow.i64"
#else
#define MUL_WITH_OVERFLOW "llvm.smul.with.overflow.i32"
#endif

namespace rubinius {

  enum MathOperation {
    cAdd, cSub, cMultiply, cDivide, cMod,
    cEqual, cLessThan, cLessThanEqual, cGreaterThan, cGreaterThanEqual
  };

  struct InlinePrimitive {
    JITOperations& ops;
    Inliner& i;
    CompiledCode* compiled_code;
    Class* klass;

    InlinePrimitive(JITOperations& _ops, Inliner& _i, CompiledCode* _code,
                    Class* _klass)
      : ops(_ops)
      , i(_i)
      , compiled_code(_code)
      , klass(_klass)
    {}

    void log(const char* name) {
      if(ops.state()->config().jit_inline_debug) {
        i.context().inline_log("inlining")
          << ops.state()->enclosure_name(compiled_code)
          << "#"
          << ops.state()->symbol_debug_str(compiled_code->name())
          << " into "
          << ops.state()->symbol_debug_str(ops.method_name())
          << ". primitive " << name << "\n";
      }
    }

    void tuple_at() {
      log("tuple_at");
      i.context().enter_inline();

      Value* rec = i.recv();

      // bool is_tuple = recv->flags & mask;

      Value* cmp = ops.check_is_tuple(rec);

      BasicBlock* is_tuple = ops.new_block("is_tuple");
      BasicBlock* access =   ops.new_block("tuple_at");
      BasicBlock* is_other = i.failure();

      ops.create_conditional_branch(is_tuple, is_other, cmp);

      ops.set_block(is_tuple);

      Value* index_val = i.arg(0);

      Value* fix_cmp = ops.check_if_fixnum(index_val);
      // Check that index is not over the end of the Tuple

      Value* tup = ops.upcast(rec, "Tuple");

      Value* index = ops.fixnum_to_native(index_val);
      Value* full_size = ops.get_tuple_size(tup);
      Value* size_cmp = ops.create_less_than(index, full_size, "is_in_bounds");

      // Combine fix_cmp and size_cmp to validate entry into access code
      Value* access_cmp = ops.create_and(fix_cmp, size_cmp, "access_cmp");
      ops.create_conditional_branch(access, is_other, access_cmp);

      ops.set_block(access);

      Value* idx[] = {
        ConstantInt::get(ops.state()->Int32Ty, 0),
        ConstantInt::get(ops.state()->Int32Ty, offset::tuple_field),
        index
      };

      Value* gep = ops.create_gep(tup, idx, 3, "field_pos");

      i.exception_safe();
      i.set_result(ops.create_load(gep, "tuple_at"));

      i.context().leave_inline();
    }

    void tuple_put() {
      log("tuple_put");
      i.context().enter_inline();

      Value* rec = i.recv();

      Value* cmp = ops.check_is_tuple(rec);

      BasicBlock* is_tuple = ops.new_block("is_tuple");
      BasicBlock* access =   ops.new_block("tuple_put");
      BasicBlock* is_other = i.failure();

      ops.create_conditional_branch(is_tuple, is_other, cmp);

      ops.set_block(is_tuple);

      Value* index_val = i.arg(0);
      Value* fix_cmp = ops.check_if_fixnum(index_val);

      Value* tup = ops.upcast(rec, "Tuple");

{'fraction_non_alphanumeric': 0.13696172248803828, 'fraction_numerical': 0.008672248803827751, 'mean_word_length': 2.932392710170488, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 19, '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': '3194441', 'n_tokens_mistral': 2381, 'n_tokens_neox': 2278, 'n_words': 448}