Skip to content

Commit

Permalink
update to avi/typelattice, incoming type lattice overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Jan 11, 2022
1 parent ef15b4c commit 22726ec
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 26 deletions.
59 changes: 51 additions & 8 deletions src/Cthulhu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ using InteractiveUtils
using UUIDs
using REPL: REPL, AbstractTerminal

using Core: MethodInstance
import Core: MethodInstance, OpaqueClosure
const Compiler = Core.Compiler
import Core.Compiler: MethodMatch, LimitedAccuracy, ignorelimited, specialize_method
import Core.Compiler: MethodMatch, specialize_method, widenconst,
LimitedAccuracy, Const, PartialStruct, InterConditional, PartialOpaque
import Base: unwrapva, isvarargtype, unwrap_unionall, rewrap_unionall

const mapany = Base.mapany

# branch on https://github.com/JuliaLang/julia/pull/42125
Expand All @@ -21,6 +23,17 @@ else
macro constprop(_, ex); esc(ex); end
end

const IS_OVERHAULED = isdefined(Core.Compiler, :LatticeElement)
@static if IS_OVERHAULED
import Core.Compiler: ⊤, ⊥, LatticeElement, NativeType, LatticeElement, isConst,
isLimitedAccuracy, Argtypes, SSAValueTypes
ignorelimited(@nospecialize x) = isa(x, LatticeElement) ? Core.Compiler.ignorelimited(x) : x
else
import Core.Compiler: ignorelimited
const Argtypes = Vector{Any}
const SSAValueTypes = Vector{Any}
end

Base.@kwdef mutable struct CthulhuConfig
enable_highlighter::Bool = false
highlighter::Cmd = `pygmentize -l`
Expand Down Expand Up @@ -212,15 +225,36 @@ end

descend(interp::CthulhuInterpreter, mi::MethodInstance; kwargs...) = _descend(interp, mi; iswarn=false, interruptexc=false, kwargs...)

@static if IS_OVERHAULED
import Core.Compiler: ConditionalInfo
function codeinst_rt(code::CodeInstance)
rettype = code.rettype
if isdefined(code, :rettype_const)
rettype_const = code.rettype_const
if isa(rettype_const, Vector{Any}) && !(Vector{Any} <: rettype)
return Core.PartialStruct(rettype, rettype_const)
elseif isa(rettype_const, Core.PartialOpaque) && rettype <: Core.OpaqueClosure
return PartialStruct(rettype, rettype_const)
elseif isa(rettype_const, PartialOpaque) && rettype <: OpaqueClosure
return rettype_const
elseif isa(rettype_const, Core.InterConditional) && !(Core.InterConditional <: rettype)
elseif isa(rettype_const, ConditionalInfo) && !(ConditionalInfo <: rettype)
@assert rettype_const.inter
return InterConditional(rettype_const.slot_id, rettype_const.vtype, rettype_const.elsetype), mi
else
return Const(rettype_const)
end
else
return rettype
end
end
else # @static if IS_OVERHAULED
function codeinst_rt(code::CodeInstance)
rettype = code.rettype
if isdefined(code, :rettype_const)
rettype_const = code.rettype_const
if isa(rettype_const, Vector{Any}) && !(Vector{Any} <: rettype)
return PartialStruct(rettype, rettype_const)
elseif isa(rettype_const, PartialOpaque) && rettype <: OpaqueClosure
return rettype_const
elseif isa(rettype_const, InterConditional) && !(InterConditional <: rettype)
return rettype_const
else
return Const(rettype_const)
Expand All @@ -229,6 +263,7 @@ function codeinst_rt(code::CodeInstance)
return rettype
end
end
end # @static if IS_OVERHAULED

