class Bpl::ConditionalIdentification

Public Instance Methods

dominators(blk;) click to toggle source
# File lib/bpl/passes/analysis/conditional_identification.rb, line 9
def dominators blk; domination.dominators[blk] end
exit?(blk) click to toggle source
# File lib/bpl/passes/analysis/conditional_identification.rb, line 11
def exit?(blk) successors(blk).empty? end
external?(blk, branches) click to toggle source
# File lib/bpl/passes/analysis/conditional_identification.rb, line 13
def external?(blk, branches) (dominators(blk) & branches).empty? end
loop?(blk) click to toggle source
# File lib/bpl/passes/analysis/conditional_identification.rb, line 12
def loop?(blk) (dominators(blk) & successors(blk)).any? end
run!(program) click to toggle source
# File lib/bpl/passes/analysis/conditional_identification.rb, line 19
def run! program
  program.declarations.each do |proc|
    next unless proc.is_a?(ProcedureDeclaration) && proc.body

    proc.body.blocks.each do |head|
      branches = successors(head)
      next unless branches.count > 1

      blocks = Set.new([head])
      exits = Set.new
      work_list = branches.to_a

      until work_list.empty?
        blk = work_list.shift

        if loop?(blk)
          blocks = nil
          break

        elsif external?(blk, branches)
          exits << blk

        else
          blocks << blk
          successors(blk).each {|b| work_list |= [b]} unless exit?(blk)
        end
      end

      save_result(head, blocks, exits) if blocks
    end
  end
end
save_result(head, blocks, exits) click to toggle source
# File lib/bpl/passes/analysis/conditional_identification.rb, line 15
def save_result(head, blocks, exits)
  conditionals[head] = { blocks: blocks, exits: exits }
end
successors(blk;) click to toggle source
# File lib/bpl/passes/analysis/conditional_identification.rb, line 8
def successors blk; cfg_construction.successors[blk] end