summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CODEOWNERS1
-rw-r--r--.github/workflows/yjit-ubuntu.yml4
-rw-r--r--doc/yjit/yjit.md8
-rw-r--r--ruby.c3
-rw-r--r--yjit.h3
-rw-r--r--yjit_core.c19
-rw-r--r--yjit_iface.c6
7 files changed, 40 insertions, 4 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 00180b15f2..15abc79af6 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -7,3 +7,4 @@ yjit* @maximecb @xrxr @tenderlove
doc/yjit/* @maximecb @xrxr @tenderlove
bootstraptest/test_yjit* @maximecb @xrxr @tenderlove
test/ruby/test_yjit* @maximecb @xrxr @tenderlove
+.github/workflows/yjit* @maximecb @xrxr @tenderlove
diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml
index a14169b6f9..826186585d 100644
--- a/.github/workflows/yjit-ubuntu.yml
+++ b/.github/workflows/yjit-ubuntu.yml
@@ -25,9 +25,7 @@ jobs:
# - ubuntu-18.04
yjit_opts: [
"--yjit",
- "--yjit --yjit-call-threshold=1 --yjit-max-versions=1",
- # "--yjit --yjit-call-threshold=1",
- # "--yjit --yjit-call-threshold=2"
+ "--yjit --yjit-call-threshold=1",
]
configure: ["", "cppflags=-DRUBY_DEBUG"]
include:
diff --git a/doc/yjit/yjit.md b/doc/yjit/yjit.md
index f84b989f6d..0da6c15911 100644
--- a/doc/yjit/yjit.md
+++ b/doc/yjit/yjit.md
@@ -78,6 +78,14 @@ To support disassembly of the generated code, `libcapstone` is also required (`b
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
```
# Choosing a specific c compiler
diff --git a/ruby.c b/ruby.c
index 0c64d4e1ce..c04810acf3 100644
--- a/ruby.c
+++ b/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")) {
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")) {
yjit_opt->gen_stats = true;
}
diff --git a/yjit.h b/yjit.h
index a3d8594a5d..c254c02cd8 100644
--- a/yjit.h
+++ b/yjit.h
@@ -29,6 +29,9 @@ struct rb_yjit_options {
// Generate versions greedily until the limit is hit
bool greedy_versioning;
+ // Disable the propagation of type information
+ bool no_type_prop;
+
// Maximum number of versions per block
// 1 means always create generic versions
unsigned max_versions;
diff --git a/yjit_core.c b/yjit_core.c
index 8d9c267908..a395285e1c 100644
--- a/yjit_core.c
+++ b/yjit_core.c
@@ -26,6 +26,11 @@ Return a pointer to the new stack top
static x86opnd_t
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
if (ctx->stack_size < MAX_TEMP_TYPES) {
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 },
TYPE_UNKNOWN
};
+
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); \
} while (false)
-
/**
Upgrade (or "learn") the type of an instruction operand
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
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) {
UPGRADE_TYPE(ctx->self_type, type);
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);
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 (stack_idx >= MAX_TEMP_TYPES)
return;
@@ -265,6 +278,10 @@ Set the type of a local variable
static void
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)
return;
diff --git a/yjit_iface.c b/yjit_iface.c
index 5c9dc891ba..a880a870ed 100644
--- a/yjit_iface.c
+++ b/yjit_iface.c
@@ -1210,6 +1210,12 @@ rb_yjit_init(struct rb_yjit_options *options)
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_single_ractor_mode = st_init_numtable();
blocks_assuming_bops = st_init_numtable();