def summarize_loops! decl

      cfg = cfg_construction


      # Identify loop-cost related annotations
      loop_vars = []
      if (has_annotation?(decl, INV_VAR_ANNOTATION_NAME)) then
        decl.body.select{ |s| is_annotation_stmt?(s, INV_VAR_ANNOTATION_NAME)}.each do |s|
          value = get_annotation_value s
          loop_vars.push(value)
        end
      end

      loop_identification.loops.each do |head, blocks|

        # Only deal with loops that are in the procedure we are processing.
        loop_is_in_decl = decl.body.blocks.find do |b|
          b.name == head.name && decl.name == head.parent.parent.name
        end

        next unless loop_is_in_decl

        # Create leakage_before_entering variable and insert right before the loop head.
        lkg_before_var = decl.body.fresh_var("$loop_l","i32")
        lkg_before_asn = AssignStatement.new lhs: lkg_before_var, rhs: bpl("$l")

        entry = cfg.predecessors[head].detect{ |b| !blocks.include?(b) }
        entry.statements.last.insert_before(lkg_before_asn)


        # Identify control blocks, body blocks and compute their costs.
        control_blocks, exit_block = extract_control_blocks(head, blocks, cfg)
        body_blocks = blocks - control_blocks

        # Identify non-nested branches, their consequent blocks and their alternative blocks.
        # TODO: raise error/warning when we encounetr a non-nested branch.

        gotos = extract_branches body_blocks

        branches = {}
        gotos.each do |goto|
          consequent = goto.identifiers.first.declaration
          alternative = goto.identifiers.last.declaration
          branches[goto] = consequent, alternative
        end

        straight_line_blocks = body_blocks
        branches.each_value do |cons, alt|
          straight_line_blocks -= [cons, alt]
        end

        control_cost = control_blocks.inject(0) { |acc, blk| (acc + (cost_of blk)) }
        straight_line_cost = straight_line_blocks.inject(0) { |acc, blk| (acc + (cost_of blk)) }

        # Identify the loop_counter variable as the intersection of live variables of the head
        # block and its predecessor.
        counter_update_block = cfg.predecessors[head].detect{ |b| blocks.include?(b) }
        args = decl.declarations.inject([]) { |acc, d| acc << d.idents[0].name }
        counter = ((liveness.live[head] & liveness.live[counter_update_block]) - args).first

        cons_inv = ""
        branches.values.each_with_index do |(cons, alt), idx|
          cons_cost = cost_of cons
          #alt_cost = cost_of alt
          cons_inv += "$sdiv.i32(#{loop_vars[idx]}+ #{counter} - 1,64)*#{cons_cost}"
          #puts "(#{continuation} - (old+ #{counter} - 1)/64)*#{alt_cost}"
        end

        straight_line_inv = "(#{counter}#{' - 1' unless cons_inv.empty?})*(#{straight_line_cost}+#{control_cost})";

        #puts "assert ($l == #{lkg_before_var}+#{straight_line_inv}#{' + ' unless cons_inv.empty?}#{cons_inv});"
        # Compute and insert leakage invariant at the beginning of the head block.
        head.prepend_children(:statements,
          bpl("assert ($l == #{lkg_before_var}+#{straight_line_inv}#{' + ' unless cons_inv.empty?}#{cons_inv});"))

      end

    end
def summarize_loops! decl

      cfg = cfg_construction


      # Identify loop-cost related annotations
      loop_vars = []
      if (has_annotation?(decl, INV_VAR_ANNOTATION_NAME)) then
        decl.body.select{ |s| is_annotation_stmt?(s, INV_VAR_ANNOTATION_NAME)}.each do |s|
          value = get_annotation_value s
          loop_vars.push(value)
        end
      end

      loop_identification.loops.each do |head, blocks|

        # Only deal with loops that are in the procedure we are processing.
        loop_is_in_decl = decl.body.blocks.find do |b|
          b.name == head.name && decl.name == head.parent.parent.name
        end

        next unless loop_is_in_decl

        # Create leakage_before_entering variable and insert right before the loop head.
        lkg_before_var = decl.body.fresh_var("$loop_l","i32")
        lkg_before_asn = AssignStatement.new lhs: lkg_before_var, rhs: bpl("$l")

        entry = cfg.predecessors[head].detect{ |b| !blocks.include?(b) }
        entry.statements.last.insert_before(lkg_before_asn)


        # Identify control blocks, body blocks and compute their costs.
        control_blocks, exit_block = extract_control_blocks(head, blocks, cfg)
        body_blocks = blocks - control_blocks

        # Identify non-nested branches, their consequent blocks and their alternative blocks.
        # TODO: raise error/warning when we encounetr a non-nested branch.

        gotos = extract_branches body_blocks

        branches = {}
        gotos.each do |goto|
          consequent = goto.identifiers.first.declaration
          alternative = goto.identifiers.last.declaration
          branches[goto] = consequent, alternative
        end

        straight_line_blocks = body_blocks
        branches.each_value do |cons, alt|
          straight_line_blocks -= [cons, alt]
        end

        control_cost = control_blocks.inject(0) { |acc, blk| (acc + (cost_of blk)) }
        straight_line_cost = straight_line_blocks.inject(0) { |acc, blk| (acc + (cost_of blk)) }

        # Identify the loop_counter variable as the intersection of live variables of the head
        # block and its predecessor.
        counter_update_block = cfg.predecessors[head].detect{ |b| blocks.include?(b) }
        args = decl.declarations.inject([]) { |acc, d| acc << d.idents[0].name }
        counter = ((liveness.live[head] & liveness.live[counter_update_block]) - args).first

        cons_inv = ""
        branches.values.each_with_index do |(cons, alt), idx|
          cons_cost = cost_of cons
          #alt_cost = cost_of alt
          cons_inv += "$sdiv.i32(#{loop_vars[idx]}+ #{counter} - 1,64)*#{cons_cost}"
          #puts "(#{continuation} - (old+ #{counter} - 1)/64)*#{alt_cost}"
        end

        straight_line_inv = "(#{counter}#{' - 1' unless cons_inv.empty?})*(#{straight_line_cost}+#{control_cost})";

        #puts "assert ($l == #{lkg_before_var}+#{straight_line_inv}#{' + ' unless cons_inv.empty?}#{cons_inv});"
        # Compute and insert leakage invariant at the beginning of the head block.
        head.prepend_children(:statements,
          bpl("assert ($l == #{lkg_before_var}+#{straight_line_inv}#{' + ' unless cons_inv.empty?}#{cons_inv});"))

      end

    end
This function automatically computes and inserts leakage-related loop invariants.
 The invariants are of the form:
 leakage = leakage_before_entering + loop_counter * (loop_body_cost + control_block_cost)