Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 14df44e

Browse files
committed
Begin peephole optimizations
1 parent b422b42 commit 14df44e

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

lib/syntax_tree/yarv/instruction_sequence.rb

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ def push(instruction)
5252
@tail_node.next_node = node
5353
@tail_node = node
5454
end
55+
56+
node
5557
end
5658
end
5759

@@ -98,15 +100,14 @@ class Label
98100
# When we're serializing the instruction sequence, we need to be able to
99101
# look up the label from the branch instructions and then access the
100102
# subsequent node. So we'll store the reference here.
101-
attr_reader :node
103+
attr_accessor :node
102104

103105
def initialize(name = nil)
104106
@name = name
105107
end
106108

107-
def patch!(name, node)
109+
def patch!(name)
108110
@name = name
109-
@node = node
110111
end
111112
end
112113

@@ -222,8 +223,9 @@ def eval
222223
def to_a
223224
versions = RUBY_VERSION.split(".").map(&:to_i)
224225

225-
# First, specialize any instructions that need to be specialized.
226+
# First, handle any compilation options that we need to.
226227
specialize_instructions! if options.specialized_instruction?
228+
peephole_optimize! if options.peephole_optimization?
227229

228230
# Next, set it up so that all of the labels get their correct name.
229231
length = 0
@@ -232,7 +234,7 @@ def to_a
232234
when Integer, Symbol
233235
# skip
234236
when Label
235-
value.patch!(:"label_#{length}", node)
237+
value.patch!(:"label_#{length}")
236238
else
237239
length += value.length
238240
end
@@ -383,6 +385,27 @@ def specialize_instructions!
383385
end
384386
end
385387

388+
def peephole_optimize!
389+
insns.each_node do |node, value|
390+
case value
391+
when Jump
392+
# jump LABEL
393+
# ...
394+
# LABEL:
395+
# leave
396+
# =>
397+
# leave
398+
# ...
399+
# LABEL:
400+
# leave
401+
# case value.label.node.next_node&.value
402+
# when Leave
403+
# node.value = Leave.new
404+
# end
405+
end
406+
end
407+
end
408+
386409
##########################################################################
387410
# Child instruction sequence methods
388411
##########################################################################
@@ -421,15 +444,18 @@ def label
421444
Label.new
422445
end
423446

424-
def push(insn)
425-
insns.push(insn)
447+
def push(value)
448+
node = insns.push(value)
426449

427-
case insn
428-
when Array, Integer, Label, Symbol
429-
insn
450+
case value
451+
when Array, Integer, Symbol
452+
value
453+
when Label
454+
value.node = node
455+
value
430456
else
431-
stack.change_by(-insn.pops + insn.pushes)
432-
insn
457+
stack.change_by(-value.pops + value.pushes)
458+
value
433459
end
434460
end
435461

0 commit comments

Comments
 (0)