From c68bff0716dfcf746f0046f64be64d01f766d2ff Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Fri, 22 Nov 2024 15:12:48 +0900 Subject: [PATCH] complete the tests for Compiler.jl as the stdlib. With JuliaLang/julia#56632, Compiler.jl as the stdlib can now be tested. However, the PR was incomplete, and when tests are actually run on `Compiler`, which is `!== Base.Compiler`, various errors occur, including issues caused by JuliaLang/julia#56647. This commit resolves all these issues: - manage the code for loading `Compiler` in `setup_Compiler.jl`, ensuring that the stdlib version of `Compiler` is loaded when `@activate Compiler` is used beforehand - replace `Base.IRShow` with `Compiler.IRShow` - test `Base.Compiler.return_type` instead of `Compiler.return_type` This was split off from JuliaLang/julia#56636. --- Compiler/src/ssair/verify.jl | 2 +- Compiler/test/AbstractInterpreter.jl | 8 ------ Compiler/test/EAUtils.jl | 18 +++++-------- Compiler/test/codegen.jl | 9 ++----- Compiler/test/compact.jl | 12 ++++----- Compiler/test/contextual.jl | 9 +------ Compiler/test/datastructures.jl | 10 ++------ Compiler/test/effects.jl | 2 ++ Compiler/test/inference.jl | 38 +++++++++++++++------------- Compiler/test/inline.jl | 4 +-- Compiler/test/interpreter_exec.jl | 10 ++------ Compiler/test/invalidation.jl | 6 ++--- Compiler/test/irutils.jl | 10 ++------ Compiler/test/runtests.jl | 9 ++++--- Compiler/test/setup_Compiler.jl | 9 +++++++ Compiler/test/ssair.jl | 12 +++------ Compiler/test/tarjan.jl | 2 ++ Compiler/test/validation.jl | 8 +----- 18 files changed, 69 insertions(+), 109 deletions(-) create mode 100644 Compiler/test/setup_Compiler.jl diff --git a/Compiler/src/ssair/verify.jl b/Compiler/src/ssair/verify.jl index 14ca6ef2dbe9a..59051058e1750 100644 --- a/Compiler/src/ssair/verify.jl +++ b/Compiler/src/ssair/verify.jl @@ -104,7 +104,7 @@ function verify_ir(ir::IRCode, print::Bool=true, error_args = Any["IR verification failed."] if isdefined(Core, :Main) && isdefined(Core.Main, :Base) # ensure we use I/O that does not yield, as this gets called during compilation - firstline = invokelatest(Core.Main.Base.IRShow.debuginfo_firstline, ir.debuginfo) + firstline = invokelatest(IRShow.debuginfo_firstline, ir.debuginfo) else firstline = nothing end diff --git a/Compiler/test/AbstractInterpreter.jl b/Compiler/test/AbstractInterpreter.jl index 81659443038e4..533eaf93937a3 100644 --- a/Compiler/test/AbstractInterpreter.jl +++ b/Compiler/test/AbstractInterpreter.jl @@ -2,14 +2,6 @@ using Test -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end - include("irutils.jl") include("newinterp.jl") diff --git a/Compiler/test/EAUtils.jl b/Compiler/test/EAUtils.jl index cec33ca265a80..5a5c42fc89106 100644 --- a/Compiler/test/EAUtils.jl +++ b/Compiler/test/EAUtils.jl @@ -2,13 +2,7 @@ module EAUtils export code_escapes, @code_escapes, __clear_cache! -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end +include("setup_Compiler.jl") using ..EscapeAnalysis const EA = EscapeAnalysis @@ -267,22 +261,22 @@ end function print_with_info(preprint, postprint, io::IO, ir::IRCode, source::Bool) io = IOContext(io, :displaysize=>displaysize(io)) - used = Base.IRShow.stmts_used(io, ir) + used = Compiler.IRShow.stmts_used(io, ir) if source line_info_preprinter = function (io::IO, indent::String, idx::Int) - r = Base.IRShow.inline_linfo_printer(ir)(io, indent, idx) + r = Compiler.IRShow.inline_linfo_printer(ir)(io, indent, idx) idx ≠ 0 && preprint(io, idx) return r end else - line_info_preprinter = Base.IRShow.lineinfo_disabled + line_info_preprinter = Compiler.IRShow.lineinfo_disabled end - line_info_postprinter = Base.IRShow.default_expr_type_printer + line_info_postprinter = Compiler.IRShow.default_expr_type_printer preprint(io) bb_idx_prev = bb_idx = 1 for idx = 1:length(ir.stmts) preprint(io, idx) - bb_idx = Base.IRShow.show_ir_stmt(io, ir, idx, line_info_preprinter, line_info_postprinter, ir.sptypes, used, ir.cfg, bb_idx) + bb_idx = Compiler.IRShow.show_ir_stmt(io, ir, idx, line_info_preprinter, line_info_postprinter, ir.sptypes, used, ir.cfg, bb_idx) postprint(io, idx, bb_idx != bb_idx_prev) bb_idx_prev = bb_idx end diff --git a/Compiler/test/codegen.jl b/Compiler/test/codegen.jl index 90ec16ca3b7ac..b6805a77124ca 100644 --- a/Compiler/test/codegen.jl +++ b/Compiler/test/codegen.jl @@ -5,14 +5,9 @@ using Random using InteractiveUtils using Libdl +using Test -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end +include("setup_Compiler.jl") const opt_level = Base.JLOptions().opt_level const coverage = (Base.JLOptions().code_coverage > 0) || (Base.JLOptions().malloc_log > 0) diff --git a/Compiler/test/compact.jl b/Compiler/test/compact.jl index a636ab8172d63..b01e209d5ce9b 100644 --- a/Compiler/test/compact.jl +++ b/Compiler/test/compact.jl @@ -1,10 +1,8 @@ -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Test + +include("irutils.jl") using .Compiler: IncrementalCompact, insert_node_here!, finish, NewInstruction, verify_ir, ReturnNode, SSAValue diff --git a/Compiler/test/contextual.jl b/Compiler/test/contextual.jl index 08dc68ba42b34..a9c63ab34c0c0 100644 --- a/Compiler/test/contextual.jl +++ b/Compiler/test/contextual.jl @@ -2,14 +2,7 @@ # N.B.: This file is also run from interpreter.jl, so needs to be standalone-executable using Test - -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end +include("setup_Compiler.jl") # Cassette # ======== diff --git a/Compiler/test/datastructures.jl b/Compiler/test/datastructures.jl index 6b37d7c89e684..608e4e770998a 100644 --- a/Compiler/test/datastructures.jl +++ b/Compiler/test/datastructures.jl @@ -1,12 +1,6 @@ -using Test +# This file is a part of Julia. License is MIT: https://julialang.org/license -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end +include("setup_Compiler.jl") @testset "CachedMethodTable" begin # cache result should be separated per `limit` and `sig` diff --git a/Compiler/test/effects.jl b/Compiler/test/effects.jl index e4677daf0c483..a7a1d18159137 100644 --- a/Compiler/test/effects.jl +++ b/Compiler/test/effects.jl @@ -1,3 +1,5 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + using Test include("irutils.jl") diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index c896c0c390285..ff27c3445f9d8 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Test + include("irutils.jl") # tests for Compiler correctness and precision @@ -823,7 +825,7 @@ end # Issue 19641 foo19641() = let a = 1.0 - Compiler.return_type(x -> x + a, Tuple{Float64}) + Base.Compiler.return_type(x -> x + a, Tuple{Float64}) end @inferred foo19641() @@ -977,15 +979,15 @@ test_no_apply(::Any) = true # issue #20033 # check return_type_tfunc for calls where no method matches -bcast_eltype_20033(f, A) = Compiler.return_type(f, Tuple{eltype(A)}) +bcast_eltype_20033(f, A) = Base.Compiler.return_type(f, Tuple{eltype(A)}) err20033(x::Float64...) = prod(x) @test bcast_eltype_20033(err20033, [1]) === Union{} @test Base.return_types(bcast_eltype_20033, (typeof(err20033), Vector{Int},)) == Any[Type{Union{}}] # return_type on builtins -@test Compiler.return_type(tuple, Tuple{Int,Int8,Int}) === Tuple{Int,Int8,Int} +@test Base.Compiler.return_type(tuple, Tuple{Int,Int8,Int}) === Tuple{Int,Int8,Int} # issue #21088 -@test Compiler.return_type(typeof, Tuple{Int}) == Type{Int} +@test Base.Compiler.return_type(typeof, Tuple{Int}) == Type{Int} # Inference of constant svecs @eval fsvecinf() = $(QuoteNode(Core.svec(Tuple{Int,Int}, Int)))[1] @@ -1535,7 +1537,7 @@ let nfields_tfunc(@nospecialize xs...) = @test sizeof_nothrow(String) @test !sizeof_nothrow(Type{String}) @test sizeof_tfunc(Type{Union{Int64, Int32}}) == Const(Core.sizeof(Union{Int64, Int32})) - let PT = Core.PartialStruct(Base.Compiler.fallback_lattice, Tuple{Int64,UInt64}, Any[Const(10), UInt64]) + let PT = Core.PartialStruct(Compiler.fallback_lattice, Tuple{Int64,UInt64}, Any[Const(10), UInt64]) @test sizeof_tfunc(PT) === Const(16) @test nfields_tfunc(PT) === Const(2) @test sizeof_nothrow(PT) @@ -2235,7 +2237,7 @@ end end |> only == Int # the `fargs = nothing` edge case @test Base.return_types((Any,)) do a - Compiler.return_type(invoke, Tuple{typeof(ispositive), Type{Tuple{Any}}, Any}) + Base.Compiler.return_type(invoke, Tuple{typeof(ispositive), Type{Tuple{Any}}, Any}) end |> only == Type{Bool} # `InterConditional` handling: `abstract_call_opaque_closure` @@ -3324,8 +3326,8 @@ _rttf_test(::Int16) = 0 _rttf_test(::Int32) = 0 _rttf_test(::Int64) = 0 _rttf_test(::Int128) = 0 -_call_rttf_test() = Compiler.return_type(_rttf_test, Tuple{Any}) -@test Compiler.return_type(_rttf_test, Tuple{Any}) === Int +_call_rttf_test() = Base.Compiler.return_type(_rttf_test, Tuple{Any}) +@test Base.Compiler.return_type(_rttf_test, Tuple{Any}) === Int @test _call_rttf_test() === Int f_with_Type_arg(::Type{T}) where {T} = T @@ -3379,9 +3381,9 @@ struct FooPartial b::Int c::Int end -let PT1 = PartialStruct(Base.Compiler.fallback_lattice, FooPartial, Any[Const(1), Const(2), Int]), - PT2 = PartialStruct(Base.Compiler.fallback_lattice, FooPartial, Any[Const(1), Int, Int]), - PT3 = PartialStruct(Base.Compiler.fallback_lattice, FooPartial, Any[Const(1), Int, Const(3)]) +let PT1 = PartialStruct(Compiler.fallback_lattice, FooPartial, Any[Const(1), Const(2), Int]), + PT2 = PartialStruct(Compiler.fallback_lattice, FooPartial, Any[Const(1), Int, Int]), + PT3 = PartialStruct(Compiler.fallback_lattice, FooPartial, Any[Const(1), Int, Const(3)]) @test PT1 ⊑ PT2 @test !(PT1 ⊑ PT3) && !(PT2 ⊑ PT1) @@ -4788,7 +4790,7 @@ end # at top level. @test let Base.Experimental.@force_compile - Compiler.return_type(+, NTuple{2, Rational}) + Base.Compiler.return_type(+, NTuple{2, Rational}) end == Rational # vararg-tuple comparison within `Compiler.PartialStruct` @@ -5186,9 +5188,9 @@ end |> only === Tuple{Int,Symbol} end end) == Type{Nothing} -# Test that Compiler.return_type inference works for the 1-arg version +# Test that Base.Compiler.return_type inference works for the 1-arg version @test Base.return_types() do - Compiler.return_type(Tuple{typeof(+), Int, Int}) + Base.Compiler.return_type(Tuple{typeof(+), Int, Int}) end |> only == Type{Int} # Test that NamedTuple abstract iteration works for PartialStruct/Const @@ -5725,7 +5727,7 @@ end @eval function has_tuin() $(Expr(:throw_undef_if_not, :x, false)) end -@test Compiler.return_type(has_tuin, Tuple{}) === Union{} +@test Base.infer_return_type(has_tuin, Tuple{}) === Union{} @test_throws UndefVarError has_tuin() function gen_tuin_from_arg(world::UInt, source, _, _) @@ -5780,7 +5782,7 @@ end # We want to make sure that both this returns `Tuple` and that # it doesn't infinite loop inside inference. -@test Compiler.return_type(gen_infinite_loop_ssa, Tuple{}) === Tuple +@test Base.infer_return_type(gen_infinite_loop_ssa, Tuple{}) === Tuple # inference local cache lookup with extended lattice elements that may be transformed # by `matching_cache_argtypes` @@ -5816,7 +5818,7 @@ function foo54341(a, b, c, d, args...) end bar54341(args...) = foo54341(4, args...) -@test Compiler.return_type(bar54341, Tuple{Vararg{Int}}) === Int +@test Base.infer_return_type(bar54341, Tuple{Vararg{Int}}) === Int # `PartialStruct` for partially initialized structs: struct PartiallyInitialized1 @@ -5953,7 +5955,7 @@ end # InterConditional rt with Vararg argtypes fcondvarargs(a, b, c, d) = isa(d, Int64) gcondvarargs(a, x...) = return fcondvarargs(a, x...) ? isa(a, Int64) : !isa(a, Int64) -@test Compiler.return_type(gcondvarargs, Tuple{Vararg{Any}}) === Bool +@test Base.infer_return_type(gcondvarargs, Tuple{Vararg{Any}}) === Bool # JuliaLang/julia#55627: argtypes check in `abstract_call_opaque_closure` issue55627_make_oc() = Base.Experimental.@opaque (x::Int) -> 2x diff --git a/Compiler/test/inline.jl b/Compiler/test/inline.jl index 158d9f545220a..46b78db3b781c 100644 --- a/Compiler/test/inline.jl +++ b/Compiler/test/inline.jl @@ -1857,7 +1857,7 @@ let i::Int, continue_::Bool ir = Compiler.ssa_inlining_pass!(ir, inlining, false) @test findfirst(isinvoke(:func_mul_int), ir.stmts.stmt) === nothing @test (i = findfirst(iscall((ir, Core.Intrinsics.mul_int)), ir.stmts.stmt)) !== nothing - lins = Base.IRShow.buildLineInfoNode(ir.debuginfo, nothing, i) + lins = Compiler.IRShow.buildLineInfoNode(ir.debuginfo, nothing, i) @test (continue_ = length(lins) == 2) # :multi_inlining1 -> :func_mul_int if continue_ def1 = lins[1].method @@ -1881,7 +1881,7 @@ let i::Int, continue_::Bool ir = Compiler.ssa_inlining_pass!(ir, inlining, false) @test findfirst(isinvoke(:func_mul_int), ir.stmts.stmt) === nothing @test (i = findfirst(iscall((ir, Core.Intrinsics.mul_int)), ir.stmts.stmt)) !== nothing - lins = Base.IRShow.buildLineInfoNode(ir.debuginfo, nothing, i) + lins = Compiler.IRShow.buildLineInfoNode(ir.debuginfo, nothing, i) @test_broken (continue_ = length(lins) == 3) # see TODO in `ir_inline_linetable!` if continue_ def1 = lins[1].method diff --git a/Compiler/test/interpreter_exec.jl b/Compiler/test/interpreter_exec.jl index 65f42a0c7b89b..4972df1a27202 100644 --- a/Compiler/test/interpreter_exec.jl +++ b/Compiler/test/interpreter_exec.jl @@ -1,17 +1,11 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license # tests that interpreter matches codegen +include("setup_Compiler.jl") + using Test using Core.IR -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end - # test that interpreter correctly handles PhiNodes (#29262) let m = Meta.@lower 1 + 1 @assert Meta.isexpr(m, :thunk) diff --git a/Compiler/test/invalidation.jl b/Compiler/test/invalidation.jl index c986cb298369f..2642c1647a682 100644 --- a/Compiler/test/invalidation.jl +++ b/Compiler/test/invalidation.jl @@ -104,7 +104,7 @@ begin let rt = only(Base.return_types(pr48932_callee, (Any,))) @test rt === Any effects = Base.infer_effects(pr48932_callee, (Any,)) - @test Compiler.Effects(effects) == Compiler.Effects() + @test effects == Compiler.Effects() end # run inference on both `pr48932_caller` and `pr48932_callee` @@ -171,7 +171,7 @@ begin take!(GLOBAL_BUFFER) let rt = only(Base.return_types(pr48932_callee_inferable, (Any,))) @test rt === Int effects = Base.infer_effects(pr48932_callee_inferable, (Any,)) - @test Compiler.Effects(effects) == Compiler.Effects() + @test effects == Compiler.Effects() end # run inference on both `pr48932_caller` and `pr48932_callee`: @@ -233,7 +233,7 @@ begin take!(GLOBAL_BUFFER) let rt = only(Base.return_types(pr48932_callee_inlined, (Any,))) @test rt === Any effects = Base.infer_effects(pr48932_callee_inlined, (Any,)) - @test Compiler.Effects(effects) == Compiler.Effects() + @test effects == Compiler.Effects() end # run inference on `pr48932_caller_inlined` and `pr48932_callee_inlined` diff --git a/Compiler/test/irutils.jl b/Compiler/test/irutils.jl index d1a3a2ea57c35..c1616ad4a8fd0 100644 --- a/Compiler/test/irutils.jl +++ b/Compiler/test/irutils.jl @@ -1,12 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end +include("setup_Compiler.jl") using Core.IR using .Compiler: IRCode, IncrementalCompact, singleton_type, VarState @@ -68,7 +62,7 @@ macro fully_eliminated(ex0...) end let m = Meta.@lower 1 + 1 - @assert Meta.isexpr(m, :thunk) + @assert isexpr(m, :thunk) orig_src = m.args[1]::CodeInfo global function make_codeinfo(code::Vector{Any}; ssavaluetypes::Union{Nothing,Vector{Any}}=nothing, diff --git a/Compiler/test/runtests.jl b/Compiler/test/runtests.jl index ea3df3aa2855d..6a38fce678ba0 100644 --- a/Compiler/test/runtests.jl +++ b/Compiler/test/runtests.jl @@ -3,7 +3,10 @@ using Test, Compiler using InteractiveUtils: @activate @activate Compiler -for file in readlines(joinpath(@__DIR__, "testgroups")) - file == "special_loading" && continue # Only applicable to Base.Compiler - include(file * ".jl") +@testset "Compiler.jl" begin + for file in readlines(joinpath(@__DIR__, "testgroups")) + file == "special_loading" && continue # Only applicable to Base.Compiler + testfile = file * ".jl" + @eval @testset $testfile include($testfile) + end end diff --git a/Compiler/test/setup_Compiler.jl b/Compiler/test/setup_Compiler.jl new file mode 100644 index 0000000000000..a28a3f918aaf9 --- /dev/null +++ b/Compiler/test/setup_Compiler.jl @@ -0,0 +1,9 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +if !@isdefined(Compiler) + if Base.REFLECTION_COMPILER[] === nothing + using Base.Compiler: Compiler + else + const Compiler = Base.REFLECTION_COMPILER[] + end +end diff --git a/Compiler/test/ssair.jl b/Compiler/test/ssair.jl index d6707e4dec9c2..6100aad673040 100644 --- a/Compiler/test/ssair.jl +++ b/Compiler/test/ssair.jl @@ -2,8 +2,8 @@ include("irutils.jl") -using Base.Meta -using Core.IR +using Test + using .Compiler: CFG, BasicBlock, NewSSAValue make_bb(preds, succs) = BasicBlock(Compiler.StmtRange(0, 0), preds, succs) @@ -393,13 +393,7 @@ f_if_typecheck() = (if nothing; end; unsafe_load(Ptr{Int}(0))) let # https://github.com/JuliaLang/julia/issues/42258 code = """ - if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end - end + using Base: Compiler function foo() a = @noinline rand(rand(0:10)) diff --git a/Compiler/test/tarjan.jl b/Compiler/test/tarjan.jl index 49124bdf650fe..aa04bd94a6f6a 100644 --- a/Compiler/test/tarjan.jl +++ b/Compiler/test/tarjan.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Test + include("irutils.jl") using .Compiler: CFGReachability, DomTree, CFG, BasicBlock, StmtRange, dominates, diff --git a/Compiler/test/validation.jl b/Compiler/test/validation.jl index 38dfa9705d542..5328516f63d36 100644 --- a/Compiler/test/validation.jl +++ b/Compiler/test/validation.jl @@ -2,13 +2,7 @@ using Test, Core.IR -if !@isdefined(Compiler) - if Base.identify_package("Compiler") === nothing - import Base.Compiler: Compiler - else - import Compiler - end -end +include("setup_Compiler.jl") function f22938(a, b, x...) nothing