Class: Optimize::Passes::DeadStashElimPass
- Inherits:
-
Optimize::Pass
- Object
- Optimize::Pass
- Optimize::Passes::DeadStashElimPass
- Defined in:
- lib/optimize/passes/dead_stash_elim_pass.rb
Overview
Peephole: drop adjacent ‘setlocal X; getlocal X` pairs where slot X has no other references at the matching level in the same function.
The producer that fed the setlocal has already pushed its value onto the operand stack; the getlocal was just reading it back. Dropping both leaves the value where subsequent instructions expect it.
Constant Summary collapse
- SETLOCAL_OPCODES =
%i[setlocal setlocal_WC_0].freeze
- GETLOCAL_OPCODES =
%i[getlocal getlocal_WC_0].freeze
- LOCAL_OPCODES =
(SETLOCAL_OPCODES + GETLOCAL_OPCODES).freeze
Instance Method Summary collapse
Methods inherited from Optimize::Pass
Instance Method Details
#apply(function, type_env:, log:, **_extras) ⇒ Object
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 |
# File 'lib/optimize/passes/dead_stash_elim_pass.rb', line 21 def apply(function, type_env:, log:, **_extras) insts = function.instructions return unless insts && insts.size >= 2 candidates = [] i = 0 while i < insts.size - 1 a = insts[i] b = insts[i + 1] if matching_pair?(a, b) && slot_has_no_other_refs?(insts, i, a) candidates << i i += 2 else i += 1 end end return if candidates.empty? candidates.reverse_each do |idx| line = (function.instructions[idx]&.line) || function.first_lineno || 0 function.splice_instructions!(idx..idx + 1, []) log.rewrite( pass: :dead_stash_elim, reason: :dead_stash_eliminated, file: function.path, line: line, ) end end |
#name ⇒ Object
17 18 19 |
# File 'lib/optimize/passes/dead_stash_elim_pass.rb', line 17 def name :dead_stash_elim end |