This repository has been archived by the owner on Nov 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
builder.rb
73 lines (54 loc) · 1.39 KB
/
builder.rb
1
2
3
4
5
6
7
8
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
63
64
65
66
67
68
69
70
71
72
73
module Furnace
class SSA::Builder
attr_reader :function
attr_accessor :block
def initialize(name, arguments=[], return_type=nil)
@function = SSA::Function.new(name, [], return_type)
@function.arguments = arguments.map do |(type, name)|
SSA::Argument.new(@function, type, name)
end
@block = @function.entry = add_block
end
def add_block
block = SSA::BasicBlock.new(@function)
@function.add block
block
end
def with(block)
old_block = @block
@block = block
yield old_block
ensure
@block = old_block
end
def insn(instruction, *uses)
insn = instruction.new(@block, uses)
@block.append insn
insn
end
def typed_insn(instruction, type, *uses)
insn = instruction.new(@block, type, uses)
@block.append insn
insn
end
def branch(block)
insn(SSA::Branch, block.to_value)
end
def phi(type, *uses)
typed_insn(SSA::Phi, type, *uses)
end
def return(value)
insn(SSA::Return, value)
nil
end
def cond(instruction, *uses)
switch(instruction, *uses, 2)
end
def switch(instruction, *uses, successor_count)
successors = successor_count.times.map { add_block }
insn(instruction, *uses, *successors.map(&:to_value))
@block = add_block
successors
end
end
end