Skip to content

Commit

Permalink
inference: define InterConditional within Core.Compiler
Browse files Browse the repository at this point in the history
When I introduced this new lattice within #38905, I defined this in
`Core` for some performance reason, but now I'm sure it is really
necessary. Rather, it is easier to develop Julia-level inference routine
in pure Julia, so this commit moves the definition of `InterConditional`
to `Core.Compiler`.
  • Loading branch information
aviatesk committed May 30, 2022
1 parent 3e3420d commit 75ffa0a
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 38 deletions.
1 change: 0 additions & 1 deletion base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ eval(Core, quote
Const(@nospecialize(v)) = $(Expr(:new, :Const, :v))
PartialStruct(typ::DataType, fields::Array{Any, 1}) = $(Expr(:new, :PartialStruct, :typ, :fields))
PartialOpaque(@nospecialize(typ), @nospecialize(env), parent::MethodInstance, source::Method) = $(Expr(:new, :PartialOpaque, :typ, :env, :parent, :source))
InterConditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype)) = $(Expr(:new, :InterConditional, :slot, :thentype, :elsetype))
MethodMatch(@nospecialize(spec_types), sparams::SimpleVector, method::Method, fully_covers::Bool) = $(Expr(:new, :MethodMatch, :spec_types, :sparams, :method, :fully_covers))
end)

Expand Down
33 changes: 16 additions & 17 deletions base/compiler/typelattice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# structs/constants #
#####################

# N.B.: Const/PartialStruct/InterConditional are defined in Core, to allow them to be used
# N.B.: Const/PartialStruct are defined in Core, to allow them to be used
# inside the global code cache.
#
# # The type of a value might be constant
Expand Down Expand Up @@ -48,22 +48,21 @@ end
Conditional(var::SlotNumber, @nospecialize(thentype), @nospecialize(elsetype)) =
Conditional(slot_id(var), thentype, elsetype)

# """
# cnd::InterConditional
#
# Similar to `Conditional`, but conveys inter-procedural constraints imposed on call arguments.
# This is separate from `Conditional` to catch logic errors: the lattice element name is `InterConditional`
# while processing a call, then `Conditional` everywhere else. Thus `InterConditional` does not appear in
# `CompilerTypes`—these type's usages are disjoint—though we define the lattice for `InterConditional`.
# """
# struct InterConditional
# slot::Int
# thentype
# elsetype
# InterConditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype)) =
# new(slot, thentype, elsetype)
# end
import Core: InterConditional
"""
cnd::InterConditional
Similar to `Conditional`, but conveys inter-procedural constraints imposed on call arguments.
This is separate from `Conditional` to catch logic errors: the lattice element name is `InterConditional`
while processing a call, then `Conditional` everywhere else. Thus `InterConditional` does not appear in
`CompilerTypes`—these type's usages are disjoint—though we define the lattice for `InterConditional`.
"""
struct InterConditional
slot::Int
thentype
elsetype
InterConditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype)) =
new(slot, thentype, elsetype)
end
InterConditional(var::SlotNumber, @nospecialize(thentype), @nospecialize(elsetype)) =
InterConditional(slot_id(var), thentype, elsetype)

Expand Down
1 change: 0 additions & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,6 @@ void jl_init_primitives(void) JL_GC_DISABLED
add_builtin("Const", (jl_value_t*)jl_const_type);
add_builtin("PartialStruct", (jl_value_t*)jl_partial_struct_type);
add_builtin("PartialOpaque", (jl_value_t*)jl_partial_opaque_type);
add_builtin("InterConditional", (jl_value_t*)jl_interconditional_type);
add_builtin("MethodMatch", (jl_value_t*)jl_method_match_type);
add_builtin("IntrinsicFunction", (jl_value_t*)jl_intrinsic_type);
add_builtin("Function", (jl_value_t*)jl_function_type);
Expand Down
1 change: 0 additions & 1 deletion src/jl_exported_data.inc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
XX(jl_int32_type) \
XX(jl_int64_type) \
XX(jl_int8_type) \
XX(jl_interconditional_type) \
XX(jl_interrupt_exception) \
XX(jl_intrinsic_type) \
XX(jl_lineinfonode_type) \
Expand Down
5 changes: 0 additions & 5 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2576,11 +2576,6 @@ void jl_init_types(void) JL_GC_DISABLED
jl_svec2(jl_datatype_type, jl_array_any_type),
jl_emptysvec, 0, 0, 2);

jl_interconditional_type = jl_new_datatype(jl_symbol("InterConditional"), core, jl_any_type, jl_emptysvec,
jl_perm_symsvec(3, "slot", "thentype", "elsetype"),
jl_svec(3, jl_long_type, jl_any_type, jl_any_type),
jl_emptysvec, 0, 0, 3);

jl_method_match_type = jl_new_datatype(jl_symbol("MethodMatch"), core, jl_any_type, jl_emptysvec,
jl_perm_symsvec(4, "spec_types", "sparams", "method", "fully_covers"),
jl_svec(4, jl_type_type, jl_simplevector_type, jl_method_type, jl_bool_type),
Expand Down
1 change: 0 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,6 @@ extern JL_DLLIMPORT jl_datatype_t *jl_argument_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_const_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_partial_struct_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_partial_opaque_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_interconditional_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_method_match_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_simplevector_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_typename_t *jl_tuple_typename JL_GLOBALLY_ROOTED;
Expand Down
3 changes: 1 addition & 2 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ extern "C" {
// TODO: put WeakRefs on the weak_refs list during deserialization
// TODO: handle finalizers

#define NUM_TAGS 155
#define NUM_TAGS 154

// An array of references that need to be restored from the sysimg
// This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C.
Expand Down Expand Up @@ -119,7 +119,6 @@ jl_value_t **const*const get_tags(void) {
INSERT_TAG(jl_const_type);
INSERT_TAG(jl_partial_struct_type);
INSERT_TAG(jl_partial_opaque_type);
INSERT_TAG(jl_interconditional_type);
INSERT_TAG(jl_method_match_type);
INSERT_TAG(jl_pinode_type);
INSERT_TAG(jl_phinode_type);
Expand Down
17 changes: 7 additions & 10 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2034,17 +2034,14 @@ end
return nothing
end == Any[Union{Nothing,Expr}]

# handle the edge case
let ts = @eval Module() begin
edgecase(_) = $(Core.Compiler.InterConditional(2, Int, Any))
# create cache
Base.return_types(edgecase, (Any,))
Base.return_types((Any,)) do x
edgecase(x) ? x : nothing # ::Any
end
# handle edge case
@test (@eval Module() begin
edgecase(_) = $(Core.Compiler.InterConditional(2, Int, Any))
Base.return_types(edgecase, (Any,)) # create cache
Base.return_types((Any,)) do x
edgecase(x)
end
@test ts == Any[Any]
end
end) == Any[Core.Compiler.InterConditional]

# a tricky case: if constant inference derives `Const` while non-constant inference has
# derived `InterConditional`, we should not discard that constant information
Expand Down

0 comments on commit 75ffa0a

Please sign in to comment.