# `@constprop :aggressive` here in order to make sure the constant propagation of `allow_no_src`
@constprop :aggressive function lookup(interp::CthulhuInterpreter, mi::MethodInstance, optimize::Bool; allow_no_src::Bool=false)
Expand All @@ -238,7 +273,11 @@ end
infos = interp.unopt[mi].stmt_info
slottypes = src.slottypes
if isnothing(slottypes)
slottypes = Any[ Any for i = 1:length(src.slotflags) ]
@static if IS_OVERHAULED
slottypes = LatticeElement[ ⊤ for i = 1:length(src.slotflags) ]
else
slottypes = Any[ Any for i = 1:length(src.slotflags) ]
end
end
else
codeinst = interp.opt[mi]
Expand All @@ -255,7 +294,11 @@ end
# But with coverage on, the empty function body isn't empty due to :code_coverage_effect expressions.
codeinf = src = nothing
infos = []
slottypes = Any[Base.unwrap_unionall(mi.specTypes).parameters...]
@static if IS_OVERHAULED
slottypes = AbstractLatticce[NativeType(t) for t in Base.unwrap_unionall(mi.specTypes).parameters]
else
slottypes = Any[Base.unwrap_unionall(mi.specTypes).parameters...]
end
else
Core.eval(Main, quote
interp = $interp
Expand All @@ -266,7 +309,7 @@ end
end
end
# NOTE return `codeinf::CodeInfo` in any case since it can provide additional information on slot names
(; src, rt, infos, slottypes, codeinf)
return (; src, rt, infos, slottypes, codeinf)
end

##
Expand Down
8 changes: 4 additions & 4 deletions src/callsite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ struct MICallInfo <: CallInfo
mi::MethodInstance
rt
function MICallInfo(mi::MethodInstance, @nospecialize(rt))
if isa(rt, LimitedAccuracy)
if @static IS_OVERHAULED ? isLimitedAccuracy(rt) : isa(rt, LimitedAccuracy)
return LimitedCallInfo(new(mi, ignorelimited(rt)))
else
return new(mi, rt)
Expand Down Expand Up @@ -36,9 +36,9 @@ struct UncachedCallInfo <: WrappedCallInfo
end

struct PureCallInfo <: CallInfo
argtypes::Vector{Any}
argtypes::Argtypes
rt
PureCallInfo(argtypes::Vector{Any}, @nospecialize(rt)) =
PureCallInfo(argtypes::Argtypes, @nospecialize(rt)) =
new(argtypes, rt)
end
get_mi(::PureCallInfo) = nothing
Expand Down Expand Up @@ -242,7 +242,7 @@ end
function show_callinfo(limiter, ci::Union{MultiCallInfo, FailedCallInfo, GeneratedCallInfo})
types = (ci.sig::DataType).parameters
ft, tt = types[1], types[2:end]
f = Compiler.singleton_type(ft)
f = Compiler.singleton_type((@static IS_OVERHAULED ? LatticeElement : identity)(ft))
if f !== nothing
name = "$f"
elseif ft isa Union
Expand Down
14 changes: 10 additions & 4 deletions src/codeview.jl
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,11 @@ function cthulhu_typed(io::IO, debuginfo::Symbol,
if isa(src, Core.CodeInfo)
# we're working on pre-optimization state, need to ignore `LimitedAccuracy`
src = copy(src)
src.ssavaluetypes = Base.mapany(ignorelimited, src.ssavaluetypes::Vector{Any})
@static if IS_OVERHAULED
src.ssavaluetypes = SSAValueTypes([ignorelimited(t) for t in src.ssavaluetypes::SSAValueTypes])
else
src.ssavaluetypes = Base.mapany(ignorelimited, src.ssavaluetypes::SSAValueTypes)
end
src.rettype = ignorelimited(src.rettype)

if src.slotnames !== nothing
Expand All @@ -144,8 +148,9 @@ function cthulhu_typed(io::IO, debuginfo::Symbol,
isa(mi, MethodInstance) || throw("`mi::MethodInstance` is required")
code = src isa IRCode ? src.stmts.inst : src.code
cst = Vector{Int}(undef, length(code))
sptypes = Core.Compiler.sptypes_from_meth_instance(mi)
params = Core.Compiler.OptimizationParams(interp)
maxcost = Core.Compiler.statement_costs!(cst, code, src, Any[mi.sparam_vals...], false, params)
maxcost = Core.Compiler.statement_costs!(cst, code, src, sptypes, false, params)
nd = ndigits(maxcost)
_lineprinter = lineprinter(src)
function preprinter(io, linestart, idx)
Expand Down Expand Up @@ -195,8 +200,9 @@ function show_variables(io, src, slotnames)
slottypes = src.slottypes
for i = 1:length(slotnames)
print(io, " ", slotnames[i])
if isa(slottypes, Vector{Any})
InteractiveUtils.warntype_type_printer(io, slottypes[i], true)
if isa(slottypes, Argtypes)
typ = (@static IS_OVERHAULED ? Core.Compiler.unwraptype : identity)(slottypes[i])
InteractiveUtils.warntype_type_printer(io, typ, true)
end
println(io)
end
Expand Down
6 changes: 3 additions & 3 deletions src/interpreter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ end
@static if isdefined(Compiler, :is_stmt_inline)
function Compiler.inlining_policy(
interp::CthulhuInterpreter, @nospecialize(src), stmt_flag::UInt8,
mi::MethodInstance, argtypes::Vector{Any})
@assert isa(src, OptimizedSource) || isnothing(src)
mi::MethodInstance, argtypes::Argtypes)
@assert isa(src, OptimizedSource) || isnothing(src) "`inlining_policy(::CthulhuInterpreter, ...)` got unexpected source: `$(typeof(src))`"
if isa(src, OptimizedSource)
if Compiler.is_stmt_inline(stmt_flag) || src.isinlineable
return src.ir
Expand All @@ -103,7 +103,7 @@ function Compiler.inlining_policy(
# the default inlining policy may try additional effor to find the source in a local cache
return Base.@invoke Compiler.inlining_policy(
interp::AbstractInterpreter, nothing, stmt_flag::UInt8,
mi::MethodInstance, argtypes::Vector{Any})
mi::MethodInstance, argtypes::Argtypes)
end
return nothing
end
Expand Down
14 changes: 7 additions & 7 deletions src/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ function transform(::Val{:CuFunction}, callsite, callexpr, CI, mi, slottypes; wo
sptypes = sptypes_from_meth_instance(mi)
tt = argextype(callexpr.args[4], CI, sptypes, slottypes)
ft = argextype(callexpr.args[3], CI, sptypes, slottypes)
isa(tt, Const) || return callsite
return Callsite(callsite.id, CuCallInfo(callinfo(Tuple{widenconst(ft), tt.val.parameters...}, Nothing; world)), callsite.head)
(@static IS_OVERHAULED ? isConst(tt) : isa(tt, Const)) || return callsite
return Callsite(callsite.id, CuCallInfo(callinfo(Tuple{widenconst(ft), tt.val.parameters...}, Nothing, world)), callsite.head)
end

const ArgTypes = Vector{Any}

function find_callsites(interp::CthulhuInterpreter, CI::Union{Core.CodeInfo, IRCode},
stmt_info::Union{Vector, Nothing}, mi::Core.MethodInstance,
slottypes::Vector{Any}, optimize::Bool=true)
slottypes::Argtypes, optimize::Bool=true)
sptypes = sptypes_from_meth_instance(mi)
callsites = Callsite[]

Expand All @@ -48,7 +46,9 @@ function find_callsites(interp::CthulhuInterpreter, CI::Union{Core.CodeInfo, IRC
if !optimize
args = (ignorelhs(c)::Expr).args
end
argtypes = mapany(function (@nospecialize(arg),)
argtypes = @static IS_OVERHAULED ?
LatticeElement[argextype(arg, CI, sptypes, slottypes) for arg in args] :
mapany(function (@nospecialize(arg),)
t = argextype(arg, CI, sptypes, slottypes)
return widenconst(ignorelimited(t))
end, args)
Expand Down Expand Up @@ -103,7 +103,7 @@ function find_callsites(interp::CthulhuInterpreter, CI::Union{Core.CodeInfo, IRC
return callsites
end

function process_info(interp, @nospecialize(info), argtypes::ArgTypes, @nospecialize(rt), optimize::Bool)
function process_info(interp, @nospecialize(info), argtypes::Argtypes, @nospecialize(rt), optimize::Bool)
is_cached(@nospecialize(key)) = haskey(optimize ? interp.opt : interp.unopt, key)
process_recursive(@nospecialize(newinfo)) = process_info(interp, newinfo, argtypes, rt, optimize)

Expand Down

0 comments on commit 22726ec

Please sign in to comment.