diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index fc8b954f..2acb39e3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -38,7 +38,10 @@ jobs: ${{ runner.os }}- - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - - name: Bounds check + - name: Coverage off # `empty_func` test doesn't work as intended with `coverage=true` + if: ${{ matrix.os == 'ubuntu-latest' }} + run: julia --project -e 'using Pkg; Pkg.test("Cthulhu"; coverage=false)' + - name: Bounds/DCE check if: ${{ matrix.os == 'ubuntu-latest' }} run: julia --project --code-coverage -e 'using Pkg; Pkg.add(["Revise", "StaticArrays"]); cd("test"); include("runtests.jl")' - uses: julia-actions/julia-processcoverage@v1 diff --git a/src/Cthulhu.jl b/src/Cthulhu.jl index 9a5bad23..bdd1348b 100644 --- a/src/Cthulhu.jl +++ b/src/Cthulhu.jl @@ -178,11 +178,20 @@ function lookup(interp::CthulhuInterpreter, mi::MethodInstance, optimize::Bool) end else codeinst = interp.opt[mi] - ir = Core.Compiler.copy(codeinst.inferred.ir::IRCode) - codeinf = ir rt = codeinst_rt(codeinst) - infos = ir.stmts.info - slottypes = ir.argtypes + codeinf0 = codeinst.inferred + if codeinf0 !== nothing + ir = Core.Compiler.copy(codeinf0.ir::IRCode) + codeinf = ir + infos = ir.stmts.info + slottypes = ir.argtypes + else + # This doesn't showed up as covered, but it is (see the CI test with `coverage=false`). + # But with coverage on, the empty function body isn't empty due to :code_coverage_effect expressions. + codeinf = nothing + infos = [] + slottypes = Any[Base.unwrap_unionall(mi.specTypes).parameters...] + end end (codeinf, rt, infos, slottypes::Vector{Any}) end diff --git a/src/reflection.jl b/src/reflection.jl index 1473edef..530d2ca5 100644 --- a/src/reflection.jl +++ b/src/reflection.jl @@ -76,7 +76,7 @@ function find_callsites(interp::CthulhuInterpreter, CI::Union{Core.CodeInfo, IRC elseif isa(info, UnionSplitInfo) return mapreduce(process_info, vcat, info.matches) elseif isa(info, UnionSplitApplyCallInfo) - return mapreduce(process_info, vcat, info.infos) + return mapreduce(process_info, vcat, info.infos; init=Core.Compiler.ApplyCallInfo[]) elseif isa(info, ApplyCallInfo) # XXX: This could probably use its own info. For now, # we ignore any implicit iterate calls. diff --git a/test/runtests.jl b/test/runtests.jl index 82966119..39ca4b8b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -25,12 +25,15 @@ end function process(@nospecialize(f), @nospecialize(TT); optimize=true) (interp, mi) = Cthulhu.mkinterp(f, TT) (ci, rt, infos, slottypes) = Cthulhu.lookup(interp, mi, optimize) - ci = Cthulhu.preprocess_ci!(ci, mi, optimize, Cthulhu.CthulhuConfig(dead_code_elimination=true)) + if ci !== nothing + ci = Cthulhu.preprocess_ci!(ci, mi, optimize, Cthulhu.CthulhuConfig(dead_code_elimination=true)) + end interp, ci, infos, mi, rt, slottypes end function find_callsites_by_ftt(@nospecialize(f), @nospecialize(TT=Tuple{}); optimize=true) interp, ci, infos, mi, _, slottypes = process(f, TT; optimize) + ci === nothing && return Cthulhu.Callsite[] callsites = Cthulhu.find_callsites(interp, ci, infos, mi, slottypes, optimize) return callsites end @@ -44,12 +47,27 @@ function test() sum(rand(T, 100)) end -let callsites = find_callsites_by_ftt(test, Tuple{}) - @test length(callsites) >= 4 +function empty_func(::Bool) end -let callsites = find_callsites_by_ftt(test, Tuple{}; optimize=false) +isordered(::Type{T}) where {T<:AbstractDict} = false + +@testset "Callsites" begin + callsites = find_callsites_by_ftt(test, Tuple{}) + @test length(callsites) >= 4 + + callsites = find_callsites_by_ftt(test, Tuple{}; optimize=false) @test length(callsites) == 4 + + callsites = find_callsites_by_ftt(empty_func, Tuple{Bool}; optimize=true) + @test isempty(callsites) + + # Some weird methods get inferred + callsites = find_callsites_by_ftt(iterate, (Base.IdSet{Any}, Union{}); optimize=false) + @test callsites[1].info isa Cthulhu.ConstPropCallInfo + + # Broken stuff in Julia + @test_broken find_callsites_by_ftt(Core.Compiler._limit_type_size, Tuple{Any, Type{Any}, Core.SimpleVector, Int, Int}) # ssair/ir.jl bug end @testset "Expr heads" begin