From 1843201324b4b3fba7d32185c29e0aadd22a44f0 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 20 Sep 2021 13:57:12 +0900 Subject: [PATCH] optimizer: fix #42246, set `ssaflags` correctly when inserting coverage statements (#42260) It seems that this change still doesn't resolve #42258 though. --- base/compiler/optimize.jl | 13 +++++++++---- base/compiler/ssair/ir.jl | 6 +++--- base/compiler/ssair/legacy.jl | 2 +- base/compiler/ssair/slot2ssa.jl | 2 +- base/compiler/typeinfer.jl | 2 +- test/compiler/inline.jl | 22 ++++++++++++++++++++++ 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index fe0c058c533cb..5acfd22eb995a 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -142,6 +142,7 @@ const SLOT_USEDUNDEF = 32 # slot has uses that might raise UndefVarError # NOTE make sure to sync the flag definitions below with julia.h and `jl_code_info_set_ir` in method.c +const IR_FLAG_NULL = 0x00 # This statement is marked as @inbounds by user. # Ff replaced by inlining, any contained boundschecks may be removed. const IR_FLAG_INBOUNDS = 0x01 << 0 @@ -349,15 +350,18 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, sv:: labelmap = coverage ? fill(0, length(code)) : changemap prevloc = zero(eltype(ci.codelocs)) stmtinfo = sv.stmt_info + codelocs = ci.codelocs ssavaluetypes = ci.ssavaluetypes::Vector{Any} + ssaflags = ci.ssaflags while idx <= length(code) - codeloc = ci.codelocs[idx] + codeloc = codelocs[idx] if coverage && codeloc != prevloc && codeloc != 0 # insert a side-effect instruction before the current instruction in the same basic block insert!(code, idx, Expr(:code_coverage_effect)) - insert!(ci.codelocs, idx, codeloc) + insert!(codelocs, idx, codeloc) insert!(ssavaluetypes, idx, Nothing) insert!(stmtinfo, idx, nothing) + insert!(ssaflags, idx, IR_FLAG_NULL) changemap[oldidx] += 1 if oldidx < length(labelmap) labelmap[oldidx + 1] += 1 @@ -369,9 +373,10 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, sv:: if !(idx < length(code) && isa(code[idx + 1], ReturnNode) && !isdefined((code[idx + 1]::ReturnNode), :val)) # insert unreachable in the same basic block after the current instruction (splitting it) insert!(code, idx + 1, ReturnNode()) - insert!(ci.codelocs, idx + 1, ci.codelocs[idx]) + insert!(codelocs, idx + 1, codelocs[idx]) insert!(ssavaluetypes, idx + 1, Union{}) insert!(stmtinfo, idx + 1, nothing) + insert!(ssaflags, idx + 1, ssaflags[idx]) if oldidx < length(changemap) changemap[oldidx + 1] += 1 coverage && (labelmap[oldidx + 1] += 1) @@ -391,7 +396,7 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, sv:: strip_trailing_junk!(ci, code, stmtinfo) cfg = compute_basic_blocks(code) types = Any[] - stmts = InstructionStream(code, types, stmtinfo, ci.codelocs, ci.ssaflags) + stmts = InstructionStream(code, types, stmtinfo, codelocs, ssaflags) ir = IRCode(stmts, cfg, collect(LineInfoNode, ci.linetable::Union{Vector{LineInfoNode},Vector{Any}}), sv.slottypes, meta, sv.sptypes) return ir end diff --git a/base/compiler/ssair/ir.jl b/base/compiler/ssair/ir.jl index a2eaf5c69cbdd..d3d62c9b2dfaa 100644 --- a/base/compiler/ssair/ir.jl +++ b/base/compiler/ssair/ir.jl @@ -172,7 +172,7 @@ end NewInstruction(@nospecialize(stmt), @nospecialize(type)) = NewInstruction(stmt, type, nothing) NewInstruction(@nospecialize(stmt), @nospecialize(type), line::Union{Nothing, Int32}) = - NewInstruction(stmt, type, nothing, line, 0x00, false) + NewInstruction(stmt, type, nothing, line, IR_FLAG_NULL, false) effect_free(inst::NewInstruction) = NewInstruction(inst.stmt, inst.type, inst.info, inst.line, inst.flag | IR_FLAG_EFFECT_FREE, true) @@ -193,7 +193,7 @@ function InstructionStream(len::Int) info = Array{Any}(undef, len) fill!(info, nothing) lines = fill(Int32(0), len) - flags = fill(0x00, len) + flags = fill(IR_FLAG_NULL, len) return InstructionStream(insts, types, info, lines, flags) end InstructionStream() = InstructionStream(0) @@ -221,7 +221,7 @@ function resize!(stmts::InstructionStream, len) resize!(stmts.flag, len) for i in (old_length + 1):len stmts.line[i] = 0 - stmts.flag[i] = 0x00 + stmts.flag[i] = IR_FLAG_NULL stmts.info[i] = nothing end return stmts diff --git a/base/compiler/ssair/legacy.jl b/base/compiler/ssair/legacy.jl index a832daa8ed418..4d2bafc2f38d9 100644 --- a/base/compiler/ssair/legacy.jl +++ b/base/compiler/ssair/legacy.jl @@ -48,7 +48,7 @@ function replace_code_newstyle!(ci::CodeInfo, ir::IRCode, nargs::Int) push!(ci.code, metanode) push!(ci.codelocs, 1) push!(ci.ssavaluetypes::Vector{Any}, Any) - push!(ci.ssaflags, 0x00) + push!(ci.ssaflags, IR_FLAG_NULL) end # Translate BB Edges to statement edges # (and undo normalization for now) diff --git a/base/compiler/ssair/slot2ssa.jl b/base/compiler/ssair/slot2ssa.jl index 489c98c6549cc..656df9b17e4c4 100644 --- a/base/compiler/ssair/slot2ssa.jl +++ b/base/compiler/ssair/slot2ssa.jl @@ -195,7 +195,7 @@ function strip_trailing_junk!(ci::CodeInfo, code::Vector{Any}, info::Vector{Any} push!(ssavaluetypes, Union{}) push!(ci.codelocs, 0) push!(info, nothing) - push!(ci.ssaflags, 0x00) + push!(ci.ssaflags, IR_FLAG_NULL) end nothing end diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index f301b8a1756d9..c3b7c4dc3a3d0 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -866,7 +866,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance) tree.code = Any[ ReturnNode(quoted(rettype_const)) ] nargs = Int(method.nargs) tree.slotnames = ccall(:jl_uncompress_argnames, Vector{Symbol}, (Any,), method.slot_syms) - tree.slotflags = fill(0x00, nargs) + tree.slotflags = fill(IR_FLAG_NULL, nargs) tree.ssavaluetypes = 1 tree.codelocs = Int32[1] tree.linetable = [LineInfoNode(method.module, method.name, method.file, Int(method.line), 0)] diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index a276e6ef65c77..e26d834817d7f 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -650,3 +650,25 @@ let @test ninlined == length(code) end end + +# https://github.com/JuliaLang/julia/issues/42246 +@test mktempdir() do dir + cd(dir) do + code = quote + issue42246() = @noinline IOBuffer("a") + let + ci, rt = only(code_typed(issue42246)) + if any(ci.code) do stmt + Meta.isexpr(stmt, :invoke) && + stmt.args[1].def.name === nameof(IOBuffer) + end + exit(0) + else + exit(1) + end + end + end |> string + cmd = `$(Base.julia_cmd()) --code-coverage=tmp.info -e $code` + success(pipeline(Cmd(cmd); stdout=stdout, stderr=stderr)) + end +end