OSDN Git Service

PR target/29978
[pf3gnuchains/gcc-fork.git] / gcc / matrix-reorg.c
index e5bd461..38b0d5e 100644 (file)
@@ -7,7 +7,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /*
    Matrix flattening optimization tries to replace a N-dimensional 
 
 /*
    Matrix flattening optimization tries to replace a N-dimensional 
@@ -224,10 +223,10 @@ collect_data_for_malloc_call (tree stmt, struct malloc_call_data *m_data)
    initial address and index of each dimension.  */
 struct access_site_info
 {
    initial address and index of each dimension.  */
 struct access_site_info
 {
-  /* The statement (INDIRECT_REF or PLUS_EXPR).  */
+  /* The statement (INDIRECT_REF or POINTER_PLUS_EXPR).  */
   tree stmt;
 
   tree stmt;
 
-  /* In case of PLUS_EXPR, what is the offset.  */
+  /* In case of POINTER_PLUS_EXPR, what is the offset.  */
   tree offset;
 
   /* The index which created the offset.  */
   tree offset;
 
   /* The index which created the offset.  */
@@ -390,7 +389,7 @@ static htab_t matrices_to_reorg = NULL;
 static hashval_t
 mtt_info_hash (const void *mtt)
 {
 static hashval_t
 mtt_info_hash (const void *mtt)
 {
-  return htab_hash_pointer (((struct matrix_info *) mtt)->decl);
+  return htab_hash_pointer (((const struct matrix_info *) mtt)->decl);
 }
 
 /* Return true if MTT1 and MTT2 (which are really both of type
 }
 
 /* Return true if MTT1 and MTT2 (which are really both of type
@@ -609,7 +608,7 @@ mark_min_matrix_escape_level (struct matrix_info *mi, int l, tree s)
 /* Find if the SSA variable is accessed inside the
    tree and record the tree containing it.
    The only relevant uses are the case of SSA_NAME, or SSA inside
 /* Find if the SSA variable is accessed inside the
    tree and record the tree containing it.
    The only relevant uses are the case of SSA_NAME, or SSA inside
-   INDIRECT_REF, CALL_EXPR, PLUS_EXPR, MULT_EXPR.  */
+   INDIRECT_REF, CALL_EXPR, PLUS_EXPR, POINTER_PLUS_EXPR, MULT_EXPR.  */
 static void
 ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
 {
 static void
 ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
 {
@@ -644,6 +643,7 @@ ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
          }
       }
       break;
          }
       }
       break;
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MULT_EXPR:
       op1 = TREE_OPERAND (t, 0);
     case PLUS_EXPR:
     case MULT_EXPR:
       op1 = TREE_OPERAND (t, 0);
@@ -818,11 +818,15 @@ analyze_matrix_allocation_site (struct matrix_info *mi, tree stmt,
                  return;
                }
            }
                  return;
                }
            }
-         /* This is a call to malloc.  Check to see if this is the first
-            call in this indirection level; if so, mark it; if not, mark
-            as escaping.  */
+         /* This is a call to malloc of level 'level'.  
+            mi->max_malloced_level-1 == level  means that we've 
+            seen a malloc statement of level 'level' before.  
+            If the statement is not the same one that we've 
+            seen before, then there's another malloc statement 
+            for the same level, which means that we need to mark 
+            it escaping.  */
          if (mi->malloc_for_level
          if (mi->malloc_for_level
-             && mi->malloc_for_level[level]
+             && mi->max_malloced_level-1 == level
              && mi->malloc_for_level[level] != stmt)
            {
              mark_min_matrix_escape_level (mi, level, stmt);
              && mi->malloc_for_level[level] != stmt)
            {
              mark_min_matrix_escape_level (mi, level, stmt);
@@ -903,7 +907,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
   for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
        i++)
     {
   for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
        i++)
     {
-      if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 1)) == PLUS_EXPR
+      if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 1)) == POINTER_PLUS_EXPR
          && acc_info->level < min_escape_l)
        {
          loop = loop_containing_stmt (acc_info->stmt);
          && acc_info->level < min_escape_l)
        {
          loop = loop_containing_stmt (acc_info->stmt);
@@ -1197,7 +1201,7 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
          return current_indirect_level;
        }
       if (rhs_acc.t_code != INDIRECT_REF
          return current_indirect_level;
        }
       if (rhs_acc.t_code != INDIRECT_REF
-         && rhs_acc.t_code != PLUS_EXPR && rhs_acc.t_code != SSA_NAME)
+         && rhs_acc.t_code != POINTER_PLUS_EXPR && rhs_acc.t_code != SSA_NAME)
        {
          mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
          return current_indirect_level;
        {
          mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
          return current_indirect_level;
@@ -1212,11 +1216,8 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
                                           current_indirect_level, true);
          current_indirect_level += 1;
        }
                                           current_indirect_level, true);
          current_indirect_level += 1;
        }
