@@ -40,8 +40,8 @@ def disasm
4040 blocks . each do |block |
4141 output . print ( block . id )
4242
43- unless block . predecessors . empty?
44- output . print ( " # from: #{ block . predecessors . map ( &:id ) . join ( ", " ) } " )
43+ unless block . incoming_blocks . empty?
44+ output . print ( " # from: #{ block . incoming_blocks . map ( &:id ) . join ( ", " ) } " )
4545 end
4646
4747 output . puts
@@ -51,9 +51,9 @@ def disasm
5151 output . puts ( insn . disasm ( fmt ) )
5252 end
5353
54- successors = block . successors . map ( &:id )
55- successors << "leaves" if block . insns . last . leaves?
56- output . print ( " # to: #{ successors . join ( ", " ) } " ) unless successors . empty?
54+ dests = block . outgoing_blocks . map ( &:id )
55+ dests << "leaves" if block . insns . last . leaves?
56+ output . print ( " # to: #{ dests . join ( ", " ) } " ) unless dests . empty?
5757
5858 output . puts
5959 end
@@ -72,49 +72,6 @@ def self.compile(iseq)
7272 Compiler . new ( iseq ) . compile
7373 end
7474
75- # This object represents a single basic block, wherein all contained
76- # instructions do not branch except for the last one.
77- class BasicBlock
78- # This is the unique identifier for this basic block.
79- attr_reader :id
80-
81- # This is the index into the list of instructions where this block
82- # starts.
83- attr_reader :block_start
84-
85- # This is the set of instructions that this block contains.
86- attr_reader :insns
87-
88- # This is an array of basic blocks that are predecessors to this block.
89- attr_reader :predecessors
90-
91- # This is an array of basic blocks that are successors to this block.
92- attr_reader :successors
93-
94- def initialize ( block_start , insns )
95- @id = "block_#{ block_start } "
96-
97- @block_start = block_start
98- @insns = insns
99-
100- @predecessors = [ ]
101- @successors = [ ]
102- end
103-
104- # Yield each instruction in this basic block along with its index from
105- # the original instruction sequence.
106- def each_with_index ( &block )
107- insns . each . with_index ( block_start , &block )
108- end
109-
110- # This method is used to verify that the basic block is well formed. It
111- # checks that the only instruction in this basic block that branches is
112- # the last instruction.
113- def verify
114- insns [ 0 ...-1 ] . each { |insn | raise unless insn . branch_targets . empty? }
115- end
116- end
117-
11875 # This class is responsible for creating a control flow graph from the
11976 # given instruction sequence.
12077 class Compiler
@@ -186,22 +143,22 @@ def build_basic_blocks
186143 end
187144 end
188145
189- # Connect the blocks by letting them know which blocks precede them and
190- # which blocks succeed them .
146+ # Connect the blocks by letting them know which blocks are incoming and
147+ # outgoing from each block .
191148 def connect_basic_blocks ( blocks )
192149 blocks . each do |block_start , block |
193150 insn = block . insns . last
194151
195152 insn . branch_targets . each do |branch_target |
196- block . successors << blocks . fetch ( labels [ branch_target ] )
153+ block . outgoing_blocks << blocks . fetch ( labels [ branch_target ] )
197154 end
198155
199156 if ( insn . branch_targets . empty? && !insn . leaves? ) || insn . falls_through?
200- block . successors << blocks . fetch ( block_start + block . insns . length )
157+ block . outgoing_blocks << blocks . fetch ( block_start + block . insns . length )
201158 end
202159
203- block . successors . each do |successor |
204- successor . predecessors << block
160+ block . outgoing_blocks . each do |outgoing_block |
161+ outgoing_block . incoming_blocks << block
205162 end
206163 end
207164 end
0 commit comments