/* RTL factoring (sequence abstraction).
   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "obstack.h"
#include "basic-block.h"
#include "resource.h"
#include "flags.h"
#include "ggc.h"
#include "regs.h"
#include "params.h"
#include "expr.h"
#include "tm_p.h"
#include "tree-pass.h"
#include "tree-flow.h"
#include "timevar.h"
#include "output.h"
#include "df.h"
#include "addresses.h"

/* Sequence abstraction:

   It is a size optimization method. The main idea of this technique is to
   find identical sequences of code, which can be turned into procedures and
   then replace all occurrences with calls to the newly created subroutine.
   It is kind of an opposite of function inlining.

   There are four major parts of this file:

   sequence fingerprint
     In order to avoid the comparison of every insn with every other, hash
     value will be designed for every insn by COMPUTE_HASH.
     These hash values are used for grouping the sequence candidates. So
     we only need to compare every insn with every other in same hash group.

     FILL_HASH_BUCKET creates all hash values and stores into HASH_BUCKETS.
     The result is used by COLLECT_PATTERN_SEQS.

   code matching
     In code matching the algorithm compares every two possible sequence
     candidates which last insns are in the same hash group. If these
     sequences are identical they will be stored and do further searches for
     finding more sequences which are identical with the first one.

     COLLECT_PATTERN_SEQS does the code matching and stores the results into
     PATTERN_SEQS.

   gain computation
     This part computes the gain of abstraction which could be archived when
     turning the pattern sequence into a pseudo-function and its matching
     sequences into pseudo-calls. After it the most effective sequences will
     be marked for abstraction.

     RECOMPUTE_GAIN does the gain computation. The sequences with the maximum
     gain is on the top of PATTERN_SEQS.

   abstract code
     This part turns the pattern sequence into a pseudo-function and its
     matching sequences into pseudo-calls.

     ABSTRACT_BEST_SEQ does the code merging.


   C code example:

   // Original source            // After sequence abstraction
   {                             {
                                   void *jump_label;
     ...                           ...
                                   jump_label = &&exit_0;
                                 entry_0:
     I0;                           I0;
     I1;                           I1;
     I2;                           I2;
     I3;                           I3;
                                   goto *jump_label;
                                 exit_0:
     ...                           ...
                                   jump_label = &&exit_1;
                                 goto entry_0;
     I0;
     I1;
     I2;
     I3;
                                 exit_1:
     ...                           ...
                                   jump_label = &&exit_2;
                                   goto entry_0;
     I0;
     I1;
     I2;
     I3;
                                 exit_2:
     ...                           ...
                                   jump_label = &&exit_3;
                                   goto entry_0;
     I0;
     I1;
     I2;
     I3;
                                exit_3:
     ...                           ...
   }                             }


   TODO:
   - Use REG_ALLOC_ORDER when choosing link register.
   - Handle JUMP_INSNs. Also handle volatile function calls (handle them
     similar to unconditional jumps.)
   - Test command line option -fpic.
*/

/* Predicate yielding nonzero iff X is an abstractable insn.  Non-jump insns are
   abstractable.  */
#define ABSTRACTABLE_INSN_P(X) (INSN_P (X) && !JUMP_P (X))

/* First parameter of the htab_create function call.  */
#define HASH_INIT 1023

/* Multiplier for cost of sequence call to avoid abstracting short
   sequences.  */
#ifndef SEQ_CALL_COST_MULTIPLIER
#define SEQ_CALL_COST_MULTIPLIER 2
#endif

/* Recomputes the cost of MSEQ pattern/matching sequence.  */
#define RECOMPUTE_COST(SEQ)                                 \
{                                                           \
  int l;                                                    \
  rtx x = SEQ->insn;                                        \
  SEQ->cost = 0;                                            \
  for (l = 0; l < SEQ->abstracted_length; l++)              \
    {                                                       \
      SEQ->cost += compute_rtx_cost (x);                    \
      x = prev_insn_in_block (x);                           \
    }                                                       \
}

/* A sequence matching a pattern sequence.  */
typedef struct matching_seq_def
{
  /* The last insn in the matching sequence.  */
  rtx insn;

  /* Index of INSN instruction.  */
  unsigned long idx;

  /* The number of insns matching in this sequence and the pattern sequence.
   */
  int matching_length;

  /* The number of insns selected to abstract from this sequence. Less than
     or equal to MATCHING_LENGTH.  */
  int abstracted_length;

  /* The cost of the sequence.  */
  int cost;

  /* The next sequence in the chain matching the same pattern.  */
  struct matching_seq_def *next_matching_seq;
} *matching_seq;


/* A pattern instruction sequence.  */
typedef struct pattern_seq_def
{
  /* The last insn in the pattern sequence.  */
  rtx insn;

  /* Index of INSN instruction.  */
  unsigned long idx;

  /* The gain of transforming the pattern sequence into a pseudo-function and
     the matching sequences into pseudo-calls.  */
  int gain;

  /* The maximum of the ABSTRACTED_LENGTH of the matching sequences.  */
  int abstracted_length;

  /* The cost of the sequence.  */
  int cost;

  /* The register used to hold the return address during the pseudo-call.  */
  rtx link_reg;

  /* The sequences matching this pattern.  */
  matching_seq matching_seqs;

  /* The next pattern sequence in the chain.  */
  struct pattern_seq_def *next_pattern_seq;
} *pattern_seq;


