Class: Kumi::Core::Analyzer::Passes::IRExecutionSchedulePass
- Defined in:
- lib/kumi/core/analyzer/passes/ir_execution_schedule_pass.rb
Overview
PRODUCES: :execution_schedules => { store_name(Symbol) => [Decl, …] }
Instance Method Summary collapse
Methods inherited from PassBase
#debug, #debug_enabled?, #initialize
Methods included from ErrorReporting
#inferred_location, #raise_localized_error, #raise_syntax_error, #raise_type_error, #report_enhanced_error, #report_error, #report_semantic_error, #report_syntax_error, #report_type_error
Constructor Details
This class inherits a constructor from Kumi::Core::Analyzer::Passes::PassBase
Instance Method Details
#run(_errors) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/kumi/core/analyzer/passes/ir_execution_schedule_pass.rb', line 9 def run(_errors) ir = get_state(:ir_module, required: true) deps = get_state(:ir_dependencies, required: true) # decl_name => [binding_name, ...] name_index = get_state(:ir_name_index, required: true) # binding_name => Decl (← use IR-specific index) by_name = ir.decls.to_h { |d| [d.name, d] } pos = ir.decls.each_with_index.to_h # for deterministic ordering closure_cache = {} visiting = {} visit = lambda do |dn| return closure_cache[dn] if closure_cache.key?(dn) raise Kumi::Core::Errors::TypeError, "cycle detected in IR at #{dn.inspect}" if visiting[dn] visiting[dn] = true # Resolve binding refs -> producing decl names preds = Array(deps[dn]).filter_map { |b| name_index[b]&.name }.uniq # Deterministic order: earlier IR decls first preds.sort_by! { |n| pos[n] || Float::INFINITY } order = [] preds.each do |p| next if p == dn # guard against self-deps; treat as error if you prefer order.concat(visit.call(p)) end order << dn unless order.last == dn visiting.delete(dn) closure_cache[dn] = order.uniq.freeze end schedules = {} ir.decls.each do |decl| target_names = [decl.name] + decl.ops.select { _1.tag == :store }.map { _1.attrs[:name] } seq = visit.call(decl.name).map { |dn| by_name.fetch(dn) }.freeze target_names.each do |t| if schedules.key?(t) && schedules[t] != seq raise Kumi::Core::Errors::TypeError, "duplicate schedule target #{t.inspect} produced by #{schedules[t].last.name} and #{decl.name}" end schedules[t] = seq end end state.with(:ir_execution_schedules, schedules.freeze) end |