Beispiel #1
0
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++;
        }
    }
}
Beispiel #2
0
static int
get_uncond_jump_length (void)
{
  rtx label, jump;
  int length;

  label = emit_label_before (gen_label_rtx (), get_insns ());
  jump = emit_jump_insn (gen_jump (label));

  length = get_attr_length (jump);

  delete_insn (jump);
  delete_insn (label);
  return length;
}
Beispiel #3
0
static bool
copy_bb_p (basic_block bb, int code_may_grow)
{
  int size = 0;
  int max_size = uncond_jump_length;
  rtx insn;
  int n_succ;
  edge e;

  if (!bb->frequency)
    return false;
  if (!bb->pred || !bb->pred->pred_next)
    return false;
  if (!cfg_layout_can_duplicate_bb_p (bb))
    return false;

  /* Avoid duplicating blocks which have many successors (PR/13430).  */
  n_succ = 0;
  for (e = bb->succ; e; e = e->succ_next)
    {
      n_succ++;
      if (n_succ > 8)
	return false;
    }

  if (code_may_grow && maybe_hot_bb_p (bb))
    max_size *= 8;

  for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
       insn = NEXT_INSN (insn))
    {
      if (INSN_P (insn))
	size += get_attr_length (insn);
    }

  if (size <= max_size)
    return true;

  if (rtl_dump_file)
    {
      fprintf (rtl_dump_file,
	       "Block %d can't be copied because its size = %d.\n",
	       bb->index, size);
    }

  return false;
}
Beispiel #4
0
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);
}