/* A block of a pattern sequence.  */
typedef struct seq_block_def
{
  /* The number of insns in the block.  */
  int length;

  /* The code_label of the block.  */
  rtx label;

  /* The sequences entering the pattern sequence at LABEL.  */
  matching_seq matching_seqs;

  /* The next block in the chain. The blocks are sorted by LENGTH in
     ascending order.  */
  struct seq_block_def *next_seq_block;
} *seq_block;

/* Contains same sequence candidates for further searching.  */
typedef struct hash_bucket_def
{
  /* The hash value of the group.  */
  unsigned int hash;

  /* List of sequence candidates.  */
  htab_t seq_candidates;
} *p_hash_bucket;
typedef const struct hash_bucket_def *const_p_hash_bucket;

/* Contains the last insn of the sequence, and its index value.  */
typedef struct hash_elem_def
{
  /* Unique index; ordered by FILL_HASH_BUCKET.  */
  unsigned long idx;

  /* The last insn in the sequence.  */
  rtx insn;

  /* The cached length of the insn.  */
  int length;
} *p_hash_elem;
typedef const struct hash_elem_def *const_p_hash_elem;

/* The list of same sequence candidates.  */
static htab_t hash_buckets;

/* The pattern sequences collected from the current functions.  */
static pattern_seq pattern_seqs;

/* The blocks of the current pattern sequence.  */
static seq_block seq_blocks;

/* Cost of calling sequence.  */
static int seq_call_cost;

/* Cost of jump.  */
static int seq_jump_cost;

/* Cost of returning.  */
static int seq_return_cost;

/* Returns the first insn preceding INSN for which INSN_P is true and belongs to
   the same basic block. Returns NULL_RTX if no such insn can be found.  */

static rtx
prev_insn_in_block (rtx insn)
{
  basic_block bb = BLOCK_FOR_INSN (insn);

  if (!bb)
    return NULL_RTX;

  while (insn != BB_HEAD (bb))
    {
      insn = PREV_INSN (insn);
      if (INSN_P (insn))
        return insn;
    }
  return NULL_RTX;
}

/* Returns the hash value of INSN.  */

static unsigned int
compute_hash (rtx insn)
{
  unsigned int hash = 0;
  rtx prev;

  hash = INSN_CODE (insn) * 100;

  prev = prev_insn_in_block (insn);
  if (prev)
    hash += INSN_CODE (prev);

  return hash;
}

/* Compute the cost of INSN rtx for abstraction.  */

static int
compute_rtx_cost (rtx insn)
{
  struct hash_bucket_def tmp_bucket;
  p_hash_bucket bucket;
  struct hash_elem_def tmp_elem;
  p_hash_elem elem = NULL;
  int cost = -1;

  /* Compute hash value for INSN.  */
  tmp_bucket.hash = compute_hash (insn);

  /* Select the hash group.  */
  bucket = (p_hash_bucket) htab_find (hash_buckets, &tmp_bucket);

  if (bucket)
  {
    tmp_elem.insn = insn;

    /* Select the insn.  */
    elem = (p_hash_elem) htab_find (bucket->seq_candidates, &tmp_elem);

    /* If INSN is parsed the cost will be the cached length.  */
    if (elem)
      cost = elem->length;
  }

  /* If we can't parse the INSN cost will be the instruction length.  */
  if (cost == -1)
  {
    cost = get_attr_length (insn);

    /* Cache the length.  */
    if (elem)
      elem->length = cost;
  }

  /* If we can't get an accurate estimate for a complex instruction,
     assume that it has the same cost as a single fast instruction.  */
  return cost != 0 ? cost : COSTS_N_INSNS (1);
}

/* Determines the number of common insns in the sequences ending in INSN1 and
   INSN2. Returns with LEN number of common insns and COST cost of sequence.
*/

static void
matching_length (rtx insn1, rtx insn2, int* len, int* cost)
{
  rtx x1;
  rtx x2;

  x1 = insn1;
  x2 = insn2;
  *len = 0;
  *cost = 0;
  while (x1 && x2 && (x1 != insn2) && (x2 != insn1)
         && rtx_equal_p (PATTERN (x1), PATTERN (x2)))
    {
      (*len)++;
      (*cost) += compute_rtx_cost (x1);
      x1 = prev_insn_in_block (x1);
      x2 = prev_insn_in_block (x2);
    }
}

/* Adds E0 as a pattern sequence to PATTERN_SEQS with E1 as a matching
   sequence.  */

static void
match_seqs (p_hash_elem e0, p_hash_elem e1)
{
  int len;
  int cost;
  matching_seq mseq, p_prev, p_next;

  /* Determines the cost of the sequence and return without doing anything
     if it is too small to produce any gain.  */
  matching_length (e0->insn, e1->insn, &len, &cost);
  if (cost <= seq_call_cost)
    return;

  /* Prepend a new PATTERN_SEQ to PATTERN_SEQS if the last pattern sequence
     does not end in E0->INSN. This assumes that once the E0->INSN changes
     the old value will never appear again.  */
  if (!pattern_seqs || pattern_seqs->insn != e0->insn)
    {
      pattern_seq pseq =
        (pattern_seq) xmalloc (sizeof (struct pattern_seq_def));
      pseq->insn = e0->insn;
      pseq->idx = e0->idx;
      pseq->gain = 0;                 /* Set to zero to force recomputing.  */
      pseq->abstracted_length = 0;
      pseq->cost = 0;
      pseq->link_reg = NULL_RTX;
      pseq->matching_seqs = NULL;
      pseq->next_pattern_seq = pattern_seqs;
      pattern_seqs = pseq;
    }

  /* Find the position of E1 in the matching sequences list.  */
  p_prev = NULL;
  p_next = pattern_seqs->matching_seqs;
  while (p_next && p_next->idx < e1->idx)
    {
      p_prev = p_next;
      p_next = p_next->next_matching_seq;
    }

  /* Add a new E1 matching sequence to the pattern sequence. We know that
     it ends in E0->INSN.  */
  mseq = (matching_seq) xmalloc (sizeof (struct matching_seq_def));
  mseq->insn = e1->insn;
  mseq->idx = e1->idx;
  mseq->matching_length = len;
  mseq->abstracted_length = 0;
  mseq->cost = cost;

  if (p_prev == NULL)
    pattern_seqs->matching_seqs = mseq;
  else
    p_prev->next_matching_seq = mseq;
  mseq->next_matching_seq = p_next;
}

