示例#1
0
文件: web.c 项目: CookieChen/gcc
void
union_defs (df_ref use, struct web_entry *def_entry,
	    unsigned int *used, struct web_entry *use_entry,
 	    bool (*fun) (struct web_entry *, struct web_entry *))
{
  struct df_insn_info *insn_info = DF_REF_INSN_INFO (use);
  struct df_link *link = DF_REF_CHAIN (use);
  rtx set;

  if (insn_info)
    {
      df_ref eq_use;

      set = single_set (insn_info->insn);
      FOR_EACH_INSN_INFO_EQ_USE (eq_use, insn_info)
	if (use != eq_use
	    && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (eq_use))
	  (*fun) (use_entry + DF_REF_ID (use), use_entry + DF_REF_ID (eq_use));
    }
  else
示例#2
0
static void
replace_ref (struct ref *ref, rtx reg)
{
  rtx oldreg = DF_REF_REAL_REG (ref);
  rtx *loc = DF_REF_REAL_LOC (ref);

  if (oldreg == reg)
    return;
  if (dump_file)
    fprintf (dump_file, "Updating insn %i (%i->%i)\n",
	     INSN_UID (DF_REF_INSN (ref)), REGNO (oldreg), REGNO (reg)); 
  *loc = reg;
}
示例#3
0
文件: web.c 项目: aosm/gcc_40
static rtx
entry_register (struct web_entry *entry, struct ref *ref, char *used)
{
  struct web_entry *root;
  rtx reg, newreg;

  /* Find the corresponding web and see if it has been visited.  */
  root = unionfind_root (entry);
  if (root->reg)
    return root->reg;

  /* We are seeing this web for the first time, do the assignment.  */
  reg = DF_REF_REAL_REG (ref);

  /* In case the original register is already assigned, generate new one.  */
  if (!used[REGNO (reg)])
    newreg = reg, used[REGNO (reg)] = 1;
  else if (REG_USERVAR_P (reg) && 0/*&& !flag_messy_debugging*/)
    {
      newreg = reg;
      if (dump_file)
	fprintf (dump_file,
		 "New web forced to keep reg=%i (user variable)\n",
		 REGNO (reg));
    }
  else
    {
      newreg = gen_reg_rtx (GET_MODE (reg));
      REG_USERVAR_P (newreg) = REG_USERVAR_P (reg);
      REG_POINTER (newreg) = REG_POINTER (reg);
      REG_LOOP_TEST_P (newreg) = REG_LOOP_TEST_P (reg);
      REG_ATTRS (newreg) = REG_ATTRS (reg);
      if (dump_file)
	fprintf (dump_file, "Web oldreg=%i newreg=%i\n", REGNO (reg),
		 REGNO (newreg));
    }

  root->reg = newreg;
  return newreg;
}
示例#4
0
static void
union_defs (struct df *df, struct ref *use, struct web_entry *def_entry,
            struct web_entry *use_entry)
{
  rtx insn = DF_REF_INSN (use);
  struct df_link *link = DF_REF_CHAIN (use);
  struct df_link *use_link = DF_INSN_USES (df, insn);
  struct df_link *def_link = DF_INSN_DEFS (df, insn);
  rtx set = single_set (insn);

  /* Some instructions may use match_dup for their operands.  In case the
     operands are dead, we will assign them different pseudos, creating
     invalid instructions, so union all uses of the same operand for each
     insn.  */

  while (use_link)
    {
      if (use != use_link->ref
	  && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (use_link->ref))
	unionfind_union (use_entry + DF_REF_ID (use),
		         use_entry + DF_REF_ID (use_link->ref));
      use_link = use_link->next;
    }

  /* Recognize trivial noop moves and attempt to keep them as noop.
     While most of noop moves should be removed, we still keep some
     of them at libcall boundaries and such.  */

  if (set
      && SET_SRC (set) == DF_REF_REG (use)
      && SET_SRC (set) == SET_DEST (set))
    {
      while (def_link)
	{
	  if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def_link->ref))
	    unionfind_union (use_entry + DF_REF_ID (use),
			     def_entry + DF_REF_ID (def_link->ref));
	  def_link = def_link->next;
	}
    }
  while (link)
    {
      unionfind_union (use_entry + DF_REF_ID (use),
		       def_entry + DF_REF_ID (link->ref));
      link = link->next;
    }

  /* A READ_WRITE use requires the corresponding def to be in the same
     register.  Find it and union.  */
  if (use->flags & DF_REF_READ_WRITE)
    {
      struct df_link *link = DF_INSN_DEFS (df, DF_REF_INSN (use));

      while (link)
	{
	  if (DF_REF_REAL_REG (link->ref) == DF_REF_REAL_REG (use))
	    unionfind_union (use_entry + DF_REF_ID (use),
			     def_entry + DF_REF_ID (link->ref));
	  link = link->next;
	}
    }
}
示例#5
0
文件: init-regs.c 项目: alcides/gcc
static void
initialize_uninitialized_regs (void)
{
  basic_block bb;
  bitmap already_genned = BITMAP_ALLOC (NULL);

  if (optimize == 1)
    {
      df_live_add_problem ();
      df_live_set_all_dirty ();
    }

  df_analyze ();

  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      bitmap lr = DF_LR_IN (bb);
      bitmap ur = DF_LIVE_IN (bb);
      bitmap_clear (already_genned);

      FOR_BB_INSNS (bb, insn)
	{
	  df_ref use;
	  if (!NONDEBUG_INSN_P (insn))
	    continue;

	  FOR_EACH_INSN_USE (use, insn)
	    {
	      unsigned int regno = DF_REF_REGNO (use);

	      /* Only do this for the pseudos.  */
	      if (regno < FIRST_PSEUDO_REGISTER)
		continue;

	      /* Do not generate multiple moves for the same regno.
		 This is common for sequences of subreg operations.
		 They would be deleted during combine but there is no
		 reason to churn the system.  */
	      if (bitmap_bit_p (already_genned, regno))
		continue;

	      /* A use is MUST uninitialized if it reaches the top of
		 the block from the inside of the block (the lr test)
		 and no def for it reaches the top of the block from
		 outside of the block (the ur test).  */
	      if (bitmap_bit_p (lr, regno)
		  && (!bitmap_bit_p (ur, regno)))
		{
		  rtx_insn *move_insn;
		  rtx reg = DF_REF_REAL_REG (use);

		  bitmap_set_bit (already_genned, regno);

		  start_sequence ();
		  emit_move_insn (reg, CONST0_RTX (GET_MODE (reg)));
		  move_insn = get_insns ();
		  end_sequence ();
		  emit_insn_before (move_insn, insn);
		  if (dump_file)
		    fprintf (dump_file,
			     "adding initialization in %s of reg %d at in block %d for insn %d.\n",
			     current_function_name (), regno, bb->index,
			     INSN_UID (insn));
		}
	    }