-      else if (rhs_acc.t_code == PLUS_EXPR)
+      else if (rhs_acc.t_code == POINTER_PLUS_EXPR)
        {
        {
-         /* ??? maybe we should check
-            the type of the PLUS_EXP and make sure it's
-            integral type.  */
          gcc_assert (rhs_acc.second_op);
          if (last_op)
            /* Currently we support only one PLUS expression on the
          gcc_assert (rhs_acc.second_op);
          if (last_op)
            /* Currently we support only one PLUS expression on the
@@ -1286,7 +1287,7 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
          /* We are placing it in an SSA, follow that SSA.  */
          analyze_matrix_accesses (mi, lhs,
                                   current_indirect_level,
          /* We are placing it in an SSA, follow that SSA.  */
          analyze_matrix_accesses (mi, lhs,
                                   current_indirect_level,
-                                  rhs_acc.t_code == PLUS_EXPR,
+                                  rhs_acc.t_code == POINTER_PLUS_EXPR,
                                   visited, record_accesses);
        }
     }
                                   visited, record_accesses);
        }
     }
@@ -1321,7 +1322,7 @@ analyze_matrix_accesses (struct matrix_info *mi, tree ssa_var,
 
 /* Now go over the uses of the SSA_NAME and check how it is used in
    each one of them.  We are mainly looking for the pattern INDIRECT_REF,
 
 /* Now go over the uses of the SSA_NAME and check how it is used in
    each one of them.  We are mainly looking for the pattern INDIRECT_REF,
-   then a PLUS_EXPR, then INDIRECT_REF etc.  while in between there could
+   then a POINTER_PLUS_EXPR, then INDIRECT_REF etc.  while in between there could
    be any number of copies and casts.  */
   gcc_assert (TREE_CODE (ssa_var) == SSA_NAME);
 
    be any number of copies and casts.  */
   gcc_assert (TREE_CODE (ssa_var) == SSA_NAME);
 
@@ -1405,6 +1406,7 @@ can_calculate_expr_before_stmt (tree expr, sbitmap visited)
     case PARM_DECL:
     case INTEGER_CST:
       return expr;
     case PARM_DECL:
     case INTEGER_CST:
       return expr;
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
@@ -1482,10 +1484,13 @@ check_allocation_function (void **slot, void *data ATTRIBUTE_UNUSED)
   block_stmt_iterator bsi;
   basic_block bb_level_0;
   struct matrix_info *mi = *slot;
   block_stmt_iterator bsi;
   basic_block bb_level_0;
   struct matrix_info *mi = *slot;
-  sbitmap visited = sbitmap_alloc (num_ssa_names);
+  sbitmap visited;
 
   if (!mi->malloc_for_level)
     return 1;
 
   if (!mi->malloc_for_level)
     return 1;
+
+  visited = sbitmap_alloc (num_ssa_names);
+
   /* Do nothing if the current function is not the allocation
      function of MI.  */
   if (mi->allocation_function_decl != current_function_decl
   /* Do nothing if the current function is not the allocation
      function of MI.  */
   if (mi->allocation_function_decl != current_function_decl
@@ -1709,7 +1714,6 @@ compute_offset (HOST_WIDE_INT orig, HOST_WIDE_INT new, tree result)
 static int
 transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 {
 static int
 transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 {
-  tree stmts;
   block_stmt_iterator bsi;
   struct matrix_info *mi = *slot;
   int min_escape_l = mi->min_indirect_level_escape;
   block_stmt_iterator bsi;
   struct matrix_info *mi = *slot;
   int min_escape_l = mi->min_indirect_level_escape;
@@ -1798,7 +1802,7 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
                    GIMPLE_STMT_OPERAND (orig, 0));
          GIMPLE_STMT_OPERAND (acc_info->stmt, 1) = orig;
        }
                    GIMPLE_STMT_OPERAND (orig, 0));
          GIMPLE_STMT_OPERAND (acc_info->stmt, 1) = orig;
        }
-      else if (TREE_CODE (orig) == PLUS_EXPR
+      else if (TREE_CODE (orig) == POINTER_PLUS_EXPR
               && acc_info->level < (min_escape_l))
        {
          imm_use_iterator imm_iter;
               && acc_info->level < (min_escape_l))
        {
          imm_use_iterator imm_iter;
@@ -1822,11 +1826,8 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
                  tree new_offset;
                  tree d_type_size, d_type_size_k;
 
                  tree new_offset;
                  tree d_type_size, d_type_size_k;
 
-                 d_type_size =
-                   build_int_cst (type,
-                                  mi->dimension_type_size[min_escape_l]);
-                 d_type_size_k =
-                   build_int_cst (type, mi->dimension_type_size[k + 1]);
+                 d_type_size = size_int (mi->dimension_type_size[min_escape_l]);
+                 d_type_size_k = size_int (mi->dimension_type_size[k + 1]);
 
                  new_offset =
                    compute_offset (mi->dimension_type_size[min_escape_l],
 
                  new_offset =
                    compute_offset (mi->dimension_type_size[min_escape_l],
@@ -1835,19 +1836,10 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
                  total_elements = new_offset;
                  if (new_offset != offset)
                    {
                  total_elements = new_offset;
                  if (new_offset != offset)
                    {
-                     tmp1 =
-                       force_gimple_operand (total_elements, &stmts, true,
-                                             NULL);
-                     if (stmts)
-                       {
-                         tree_stmt_iterator tsi;
-
-                         for (tsi = tsi_start (stmts); !tsi_end_p (tsi);
-                              tsi_next (&tsi))
-                           mark_symbols_for_renaming (tsi_stmt (tsi));
-                         bsi = bsi_for_stmt (acc_info->stmt);
-                         bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-                       }
+                     bsi = bsi_for_stmt (acc_info->stmt);
+                     tmp1 = force_gimple_operand_bsi (&bsi, total_elements,
+                                                      true, NULL,
+                                                      true, BSI_SAME_STMT);
                    }
                  else
                    tmp1 = offset;
                    }
                  else
                    tmp1 = offset;
@@ -1857,19 +1849,12 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
            {
              d_size = mi->dimension_size[mi->dim_map[k] + 1];
              num_elements =
            {
              d_size = mi->dimension_size[mi->dim_map[k] + 1];
              num_elements =
-               fold_build2 (MULT_EXPR, type, acc_info->index, d_size);
-             tmp1 = force_gimple_operand (num_elements, &stmts, true, NULL);
+               fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, acc_info->index),
+                           fold_convert (sizetype, d_size));
              add_referenced_var (d_size);
              add_referenced_var (d_size);
-             if (stmts)
-               {
-                 tree_stmt_iterator tsi;
-
-                 for (tsi = tsi_start (stmts); !tsi_end_p (tsi);
-                      tsi_next (&tsi))
-                   mark_symbols_for_renaming (tsi_stmt (tsi));
-                 bsi = bsi_for_stmt (acc_info->stmt);
-                 bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-               }
+             bsi = bsi_for_stmt (acc_info->stmt);
+             tmp1 = force_gimple_operand_bsi (&bsi, num_elements, true,
+                                              NULL, true, BSI_SAME_STMT);
            }
          /* Replace the offset if needed.  */
          if (tmp1 != offset)
            }
          /* Replace the offset if needed.  */
          if (tmp1 != offset)
@@ -1880,8 +1865,8 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 
                  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, offset)
                    FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
 
                  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, offset)
                    FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
-                   if (use_stmt == acc_info->stmt)
-                   SET_USE (use_p, tmp1);
+                     if (use_stmt == acc_info->stmt)
+                       SET_USE (use_p, tmp1);
                }
              else
                {
                }
              else
                {
@@ -1945,7 +1930,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 {
   int i;
   struct matrix_info *mi;
 {
   int i;
   struct matrix_info *mi;
-  tree type, call_stmt_0, malloc_stmt, oldfn, stmts, prev_dim_size, use_stmt;
+  tree type, call_stmt_0, malloc_stmt, oldfn, prev_dim_size, use_stmt;
   struct cgraph_node *c_node;
   struct cgraph_edge *e;
   block_stmt_iterator bsi;
   struct cgraph_node *c_node;
   struct cgraph_edge *e;
   block_stmt_iterator bsi;
@@ -2060,7 +2045,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
   /* To be able to produce gimple temporaries.  */
   oldfn = current_function_decl;
   current_function_decl = mi->allocation_function_decl;
   /* To be able to produce gimple temporaries.  */
   oldfn = current_function_decl;
   current_function_decl = mi->allocation_function_decl;
-  cfun = DECL_STRUCT_FUNCTION (mi->allocation_function_decl);
+  push_cfun (DECL_STRUCT_FUNCTION (mi->allocation_function_decl));
 
   /* Set the dimension sizes as follows:
      DIM_SIZE[i] = DIM_SIZE[n] * ... * DIM_SIZE[i]
 
   /* Set the dimension sizes as follows:
      DIM_SIZE[i] = DIM_SIZE[n] * ... * DIM_SIZE[i]
@@ -2072,7 +2057,6 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
     {
       tree dim_size, dim_var, tmp;
       tree d_type_size;
     {
       tree dim_size, dim_var, tmp;
       tree d_type_size;
-      tree_stmt_iterator tsi;
 
       /* Now put the size expression in a global variable and initialize it to
          the size expression before the malloc of level 0.  */
 
       /* Now put the size expression in a global variable and initialize it to
          the size expression before the malloc of level 0.  */
@@ -2102,20 +2086,13 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 
          dim_size = fold_build2 (MULT_EXPR, type, dim_size, prev_dim_size);
        }
 
          dim_size = fold_build2 (MULT_EXPR, type, dim_size, prev_dim_size);
        }
-      dim_size = force_gimple_operand (dim_size, &stmts, true, NULL);
-      if (stmts)
-       {
-         for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
-           mark_symbols_for_renaming (tsi_stmt (tsi));
-         bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-         bsi = bsi_for_stmt (call_stmt_0);
-       }
+      dim_size = force_gimple_operand_bsi (&bsi, dim_size, true, NULL,
+                                          true, BSI_SAME_STMT);
       /* GLOBAL_HOLDING_THE_SIZE = DIM_SIZE.  */
       tmp = fold_build2 (GIMPLE_MODIFY_STMT, type, dim_var, dim_size);
       GIMPLE_STMT_OPERAND (tmp, 0) = dim_var;
       mark_symbols_for_renaming (tmp);
       /* GLOBAL_HOLDING_THE_SIZE = DIM_SIZE.  */
       tmp = fold_build2 (GIMPLE_MODIFY_STMT, type, dim_var, dim_size);
       GIMPLE_STMT_OPERAND (tmp, 0) = dim_var;
       mark_symbols_for_renaming (tmp);
-      bsi_insert_before (&bsi, tmp, BSI_NEW_STMT);
-      bsi = bsi_for_stmt (call_stmt_0);
+      bsi_insert_before (&bsi, tmp, BSI_SAME_STMT);
 
       prev_dim_size = mi->dimension_size[i] = dim_var;
     }
 
       prev_dim_size = mi->dimension_size[i] = dim_var;
     }
