OSDN Git Service

* config/avr/avr.h (PREFERRED_RELOAD_CLASS): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-ivopts.c
index 0a1c44e..88fc015 100644 (file)
@@ -1443,9 +1443,6 @@ idx_find_step (tree base, tree *idx, void *data)
   tree step, iv_base, iv_step, lbound, off;
   struct loop *loop = dta->ivopts_data->current_loop;
 
-  if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
-    return false;
-
   /* If base is a component ref, require that the offset of the reference
      be invariant.  */
   if (TREE_CODE (base) == COMPONENT_REF)
@@ -1765,8 +1762,6 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
        goto fail;
       step = ifs_ivopts_data.step;
 
-      gcc_assert (TREE_CODE (base) != MISALIGNED_INDIRECT_REF);
-
       /* Check that the base expression is addressable.  This needs
         to be done after substituting bases of IVs into it.  */
       if (may_be_nonaddressable_p (base))
@@ -1788,14 +1783,9 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
            ref = &TREE_OPERAND (*ref, 0);
          if (TREE_CODE (*ref) == MEM_REF)
            {
-             tree tem = TREE_OPERAND (*ref, 0);
-             STRIP_NOPS (tem);
-             if (tem != TREE_OPERAND (*ref, 0))
-               tem = fold_build2 (MEM_REF, TREE_TYPE (*ref),
-                                  tem, TREE_OPERAND (*ref, 1));
-             else
-               tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
-                                  tem, TREE_OPERAND (*ref, 1));
+             tree tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
+                                     TREE_OPERAND (*ref, 0),
+                                     TREE_OPERAND (*ref, 1));
              if (tem)
                *ref = tem;
            }
@@ -5873,7 +5863,16 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
       comp = force_gimple_operand_gsi (&bsi, comp, true, NULL_TREE,
                                       true, GSI_SAME_STMT);
       if (POINTER_TYPE_P (TREE_TYPE (tgt)))
-       duplicate_ssa_name_ptr_info (comp, SSA_NAME_PTR_INFO (tgt));
+       {
+         duplicate_ssa_name_ptr_info (comp, SSA_NAME_PTR_INFO (tgt));
+         /* As this isn't a plain copy we have to reset alignment
+            information.  */
+         if (SSA_NAME_PTR_INFO (comp))
+           {
+             SSA_NAME_PTR_INFO (comp)->align = 1;
+             SSA_NAME_PTR_INFO (comp)->misalign = 0;
+           }
+       }
     }
 
   if (gimple_code (use->stmt) == GIMPLE_PHI)
@@ -5901,26 +5900,44 @@ copy_ref_info (tree new_ref, tree old_ref)
   TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref);
   TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref);
 
-  if (TREE_CODE (new_ref) == TARGET_MEM_REF)
-    new_ptr_base = TMR_BASE (new_ref);
-  else if (TREE_CODE (new_ref) == MEM_REF)
-    new_ptr_base = TREE_OPERAND (new_ref, 0);
+  new_ptr_base = TREE_OPERAND (new_ref, 0);
 
   /* We can transfer points-to information from an old pointer
      or decl base to the new one.  */
   if (new_ptr_base
       && TREE_CODE (new_ptr_base) == SSA_NAME
-      && POINTER_TYPE_P (TREE_TYPE (new_ptr_base))
       && !SSA_NAME_PTR_INFO (new_ptr_base))
     {
       tree base = get_base_address (old_ref);
       if (!base)
        ;
-      else if ((INDIRECT_REF_P (base)
-               || TREE_CODE (base) == MEM_REF)
-              && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
-       duplicate_ssa_name_ptr_info
-         (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
+      else if ((TREE_CODE (base) == MEM_REF
+               || TREE_CODE (base) == TARGET_MEM_REF)
+              && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
+              && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)))
+       {
+         struct ptr_info_def *new_pi;
+         duplicate_ssa_name_ptr_info
+           (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
+         new_pi = SSA_NAME_PTR_INFO (new_ptr_base);
+         /* We have to be careful about transfering alignment information.  */
+         if (TREE_CODE (old_ref) == MEM_REF
+             && !(TREE_CODE (new_ref) == TARGET_MEM_REF
+                  && (TMR_INDEX2 (new_ref)
+                      || (TMR_STEP (new_ref)
+                          && (TREE_INT_CST_LOW (TMR_STEP (new_ref))
+                              < new_pi->align)))))
+           {
+             new_pi->misalign += double_int_sub (mem_ref_offset (old_ref),
+                                                 mem_ref_offset (new_ref)).low;
+             new_pi->misalign &= (new_pi->align - 1);
+           }
+         else
+           {
+             new_pi->align = 1;
+             new_pi->misalign = 0;
+           }
+       }
       else if (TREE_CODE (base) == VAR_DECL
               || TREE_CODE (base) == PARM_DECL
               || TREE_CODE (base) == RESULT_DECL)