/* Collects all pattern sequences and their matching sequences and puts them
   into PATTERN_SEQS.  */

static void
collect_pattern_seqs (void)
{
  htab_iterator hti0, hti1, hti2;
  p_hash_bucket hash_bucket;
  p_hash_elem e0, e1;
#if defined STACK_REGS || defined HAVE_cc0
  basic_block bb;
  bitmap_head dont_collect;

  /* Extra initialization step to ensure that no stack registers (if present)
     or cc0 code (if present) are live across abnormal edges.
     Set a flag in DONT_COLLECT for an insn if a stack register is live
     after the insn or the insn is cc0 setter or user.  */
  bitmap_initialize (&dont_collect, NULL);

#ifdef STACK_REGS
  FOR_EACH_BB (bb)
  {
    regset_head live;
    rtx insn;
    rtx prev;

    /* Initialize liveness propagation.  */
    INIT_REG_SET (&live);
    bitmap_copy (&live, DF_LR_OUT (bb));
    df_simulate_initialize_backwards (bb, &live);

    /* Propagate liveness info and mark insns where a stack reg is live.  */
    insn = BB_END (bb);
    for (insn = BB_END (bb); ; insn = prev)
      {
	prev = PREV_INSN (insn);
	if (INSN_P (insn))
	  {
	    int reg;
	    for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
	      {
		if (REGNO_REG_SET_P (&live, reg))
		  {
		    bitmap_set_bit (&dont_collect, INSN_UID (insn));
		    break;
		  }
	      }
	    
	  }
	if (insn == BB_HEAD (bb))
	  break;
	df_simulate_one_insn_backwards (bb, insn, &live);
	insn = prev;
      }

    /* Free unused data.  */
    CLEAR_REG_SET (&live);
  }
#endif

#ifdef HAVE_cc0
  /* Mark CC0 setters and users as ineligible for collection into sequences.
     This is an over-conservative fix, since it is OK to include
     a cc0_setter, but only if we also include the corresponding cc0_user,
     and vice versa.  */
  FOR_EACH_BB (bb)
  {
    rtx insn;
    rtx next_tail;

    next_tail = NEXT_INSN (BB_END (bb));

    for (insn = BB_HEAD (bb); insn != next_tail; insn = NEXT_INSN (insn))
      {
	if (INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
	  bitmap_set_bit (&dont_collect, INSN_UID (insn));
      }
  }
#endif

#endif /* defined STACK_REGS || defined HAVE_cc0 */

  /* Initialize PATTERN_SEQS to empty.  */
  pattern_seqs = 0;

  /* Try to match every abstractable insn with every other insn in the same
     HASH_BUCKET.  */

  FOR_EACH_HTAB_ELEMENT (hash_buckets, hash_bucket, p_hash_bucket, hti0)
    if (htab_elements (hash_bucket->seq_candidates) > 1)
      FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e0, p_hash_elem, hti1)
        FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e1, p_hash_elem,
                               hti2)
          if (e0 != e1
#if defined STACK_REGS || defined HAVE_cc0
              && !bitmap_bit_p (&dont_collect, INSN_UID (e0->insn))
              && !bitmap_bit_p (&dont_collect, INSN_UID (e1->insn))
#endif
             )
            match_seqs (e0, e1);
#if defined STACK_REGS || defined HAVE_cc0
  /* Free unused data.  */
  bitmap_clear (&dont_collect);
#endif
}

/* Transforms a regset to a HARD_REG_SET. Every hard register in REGS is added
   to hregs. Additionally, the hard counterpart of every renumbered pseudo
   register is also added.  */

static void
renumbered_reg_set_to_hard_reg_set (HARD_REG_SET * hregs, regset regs)
{
  int r;

  REG_SET_TO_HARD_REG_SET (*hregs, regs);
  for (r = FIRST_PSEUDO_REGISTER; r < max_regno; r++)
    if (REGNO_REG_SET_P (regs, r) && reg_renumber[r] >= 0)
      SET_HARD_REG_BIT (*hregs, reg_renumber[r]);
}

/* Clears the bits in REGS for all registers, which are live in the sequence
   give by its last INSN and its LENGTH.  */