@@ -2125,17 +2102,8 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
   malloc_stmt = GIMPLE_STMT_OPERAND (call_stmt_0, 1);
   c_node = cgraph_node (mi->allocation_function_decl);
   old_size_0 = CALL_EXPR_ARG (malloc_stmt, 0);
   malloc_stmt = GIMPLE_STMT_OPERAND (call_stmt_0, 1);
   c_node = cgraph_node (mi->allocation_function_decl);
   old_size_0 = CALL_EXPR_ARG (malloc_stmt, 0);
-  bsi = bsi_for_stmt (call_stmt_0);
-  tmp = force_gimple_operand (mi->dimension_size[0], &stmts, true, NULL);
-  if (stmts)
-    {
-      tree_stmt_iterator tsi;
-
-      for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
-       mark_symbols_for_renaming (tsi_stmt (tsi));
-      bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-      bsi = bsi_for_stmt (call_stmt_0);
-    }
+  tmp = force_gimple_operand_bsi (&bsi, mi->dimension_size[0], true,
+                                 NULL, true, BSI_SAME_STMT);
   if (TREE_CODE (old_size_0) == SSA_NAME)
     {
       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, old_size_0)
   if (TREE_CODE (old_size_0) == SSA_NAME)
     {
       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, old_size_0)
@@ -2201,13 +2169,13 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
       gcc_assert (e);
       cgraph_remove_edge (e);
       current_function_decl = mi->free_stmts[i].func;
       gcc_assert (e);
       cgraph_remove_edge (e);
       current_function_decl = mi->free_stmts[i].func;
