Module: Kumi::IR::Loop::Passes::Support

Defined in:
lib/kumi/ir/loop/passes/support/structure.rb

Defined Under Namespace

Classes: Nest

Class Method Summary collapse

Class Method Details

.each_instruction(items, &blk) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/kumi/ir/loop/passes/support/structure.rb', line 59

def each_instruction(items, &blk)
  items.each do |item|
    if item.is_a?(Nest)
      yield(item.start)
      each_instruction(item.body, &blk)
      yield(item.end_node)
    else
      yield(item)
    end
  end
end

.flatten(items) ⇒ Object



53
54
55
56
57
# File 'lib/kumi/ir/loop/passes/support/structure.rb', line 53

def flatten(items)
  items.flat_map do |item|
    item.is_a?(Nest) ? [item.start, *flatten(item.body), item.end_node] : [item]
  end
end

.parse(instructions) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/kumi/ir/loop/passes/support/structure.rb', line 32

def parse(instructions)
  root = []
  bodies = [root]
  starts = []

  instructions.each do |instr|
    case instr.opcode
    when :loop_start
      starts << instr
      bodies << []
    when :loop_end
      body = bodies.pop
      bodies.last << Nest.new(start: starts.pop, body: body, end_node: instr)
    else
      bodies.last << instr
    end
  end

  root
end

.remap(instr, map) ⇒ Object

Rebuilds an instruction with inputs substituted through the map. Downstream consumers dispatch on opcode, so the generic node class is sufficient for rewritten instructions.



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/kumi/ir/loop/passes/support/structure.rb', line 74

def remap(instr, map)
  return instr if instr.uses.none? { |r| map.key?(r) }

  Kumi::IR::Base::Instruction.new(
    opcode: instr.opcode,
    result: instr.result,
    inputs: instr.inputs.map { |r| map.fetch(r, r) },
    attributes: instr.attributes,
    metadata: instr.,
    effects: instr.effects
  )
end

.remap_items(items, map) ⇒ Object



87
88
89
90
91
92
93
94
95
# File 'lib/kumi/ir/loop/passes/support/structure.rb', line 87

def remap_items(items, map)
  items.map do |item|
    if item.is_a?(Nest)
      Nest.new(start: remap(item.start, map), body: remap_items(item.body, map), end_node: item.end_node)
    else
      remap(item, map)
    end
  end
end