static void
clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
{
  basic_block bb;
  regset_head live;
  HARD_REG_SET hlive;
  rtx x;
  int i;

  /* Initialize liveness propagation.  */
  bb = BLOCK_FOR_INSN (insn);
  INIT_REG_SET (&live);
  bitmap_copy (&live, DF_LR_OUT (bb));
  df_simulate_initialize_backwards (bb, &live);

  /* Propagate until INSN if found.  */
  for (x = BB_END (bb); x != insn; x = PREV_INSN (x))
    df_simulate_one_insn_backwards (bb, x, &live);

  /* Clear registers live after INSN.  */
  renumbered_reg_set_to_hard_reg_set (&hlive, &live);
  AND_COMPL_HARD_REG_SET (*regs, hlive);

  /* Clear registers live in and before the sequence.  */
  for (i = 0; i < length;)
    {
      rtx prev = PREV_INSN (x);
      df_simulate_one_insn_backwards (bb, x, &live);

      if (INSN_P (x))
        {
          renumbered_reg_set_to_hard_reg_set (&hlive, &live);
          AND_COMPL_HARD_REG_SET (*regs, hlive);
          i++;
        }

      x = prev;
    }

  /* Free unused data.  */
  CLEAR_REG_SET (&live);
}

/* Computes the gain of turning PSEQ into a pseudo-function and its matching
   sequences into pseudo-calls. Also computes and caches the number of insns to
   abstract from  the matching sequences.  */

static void
recompute_gain_for_pattern_seq (pattern_seq pseq)
{
  matching_seq mseq;
  rtx x;
  int i;
  int hascall;
  HARD_REG_SET linkregs;

  /* Initialize data.  */
  SET_HARD_REG_SET (linkregs);
  pseq->link_reg = NULL_RTX;
  pseq->abstracted_length = 0;

  pseq->gain = -(seq_call_cost - seq_jump_cost + seq_return_cost);

  /* Determine ABSTRACTED_LENGTH and COST for matching sequences of PSEQ.
     ABSTRACTED_LENGTH may be less than MATCHING_LENGTH if sequences in the
     same block overlap. */

  for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
    {
      /* Determine ABSTRACTED_LENGTH.  */
      if (mseq->next_matching_seq)
        mseq->abstracted_length = (int)(mseq->next_matching_seq->idx -
                                        mseq->idx);
      else
        mseq->abstracted_length = mseq->matching_length;

      if (mseq->abstracted_length > mseq->matching_length)
        mseq->abstracted_length = mseq->matching_length;

      /* Compute the cost of sequence.  */
      RECOMPUTE_COST (mseq);

      /* If COST is big enough registers live in this matching sequence
         should not be used as a link register. Also set ABSTRACTED_LENGTH
         of PSEQ.  */
      if (mseq->cost > seq_call_cost)
        {
          clear_regs_live_in_seq (&linkregs, mseq->insn,
                                  mseq->abstracted_length);
          if (mseq->abstracted_length > pseq->abstracted_length)
            pseq->abstracted_length = mseq->abstracted_length;
        }
    }

  /* Modify ABSTRACTED_LENGTH of PSEQ if pattern sequence overlaps with one
     of the matching sequences.  */
  for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
    {
      x = pseq->insn;
      for (i = 0; (i < pseq->abstracted_length) && (x != mseq->insn); i++)
        x = prev_insn_in_block (x);
      pseq->abstracted_length = i;
    }

  /* Compute the cost of pattern sequence.  */
  RECOMPUTE_COST (pseq);

  /* No gain if COST is too small.  */
  if (pseq->cost <= seq_call_cost)
  {
    pseq->gain = -1;
    return;
  }

  /* Ensure that no matching sequence is longer than the pattern sequence.  */
  for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
    {
      if (mseq->abstracted_length > pseq->abstracted_length)
        {
          mseq->abstracted_length = pseq->abstracted_length;
          RECOMPUTE_COST (mseq);
        }
      /* Once the length is stabilizing the gain can be calculated.  */
      if (mseq->cost > seq_call_cost)
        pseq->gain += mseq->cost - seq_call_cost;
    }

  /* No need to do further work if there is no gain.  */
  if (pseq->gain <= 0)
    return;

  /* Should not use registers live in the pattern sequence as link register.
   */
  clear_regs_live_in_seq (&linkregs, pseq->insn, pseq->abstracted_length);

  /* Determine whether pattern sequence contains a call_insn.  */
  hascall = 0;
  x = pseq->insn;
  for (i = 0; i < pseq->abstracted_length; i++)
    {
      if (CALL_P (x))
        {
          hascall = 1;
          break;
        }
      x = prev_insn_in_block (x);
    }

  /* Should not use a register as a link register if - it is a fixed
     register, or - the sequence contains a call insn and the register is a
     call used register, or - the register needs to be saved if used in a
     function but was not used before (since saving it can invalidate already
     computed frame pointer offsets), or - the register cannot be used as a
     base register.  */

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (fixed_regs[i]
#ifdef REGNO_OK_FOR_INDIRECT_JUMP_P
        || (!REGNO_OK_FOR_INDIRECT_JUMP_P (i, Pmode))
#else
        || (!ok_for_base_p_1 (i, Pmode, MEM, SCRATCH))
        || (!reg_class_subset_p (REGNO_REG_CLASS (i),
				 base_reg_class (VOIDmode, MEM, SCRATCH)))
#endif
        || (hascall && call_used_regs[i])
        || (!call_used_regs[i] && !df_regs_ever_live_p (i)))
      CLEAR_HARD_REG_BIT (linkregs, i);

  /* Find an appropriate register to be used as the link register.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (TEST_HARD_REG_BIT (linkregs, i))
      {
        pseq->link_reg = gen_rtx_REG (Pmode, i);
        break;
      }

  /* Abstraction is not possible if no link register is available, so set
     gain to 0.  */
  if (!pseq->link_reg)
    pseq->gain = 0;
}