-      cfun = DECL_STRUCT_FUNCTION (mi->free_stmts[i].func);
+      set_cfun (DECL_STRUCT_FUNCTION (mi->free_stmts[i].func));
       bsi = bsi_for_stmt (mi->free_stmts[i].stmt);
       bsi_remove (&bsi, true);
     }
   /* Return to the previous situation.  */
   current_function_decl = oldfn;
       bsi = bsi_for_stmt (mi->free_stmts[i].stmt);
       bsi_remove (&bsi, true);
     }
   /* Return to the previous situation.  */
   current_function_decl = oldfn;
-  cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL;
+  pop_cfun ();
   return 1;
 
 }
   return 1;
 
 }
@@ -2336,7 +2304,7 @@ matrix_reorg (void)
   htab_traverse (matrices_to_reorg, dump_matrix_reorg_analysis, NULL);
 
   current_function_decl = NULL;
   htab_traverse (matrices_to_reorg, dump_matrix_reorg_analysis, NULL);
 
   current_function_decl = NULL;
-  cfun = NULL;
+  set_cfun (NULL);
   matrices_to_reorg = NULL;
   return 0;
 }
   matrices_to_reorg = NULL;
   return 0;
 }
@@ -2346,7 +2314,7 @@ matrix_reorg (void)
 static bool
 gate_matrix_reorg (void)
 {
 static bool
 gate_matrix_reorg (void)
 {
-  return flag_ipa_matrix_reorg /*&& flag_whole_program */ ;
+  return flag_ipa_matrix_reorg && flag_whole_program;
 }
 
 struct tree_opt_pass pass_ipa_matrix_reorg = {
 }
 
 struct tree_opt_pass pass_ipa_matrix_reorg = {