Class: Optimize::Passes::ConstFoldTier2Pass

Inherits:
Optimize::Pass show all
Defined in:
lib/optimize/passes/const_fold_tier2_pass.rb

Overview

Tier 2 const-fold: frozen top-level constants.

Scans the whole IR tree for ‘setconstant :NAME` sites. Admits a name to the fold table only when its sole assignment is a top-level literal:

<literal-producer>
putspecialobject 3
setconstant :NAME

Any other assignment shape (nested ‘dup`-flavored, non-literal RHS, reassignment) taints the name — both removing it from the fold table and barring re-admission.

Fold phase rewrites ‘opt_getconstant_path <idx>` where `object_table` is a single-element T_ARRAY whose symbol is in the fold table.

Constant Summary collapse

TABLE_KEY =
:const_fold_tier2_table
TAINTED_KEY =
:const_fold_tier2_tainted
SCANNED_KEY =
:const_fold_tier2_scanned

Instance Method Summary collapse

Methods inherited from Optimize::Pass

#one_shot?

Instance Method Details

#apply(function, type_env:, log:, object_table: nil, **_extras) ⇒ Object



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
63
64
65
66
67
68
# File 'lib/optimize/passes/const_fold_tier2_pass.rb', line 33

def apply(function, type_env:, log:, object_table: nil, **_extras)
  _ = type_env
  return unless object_table

  root = tree_root(function)
  root.misc ||= {}
  unless root.misc[SCANNED_KEY]
    root.misc[SCANNED_KEY]  = true
    root.misc[TABLE_KEY]    = {}
    root.misc[TAINTED_KEY]  = Set.new
    scan_tree(root, object_table, log, root.misc[TABLE_KEY], root.misc[TAINTED_KEY])
  end

  table = root.misc[TABLE_KEY]
  return if table.empty?

  insts = function.instructions
  return unless insts

  i = 0
  while i < insts.size
    inst = insts[i]
    if inst.opcode == :opt_getconstant_path
      name = single_name_for_path(inst, object_table)
      if name && table.key?(name)
        replacement = emit_literal(table[name], line: inst.line, object_table: object_table)
        if replacement
          function.splice_instructions!(i..i, [replacement])
          log.rewrite(pass: name_sym, reason: :folded,
                      file: function.path, line: (inst.line || function.first_lineno || 0))
        end
      end
    end
    i += 1
  end
end

#nameObject



31
# File 'lib/optimize/passes/const_fold_tier2_pass.rb', line 31

def name = :const_fold_tier2