Skip to content

Commit c396f3d

Browse files
authored
Merge branch 'master' into mem_truncate
2 parents 3083d4e + c894e04 commit c396f3d

File tree

124 files changed

+2564
-1382
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+2564
-1382
lines changed

Compiler/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "Compiler"
22
uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1"
3-
version = "0.0.3"
3+
version = "0.0.0"
44

55
[compat]
66
julia = "1.10"

Compiler/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# The `Compiler` module
2+
3+
This directory maintains the implementation of the Julia compiler.
4+
5+
Through a bootstrapping process, it is bundled into the Julia runtime as `Base.Compiler`.
6+
7+
You can also use this `Compiler` module as the `Compiler` standard library by following the steps below.
8+
9+
## How to use
10+
11+
To utilize this `Compiler.jl` standard library, you need to declare it as a dependency in
12+
your `Project.toml` as follows:
13+
> Project.toml
14+
```toml
15+
[deps]
16+
Compiler = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1"
17+
18+
[compat]
19+
Compiler = "0"
20+
```
21+
22+
With the setup above, [the special placeholder version (v0.0.0)](https://github.com/JuliaLang/BaseCompiler.jl)
23+
will be installed by default.[^1]
24+
25+
[^1]: Currently, only version v0.0.0 is registered in the [General](https://github.com/JuliaRegistries/General) registry.
26+
27+
If needed, you can switch to a custom implementation of the `Compiler` module by running
28+
```julia-repl
29+
pkg> dev /path/to/Compiler.jl # to use a local implementation
30+
```
31+
or
32+
```julia-repl
33+
pkg> add https://url/of/Compiler/branch # to use a remote implementation
34+
```
35+
This feature is particularly useful for developing or experimenting with alternative compiler implementations.
36+
37+
> [!note]
38+
> The Compiler.jl standard library is available starting from Julia v1.10.
39+
> However, switching to a custom compiler implementation is supported only from
40+
> Julia v1.12 onwards.
41+
42+
> [!warning]
43+
> When using a custom, non-`Base` version of `Compiler` implementation, it may be necessary
44+
> to run `InteractiveUtils.@activate Compiler` to ensure proper functionality of certain
45+
> reflection utilities.

Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ end
4747

4848
function Compiler.transform_result_for_cache(interp::SplitCacheInterp, result::Compiler.InferenceResult, edges::Compiler.SimpleVector)
4949
opt = result.src::Compiler.OptimizationState
50-
ir = opt.result.ir::Compiler.IRCode
50+
ir = opt.optresult.ir::Compiler.IRCode
5151
override = with_new_compiler
5252
for inst in ir.stmts
5353
stmt = inst[:stmt]

Compiler/src/Compiler.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali
6565
structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout,
6666
uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal,
6767
_uncompressed_ir, maybe_add_binding_backedge!, datatype_min_ninitialized,
68-
partialstruct_init_undefs, fieldcount_noerror
68+
partialstruct_init_undefs, fieldcount_noerror, _eval_import, _eval_using
6969
using Base.Order
7070

7171
import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!,

Compiler/src/abstractinterpretation.jl

Lines changed: 128 additions & 74 deletions
Large diffs are not rendered by default.

Compiler/src/optimize.jl

Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,14 @@ function inline_cost_clamp(x::Int)
116116
return convert(InlineCostType, x)
117117
end
118118

119+
const SRC_FLAG_DECLARED_INLINE = 0x1
120+
const SRC_FLAG_DECLARED_NOINLINE = 0x2
121+
119122
is_declared_inline(@nospecialize src::MaybeCompressed) =
120-
ccall(:jl_ir_flag_inlining, UInt8, (Any,), src) == 1
123+
ccall(:jl_ir_flag_inlining, UInt8, (Any,), src) == SRC_FLAG_DECLARED_INLINE
121124

122125
is_declared_noinline(@nospecialize src::MaybeCompressed) =
123-
ccall(:jl_ir_flag_inlining, UInt8, (Any,), src) == 2
126+
ccall(:jl_ir_flag_inlining, UInt8, (Any,), src) == SRC_FLAG_DECLARED_NOINLINE
124127

125128
#####################
126129
# OptimizationState #
@@ -157,6 +160,7 @@ code_cache(state::InliningState) = WorldView(code_cache(state.interp), state.wor
157160

158161
mutable struct OptimizationResult
159162
ir::IRCode
163+
inline_flag::UInt8
160164
simplified::Bool # indicates whether the IR was processed with `cfg_simplify!`
161165
end
162166

@@ -168,7 +172,7 @@ end
168172
mutable struct OptimizationState{Interp<:AbstractInterpreter}
169173
linfo::MethodInstance
170174
src::CodeInfo
171-
result::Union{Nothing, OptimizationResult}
175+
optresult::Union{Nothing, OptimizationResult}
172176
stmt_info::Vector{CallInfo}
173177
mod::Module
174178
sptypes::Vector{VarState}
@@ -236,13 +240,29 @@ include("ssair/EscapeAnalysis.jl")
236240
include("ssair/passes.jl")
237241
include("ssair/irinterp.jl")
238242

243+
function ir_to_codeinf!(opt::OptimizationState, frame::InferenceState, edges::SimpleVector)
244+
ir_to_codeinf!(opt, edges, compute_inlining_cost(frame.interp, frame.result, opt.optresult))
245+
end
246+
247+
function ir_to_codeinf!(opt::OptimizationState, edges::SimpleVector, inlining_cost::InlineCostType)
248+
src = ir_to_codeinf!(opt, edges)
249+
src.inlining_cost = inlining_cost
250+
src
251+
end
252+
253+
function ir_to_codeinf!(opt::OptimizationState, edges::SimpleVector)
254+
src = ir_to_codeinf!(opt)
255+
src.edges = edges
256+
src
257+
end
258+
239259
function ir_to_codeinf!(opt::OptimizationState)
240-
(; linfo, src, result) = opt
241-
if result === nothing
260+
(; linfo, src, optresult) = opt
261+
if optresult === nothing
242262
return src
243263
end
244-
src = ir_to_codeinf!(src, result.ir)
245-
opt.result = nothing
264+
src = ir_to_codeinf!(src, optresult.ir)
265+
opt.optresult = nothing
246266
opt.src = src
247267
maybe_validate_code(linfo, src, "optimized")
248268
return src
@@ -485,63 +505,12 @@ end
485505
abstract_eval_ssavalue(s::SSAValue, src::Union{IRCode,IncrementalCompact}) = types(src)[s]
486506

487507
"""
488-
finish(interp::AbstractInterpreter, opt::OptimizationState,
489-
ir::IRCode, caller::InferenceResult)
508+
finishopt!(interp::AbstractInterpreter, opt::OptimizationState, ir::IRCode)
490509
491-
Post-process information derived by Julia-level optimizations for later use.
492-
In particular, this function determines the inlineability of the optimized code.
510+
Called at the end of optimization to store the resulting IR back into the OptimizationState.
493511
"""
494-
function finish(interp::AbstractInterpreter, opt::OptimizationState,
495-
ir::IRCode, caller::InferenceResult)
496-
(; src, linfo) = opt
497-
(; def, specTypes) = linfo
498-
499-
force_noinline = is_declared_noinline(src)
500-
501-
# compute inlining and other related optimizations
502-
result = caller.result
503-
@assert !(result isa LimitedAccuracy)
504-
result = widenslotwrapper(result)
505-
506-
opt.result = OptimizationResult(ir, false)
507-
508-
# determine and cache inlineability
509-
if !force_noinline
510-
sig = unwrap_unionall(specTypes)
511-
if !(isa(sig, DataType) && sig.name === Tuple.name)
512-
force_noinline = true
513-
end
514-
if !is_declared_inline(src) && result === Bottom
515-
force_noinline = true
516-
end
517-
end
518-
if force_noinline
519-
set_inlineable!(src, false)
520-
elseif isa(def, Method)
521-
if is_declared_inline(src) && isdispatchtuple(specTypes)
522-
# obey @inline declaration if a dispatch barrier would not help
523-
set_inlineable!(src, true)
524-
else
525-
# compute the cost (size) of inlining this code
526-
params = OptimizationParams(interp)
527-
cost_threshold = default = params.inline_cost_threshold
528-
if (optimizer_lattice(interp), result, Tuple) && !isconcretetype(widenconst(result))
529-
cost_threshold += params.inline_tupleret_bonus
530-
end
531-
# if the method is declared as `@inline`, increase the cost threshold 20x
532-
if is_declared_inline(src)
533-
cost_threshold += 19*default
534-
end
535-
# a few functions get special treatment
536-
if def.module === _topmod(def.module)
537-
name = def.name
538-
if name === :iterate || name === :unsafe_convert || name === :cconvert
539-
cost_threshold += 4*default
540-
end
541-
end
542-
src.inlining_cost = inline_cost(ir, params, cost_threshold)
543-
end
544-
end
512+
function finishopt!(interp::AbstractInterpreter, opt::OptimizationState, ir::IRCode)
513+
opt.optresult = OptimizationResult(ir, ccall(:jl_ir_flag_inlining, UInt8, (Any,), opt.src), false)
545514
return nothing
546515
end
547516

@@ -1015,7 +984,8 @@ end
1015984
function optimize(interp::AbstractInterpreter, opt::OptimizationState, caller::InferenceResult)
1016985
@zone "CC: OPTIMIZER" ir = run_passes_ipo_safe(opt.src, opt)
1017986
ipo_dataflow_analysis!(interp, opt, ir, caller)
1018-
return finish(interp, opt, ir, caller)
987+
finishopt!(interp, opt, ir)
988+
return nothing
1019989
end
1020990

1021991
const ALL_PASS_NAMES = String[]
@@ -1466,7 +1436,7 @@ function statement_or_branch_cost(@nospecialize(stmt), line::Int, src::Union{Cod
14661436
return thiscost
14671437
end
14681438

1469-
function inline_cost(ir::IRCode, params::OptimizationParams, cost_threshold::Int)
1439+
function inline_cost_model(ir::IRCode, params::OptimizationParams, cost_threshold::Int)
14701440
bodycost = 0
14711441
for i = 1:length(ir.stmts)
14721442
stmt = ir[SSAValue(i)][:stmt]

Compiler/src/ssair/inlining.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ function retrieve_ir_for_inlining(mi::MethodInstance, ir::IRCode, preserve_local
976976
return ir, spec_info, DebugInfo(ir.debuginfo, length(ir.stmts))
977977
end
978978
function retrieve_ir_for_inlining(mi::MethodInstance, opt::OptimizationState, preserve_local_sources::Bool)
979-
result = opt.result
979+
result = opt.optresult
980980
if result !== nothing
981981
!result.simplified && simplify_ir!(result)
982982
return retrieve_ir_for_inlining(mi, result.ir, preserve_local_sources)

Compiler/src/tfuncs.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,10 @@ end
450450
return Const(true)
451451
end
452452
end
453+
# datatype_fieldcount is what `fieldcount` uses internally
454+
# and returns nothing (!==0) for non-definite field counts.
455+
elseif datatype_fieldcount(a1) === 0
456+
return Const(false)
453457
end
454458
elseif isa(a1, Union)
455459
# Results can only be `Const` or `Bool`

0 commit comments

Comments
 (0)