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:
parent
f3dcb4bbf7
commit
cdebf57ec6
Notes:
git
2021-11-19 00:45:02 +09:00
Merged-By: maximecb <maximecb@ruby-lang.org>
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -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
|
||||||
|
4
.github/workflows/yjit-ubuntu.yml
vendored
4
.github/workflows/yjit-ubuntu.yml
vendored
@ -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:
|
||||||
|
@ -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
3
ruby.c
@ -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
3
yjit.h
@ -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;
|
||||||
|
19
yjit_core.c
19
yjit_core.c
@ -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;
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user