Skip to content

Commit

Permalink
complete the tests for Compiler.jl as the stdlib.
Browse files Browse the repository at this point in the history
With #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 #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 #56636.
  • Loading branch information
aviatesk committed Nov 22, 2024
1 parent 1bf2ef9 commit c68bff0
Show file tree
Hide file tree
Showing 18 changed files with 69 additions and 109 deletions.
2 changes: 1 addition & 1 deletion Compiler/src/ssair/verify.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 0 additions & 8 deletions Compiler/test/AbstractInterpreter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
18 changes: 6 additions & 12 deletions Compiler/test/EAUtils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 2 additions & 7 deletions Compiler/test/codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 5 additions & 7 deletions Compiler/test/compact.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
9 changes: 1 addition & 8 deletions Compiler/test/contextual.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ========
Expand Down
10 changes: 2 additions & 8 deletions Compiler/test/datastructures.jl
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
2 changes: 2 additions & 0 deletions Compiler/test/effects.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

using Test
include("irutils.jl")

Expand Down
38 changes: 20 additions & 18 deletions Compiler/test/inference.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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, _, _)
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Compiler/test/inline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 2 additions & 8 deletions Compiler/test/interpreter_exec.jl
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
6 changes: 3 additions & 3 deletions Compiler/test/invalidation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -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`:
Expand Down Expand Up @@ -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`
Expand Down
10 changes: 2 additions & 8 deletions Compiler/test/irutils.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
Expand Down
9 changes: 6 additions & 3 deletions Compiler/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 9 additions & 0 deletions Compiler/test/setup_Compiler.jl
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit c68bff0

Please sign in to comment.