/* Deallocates memory occupied by PSEQ and its matching seqs.  */

static void
free_pattern_seq (pattern_seq pseq)
{
  while (pseq->matching_seqs)
    {
      matching_seq mseq = pseq->matching_seqs;
      pseq->matching_seqs = mseq->next_matching_seq;
      free (mseq);
    }
  free (pseq);
}


/* Computes the gain for pattern sequences. Pattern sequences producing no gain
   are deleted. The pattern sequence with the biggest gain is moved to the first
   place of PATTERN_SEQS.  */

static void
recompute_gain (void)
{
  pattern_seq *pseq;
  int maxgain;

  maxgain = 0;
  for (pseq = &pattern_seqs; *pseq;)
    {
      if ((*pseq)->gain <= 0)
        recompute_gain_for_pattern_seq (*pseq);

      if ((*pseq)->gain > 0)
        {
          if ((*pseq)->gain > maxgain)
            {
              pattern_seq temp = *pseq;
              (*pseq) = temp->next_pattern_seq;
              temp->next_pattern_seq = pattern_seqs;
              pattern_seqs = temp;
              maxgain = pattern_seqs->gain;
            }
          else
            {
              pseq = &(*pseq)->next_pattern_seq;
            }
        }
      else
        {
          pattern_seq temp = *pseq;
          *pseq = temp->next_pattern_seq;
          free_pattern_seq (temp);
        }
    }
}

/* Updated those pattern sequences and matching sequences, which overlap with
   the sequence given by INSN and LEN. Deletes sequences shrinking below a
   limit.  */

static void
erase_from_pattern_seqs (rtx insn, int len)
{
  pattern_seq *pseq;
  matching_seq *mseq;
  rtx x;
  int plen, mlen;
  int pcost, mcost;

  while (len > 0)
    {
      for (pseq = &pattern_seqs; *pseq;)
        {
          plen = 0;
          pcost = 0;
          for (x = (*pseq)->insn; x && (x != insn);
               x = prev_insn_in_block (x))
            {
              plen++;
              pcost += compute_rtx_cost (x);
            }

          if (pcost <= seq_call_cost)
            {
              pattern_seq temp = *pseq;
              *pseq = temp->next_pattern_seq;
              free_pattern_seq (temp);
            }
          else
            {
              for (mseq = &(*pseq)->matching_seqs; *mseq;)
                {
                  mlen = 0;
                  mcost = 0;
                  for (x = (*mseq)->insn;
                       x && (x != insn) && (mlen < plen)
                       && (mlen < (*mseq)->matching_length);
                       x = prev_insn_in_block (x))
                    {
                      mlen++;
                      mcost += compute_rtx_cost (x);
                    }

                  if (mcost <= seq_call_cost)
                    {
                      matching_seq temp = *mseq;
                      *mseq = temp->next_matching_seq;
                      free (temp);
                      /* Set to 0 to force gain recomputation.  */
                      (*pseq)->gain = 0;
                    }
                  else
                    {
                      if (mlen < (*mseq)->matching_length)
                        {
                          (*mseq)->cost = mcost;
                          (*mseq)->matching_length = mlen;
                          /* Set to 0 to force gain recomputation.  */
                          (*pseq)->gain = 0;
                        }
                      mseq = &(*mseq)->next_matching_seq;
                    }
                }

              pseq = &(*pseq)->next_pattern_seq;
            }
        }

      len--;
      insn = prev_insn_in_block (insn);
    }
}

/* Updates those pattern sequences and matching sequences, which overlap with
   the pattern sequence with the biggest gain and its matching sequences.  */

