Class: Optimize::Pipeline
- Inherits:
-
Object
- Object
- Optimize::Pipeline
- Defined in:
- lib/optimize/pipeline.rb
Defined Under Namespace
Classes: FixedPointOverflow
Constant Summary collapse
- MAX_ITERATIONS =
8
Instance Attribute Summary collapse
-
#passes ⇒ Object
readonly
Returns the value of attribute passes.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(passes) ⇒ Pipeline
constructor
A new instance of Pipeline.
-
#run(ir, type_env:, env_snapshot: nil) ⇒ Object
Run all passes over every Function in the IR tree.
Constructor Details
#initialize(passes) ⇒ Pipeline
Returns a new instance of Pipeline.
54 55 56 |
# File 'lib/optimize/pipeline.rb', line 54 def initialize(passes) @passes = passes end |
Instance Attribute Details
#passes ⇒ Object (readonly)
Returns the value of attribute passes.
52 53 54 |
# File 'lib/optimize/pipeline.rb', line 52 def passes @passes end |
Class Method Details
.default ⇒ Object
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 |
# File 'lib/optimize/pipeline.rb', line 26 def self.default new([ Passes::InliningPass.new, # DeadStashElimPass runs directly after InliningPass to clean up the # argument-stash round-trip (`setlocal X; getlocal X` with X # unreferenced elsewhere). Exposes the producer to the following # instruction so arith/const-fold can cascade through it. Passes::DeadStashElimPass.new, Passes::ArithReassocPass.new, # ConstFoldTier2Pass rewrites frozen top-level constant references # to their literal values. Runs before the other const-folders so # `FOO + 1` → `42 + 1` → `43` cascades in one pipeline run. Passes::ConstFoldTier2Pass.new, # ConstFoldEnvPass runs BEFORE ConstFoldPass so `ENV["FLAG"] == "true"` # can cascade through string-eq folding in a single pipeline run. Passes::ConstFoldEnvPass.new, Passes::ConstFoldPass.new, Passes::IdentityElimPass.new, # DeadBranchFoldPass runs LAST — any earlier pass that turns a # branch condition into a literal (ConstFold*, IdentityElim) feeds # this pass, which collapses `<lit>; branch*` into either a # `jump` (taken) or a drop (not taken). Passes::DeadBranchFoldPass.new, ]) end |
Instance Method Details
#run(ir, type_env:, env_snapshot: nil) ⇒ Object
Run all passes over every Function in the IR tree. Returns the Optimize::Log accumulated during the run.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/optimize/pipeline.rb', line 60 def run(ir, type_env:, env_snapshot: nil) log = Log.new object_table = ir.misc && ir.misc[:object_table] callee_map = build_callee_map(ir) slot_type_map, signature_map = build_type_maps(ir, type_env, object_table) seen_fns = {}.compare_by_identity each_function(ir) do |function| next if seen_fns[function] seen_fns[function] = true one_shot_passes, iterative_passes = @passes.partition(&:one_shot?) # One-shot passes: run exactly once per function. one_shot_passes.each do |pass| run_single_pass(pass, function, type_env, log, object_table, callee_map, slot_type_map, signature_map, env_snapshot) end # Iterative passes: sweep until rewrite_count stops growing. Cap at # MAX_ITERATIONS; raising beyond that signals either pass oscillation # or a pass that records rewrites without changing IR. iterations = 0 if iterative_passes.any? loop do iterations += 1 snapshot = log.rewrite_count iterative_passes.each do |pass| run_single_pass(pass, function, type_env, log, object_table, callee_map, slot_type_map, signature_map, env_snapshot) end break if log.rewrite_count == snapshot if iterations >= MAX_ITERATIONS raise FixedPointOverflow.new(function_name: function.name, iterations: iterations) end end end log.record_convergence(function.name, iterations) end log end |