Exemple #1
0
static struct df_link *
get_defs (rtx_insn *insn, rtx reg, vec<rtx_insn *> *dest)
{
  df_ref use;
  struct df_link *ref_chain, *ref_link;

  FOR_EACH_INSN_USE (use, insn)
    {
      if (GET_CODE (DF_REF_REG (use)) == SUBREG)
        return NULL;
      if (REGNO (DF_REF_REG (use)) == REGNO (reg))
	break;
    }

  gcc_assert (use != NULL);

  ref_chain = DF_REF_CHAIN (use);

  for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
    {
      /* Problem getting some definition for this instruction.  */
      if (ref_link->ref == NULL)
        return NULL;
      if (DF_REF_INSN_INFO (ref_link->ref) == NULL)
        return NULL;
    }

  if (dest)
    for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
      dest->safe_push (DF_REF_INSN (ref_link->ref));

  return ref_chain;
}
Exemple #2
0
static struct df_link *
get_uses (rtx_insn *insn, rtx reg)
{
  df_ref def;
  struct df_link *ref_chain, *ref_link;

  FOR_EACH_INSN_DEF (def, insn)
    if (REGNO (DF_REF_REG (def)) == REGNO (reg))
      break;

  gcc_assert (def != NULL);

  ref_chain = DF_REF_CHAIN (def);

  for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
    {
      /* Problem getting some use for this instruction.  */
      if (ref_link->ref == NULL)
        return NULL;
      if (DF_REF_CLASS (ref_link->ref) != DF_REF_REGULAR)
	return NULL;
    }

  return ref_chain;
}
Exemple #3
0
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
Exemple #4
0
static struct df_link *
get_defs (rtx_insn *insn, rtx reg, vec<rtx_insn *> *dest)
{
  df_ref use;
  struct df_link *ref_chain, *ref_link;

  FOR_EACH_INSN_USE (use, insn)
    {
      if (GET_CODE (DF_REF_REG (use)) == SUBREG)
        return NULL;
      if (REGNO (DF_REF_REG (use)) == REGNO (reg))
	break;
    }

  gcc_assert (use != NULL);

  ref_chain = DF_REF_CHAIN (use);

  for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
    {
      /* Problem getting some definition for this instruction.  */
      if (ref_link->ref == NULL)
        return NULL;
      if (DF_REF_INSN_INFO (ref_link->ref) == NULL)
        return NULL;
      /* As global regs are assumed to be defined at each function call
	 dataflow can report a call_insn as being a definition of REG.
	 But we can't do anything with that in this pass so proceed only
	 if the instruction really sets REG in a way that can be deduced
	 from the RTL structure.  */
      if (global_regs[REGNO (reg)]
	  && !set_of (reg, DF_REF_INSN (ref_link->ref)))
	return NULL;
    }

  if (dest)
    for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
      dest->safe_push (DF_REF_INSN (ref_link->ref));

  return ref_chain;
}
Exemple #5
0
Fichier : ree.c Projet : aixoss/gcc
static struct df_link *
get_defs (rtx insn, rtx reg, vec<rtx> *dest)
{
  df_ref reg_info, *uses;
  struct df_link *ref_chain, *ref_link;

  reg_info = NULL;

  for (uses = DF_INSN_USES (insn); *uses; uses++)
    {
      reg_info = *uses;
      if (GET_CODE (DF_REF_REG (reg_info)) == SUBREG)
        return NULL;
      if (REGNO (DF_REF_REG (reg_info)) == REGNO (reg))
        break;
    }

  gcc_assert (reg_info != NULL && uses != NULL);

  ref_chain = DF_REF_CHAIN (reg_info);

  for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
    {
      /* Problem getting some definition for this instruction.  */
      if (ref_link->ref == NULL)
        return NULL;
      if (DF_REF_INSN_INFO (ref_link->ref) == NULL)
        return NULL;
    }

  if (dest)
    for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
      dest->safe_push (DF_REF_INSN (ref_link->ref));

  return ref_chain;
}
Exemple #6
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;
	}
    }
}
Exemple #7
0
static bool
find_call_stack_args (rtx_call_insn *call_insn, bool do_mark, bool fast,
		      bitmap arg_stores)
{
  rtx p;
  rtx_insn *insn, *prev_insn;
  bool ret;
  HOST_WIDE_INT min_sp_off, max_sp_off;
  bitmap sp_bytes;

  gcc_assert (CALL_P (call_insn));
  if (!ACCUMULATE_OUTGOING_ARGS)
    return true;

  if (!do_mark)
    {
      gcc_assert (arg_stores);
      bitmap_clear (arg_stores);
    }

  min_sp_off = INTTYPE_MAXIMUM (HOST_WIDE_INT);
  max_sp_off = 0;

  /* First determine the minimum and maximum offset from sp for
     stored arguments.  */
  for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
    if (GET_CODE (XEXP (p, 0)) == USE
	&& MEM_P (XEXP (XEXP (p, 0), 0)))
      {
	rtx mem = XEXP (XEXP (p, 0), 0), addr;
	HOST_WIDE_INT off = 0, size;
	if (!MEM_SIZE_KNOWN_P (mem))
	  return false;
	size = MEM_SIZE (mem);
	addr = XEXP (mem, 0);
	if (GET_CODE (addr) == PLUS
	    && REG_P (XEXP (addr, 0))
	    && CONST_INT_P (XEXP (addr, 1)))
	  {
	    off = INTVAL (XEXP (addr, 1));
	    addr = XEXP (addr, 0);
	  }
	if (addr != stack_pointer_rtx)
	  {
	    if (!REG_P (addr))
	      return false;
	    /* If not fast, use chains to see if addr wasn't set to
	       sp + offset.  */
	    if (!fast)
	      {
		df_ref use;
		struct df_link *defs;
		rtx set;

		FOR_EACH_INSN_USE (use, call_insn)
		  if (rtx_equal_p (addr, DF_REF_REG (use)))
		    break;

		if (use == NULL)
		  return false;

		for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
		  if (! DF_REF_IS_ARTIFICIAL (defs->ref))
		    break;

		if (defs == NULL)
		  return false;

		set = single_set (DF_REF_INSN (defs->ref));
		if (!set)
		  return false;

		if (GET_CODE (SET_SRC (set)) != PLUS
		    || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
		    || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
		  return false;

		off += INTVAL (XEXP (SET_SRC (set), 1));
	      }
	    else
	      return false;