static void
update_pattern_seqs (void)
{
  pattern_seq bestpseq;
  matching_seq mseq;

  bestpseq = pattern_seqs;
  pattern_seqs = bestpseq->next_pattern_seq;

  for (mseq = bestpseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
    if (mseq->cost > seq_call_cost)
      erase_from_pattern_seqs (mseq->insn, mseq->abstracted_length);
  erase_from_pattern_seqs (bestpseq->insn, bestpseq->abstracted_length);

  bestpseq->next_pattern_seq = pattern_seqs;
  pattern_seqs = bestpseq;
}

/* Groups together those matching sequences of the best pattern sequence, which
   have the same ABSTRACTED_LENGTH and puts these groups in ascending order.
   SEQ_BLOCKS contains the result.  */

static void
determine_seq_blocks (void)
{
  seq_block sb;
  matching_seq *mseq;
  matching_seq m;

  /* Initialize SEQ_BLOCKS to empty.  */
  seq_blocks = 0;

  /* Process all matching sequences.  */
  for (mseq = &pattern_seqs->matching_seqs; *mseq;)
    {
      /* Deal only with matching sequences being long enough. */
      if ((*mseq)->cost <= seq_call_cost)
        {
          mseq = &(*mseq)->next_matching_seq;
          continue;
        }

      /* Ensure that SB contains a seq_block with the appropriate length.
         Insert a new seq_block if necessary.  */
      if (!seq_blocks || ((*mseq)->abstracted_length < seq_blocks->length))
        {
          sb = (seq_block) xmalloc (sizeof (struct seq_block_def));
          sb->length = (*mseq)->abstracted_length;
          sb->label = NULL_RTX;
          sb->matching_seqs = 0;
          sb->next_seq_block = seq_blocks;
          seq_blocks = sb;
        }
      else
        {
          for (sb = seq_blocks; sb; sb = sb->next_seq_block)
            {
              if ((*mseq)->abstracted_length == sb->length)
                break;
              if (!sb->next_seq_block
                  || ((*mseq)->abstracted_length <
                      sb->next_seq_block->length))
                {
                  seq_block temp =
                    (seq_block) xmalloc (sizeof (struct seq_block_def));
                  temp->length = (*mseq)->abstracted_length;
                  temp->label = NULL_RTX;
                  temp->matching_seqs = 0;
                  temp->next_seq_block = sb->next_seq_block;
                  sb->next_seq_block = temp;
                }
            }
        }

      /* Remove the matching sequence from the linked list of the pattern
         sequence and link it to SB.  */
      m = *mseq;
      *mseq = m->next_matching_seq;
      m->next_matching_seq = sb->matching_seqs;
      sb->matching_seqs = m;
    }
}

/* Builds a symbol_ref for LABEL.  */

static rtx
gen_symbol_ref_rtx_for_label (const_rtx label)
{
  char name[20];
  rtx sym;

  ASM_GENERATE_INTERNAL_LABEL (name, "L", CODE_LABEL_NUMBER (label));
  sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
  SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
  return sym;
}

/* Splits basic block at the requested insn and rebuilds dataflow.  */

static basic_block
split_block_and_df_analyze (basic_block bb, rtx insn)
{
  basic_block next;
  next = split_block (bb, insn)->dest;
  df_analyze ();
  return next;
}

/* Ensures that INSN is the last insn in its block and returns the block label
   of the next block.  */

static rtx
block_label_after (rtx insn)
{
  basic_block bb = BLOCK_FOR_INSN (insn);
  if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR))
    return block_label (bb->next_bb);
  else
    return block_label (split_block_and_df_analyze (bb, insn));
}

/* Ensures that the last insns of the best pattern and its matching sequences
   are the last insns in their block. Additionally, extends the live set at the
   end of the pattern sequence with the live sets at the end of the matching
   sequences.  */

static void
split_blocks_after_seqs (void)
{
  seq_block sb;
  matching_seq mseq;

  block_label_after (pattern_seqs->insn);
  for (sb = seq_blocks; sb; sb = sb->next_seq_block)
    {
      for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
        {
          block_label_after (mseq->insn);
          IOR_REG_SET (df_get_live_out (BLOCK_FOR_INSN (pattern_seqs->insn)),
                       df_get_live_out (BLOCK_FOR_INSN (mseq->insn)));
        }
    }
}

/* Splits the best pattern sequence according to SEQ_BLOCKS. Emits pseudo-call
   and -return insns before and after the sequence.  */

static void
split_pattern_seq (void)
{
  rtx insn;
  basic_block bb;
  rtx retlabel, retjmp, saveinsn;
  int i;
  seq_block sb;

  insn = pattern_seqs->insn;
  bb = BLOCK_FOR_INSN (insn);

  /* Get the label after the sequence. This will be the return address. The
     label will be referenced using a symbol_ref so protect it from
     deleting.  */
  retlabel = block_label_after (insn);
  LABEL_PRESERVE_P (retlabel) = 1;

  /* Emit an indirect jump via the link register after the sequence acting
     as the return insn.  Also emit a barrier and update the basic block.  */
  if (!find_reg_note (BB_END (bb), REG_NORETURN, NULL))
    retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
                                   BB_END (bb));
  emit_barrier_after (BB_END (bb));

  /* Replace all outgoing edges with a new one to the block of RETLABEL.  */
  while (EDGE_COUNT (bb->succs) != 0)
    remove_edge (EDGE_SUCC (bb, 0));
  make_edge (bb, BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);

  /* Split the sequence according to SEQ_BLOCKS and cache the label of the
     resulting basic blocks.  */
  i = 0;
  for (sb = seq_blocks; sb; sb = sb->next_seq_block)
    {
      for (; i < sb->length; i++)
        insn = prev_insn_in_block (insn);

      sb->label = block_label (split_block_and_df_analyze (bb, insn));
    }

  /* Emit an insn saving the return address to the link register before the
     sequence.  */
  saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
                              gen_symbol_ref_rtx_for_label
                              (retlabel)), BB_END (bb));
  /* Update liveness info.  */
  SET_REGNO_REG_SET (df_get_live_out (bb),
                     REGNO (pattern_seqs->link_reg));
}

/* Deletes the insns of the matching sequences of the best pattern sequence and
   replaces them with pseudo-calls to the pattern sequence.  */

