|
1 | 1 | # This file is a part of Julia. License is MIT: https://julialang.org/license
|
2 | 2 |
|
3 |
| -if isdefined(Base, :end_base_include) && !isdefined(Base, :Compiler) |
4 |
| - |
5 |
| -# Define a dummy `Compiler` module to make it installable even on Julia versions where |
6 |
| -# Compiler.jl is not available as a standard library. |
7 |
| -@eval module Compiler |
8 |
| - function __init__() |
9 |
| - println(""" |
10 |
| - The `Compiler` standard library is not available for this version of Julia. |
11 |
| - Use Julia version `v"1.12.0-DEV.1581"` or later. |
12 |
| - """) |
13 |
| - end |
14 |
| -end |
15 |
| - |
16 |
| -# When generating an incremental precompile file, we first check whether we |
17 |
| -# already have a copy of this *exact* code in the system image. If so, we |
18 |
| -# simply generates a pkgimage that has the dependency edges we recorded in |
19 |
| -# the system image and simply returns that copy of the compiler. If not, |
20 |
| -# we proceed to load/precompile this as an ordinary package. |
21 |
| -elseif (isdefined(Base, :generating_output) && Base.generating_output(true) && |
22 |
| - Base.samefile(joinpath(Sys.BINDIR, Base.DATAROOTDIR, Base._compiler_require_dependencies[1][2]), @eval @__FILE__) && |
23 |
| - !Base.any_includes_stale( |
24 |
| - map(Base.compiler_chi, Base._compiler_require_dependencies), |
25 |
| - "sysimg", nothing)) |
26 |
| - |
27 |
| - Base.prepare_compiler_stub_image!() |
28 |
| - append!(Base._require_dependencies, map(Base.expand_compiler_path, Base._compiler_require_dependencies)) |
29 |
| - # There isn't much point in precompiling native code - downstream users will |
30 |
| - # specialize their own versions of the compiler code and we don't activate |
31 |
| - # the compiler by default anyway, so let's save ourselves some disk space. |
32 |
| - ccall(:jl_suppress_precompile, Cvoid, (Cint,), 1) |
33 |
| - |
34 |
| -else |
35 |
| - |
36 |
| -@eval baremodule Compiler |
37 |
| - |
38 |
| -using Core.Intrinsics, Core.IR |
39 |
| - |
40 |
| -using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch, |
41 |
| - MethodTable, PartialOpaque, SimpleVector, TypeofVararg, |
42 |
| - _apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned, |
43 |
| - memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec, |
44 |
| - typename, unsafe_write, write |
45 |
| - |
46 |
| -using Base |
47 |
| -using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospecializeinfer, |
48 |
| - PARTITION_KIND_GLOBAL, PARTITION_KIND_UNDEF_CONST, PARTITION_KIND_BACKDATED_CONST, PARTITION_KIND_DECLARED, |
49 |
| - PARTITION_FLAG_DEPWARN, |
50 |
| - Base, BitVector, Bottom, Callable, DataTypeFieldDesc, |
51 |
| - EffectsOverride, Filter, Generator, IteratorSize, JLOptions, NUM_EFFECTS_OVERRIDES, |
52 |
| - OneTo, Ordering, RefValue, SizeUnknown, _NAMEDTUPLE_NAME, |
53 |
| - _array_for, _bits_findnext, _methods_by_ftype, _uniontypes, all, allocatedinline, any, |
54 |
| - argument_datatype, binding_kind, cconvert, copy_exprargs, datatype_arrayelem, |
55 |
| - datatype_fieldcount, datatype_fieldtypes, datatype_layoutsize, datatype_nfields, |
56 |
| - datatype_pointerfree, decode_effects_override, diff_names, fieldindex, |
57 |
| - generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars, |
58 |
| - hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def, |
59 |
| - is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, is_defined_const_binding, |
60 |
| - is_some_const_binding, is_some_guard, is_some_imported, is_some_explicit_imported, is_some_binding_imported, is_valid_intrinsic_elptr, |
61 |
| - isbitsunion, isconcretedispatch, isdispatchelem, isexpr, isfieldatomic, isidentityfree, |
62 |
| - iskindtype, ismutabletypename, ismutationfree, issingletontype, isvarargtype, isvatuple, |
63 |
| - kwerr, lookup_binding_partition, may_invoke_generator, methods, midpoint, moduleroot, |
64 |
| - partition_restriction, quoted, rename_unionall, rewrap_unionall, specialize_method, |
65 |
| - structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout, |
66 |
| - uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal, |
67 |
| - _uncompressed_ir, maybe_add_binding_backedge!, datatype_min_ninitialized, |
68 |
| - partialstruct_init_undefs, fieldcount_noerror |
69 |
| -using Base.Order |
70 |
| - |
71 |
| -import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!, |
72 |
| - getindex, haskey, in, isempty, isready, iterate, iterate, last, length, max_world, |
73 |
| - min_world, popfirst!, push!, resize!, setindex!, size, intersect |
74 |
| - |
75 |
| -# Needs to match UUID defined in Project.toml |
76 |
| -ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler, |
77 |
| - (0x807dbc54_b67e_4c79, 0x8afb_eafe4df6f2e1)) |
78 |
| - |
79 |
| -const getproperty = Core.getfield |
80 |
| -const setproperty! = Core.setfield! |
81 |
| -const swapproperty! = Core.swapfield! |
82 |
| -const modifyproperty! = Core.modifyfield! |
83 |
| -const replaceproperty! = Core.replacefield! |
84 |
| -const _DOCS_ALIASING_WARNING = "" |
85 |
| - |
86 |
| -ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Compiler, false) |
87 |
| - |
88 |
| -eval(x) = Core.eval(Compiler, x) |
89 |
| -eval(m, x) = Core.eval(m, x) |
90 |
| - |
91 |
| -function include(x::String) |
92 |
| - if !isdefined(Base, :end_base_include) |
93 |
| - # During bootstrap, all includes are relative to `base/` |
94 |
| - x = Base.strcat(Base.strcat(Base.DATAROOT, "julia/Compiler/src/"), x) |
95 |
| - end |
96 |
| - Base.include(Compiler, x) |
97 |
| -end |
98 |
| - |
99 |
| -function include(mod::Module, x::String) |
100 |
| - if !isdefined(Base, :end_base_include) |
101 |
| - x = Base.strcat(Base.strcat(Base.DATAROOT, "julia/Compiler/src/"), x) |
102 |
| - end |
103 |
| - Base.include(mod, x) |
104 |
| -end |
105 |
| - |
106 |
| -macro _boundscheck() Expr(:boundscheck) end |
107 |
| - |
108 |
| -function return_type end |
109 |
| -function is_return_type(Core.@nospecialize(f)) |
110 |
| - f === return_type && return true |
111 |
| - if isdefined(Base, :Compiler) && Compiler !== Base.Compiler |
112 |
| - # Also model the return_type function of the builtin Compiler the same. |
113 |
| - # This isn't completely sound. We don't actually have any idea what the |
114 |
| - # base compiler will do at runtime. In the fullness of time, we should |
115 |
| - # re-work the semantics to make the cache primary and thus avoid having |
116 |
| - # to reason about what the compiler may do at runtime, but we're not |
117 |
| - # fully there yet. |
118 |
| - return f === Base.Compiler.return_type |
119 |
| - end |
120 |
| - return false |
121 |
| -end |
122 |
| - |
123 |
| -include("profiling.jl") |
124 |
| -include("sort.jl") |
125 |
| - |
126 |
| -# We don't include some.jl, but this definition is still useful. |
127 |
| -something(x::Nothing, y...) = something(y...) |
128 |
| -something(x::Any, y...) = x |
129 |
| - |
130 |
| -############ |
131 |
| -# compiler # |
132 |
| -############ |
133 |
| - |
134 |
| -baremodule BuildSettings |
135 |
| -using Core: ARGS, include, Int, === |
136 |
| -using ..Compiler: >, getindex, length |
137 |
| - |
138 |
| -global MAX_METHODS::Int = 3 |
139 |
| - |
140 |
| -if length(ARGS) > 2 && ARGS[2] === "--buildsettings" |
141 |
| - include(BuildSettings, ARGS[3]) |
142 |
| -end |
143 |
| -end |
144 |
| - |
145 |
| -if !isdefined(Base, :end_base_include) |
146 |
| - macro show(ex...) |
147 |
| - blk = Expr(:block) |
148 |
| - for s in ex |
149 |
| - push!(blk.args, :(println(stdout, $(QuoteNode(s)), " = ", |
150 |
| - begin local value = $(esc(s)) end))) |
| 3 | +""" |
| 4 | + Compiler |
| 5 | +
|
| 6 | +This experimental standard library module provides an interface to Julia's internal compiler APIs. |
| 7 | +
|
| 8 | +By default, `Compiler` exports the same names as `Base.Compiler`, making its usage |
| 9 | +functionally equivalent to directly using `Base.Compiler`. |
| 10 | +Until proper versioning of the `Compiler.jl` standard library is implemented, this default |
| 11 | +fallback behavior is beneficial for maintaining compatibility among the Julia runtime, |
| 12 | +the Julia compiler, and external package implementations relying on the compiler internals. |
| 13 | +
|
| 14 | +To utilize this `Compiler.jl` standard library, you need to declare it as a dependency in |
| 15 | +your `Project.toml` as follows: |
| 16 | +> Project.toml |
| 17 | +```toml |
| 18 | +[deps] |
| 19 | +Compiler = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" |
| 20 | +
|
| 21 | +[compat] |
| 22 | +Compiler = "0" |
| 23 | +``` |
| 24 | +
|
| 25 | +You can switch to a custom implementation of the `Compiler` module by executing |
| 26 | +`pkg> dev /path/to/Compiler.jl` or `pkg> add https://url/of/Compiler/branch`. |
| 27 | +This feature is particularly useful for developing or experimenting with alternative |
| 28 | +compiler implementations. |
| 29 | +
|
| 30 | +!!! note |
| 31 | + The Compiler.jl standard library is available starting from Julia v1.10. |
| 32 | + However, switching to a custom compiler implementation is supported only from |
| 33 | + Julia v1.12 onwards. |
| 34 | +
|
| 35 | +!!! warning |
| 36 | + When using a custom, non-`Base` version of `Compiler` implementation, it may be necessary |
| 37 | + to run `InteractiveUtils.@activate Compiler` to ensure proper functionality of certain |
| 38 | + reflection utilities. |
| 39 | +""" |
| 40 | +baremodule Compiler |
| 41 | + |
| 42 | +using Base: Base |
| 43 | +const BaseCompiler = Base.:(>=)(Base.VERSION.minor, 12) ? Base.Compiler : Core.Compiler |
| 44 | +let names = Base.:(>=)(Base.VERSION.minor, 12) ? |
| 45 | + Base.names(BaseCompiler; all=true, imported=true, usings=true) : |
| 46 | + Base.names(BaseCompiler; all=true, imported=true) |
| 47 | + for name in names |
| 48 | + if name === :Compiler |
| 49 | + continue |
151 | 50 | end
|
152 |
| - isempty(ex) || push!(blk.args, :value) |
153 |
| - blk |
| 51 | + Core.eval(Compiler, :(using .BaseCompiler: $name)) |
| 52 | + Core.eval(Compiler, Expr(:public, name)) |
154 | 53 | end
|
155 |
| -else |
156 |
| - using Base: @show |
157 | 54 | end
|
158 | 55 |
|
159 |
| -include("cicache.jl") |
160 |
| -include("methodtable.jl") |
161 |
| -include("effects.jl") |
162 |
| -include("types.jl") |
163 |
| -include("utilities.jl") |
164 |
| -include("validation.jl") |
165 |
| - |
166 |
| -include("ssair/basicblock.jl") |
167 |
| -include("ssair/domtree.jl") |
168 |
| -include("ssair/ir.jl") |
169 |
| -include("ssair/tarjan.jl") |
170 |
| - |
171 |
| -include("abstractlattice.jl") |
172 |
| -include("stmtinfo.jl") |
173 |
| -include("inferenceresult.jl") |
174 |
| -include("inferencestate.jl") |
175 |
| - |
176 |
| -include("typeutils.jl") |
177 |
| -include("typelimits.jl") |
178 |
| -include("typelattice.jl") |
179 |
| -include("tfuncs.jl") |
180 |
| - |
181 |
| -include("abstractinterpretation.jl") |
182 |
| -include("typeinfer.jl") |
183 |
| -include("optimize.jl") |
184 |
| - |
185 |
| -include("bootstrap.jl") |
186 |
| -include("reflection_interface.jl") |
187 |
| -include("opaque_closure.jl") |
188 |
| - |
189 |
| -macro __SOURCE_FILE__() |
190 |
| - __source__.file === nothing && return nothing |
191 |
| - return QuoteNode(__source__.file::Symbol) |
192 | 56 | end
|
193 |
| - |
194 |
| -module IRShow end # relies on string and IO operations defined in Base |
195 |
| -baremodule TrimVerifier using Core end # relies on IRShow, so define this afterwards |
196 |
| - |
197 |
| -if isdefined(Base, :end_base_include) |
198 |
| - # When this module is loaded as the standard library, include these files as usual |
199 |
| - include(IRShow, "ssair/show.jl") |
200 |
| - include(TrimVerifier, "verifytrim.jl") |
201 |
| -else |
202 |
| - function load_irshow!() |
203 |
| - Base.delete_method(Base.which(verify_typeinf_trim, (IO, Vector{Any}, Bool)),) |
204 |
| - include(IRShow, "ssair/show.jl") |
205 |
| - include(TrimVerifier, "verifytrim.jl") |
206 |
| - end |
207 |
| - function verify_typeinf_trim(io::IO, codeinfos::Vector{Any}, onlywarn::Bool) |
208 |
| - # stub implementation |
209 |
| - msg = "--trim verifier not defined" |
210 |
| - onlywarn ? println(io, msg) : error(msg) |
211 |
| - end |
212 |
| - # During bootstrap, skip including these files and defer to base/show.jl to include it later |
213 |
| -end |
214 |
| - |
215 |
| -end # baremodule Compiler |
216 |
| - |
217 |
| -end # if isdefined(Base, :generating_output) && ... |
0 commit comments