OSDN Git Service

2010-11-24 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / alias.c
index fac5a02..5b04f85 100644 (file)
@@ -301,14 +301,14 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
        ref->base = build_simple_mem_ref (*(tree *)namep);
     }
   else if (TREE_CODE (base) == TARGET_MEM_REF
-          && TMR_SYMBOL (base)
-          && TREE_CODE (TMR_SYMBOL (base)) == VAR_DECL
-          && ! TREE_STATIC (TMR_SYMBOL (base))
+          && TREE_CODE (TMR_BASE (base)) == ADDR_EXPR
+          && TREE_CODE (TREE_OPERAND (TMR_BASE (base), 0)) == VAR_DECL
+          && ! TREE_STATIC (TREE_OPERAND (TMR_BASE (base), 0))
           && cfun->gimple_df->decls_to_pointers != NULL)
     {
       void *namep;
       namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers,
-                                   TMR_SYMBOL (base));
+                                   TREE_OPERAND (TMR_BASE (base), 0));
       if (namep)
        ref->base = build_simple_mem_ref (*(tree *)namep);
     }
@@ -761,6 +761,62 @@ get_alias_set (tree t)
   else if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (t))
     set = get_alias_set (TREE_TYPE (t));
 
+  /* From the former common C and C++ langhook implementation:
+
+     Unfortunately, there is no canonical form of a pointer type.
+     In particular, if we have `typedef int I', then `int *', and
+     `I *' are different types.  So, we have to pick a canonical
+     representative.  We do this below.
+
+     Technically, this approach is actually more conservative that
+     it needs to be.  In particular, `const int *' and `int *'
+     should be in different alias sets, according to the C and C++
+     standard, since their types are not the same, and so,
+     technically, an `int **' and `const int **' cannot point at
+     the same thing.
+
+     But, the standard is wrong.  In particular, this code is
+     legal C++:
+
+     int *ip;
+     int **ipp = &ip;
+     const int* const* cipp = ipp;
+     And, it doesn't make sense for that to be legal unless you
+     can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
+     the pointed-to types.  This issue has been reported to the
+     C++ committee.
+
+     In addition to the above canonicalization issue, with LTO
+     we should also canonicalize `T (*)[]' to `T *' avoiding
+     alias issues with pointer-to element types and pointer-to
+     array types.
+
+     Likewise we need to deal with the situation of incomplete
+     pointed-to types and make `*(struct X **)&a' and
+     `*(struct X {} **)&a' alias.  Otherwise we will have to
+     guarantee that all pointer-to incomplete type variants
+     will be replaced by pointer-to complete type variants if
+     they are available.
+
+     With LTO the convenient situation of using `void *' to
+     access and store any pointer type will also become
+     more apparent (and `void *' is just another pointer-to
+     incomplete type).  Assigning alias-set zero to `void *'
+     and all pointer-to incomplete types is a not appealing
+     solution.  Assigning an effective alias-set zero only
+     affecting pointers might be - by recording proper subset
+     relationships of all pointer alias-sets.
+
+     Pointer-to function types are another grey area which
+     needs caution.  Globbing them all into one alias-set
+     or the above effective zero set would work.
+
+     For now just assign the same alias-set to all pointers.
+     That's simple and avoids all the above problems.  */
+  else if (POINTER_TYPE_P (t)
+          && t != ptr_type_node)
+    return get_alias_set (ptr_type_node);
+
   /* Otherwise make a new alias set for this type.  */
   else
     set = new_alias_set ();
@@ -1235,6 +1291,14 @@ record_set (rtx dest, const_rtx set, void *data ATTRIBUTE_UNUSED)
   reg_seen[regno] = 1;
 }
 
+/* Return REG_BASE_VALUE for REGNO.  Selective scheduler uses this to avoid
+   using hard registers with non-null REG_BASE_VALUE for renaming.  */
+rtx
+get_reg_base_value (unsigned int regno)
+{
+  return VEC_index (rtx, reg_base_value, regno);
+}
+
 /* If a value is known for REGNO, return it.  */
 
 rtx
@@ -2403,7 +2467,7 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
 
   /* We cannot use aliases_everything_p to test MEM, since we must look
      at MEM_ADDR, rather than XEXP (mem, 0).  */
-  if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
+  if (GET_CODE (mem_addr) == AND)
     return 1;
 
   /* ??? In true_dependence we also allow BLKmode to alias anything.  Why
@@ -2599,7 +2663,7 @@ may_alias_p (const_rtx mem, const_rtx x)
 
   /* We cannot use aliases_everything_p to test MEM, since we must look
      at MEM_ADDR, rather than XEXP (mem, 0).  */
-  if (GET_MODE (mem) == QImode || GET_CODE (mem_addr) == AND)
+  if (GET_CODE (mem_addr) == AND)
     return 1;
 
   if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
@@ -2632,7 +2696,7 @@ init_alias_target (void)
     = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
   static_reg_base_value[FRAME_POINTER_REGNUM]
     = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
+#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
   static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
     = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
 #endif
@@ -2850,6 +2914,15 @@ init_alias_analysis (void)
   timevar_pop (TV_ALIAS_ANALYSIS);
 }
 
+/* Equate REG_BASE_VALUE (reg1) to REG_BASE_VALUE (reg2).
+   Special API for var-tracking pass purposes.  */
+
+void
+vt_equate_reg_base_value (const_rtx reg1, const_rtx reg2)
+{
+  VEC_replace (rtx, reg_base_value, REGNO (reg1), REG_BASE_VALUE (reg2));
+}
+
 void
 end_alias_analysis (void)
 {