Ejemplo n.º 1
0
/* Write out the complete conditions table, its size, and a flag
   indicating that gensupport.c can now do insn elision.  */
static void
write_conditions (void)
{
  puts ("\
/* This table lists each condition found in the machine description.\n\
   Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
   cannot be calculated at compile time. */\n\
\n\
const struct c_test insn_conditions[] = {");

  htab_traverse (condition_table, write_one_condition, 0);

  puts ("};\n");

  printf ("const size_t n_insn_conditions = %lu;\n",
	  (unsigned long) htab_elements (condition_table));
  puts ("const int insn_elision_unavailable = 0;\n#endif");
}
Ejemplo n.º 2
0
static unsigned int
rest_of_handle_simplify_got (void)
{
  df_ref ref;
  rtx use = NULL_RTX;
  int i, n_symbol, n_access = 0;
  struct got_access_info* got_accesses;
  htab_t var_table = htab_create (VAR_TABLE_SIZE,
				  htab_hash_pointer,
				  htab_eq_pointer,
				  NULL);
  rtx pic_reg = targetm.got_access.get_pic_reg ();
  gcc_assert (pic_reg);

  ref = DF_REG_USE_CHAIN (REGNO (pic_reg));
  got_accesses = XNEWVEC(struct got_access_info,
			 DF_REG_USE_COUNT (REGNO (pic_reg)));

  /* Check if all uses of pic_reg are loading global address through the
     default method.  */
  while (ref)
    {
      rtx_insn* insn = DF_REF_INSN (ref);

      /* Check for the special USE insn, it is not a real usage of pic_reg.  */
      if (GET_CODE (PATTERN (insn)) == USE)
	use = insn;
      else
	{
	  /* If an insn both set and use pic_reg, it is in the process of
	     constructing the value of pic_reg. We should also ignore it.  */
	  rtx set = single_set (insn);
	  if (!(set && SET_DEST (set) == pic_reg))
	    {
	      rtx offset_reg;
	      rtx offset_insn;
	      rtx symbol = targetm.got_access.loaded_global_var (insn,
								 &offset_reg,
								 &offset_insn);
	      if (symbol)
		{
		  rtx* slot = (rtx*) htab_find_slot (var_table, symbol, INSERT);
		  if (*slot == HTAB_EMPTY_ENTRY)
		    *slot = symbol;

		  gcc_assert (set);
		  got_accesses[n_access].symbol = symbol;
		  got_accesses[n_access].offset_reg = offset_reg;
		  got_accesses[n_access].address_reg = SET_DEST (set);
		  got_accesses[n_access].load_insn = insn;
		  got_accesses[n_access].offset_insn = offset_insn;
		  n_access++;
		}
	      else
		{
		  /* This insn doesn't load a global address, but it has
		     other unexpected usage of pic_reg, give up.  */
		  free (got_accesses);
		  htab_delete (var_table);
		  return 0;
		}
	    }
	}
      ref = DF_REF_NEXT_REG(ref);
    }

  /* Check if we can simplify it.  */
  n_symbol = htab_elements (var_table);
  gcc_assert (n_symbol <= n_access);
  if (!targetm.got_access.can_simplify_got_access (n_symbol, n_access))
    {
      free (got_accesses);
      htab_delete (var_table);
      return 0;
    }

  /* Rewrite the global address loading insns.  */
  for (i=0; i<n_access; i++)
    targetm.got_access.load_global_address (got_accesses[i].symbol,
					    got_accesses[i].offset_reg,
					    got_accesses[i].address_reg,
					    got_accesses[i].load_insn,
					    got_accesses[i].offset_insn);

  /* Since there is no usage of pic_reg now, we can remove it.  */
  if (use)
    remove_insn (use);
  targetm.got_access.clear_pic_reg ();
  free (got_accesses);
  htab_delete (var_table);
  return 0;
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
size_t
(htab_elements) (htab_t htab)
{
  return htab_elements (htab);
}