static void
erase_matching_seqs (void)
{
  seq_block sb;
  matching_seq mseq;
  rtx insn;
  basic_block bb;
  rtx retlabel, saveinsn, callinsn;
  int i;

  for (sb = seq_blocks; sb; sb = sb->next_seq_block)
    {
      for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
        {
          insn = mseq->insn;
          bb = BLOCK_FOR_INSN (insn);

          /* Get the label after the sequence. This will be the return
             address. The label will be referenced using a symbol_ref so
             protect it from deleting.  */
          retlabel = block_label_after (insn);
          LABEL_PRESERVE_P (retlabel) = 1;

          /* Delete the insns of the sequence.  */
          for (i = 0; i < sb->length; i++)
            insn = prev_insn_in_block (insn);
          delete_basic_block (split_block_and_df_analyze (bb, insn));

          /* Emit an insn saving the return address to the link register
             before the deleted sequence.  */
          saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
                                      gen_symbol_ref_rtx_for_label
                                      (retlabel)),
                                      BB_END (bb));
          BLOCK_FOR_INSN (saveinsn) = bb;

          /* Emit a jump to the appropriate part of the pattern sequence
             after the save insn. Also update the basic block.  */
          callinsn = emit_jump_insn_after (gen_jump (sb->label), saveinsn);
          JUMP_LABEL (callinsn) = sb->label;
          LABEL_NUSES (sb->label)++;
          BLOCK_FOR_INSN (callinsn) = bb;
          BB_END (bb) = callinsn;

          /* Maintain control flow and liveness information.  */
          SET_REGNO_REG_SET (df_get_live_out (bb),
                             REGNO (pattern_seqs->link_reg));
          emit_barrier_after (BB_END (bb));
          make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0);
          IOR_REG_SET (df_get_live_out (bb),
		       df_get_live_in (BLOCK_FOR_INSN (sb->label)));

          make_edge (BLOCK_FOR_INSN (seq_blocks->label),
                     BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
        }
    }
}

/* Deallocates SEQ_BLOCKS and all the matching sequences.  */

static void
free_seq_blocks (void)
{
  while (seq_blocks)
    {
      seq_block sb = seq_blocks;
      while (sb->matching_seqs)
        {
          matching_seq mseq = sb->matching_seqs;
          sb->matching_seqs = mseq->next_matching_seq;
          free (mseq);
        }
      seq_blocks = sb->next_seq_block;
      free (sb);
    }
}

/* Transforms the best pattern sequence into a pseudo-function and its matching
   sequences to pseudo-calls. Afterwards the best pattern sequence is removed
   from PATTERN_SEQS.  */

static void
abstract_best_seq (void)
{
  pattern_seq bestpseq;

  /* Do the abstraction.  */
  determine_seq_blocks ();
  split_blocks_after_seqs ();
  split_pattern_seq ();
  erase_matching_seqs ();
  free_seq_blocks ();

  /* Record the usage of the link register.  */
  df_set_regs_ever_live (REGNO (pattern_seqs->link_reg), true);

  /* Remove the best pattern sequence.  */
  bestpseq = pattern_seqs;
  pattern_seqs = bestpseq->next_pattern_seq;
  free_pattern_seq (bestpseq);
}

/* Prints info on the pattern sequences to the dump file.  */

static void
dump_pattern_seqs (void)
{
  pattern_seq pseq;
  matching_seq mseq;

  if (!dump_file)
    return;

  fprintf (dump_file, ";; Pattern sequences\n");
  for (pseq = pattern_seqs; pseq; pseq = pseq->next_pattern_seq)
    {
      fprintf (dump_file, "Pattern sequence at insn %d matches sequences at",
               INSN_UID (pseq->insn));
      for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
        {
          fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
                   mseq->matching_length);
          if (mseq->next_matching_seq)
            fprintf (dump_file, ",");
        }
      fprintf (dump_file, ".\n");
    }
  fprintf (dump_file, "\n");
}

/* Prints info on the best pattern sequence transformed in the ITER-th
   iteration to the dump file.  */

static void
dump_best_pattern_seq (int iter)
{
  matching_seq mseq;

  if (!dump_file)
    return;

  fprintf (dump_file, ";; Iteration %d\n", iter);
  fprintf (dump_file,
           "Best pattern sequence with %d gain is at insn %d (length %d).\n",
           pattern_seqs->gain, INSN_UID (pattern_seqs->insn),
           pattern_seqs->abstracted_length);
  fprintf (dump_file, "Matching sequences are at");
  for (mseq = pattern_seqs->matching_seqs; mseq;
       mseq = mseq->next_matching_seq)
    {
      fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
               mseq->abstracted_length);
      if (mseq->next_matching_seq)
        fprintf (dump_file, ",");
    }
  fprintf (dump_file, ".\n");
  fprintf (dump_file, "Using reg %d as link register.\n\n",
           REGNO (pattern_seqs->link_reg));
}

/* Htab hash function for hash_bucket_def structure.  */

static unsigned int
htab_hash_bucket (const void *p)
{
  const_p_hash_bucket bucket = (const_p_hash_bucket) p;
  return bucket->hash;
}

/* Htab equal function for hash_bucket_def structure.  */

static int
htab_eq_bucket (const void *p0, const void *p1)
{
  return htab_hash_bucket (p0) == htab_hash_bucket (p1);
}

/* Htab delete function for hash_bucket_def structure.  */

static void
htab_del_bucket (void *p)
{
  p_hash_bucket bucket = (p_hash_bucket) p;

  if (bucket->seq_candidates)
    htab_delete (bucket->seq_candidates);

  free (bucket);
}

/* Htab hash function for hash_bucket_def structure.  */

static unsigned int
htab_hash_elem (const void *p)
{
  const_p_hash_elem elem = (const_p_hash_elem) p;
  return htab_hash_pointer (elem->insn);
}

/* Htab equal function for hash_bucket_def structure.  */

static int
htab_eq_elem (const void *p0, const void *p1)
{
  return htab_hash_elem (p0) == htab_hash_elem (p1);
}

/* Htab delete function for hash_bucket_def structure.  */

static void
htab_del_elem (void *p)
{
  p_hash_elem elem = (p_hash_elem) p;
  free (elem);
}

/* Creates a hash value for each sequence candidate and saves them
   in HASH_BUCKET.  */

