示例#1
0
  FOR_EACH_REFERENCED_VAR (var, rvi)
    {
      var_ann_t ann;
      ann = var_ann (var);

      if (!MTAG_P (var)
	  && ann->is_aliased
	  && !bitmap_bit_p (visited, DECL_UID (var)))
	{
	  error ("addressable variable that is aliased but is not in any alias set");
	  goto err;
	}
    }
示例#2
0
bool
is_gimple_reg (tree t)
{
  if (TREE_CODE (t) == SSA_NAME)
    t = SSA_NAME_VAR (t);

  if (MTAG_P (t))
    return false;

  if (!is_gimple_variable (t))
    return false;

  if (!is_gimple_reg_type (TREE_TYPE (t)))
    return false;

  /* A volatile decl is not acceptable because we can't reuse it as
     needed.  We need to copy it into a temp first.  */
  if (TREE_THIS_VOLATILE (t))
    return false;

  /* We define "registers" as things that can be renamed as needed,
     which with our infrastructure does not apply to memory.  */
  if (needs_to_live_in_memory (t))
    return false;

  /* Hard register variables are an interesting case.  For those that
     are call-clobbered, we don't know where all the calls are, since
     we don't (want to) take into account which operations will turn
     into libcalls at the rtl level.  For those that are call-saved,
     we don't currently model the fact that calls may in fact change
     global hard registers, nor do we examine ASM_CLOBBERS at the tree
     level, and so miss variable changes that might imply.  All around,
     it seems safest to not do too much optimization with these at the
     tree level at all.  We'll have to rely on the rtl optimizers to
     clean this up, as there we've got all the appropriate bits exposed.  */
  if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
    return false;

  /* Complex values must have been put into ssa form.  That is, no 
     assignments to the individual components.  */
  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
    return DECL_COMPLEX_GIMPLE_REG_P (t);

  return true;
}
bool
may_propagate_copy (tree dest, tree orig)
{
    tree type_d = TREE_TYPE (dest);
    tree type_o = TREE_TYPE (orig);

    /* If ORIG flows in from an abnormal edge, it cannot be propagated.  */
    if (TREE_CODE (orig) == SSA_NAME
            && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
        return false;

    /* If DEST is an SSA_NAME that flows from an abnormal edge, then it
       cannot be replaced.  */
    if (TREE_CODE (dest) == SSA_NAME
            && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
        return false;

    /* For memory partitions, copies are OK as long as the memory symbol
       belongs to the partition.  */
    if (TREE_CODE (dest) == SSA_NAME
            && TREE_CODE (SSA_NAME_VAR (dest)) == MEMORY_PARTITION_TAG)
        return (TREE_CODE (orig) == SSA_NAME
                && !is_gimple_reg (orig)
                && (SSA_NAME_VAR (dest) == SSA_NAME_VAR (orig)
                    || bitmap_bit_p (MPT_SYMBOLS (SSA_NAME_VAR (dest)),
                                     DECL_UID (SSA_NAME_VAR (orig)))));

    if (TREE_CODE (orig) == SSA_NAME
            && TREE_CODE (SSA_NAME_VAR (orig)) == MEMORY_PARTITION_TAG)
        return (TREE_CODE (dest) == SSA_NAME
                && !is_gimple_reg (dest)
                && (SSA_NAME_VAR (dest) == SSA_NAME_VAR (orig)
                    || bitmap_bit_p (MPT_SYMBOLS (SSA_NAME_VAR (orig)),
                                     DECL_UID (SSA_NAME_VAR (dest)))));

    /* Do not copy between types for which we *do* need a conversion.  */
    if (!useless_type_conversion_p (type_d, type_o))
        return false;

    /* FIXME.  GIMPLE is allowing pointer assignments and comparisons of
       pointers that have different alias sets.  This means that these
       pointers will have different memory tags associated to them.

       If we allow copy propagation in these cases, statements de-referencing
       the new pointer will now have a reference to a different memory tag
       with potentially incorrect SSA information.

       This was showing up in libjava/java/util/zip/ZipFile.java with code
       like:

       	struct java.io.BufferedInputStream *T.660;
    struct java.io.BufferedInputStream *T.647;
    struct java.io.InputStream *is;
    struct java.io.InputStream *is.662;
    [ ... ]
    T.660 = T.647;
    is = T.660;	<-- This ought to be type-casted
    is.662 = is;

       Also, f/name.c exposed a similar problem with a COND_EXPR predicate
       that was causing DOM to generate and equivalence with two pointers of
       alias-incompatible types:

       	struct _ffename_space *n;
    struct _ffename *ns;
    [ ... ]
    if (n == ns)
      goto lab;
    ...
    lab:
    return n;

       I think that GIMPLE should emit the appropriate type-casts.  For the
       time being, blocking copy-propagation in these cases is the safe thing
       to do.  */
    if (TREE_CODE (dest) == SSA_NAME
            && TREE_CODE (orig) == SSA_NAME
            && POINTER_TYPE_P (type_d)
            && POINTER_TYPE_P (type_o))
    {
        tree mt_dest = symbol_mem_tag (SSA_NAME_VAR (dest));
        tree mt_orig = symbol_mem_tag (SSA_NAME_VAR (orig));
        if (mt_dest && mt_orig && mt_dest != mt_orig)
            return false;
        else if (get_alias_set (TREE_TYPE (type_d)) !=
                 get_alias_set (TREE_TYPE (type_o)))
            return false;
        else if (!MTAG_P (SSA_NAME_VAR (dest))
                 && !MTAG_P (SSA_NAME_VAR (orig))
                 && (DECL_NO_TBAA_P (SSA_NAME_VAR (dest))
                     != DECL_NO_TBAA_P (SSA_NAME_VAR (orig))))
            return false;

        /* Also verify flow-sensitive information is compatible.  */
        if (SSA_NAME_PTR_INFO (orig) && SSA_NAME_PTR_INFO (dest))
        {
            struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig);
            struct ptr_info_def *dest_ptr_info = SSA_NAME_PTR_INFO (dest);

            if (orig_ptr_info->name_mem_tag
                    && dest_ptr_info->name_mem_tag
                    && orig_ptr_info->pt_vars
                    && dest_ptr_info->pt_vars
                    && !bitmap_intersect_p (dest_ptr_info->pt_vars,
                                            orig_ptr_info->pt_vars))
                return false;
        }
    }

    /* If the destination is a SSA_NAME for a virtual operand, then we have
       some special cases to handle.  */
    if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
    {
        /* If both operands are SSA_NAMEs referring to virtual operands, then
        we can always propagate.  */
        if (TREE_CODE (orig) == SSA_NAME
                && !is_gimple_reg (orig))
            return true;

        /* We have a "copy" from something like a constant into a virtual
        operand.  Reject these.  */
        return false;
    }

    /* Anything else is OK.  */
    return true;
}