Class: CastOff::Compiler::Translator::CFG::BasicBlock
- Inherits:
-
Object
- Object
- CastOff::Compiler::Translator::CFG::BasicBlock
- Includes:
- Instruction, SimpleIR, Util
- Defined in:
- lib/cast_off/compile/information.rb,
lib/cast_off/compile/stack.rb,
lib/cast_off/compile/basicblock.rb
Overview
Alias
Constant Summary
Constants included from SimpleIR
SimpleIR::SPLATCALL_LIMIT, SimpleIR::SupportLoopInstruction
Constants included from Instruction
Instruction::BlockSeparator, Instruction::BranchInstruction, Instruction::IgnoreInstruction, Instruction::JumpOrReturnInstruction, Instruction::SupportInstruction, Instruction::TypeInfoUser, Instruction::VM_CALL_ARGS_BLOCKARG_BIT, Instruction::VM_CALL_ARGS_SPLAT_BIT, Instruction::VM_CALL_FCALL_BIT, Instruction::VM_CALL_OPT_SEND_BIT, Instruction::VM_CALL_SUPER_BIT, Instruction::VM_CALL_TAILCALL_BIT, Instruction::VM_CALL_TAILRECURSION_BIT, Instruction::VM_CALL_VCALL_BIT
Instance Attribute Summary collapse
-
#egen ⇒ Object
readonly
Returns the value of attribute egen.
-
#ekill ⇒ Object
readonly
Returns the value of attribute ekill.
-
#in_guards ⇒ Object
Returns the value of attribute in_guards.
-
#in_undefined ⇒ Object
Returns the value of attribute in_undefined.
-
#information ⇒ Object
Returns the value of attribute information.
-
#insns ⇒ Object
readonly
Returns the value of attribute insns.
-
#irs ⇒ Object
readonly
Returns the value of attribute irs.
-
#iseq ⇒ Object
readonly
Returns the value of attribute iseq.
-
#labels ⇒ Object
readonly
Returns the value of attribute labels.
-
#next ⇒ Object
readonly
Returns the value of attribute next.
-
#number ⇒ Object
readonly
Returns the value of attribute number.
-
#out_undefined ⇒ Object
Returns the value of attribute out_undefined.
-
#pre ⇒ Object
readonly
Returns the value of attribute pre.
Instance Method Summary collapse
- #calc_egen ⇒ Object
- #calc_ekill(all) ⇒ Object
- #entry_point? ⇒ Boolean
- #find_insn_stack_depth(insn) ⇒ Object
- #gen_ir ⇒ Object
- #in_depth ⇒ Object
- #in_depth=(depth) ⇒ Object
-
#initialize(cfg, insns, number) ⇒ BasicBlock
constructor
A new instance of BasicBlock.
- #out_depth ⇒ Object
- #set_next_block(blocks) ⇒ Object
- #set_prev_block(blocks) ⇒ Object
- #source ⇒ Object
- #to_c ⇒ Object
- #to_s ⇒ Object
Methods included from SimpleIR
#block_argument_is_unsupported, #generate_ir
Methods included from Util
Constructor Details
#initialize(cfg, insns, number) ⇒ BasicBlock
Returns a new instance of BasicBlock.
12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/cast_off/compile/basicblock.rb', line 12 def initialize(cfg, insns, number) @cfg = cfg @insns = insns bug() if @insns.find{|i| not i.instance_of?(InsnInfo)} @number = number @pre = nil @next = nil @labels = [] @irs = nil @entry_point = number == 0 @iseq = @insns[0].iseq bug() if @insns.find{|i| i.iseq != @iseq} end |
Instance Attribute Details
#egen ⇒ Object (readonly)
Returns the value of attribute egen.
603 604 605 |
# File 'lib/cast_off/compile/information.rb', line 603 def egen @egen end |
#ekill ⇒ Object (readonly)
Returns the value of attribute ekill.
603 604 605 |
# File 'lib/cast_off/compile/information.rb', line 603 def ekill @ekill end |
#in_guards ⇒ Object
Returns the value of attribute in_guards.
605 606 607 |
# File 'lib/cast_off/compile/information.rb', line 605 def in_guards @in_guards end |
#in_undefined ⇒ Object
Returns the value of attribute in_undefined.
604 605 606 |
# File 'lib/cast_off/compile/information.rb', line 604 def in_undefined @in_undefined end |
#information ⇒ Object
Returns the value of attribute information.
604 605 606 |
# File 'lib/cast_off/compile/information.rb', line 604 def information @information end |
#insns ⇒ Object (readonly)
Returns the value of attribute insns.
10 11 12 |
# File 'lib/cast_off/compile/basicblock.rb', line 10 def insns @insns end |
#irs ⇒ Object (readonly)
Returns the value of attribute irs.
10 11 12 |
# File 'lib/cast_off/compile/basicblock.rb', line 10 def irs @irs end |
#iseq ⇒ Object (readonly)
Returns the value of attribute iseq.
10 11 12 |
# File 'lib/cast_off/compile/basicblock.rb', line 10 def iseq @iseq end |
#labels ⇒ Object (readonly)
Returns the value of attribute labels.
10 11 12 |
# File 'lib/cast_off/compile/basicblock.rb', line 10 def labels @labels end |
#next ⇒ Object (readonly)
Returns the value of attribute next.
10 11 12 |
# File 'lib/cast_off/compile/basicblock.rb', line 10 def next @next end |
#number ⇒ Object (readonly)
Returns the value of attribute number.
10 11 12 |
# File 'lib/cast_off/compile/basicblock.rb', line 10 def number @number end |
#out_undefined ⇒ Object
Returns the value of attribute out_undefined.
604 605 606 |
# File 'lib/cast_off/compile/information.rb', line 604 def out_undefined @out_undefined end |
#pre ⇒ Object (readonly)
Returns the value of attribute pre.
10 11 12 |
# File 'lib/cast_off/compile/basicblock.rb', line 10 def pre @pre end |
Instance Method Details
#calc_egen ⇒ Object
607 608 609 610 611 612 613 614 615 616 617 618 619 |
# File 'lib/cast_off/compile/information.rb', line 607 def calc_egen() egen = [] kill = [] @irs.reverse.each do |ir| next unless ir.result_variable gen = [ir] egen |= (gen - kill) kill |= @irs.select{|i| i.result_variable == ir.result_variable && i != ir } kill |= @irs.select{|i| i.result_variable.is_a?(Pointer) && i != ir } if ir.dispatch_method? end @egen = egen @egen.freeze() end |
#calc_ekill(all) ⇒ Object
621 622 623 624 625 626 627 628 629 630 |
# File 'lib/cast_off/compile/information.rb', line 621 def calc_ekill(all) kill = [] @irs.each do |ir| next unless ir.result_variable kill |= all.select{|i| i.result_variable == ir.result_variable && i != ir } kill |= all.select{|i| i.result_variable.is_a?(Pointer) && i != ir } if ir.dispatch_method? end @ekill = kill @ekill.freeze() end |
#entry_point? ⇒ Boolean
38 39 40 |
# File 'lib/cast_off/compile/basicblock.rb', line 38 def entry_point? @entry_point end |
#find_insn_stack_depth(insn) ⇒ Object
19 20 21 22 23 24 25 26 27 |
# File 'lib/cast_off/compile/stack.rb', line 19 def find_insn_stack_depth(insn) bug() unless @insns.include?(insn) depth = in_depth() @insns.each do |i| return depth if i == insn depth += i.stack_usage() end bug() end |
#gen_ir ⇒ Object
124 125 126 |
# File 'lib/cast_off/compile/basicblock.rb', line 124 def gen_ir() @irs = generate_ir(@cfg, @insns, in_depth()) end |
#in_depth ⇒ Object
9 10 11 12 |
# File 'lib/cast_off/compile/stack.rb', line 9 def in_depth() bug() unless @in_depth @in_depth end |
#in_depth=(depth) ⇒ Object
5 6 7 |
# File 'lib/cast_off/compile/stack.rb', line 5 def in_depth=(depth) @in_depth = depth end |
#out_depth ⇒ Object
14 15 16 17 |
# File 'lib/cast_off/compile/stack.rb', line 14 def out_depth() bug() unless @in_depth @in_depth + stackincrease() end |
#set_next_block(blocks) ⇒ Object
118 119 120 121 122 |
# File 'lib/cast_off/compile/basicblock.rb', line 118 def set_next_block(blocks) @next = [] bug() if blocks.find{|b| b.instance_of?(BasicBlock) && !b.pre } blocks.each{|b| @next << b if b.instance_of?(BasicBlock) && b.pre.include?(self)} end |
#set_prev_block(blocks) ⇒ Object
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/cast_off/compile/basicblock.rb', line 42 def set_prev_block(blocks) @pre = [] index = blocks.index(self) if index != 0 pre = blocks[index - 1] case pre when Symbol # this block is branch or jump target @labels << pre i = index - 2 while i >= 0 break unless blocks[i].is_a?(Symbol) @labels << blocks[i] i -= 1 end matchlabels = [] blocks.each do |basicblock| case basicblock when BasicBlock last_insn = basicblock.insns.last op = last_insn.op argv = last_insn.argv if BranchInstruction.include?(op) case op when :jump, :branchunless, :branchif, \ :cast_off_enter_block, :cast_off_leave_block, :cast_off_continue_loop, \ :cast_off_break_block targets = [argv[0]] when :cast_off_handle_optional_args targets = argv[0] else bug("unexpected instruction #{op}") end targets.each do |t| if @labels.include?(t) matchlabels << t @pre << basicblock unless @pre.include?(basicblock) end end end end end if @pre.empty? # join point with exception handler # nothing to do @labels = [] else @labels = @labels & matchlabels bug() if @labels.empty? end # consider fall-throuth from previous block i = index - 2 while i >= 0 pre = blocks[i] break if pre.is_a?(BasicBlock) i -= 1 end if pre.is_a?(BasicBlock) last_insn = pre.insns.last @pre << pre if !JumpOrReturnInstruction.include?(last_insn.op) end when BasicBlock # fall-throuth from previous block last_insn = pre.insns.last if JumpOrReturnInstruction.include?(last_insn.op) # dead block else @pre << pre end else bug() end else # entry point end end |
#source ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/cast_off/compile/basicblock.rb', line 26 def source return '' unless @irs line = nil @irs.inject(''){|src, ir| insn = ir.insn next src if insn.line == line next src if insn.source.empty? line = insn.line src.concat(insn.source).concat("\n") }.chomp end |
#to_c ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/cast_off/compile/basicblock.rb', line 128 def to_c() params = [] codes = [] @labels.each{|label| codes << "#{label}:" } @irs.each do |ir| bug() unless ir.insn.iseq == @iseq ir.variables.each{|v| @iseq.declare_local_variable("#{v.declare()} #{v}") if v.declare?} case ir when SubIR, JumpIR, ReturnIR, GuardIR codes << ir.to_c() when ParamIR params << ir.param_value when CallIR codes << ir.to_c(params) else bug("invalid ir #{ir}") end end bug() unless params.empty? codes.join("\n") end |
#to_s ⇒ Object
150 151 152 153 154 |
# File 'lib/cast_off/compile/basicblock.rb', line 150 def to_s() pstr = "#{@pre.map{|b| "BB#{b.number}"}.join(", ")}" nstr = "#{@next.map{|b| "BB#{b.number}"}.join(", ")}" "(#{pstr})BB#{@number}-#{@iseq}(#{nstr})" end |