Add --yjit-no-type-prop so we can test YJIT without type propagation (#5135)

* Add --yjit-no-type-prop so we can test YJIT without type propagation

* Fix typo in command line option

* Leave just two test workflows enable for YJIT
This commit is contained in:
Maxime Chevalier-Boisvert 2021-11-18 10:44:31 -05:00 committed by GitHub
parent f3dcb4bbf7
commit cdebf57ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
Notes: git 2021-11-19 00:45:02 +09:00
Merged-By: maximecb <maximecb@ruby-lang.org>
7 changed files with 40 additions and 4 deletions

1
.github/CODEOWNERS vendored
View File

@ -7,3 +7,4 @@ yjit* @maximecb @xrxr @tenderlove
doc/yjit/* @maximecb @xrxr @tenderlove doc/yjit/* @maximecb @xrxr @tenderlove
bootstraptest/test_yjit* @maximecb @xrxr @tenderlove bootstraptest/test_yjit* @maximecb @xrxr @tenderlove
test/ruby/test_yjit* @maximecb @xrxr @tenderlove test/ruby/test_yjit* @maximecb @xrxr @tenderlove
.github/workflows/yjit* @maximecb @xrxr @tenderlove

View File

@ -25,9 +25,7 @@ jobs:
# - ubuntu-18.04 # - ubuntu-18.04
yjit_opts: [ yjit_opts: [
"--yjit", "--yjit",
"--yjit --yjit-call-threshold=1 --yjit-max-versions=1", "--yjit --yjit-call-threshold=1",
# "--yjit --yjit-call-threshold=1",
# "--yjit --yjit-call-threshold=2"
] ]
configure: ["", "cppflags=-DRUBY_DEBUG"] configure: ["", "cppflags=-DRUBY_DEBUG"]
include: include:

View File

@ -78,6 +78,14 @@ To support disassembly of the generated code, `libcapstone` is also required (`b
make -j16 install make -j16 install
``` ```
On macOS, you may need to specify where to find openssl, libyaml and gdbm:
```
# Configure with debugging/stats options for development, build and install
./configure cppflags="-DRUBY_DEBUG -DYJIT_STATS" --prefix=$HOME/.rubies/ruby-yjit --disable-install-doc --disable--install-rdoc --with-opt-dir=$(brew --prefix openssl):$(brew --prefix readline):$(brew --prefix libyaml):$(brew --prefix gdbm)
make -j16 install
```
Typically configure will choose default C compiler. To specify the C compiler, use Typically configure will choose default C compiler. To specify the C compiler, use
``` ```
# Choosing a specific c compiler # Choosing a specific c compiler

3
ruby.c
View File

@ -1091,6 +1091,9 @@ setup_yjit_options(const char *s, struct rb_yjit_options *yjit_opt)
else if (yjit_opt_match_noarg(s, l, "greedy-versioning")) { else if (yjit_opt_match_noarg(s, l, "greedy-versioning")) {
yjit_opt->greedy_versioning = true; yjit_opt->greedy_versioning = true;
} }
else if (yjit_opt_match_noarg(s, l, "no-type-prop")) {
yjit_opt->no_type_prop = true;
}
else if (yjit_opt_match_noarg(s, l, "stats")) { else if (yjit_opt_match_noarg(s, l, "stats")) {
yjit_opt->gen_stats = true; yjit_opt->gen_stats = true;
} }

3
yjit.h
View File

@ -29,6 +29,9 @@ struct rb_yjit_options {
// Generate versions greedily until the limit is hit // Generate versions greedily until the limit is hit
bool greedy_versioning; bool greedy_versioning;
// Disable the propagation of type information
bool no_type_prop;
// Maximum number of versions per block // Maximum number of versions per block
// 1 means always create generic versions // 1 means always create generic versions
unsigned max_versions; unsigned max_versions;

View File

@ -26,6 +26,11 @@ Return a pointer to the new stack top
static x86opnd_t static x86opnd_t
ctx_stack_push_mapping(ctx_t *ctx, temp_type_mapping_t mapping) ctx_stack_push_mapping(ctx_t *ctx, temp_type_mapping_t mapping)
{ {
// If type propagation is disabled, store no types
if (rb_yjit_opts.no_type_prop) {
mapping.type = TYPE_UNKNOWN;
}
// Keep track of the type and mapping of the value // Keep track of the type and mapping of the value
if (ctx->stack_size < MAX_TEMP_TYPES) { if (ctx->stack_size < MAX_TEMP_TYPES) {
ctx->temp_mapping[ctx->stack_size] = mapping.mapping; ctx->temp_mapping[ctx->stack_size] = mapping.mapping;
@ -80,6 +85,7 @@ ctx_stack_push_local(ctx_t *ctx, size_t local_idx)
(temp_mapping_t){ .kind = TEMP_LOCAL, .idx = local_idx }, (temp_mapping_t){ .kind = TEMP_LOCAL, .idx = local_idx },
TYPE_UNKNOWN TYPE_UNKNOWN
}; };
return ctx_stack_push_mapping(ctx, mapping); return ctx_stack_push_mapping(ctx, mapping);
} }
@ -165,7 +171,6 @@ static int type_diff(val_type_t src, val_type_t dst);
(dest) = (src); \ (dest) = (src); \
} while (false) } while (false)
/** /**
Upgrade (or "learn") the type of an instruction operand Upgrade (or "learn") the type of an instruction operand
This value must be compatible and at least as specific as the previously known type. This value must be compatible and at least as specific as the previously known type.
@ -175,6 +180,10 @@ propagated back to its source.
static void static void
ctx_upgrade_opnd_type(ctx_t *ctx, insn_opnd_t opnd, val_type_t type) ctx_upgrade_opnd_type(ctx_t *ctx, insn_opnd_t opnd, val_type_t type)
{ {
// If type propagation is disabled, store no types
if (rb_yjit_opts.no_type_prop)
return;
if (opnd.is_self) { if (opnd.is_self) {
UPGRADE_TYPE(ctx->self_type, type); UPGRADE_TYPE(ctx->self_type, type);
return; return;
@ -249,6 +258,10 @@ ctx_set_opnd_mapping(ctx_t *ctx, insn_opnd_t opnd, temp_type_mapping_t type_mapp
RUBY_ASSERT(opnd.idx < ctx->stack_size); RUBY_ASSERT(opnd.idx < ctx->stack_size);
int stack_idx = ctx->stack_size - 1 - opnd.idx; int stack_idx = ctx->stack_size - 1 - opnd.idx;
// If type propagation is disabled, store no types
if (rb_yjit_opts.no_type_prop)
return;
// If outside of tracked range, do nothing // If outside of tracked range, do nothing
if (stack_idx >= MAX_TEMP_TYPES) if (stack_idx >= MAX_TEMP_TYPES)
return; return;
@ -265,6 +278,10 @@ Set the type of a local variable
static void static void
ctx_set_local_type(ctx_t *ctx, size_t idx, val_type_t type) ctx_set_local_type(ctx_t *ctx, size_t idx, val_type_t type)
{ {
// If type propagation is disabled, store no types
if (rb_yjit_opts.no_type_prop)
return;
if (idx >= MAX_LOCAL_TYPES) if (idx >= MAX_LOCAL_TYPES)
return; return;

View File

@ -1210,6 +1210,12 @@ rb_yjit_init(struct rb_yjit_options *options)
rb_yjit_opts.max_versions = 4; rb_yjit_opts.max_versions = 4;
} }
// If type propagation is disabled, max 1 version per block
if (rb_yjit_opts.no_type_prop)
{
rb_yjit_opts.max_versions = 1;
}
blocks_assuming_stable_global_constant_state = st_init_numtable(); blocks_assuming_stable_global_constant_state = st_init_numtable();
blocks_assuming_single_ractor_mode = st_init_numtable(); blocks_assuming_single_ractor_mode = st_init_numtable();
blocks_assuming_bops = st_init_numtable(); blocks_assuming_bops = st_init_numtable();