Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions Compiler/src/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ mutable struct InferenceState
bb_vartables::Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet
bb_saw_latestworld::Vector{Bool}
ssavaluetypes::Vector{Any}
ssaflags::Vector{UInt32}
edges::Vector{Any}
stmt_info::Vector{CallInfo}

Expand Down Expand Up @@ -343,6 +344,7 @@ mutable struct InferenceState
bb_vartable1[i] = VarState(argtyp, i > nargtypes)
end
src.ssavaluetypes = ssavaluetypes = Any[ NOT_FOUND for i = 1:nssavalues ]
ssaflags = copy(src.ssaflags)

unreachable = BitSet()
pclimitations = IdSet{InferenceState}()
Expand Down Expand Up @@ -374,7 +376,7 @@ mutable struct InferenceState

this = new(
mi, WorldWithRange(world, valid_worlds), mod, sptypes, slottypes, src, cfg, spec_info,
currbb, currpc, ip, handler_info, ssavalue_uses, bb_vartables, bb_saw_latestworld, ssavaluetypes, edges, stmt_info,
currbb, currpc, ip, handler_info, ssavalue_uses, bb_vartables, bb_saw_latestworld, ssavaluetypes, ssaflags, edges, stmt_info,
tasks, pclimitations, limitations, cycle_backedges, callstack, parentid, frameid, cycleid,
result, unreachable, bestguess, exc_bestguess, ipo_effects,
restrict_abstract_call_sites, cache_mode, insert_coverage,
Expand Down Expand Up @@ -1004,25 +1006,22 @@ function callers_in_cycle(sv::InferenceState)
end
callers_in_cycle(sv::IRInterpretationState) = AbsIntCycle(sv.callstack::Vector{AbsIntState}, 0, 0)

get_curr_ssaflag(sv::InferenceState) = sv.src.ssaflags[sv.currpc]
get_curr_ssaflag(sv::InferenceState) = sv.ssaflags[sv.currpc]
get_curr_ssaflag(sv::IRInterpretationState) = sv.ir.stmts[sv.curridx][:flag]

has_curr_ssaflag(sv::InferenceState, flag::UInt32) = has_flag(sv.src.ssaflags[sv.currpc], flag)
has_curr_ssaflag(sv::InferenceState, flag::UInt32) = has_flag(sv.ssaflags[sv.currpc], flag)
has_curr_ssaflag(sv::IRInterpretationState, flag::UInt32) = has_flag(sv.ir.stmts[sv.curridx][:flag], flag)

function set_curr_ssaflag!(sv::InferenceState, flag::UInt32, mask::UInt32=typemax(UInt32))
curr_flag = sv.src.ssaflags[sv.currpc]
sv.src.ssaflags[sv.currpc] = (curr_flag & ~mask) | flag
end
function set_curr_ssaflag!(sv::IRInterpretationState, flag::UInt32, mask::UInt32=typemax(UInt32))
curr_flag = sv.ir.stmts[sv.curridx][:flag]
sv.ir.stmts[sv.curridx][:flag] = (curr_flag & ~mask) | flag
curr_flag = sv.ssaflags[sv.currpc]
sv.ssaflags[sv.currpc] = (curr_flag & ~mask) | flag
nothing
end

add_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.src.ssaflags[sv.currpc] |= flag
add_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.ssaflags[sv.currpc] |= flag
add_curr_ssaflag!(sv::IRInterpretationState, flag::UInt32) = add_flag!(sv.ir.stmts[sv.curridx], flag)

sub_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.src.ssaflags[sv.currpc] &= ~flag
sub_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.ssaflags[sv.currpc] &= ~flag
sub_curr_ssaflag!(sv::IRInterpretationState, flag::UInt32) = sub_flag!(sv.ir.stmts[sv.curridx], flag)

function merge_effects!(::AbstractInterpreter, caller::InferenceState, effects::Effects)
Expand All @@ -1035,8 +1034,8 @@ function merge_effects!(::AbstractInterpreter, caller::InferenceState, effects::
end
merge_effects!(::AbstractInterpreter, ::IRInterpretationState, ::Effects) = return

decode_statement_effects_override(sv::AbsIntState) =
decode_statement_effects_override(get_curr_ssaflag(sv))
decode_statement_effects_override(sv::InferenceState) = decode_statement_effects_override(sv.src.ssaflags[sv.currpc])
decode_statement_effects_override(sv::IRInterpretationState) = decode_statement_effects_override(UInt32(0))

struct InferenceLoopState
rt
Expand Down
45 changes: 25 additions & 20 deletions Compiler/src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,41 @@ const SLOT_USEDUNDEF = 32 # slot has uses that might raise UndefVarError

const IR_FLAG_NULL = zero(UInt32)
# This statement is marked as @inbounds by user.
# Ff replaced by inlining, any contained boundschecks may be removed.
# If replaced by inlining, any contained boundschecks may be removed.
const IR_FLAG_INBOUNDS = one(UInt32) << 0
# This statement is marked as @inline by user
const IR_FLAG_INLINE = one(UInt32) << 1
# This statement is marked as @noinline by user
const IR_FLAG_NOINLINE = one(UInt32) << 2
# An optimization pass has updated this statement in a way that may
# have exposed information that inference did not see. Re-running
# inference on this statement may be profitable.
const IR_FLAG_REFINED = one(UInt32) << 3
# This statement is proven :consistent
const IR_FLAG_CONSISTENT = one(UInt32) << 4
const IR_FLAG_CONSISTENT = one(UInt32) << 3
# This statement is proven :effect_free
const IR_FLAG_EFFECT_FREE = one(UInt32) << 5
const IR_FLAG_EFFECT_FREE = one(UInt32) << 4
# This statement is proven :nothrow
const IR_FLAG_NOTHROW = one(UInt32) << 6
# This statement is proven :terminates
const IR_FLAG_TERMINATES = one(UInt32) << 7
# This statement is proven :noub
const IR_FLAG_NOUB = one(UInt32) << 8
# TODO: Both of these should eventually go away once
# This statement is :effect_free == EFFECT_FREE_IF_INACCESSIBLEMEMONLY
const IR_FLAG_EFIIMO = one(UInt32) << 9
# This statement is :inaccessiblememonly == INACCESSIBLEMEM_OR_ARGMEMONLY
const IR_FLAG_INACCESSIBLEMEM_OR_ARGMEM = one(UInt32) << 10
const IR_FLAG_NOTHROW = one(UInt32) << 5
# This statement is proven :terminates_globally
const IR_FLAG_TERMINATES = one(UInt32) << 6
#const IR_FLAG_TERMINATES_LOCALLY = one(UInt32) << 7
#const IR_FLAG_NOTASKSTATE = one(UInt32) << 8
#const IR_FLAG_INACCESSIBLEMEM = one(UInt32) << 9
const IR_FLAG_NOUB = one(UInt32) << 10
#const IR_FLAG_NOUBINIB = one(UInt32) << 11
#const IR_FLAG_CONSISTENTOVERLAY = one(UInt32) << 12
# This statement is :nortcall
const IR_FLAG_NORTCALL = one(UInt32) << 11
const IR_FLAG_NORTCALL = one(UInt32) << 13
# An optimization pass has updated this statement in a way that may
# have exposed information that inference did not see. Re-running
# inference on this statement may be profitable.
const IR_FLAG_REFINED = one(UInt32) << 16
Comment on lines +42 to +45
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

# This statement has no users and may be deleted if flags get refined to IR_FLAGS_REMOVABLE
const IR_FLAG_UNUSED = one(UInt32) << 12
const IR_FLAG_UNUSED = one(UInt32) << 17
# TODO: Both of these next two should eventually go away once
# This statement is :effect_free == EFFECT_FREE_IF_INACCESSIBLEMEMONLY
const IR_FLAG_EFIIMO = one(UInt32) << 18
# This statement is :inaccessiblememonly == INACCESSIBLEMEM_OR_ARGMEMONLY
const IR_FLAG_INACCESSIBLEMEM_OR_ARGMEM = one(UInt32) << 19

const NUM_IR_FLAGS = 13 # sync with julia.h
const NUM_IR_FLAGS = 3 # sync with julia.h

const IR_FLAGS_EFFECTS =
IR_FLAG_CONSISTENT | IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW |
Expand Down Expand Up @@ -815,6 +819,7 @@ function scan_non_dataflow_flags!(inst::Instruction, sv::PostOptAnalysisState)
sv.nortcall = false
end
end
nothing
end

function scan_inconsistency!(inst::Instruction, sv::PostOptAnalysisState)
Expand Down
3 changes: 2 additions & 1 deletion Compiler/src/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter)
ipo_effects = result.ipo_effects = me.ipo_effects = adjust_effects(me)
result.exc_result = me.exc_bestguess = refine_exception_type(me.exc_bestguess, ipo_effects)
me.src.rettype = widenconst(ignorelimited(bestguess))
me.src.ssaflags = me.ssaflags
me.src.min_world = first(me.world.valid_worlds)
me.src.max_world = last(me.world.valid_worlds)
istoplevel = !(me.linfo.def isa Method)
Expand Down Expand Up @@ -936,7 +937,7 @@ function codeinfo_for_const(interp::AbstractInterpreter, mi::MethodInstance, @no
tree.slotflags = fill(0x00, nargs)
tree.ssavaluetypes = 1
tree.debuginfo = DebugInfo(mi)
tree.ssaflags = UInt32[0]
tree.ssaflags = [IR_FLAG_NULL]
tree.rettype = Core.Typeof(val)
tree.edges = Core.svec()
set_inlineable!(tree, true)
Expand Down
13 changes: 3 additions & 10 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ typedef union __jl_purity_overrides_t {
} _jl_purity_overrides_t;

#define NUM_EFFECTS_OVERRIDES 11
#define NUM_IR_FLAGS 13
#define NUM_IR_FLAGS 3

// This type describes a single function body
typedef struct _jl_code_info_t {
Expand All @@ -292,15 +292,8 @@ typedef struct _jl_code_info_t {
// 1 << 0 = inbounds region
// 1 << 1 = callsite inline region
// 1 << 2 = callsite noinline region
// 1 << 3 = refined statement
// 1 << 4 = :consistent
// 1 << 5 = :effect_free
// 1 << 6 = :nothrow
// 1 << 7 = :terminates
// 1 << 8 = :noub
// 1 << 9 = :effect_free_if_inaccessiblememonly
// 1 << 10 = :inaccessiblemem_or_argmemonly
// 1 << 11-19 = callsite effects overrides
// 1 << 3-14 = purity
// 1 << 16+ = reserved for inference
// miscellaneous data:
jl_array_t *slotnames; // names of local variables
jl_array_t *slotflags; // local var bit flags
Expand Down
Loading