Skip to content

Commit 6185d24

Browse files
authored
Add a "context" hook for generic calls during codegen (#36398)
This adds a new context field that rewrites generic calls like `apply_generic(f, (args...,))` to `apply_generic(context, (f, args...))` during codegen. The intention here is to allow external AbstractInterpreters to provide custom implementations of apply_generic (usually recursing analysis using the same interpreter, but other behavior may be desired). This is a bit of a stopgap solution. I think in the fullness of time, we'll probably want completely custom codegen for generic callsites, to avoid the potential of a double-dispatch impact, but for the moment this allows prototyping.
1 parent 9d71d37 commit 6185d24

File tree

4 files changed

+24
-6
lines changed

4 files changed

+24
-6
lines changed

base/reflection.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -983,18 +983,22 @@ struct CodegenParams
983983

984984
lookup::Ptr{Cvoid}
985985

986+
generic_context::Any
987+
986988
function CodegenParams(; track_allocations::Bool=true, code_coverage::Bool=true,
987989
static_alloc::Bool=true, prefer_specsig::Bool=false,
988990
gnu_pubnames=true, debug_info_kind::Cint = default_debug_info_kind(),
989991
module_setup=nothing, module_activation=nothing, raise_exception=nothing,
990992
emit_function=nothing, emitted_function=nothing,
991-
lookup::Ptr{Cvoid}=cglobal(:jl_rettype_inferred))
993+
lookup::Ptr{Cvoid}=cglobal(:jl_rettype_inferred),
994+
generic_context = nothing)
992995
return new(
993996
Cint(track_allocations), Cint(code_coverage),
994997
Cint(static_alloc), Cint(prefer_specsig),
995998
Cint(gnu_pubnames), debug_info_kind,
996999
module_setup, module_activation, raise_exception,
997-
emit_function, emitted_function, lookup)
1000+
emit_function, emitted_function, lookup,
1001+
generic_context)
9981002
end
9991003
end
10001004

src/cgutils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2872,5 +2872,6 @@ static int compare_cgparams(const jl_cgparams_t *a, const jl_cgparams_t *b)
28722872
// hooks
28732873
(a->module_setup == b->module_setup) &&
28742874
(a->module_activation == b->module_activation) &&
2875-
(a->raise_exception == b->raise_exception);
2875+
(a->raise_exception == b->raise_exception) &&
2876+
(a->generic_context == b->generic_context);
28762877
}

src/codegen.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ extern "C" {
821821
1,
822822
#endif
823823
jl_default_debug_info_kind, NULL, NULL, NULL, NULL, NULL,
824-
jl_rettype_inferred };
824+
jl_rettype_inferred, NULL };
825825
}
826826

827827
template<typename T>
@@ -3379,7 +3379,15 @@ static jl_cgval_t emit_call(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt)
33793379
return emit_intrinsic(ctx, fi, args, nargs - 1);
33803380
}
33813381

3382-
jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
3382+
jl_value_t *context = ctx.params->generic_context == jl_nothing ? nullptr : ctx.params->generic_context;
3383+
size_t n_generic_args = nargs + (context ? 1 : 0);
3384+
3385+
jl_cgval_t *generic_argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * n_generic_args);
3386+
jl_cgval_t *argv = generic_argv;
3387+
if (context) {
3388+
generic_argv[0] = mark_julia_const(context);
3389+
argv = &generic_argv[1];
3390+
}
33833391
argv[0] = f;
33843392
for (size_t i = 1; i < nargs; ++i) {
33853393
argv[i] = emit_expr(ctx, args[i]);
@@ -3405,7 +3413,7 @@ static jl_cgval_t emit_call(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt)
34053413
}
34063414

34073415
// emit function and arguments
3408-
Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, nargs, JLCALL_F_CC);
3416+
Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, generic_argv, n_generic_args, JLCALL_F_CC);
34093417
return mark_julia_type(ctx, callval, true, rt);
34103418
}
34113419

@@ -7425,6 +7433,7 @@ extern "C" void jl_init_llvm(void)
74257433
jl_default_cgparams.raise_exception = jl_nothing;
74267434
jl_default_cgparams.emit_function = jl_nothing;
74277435
jl_default_cgparams.emitted_function = jl_nothing;
7436+
jl_default_cgparams.generic_context = jl_nothing;
74287437
jl_init_debuginfo();
74297438

74307439
InitializeNativeTarget();

src/julia.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,6 +2100,10 @@ typedef struct {
21002100

21012101
// Cache access. Default: jl_rettype_inferred.
21022102
jl_codeinstance_lookup_t lookup;
2103+
2104+
// If not `nothing`, rewrite all generic calls to call
2105+
// generic_context(f, args...) instead of f(args...).
2106+
jl_value_t *generic_context;
21032107
} jl_cgparams_t;
21042108
extern JL_DLLEXPORT jl_cgparams_t jl_default_cgparams;
21052109
extern JL_DLLEXPORT int jl_default_debug_info_kind;

0 commit comments

Comments
 (0)