static void
fill_hash_bucket (void)
{
  basic_block bb;
  rtx insn;
  void **slot;
  p_hash_bucket bucket;
  struct hash_bucket_def tmp_bucket;
  p_hash_elem elem;
  unsigned long insn_idx;

  insn_idx = 0;
  FOR_EACH_BB (bb)
    {
      FOR_BB_INSNS_REVERSE (bb, insn)
        {
          if (!ABSTRACTABLE_INSN_P (insn))
            continue;

          /* Compute hash value for INSN.  */
          tmp_bucket.hash = compute_hash (insn);

          /* Select the hash group.  */
          bucket = (p_hash_bucket) htab_find (hash_buckets, &tmp_bucket);

          if (!bucket)
            {
              /* Create a new hash group.  */
              bucket = (p_hash_bucket) xcalloc (1,
                                        sizeof (struct hash_bucket_def));
              bucket->hash = tmp_bucket.hash;
              bucket->seq_candidates = NULL;

              slot = htab_find_slot (hash_buckets, &tmp_bucket, INSERT);
              *slot = bucket;
            }

          /* Create new list for storing sequence candidates.  */
          if (!bucket->seq_candidates)
              bucket->seq_candidates = htab_create (HASH_INIT,
                                                    htab_hash_elem,
                                                    htab_eq_elem,
                                                    htab_del_elem);

          elem = (p_hash_elem) xcalloc (1, sizeof (struct hash_elem_def));
          elem->insn = insn;
          elem->idx = insn_idx;
          elem->length = get_attr_length (insn);

          /* Insert INSN into BUCKET hash bucket.  */
          slot = htab_find_slot (bucket->seq_candidates, elem, INSERT);
          *slot = elem;

          insn_idx++;
        }
    }
}

/* Computes the cost of calling sequence and the cost of return.  */

static void
compute_init_costs (void)
{
  rtx rtx_jump, rtx_store, rtx_return, reg, label;
  basic_block bb;

  FOR_EACH_BB (bb)
    if (BB_HEAD (bb))
      break;

  label = block_label (bb);
  reg = gen_rtx_REG (Pmode, 0);

  /* Pattern for indirect jump.  */
  rtx_jump = gen_indirect_jump (reg);

  /* Pattern for storing address.  */
  rtx_store = gen_rtx_SET (VOIDmode, reg, gen_symbol_ref_rtx_for_label (label));

  /* Pattern for return insn.  */
  rtx_return = gen_jump (label);

  /* The cost of jump.  */
  seq_jump_cost = compute_rtx_cost (make_jump_insn_raw (rtx_jump));

  /* The cost of calling sequence.  */
  seq_call_cost = seq_jump_cost + compute_rtx_cost (make_insn_raw (rtx_store));

  /* The cost of return.  */
  seq_return_cost = compute_rtx_cost (make_jump_insn_raw (rtx_return));

  /* Simple heuristic for minimal sequence cost.  */
  seq_call_cost   = (int)(seq_call_cost * (double)SEQ_CALL_COST_MULTIPLIER);
}

/* Finds equivalent insn sequences in the current function and retains only one
   instance of them which is turned into a pseudo-function. The additional
   copies are erased and replaced by pseudo-calls to the retained sequence.  */

static void
rtl_seqabstr (void)
{
  int iter;
  df_set_flags (DF_LR_RUN_DCE);
  df_analyze ();

  /* Create a hash list for COLLECT_PATTERN_SEQS.  */
  hash_buckets = htab_create (HASH_INIT, htab_hash_bucket , htab_eq_bucket ,
                              htab_del_bucket);
  fill_hash_bucket ();

  /* Compute the common cost of abstraction.  */
  compute_init_costs ();

  /* Build an initial set of pattern sequences from the current function.  */
  collect_pattern_seqs ();
  dump_pattern_seqs ();

  /* Iterate until there are no sequences to abstract.  */
  for (iter = 1;; iter++)
    {
      /* Recompute gain for sequences if necessary and select sequence with
         biggest gain.  */
      recompute_gain ();
      if (!pattern_seqs)
        break;
      dump_best_pattern_seq (iter);
      /* Update the cached info of the other sequences and force gain
         recomputation where needed.  */
      update_pattern_seqs ();
      /* Turn best sequences into pseudo-functions and -calls.  */
      abstract_best_seq ();
    }

  /* Cleanup hash tables.  */
  htab_delete (hash_buckets);
}

/* The gate function for TREE_OPT_PASS.  */

static bool
gate_rtl_seqabstr (void)
{
  return flag_rtl_seqabstr;
}

/* The entry point of the sequence abstraction algorithm.  */

static unsigned int
rest_of_rtl_seqabstr (void)
{
  /* Abstract out common insn sequences. */
  rtl_seqabstr ();
  return 0;
}

struct rtl_opt_pass pass_rtl_seqabstr = 
{
 {
  RTL_PASS,
  "seqabstr",                           /* name */
  gate_rtl_seqabstr,                    /* gate */
  rest_of_rtl_seqabstr,                 /* execute */
  NULL,                                 /* sub */
  NULL,                                 /* next */
  0,                                    /* static_pass_number */
  TV_SEQABSTR,                          /* tv_id */
  0,                                    /* properties_required */
  0,                                    /* properties_provided */
  0,                                    /* properties_destroyed */
  0,                                    /* todo_flags_start */
  TODO_df_finish | TODO_verify_rtl_sharing |
  TODO_dump_func |
  TODO_ggc_collect                      /* todo_flags_finish */
 }
};
