OSDN Git Service

* config/i386/xmmintrin.h (_mm_prefetch): Added const to first arg.
[pf3gnuchains/gcc-fork.git] / gcc / ipa-struct-reorg.c
index 9a04289..514b9a2 100644 (file)
@@ -187,7 +187,7 @@ typedef struct func_alloc_sites *fallocs_t;
 typedef const struct func_alloc_sites *const_fallocs_t;
 
 /* All allocation sites in the program.  */
-htab_t alloc_sites;
+htab_t alloc_sites = NULL;
 
 /* New global variables. Generated once for whole program.  */
 htab_t new_global_vars;
@@ -623,7 +623,12 @@ gen_size (tree num, tree type, tree *res)
     add_referenced_var (*res);
 
   if (exact_log2 (struct_size_int) == -1)
-    new_stmt = build_gimple_modify_stmt (num, struct_size);
+    {
+      tree size = build_int_cst (TREE_TYPE (num), struct_size_int);
+      new_stmt = build_gimple_modify_stmt (*res, build2 (MULT_EXPR,
+                                                        TREE_TYPE (num),
+                                                        num, size));
+    }
   else
     {
       tree C = build_int_cst (TREE_TYPE (num), exact_log2 (struct_size_int));
@@ -957,18 +962,19 @@ replace_field_acc (struct field_access_site *acc, tree new_type)
   tree new_acc;
   tree field_id = DECL_NAME (acc->field_decl);
   VEC (type_wrapper_t, heap) *wrapper = VEC_alloc (type_wrapper_t, heap, 10);
-  type_wrapper_t wr;
   type_wrapper_t *wr_p = NULL;
   
   while (TREE_CODE (ref_var) == INDIRECT_REF
         || TREE_CODE (ref_var) == ARRAY_REF)
     {
+      type_wrapper_t wr;
+
       if ( TREE_CODE (ref_var) == INDIRECT_REF)
        {
          wr.wrap = 0;
          wr.domain = 0;
        }
-      else if (TREE_CODE (ref_var) == ARRAY_REF)
+      else
        {
          wr.wrap = 1;
          wr.domain = TREE_OPERAND (ref_var, 1);
@@ -1245,12 +1251,15 @@ create_new_stmts_for_cond_expr (tree stmt)
   s0 = (str0 != length) ? true : false;
   s1 = (str1 != length) ? true : false;
 
-  gcc_assert ((!s0 && s1) || (!s1 && s0));
+  gcc_assert (s0 || s1);
+  /* For now we allow only comparison with 0 or NULL.  */
+  gcc_assert (integer_zerop (arg0) || integer_zerop (arg1));
   
-  str = s0 ? VEC_index (structure, structures, str0): 
-    VEC_index (structure, structures, str1);
-  arg = s0 ? arg0 : arg1;
-  pos = s0 ? 0 : 1;
+  str = integer_zerop (arg0) ?
+    VEC_index (structure, structures, str1): 
+    VEC_index (structure, structures, str0);
+  arg = integer_zerop (arg0) ? arg1 : arg0;
+  pos = integer_zerop (arg0) ? 1 : 0;
   
   for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++)
     {
@@ -1729,7 +1738,7 @@ create_new_malloc (tree malloc_stmt, tree new_type, tree *new_stmts, tree num)
   append_to_statement_list (new_stmt, new_stmts);
 
   /* Generate new call for malloc.  */
-  malloc_res = create_tmp_var (integer_type_node, NULL);
+  malloc_res = create_tmp_var (ptr_type_node, NULL);
 
   if (malloc_res)
     add_referenced_var (malloc_res);
@@ -2009,7 +2018,15 @@ is_candidate (tree var, tree *type_p, VEC (tree, heap) **unsuitable_types)
       else
        {
          if (initialized && unsuitable_types && *unsuitable_types)
-           add_unsuitable_type (unsuitable_types, type);
+           {
+             if (dump_file)
+               {
+                 fprintf (dump_file, "The type ");
+                 print_generic_expr (dump_file, type, 0);
+                 fprintf (dump_file, " is initialized...Excluded.");             
+               }
+             add_unsuitable_type (unsuitable_types, type);
+           }
          *type_p = type;
          return true;
       }
@@ -2330,6 +2347,41 @@ dump_access_sites (htab_t accs)
     htab_traverse (accs, dump_acc, NULL);
 }
 
+/* This function is a callback for alloc_sites hashtable 
+   traversal. SLOT is a pointer to fallocs_t. This function
+   removes all allocations of the structure defined by DATA.  */
+
+static int
+remove_str_allocs_in_func (void **slot, void *data)
+{
+  fallocs_t fallocs = *(fallocs_t *) slot;
+  unsigned i = 0;
+  alloc_site_t *call;
+
+  while (VEC_iterate (alloc_site_t, fallocs->allocs, i, call))
+    {
+      if (call->str == (d_str) data)
+       VEC_ordered_remove (alloc_site_t, fallocs->allocs, i);
+      else
+       i++;
+    }
+
+  return 1;
+}
+
+/* This function remove all entries corresponding to the STR structure
+   from alloc_sites hashtable.   */
+
+static void
+remove_str_allocs (d_str str)
+{
+  if (!str)
+    return;
+
+  if (alloc_sites)
+    htab_traverse (alloc_sites, remove_str_allocs_in_func, str);
+}
+
 /* This function removes the structure with index I from structures vector.  */
 
 static void 
@@ -2340,7 +2392,11 @@ remove_structure (unsigned i)
   if (i >= VEC_length (structure, structures))
     return;
 
-  str = VEC_index (structure, structures, i);  
+  str = VEC_index (structure, structures, i);
+  
+  /* Before removing the structure str, we have to remove its
+     allocations from alloc_sites hashtable.  */
+  remove_str_allocs (str);
   free_data_struct (str);
   VEC_ordered_remove (structure, structures, i);
 }
@@ -2374,8 +2430,12 @@ is_safe_cond_expr (tree cond_stmt)
 
   s0 = (str0 != length) ? true : false;
   s1 = (str1 != length) ? true : false;
+  
+  if (!s0 && !s1)
+    return false;
 
-  if (!((!s0 && s1) || (!s1 && s0)))
+  /* For now we allow only comparison with 0 or NULL.  */
+  if (!integer_zerop (arg0) && !integer_zerop (arg1))
     return false;
 
   return true;
@@ -2436,7 +2496,15 @@ get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
        unsigned i = find_structure (type);
 
        if (i != VEC_length (structure, structures))
-         remove_structure (i); 
+         {
+           if (dump_file)
+             {
+               fprintf (dump_file, "\nThe type ");
+               print_generic_expr (dump_file, type, 0);
+               fprintf (dump_file, " has bitfield.");
+             }     
+           remove_structure (i);
+         }
       }
       break;
 
@@ -2475,6 +2543,15 @@ get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
                       we can deal with.  */
                    if (!decompose_access (str->decl, acc))
                      {
+                       if (dump_file)
+                         {
+                           fprintf (dump_file, "\nThe type ");
+                           print_generic_expr (dump_file, type, 0);
+                           fprintf (dump_file, 
+                                    " has complicate access in statement ");
+                           print_generic_stmt (dump_file, stmt, 0);
+                         }
+                       
                        remove_structure (i);
                        free (acc);
                      }
@@ -3043,19 +3120,24 @@ dump_accs (d_str str)
 }
 
 /* This function checks whether an access statement, pointed by SLOT,
-   is a condition we are capable to transform. If not, it removes
-   the structure with index, represented by DATA, from the vector
-   of structures.  */
+   is a condition we are capable to transform.  It returns false if not,
+   setting bool *DATA to false.  */
  
 static int
 safe_cond_expr_check (void **slot, void *data)
 {
   struct access_site *acc = *(struct access_site **) slot;
 
-  if (TREE_CODE (acc->stmt) == COND_EXPR)
+  if (TREE_CODE (acc->stmt) == COND_EXPR
+      && !is_safe_cond_expr (acc->stmt))
     {
-      if (!is_safe_cond_expr (acc->stmt))
-       remove_structure (*(unsigned *) data);
+      if (dump_file)
+       {
+         fprintf (dump_file, "\nUnsafe conditional statement ");
+         print_generic_stmt (dump_file, acc->stmt, 0);
+       }
+      *(bool *) data = false;
+      return 0;
     }
   return 1;
 }
@@ -3468,7 +3550,15 @@ collect_alloc_sites (void)
                            add_alloc_site (node->decl, stmt, str);
                          }
                        else
-                         remove_structure (i);         
+                         {
+                           if (dump_file)
+                             {
+                               fprintf (dump_file, 
+                                        "\nUnsupported allocation function ");
+                               print_generic_stmt (dump_file, stmt, 0);
+                             }
+                           remove_structure (i);               
+                         }
                      }
                  }
              }       
@@ -3501,9 +3591,18 @@ check_cond_exprs (void)
   d_str str;
   unsigned i;
 
-  for (i = 0; VEC_iterate (structure, structures, i, str); i++)
-    if (str->accs)
-      htab_traverse (str->accs, safe_cond_expr_check, &i);
+  i = 0;
+  while (VEC_iterate (structure, structures, i, str))
+    {
+      bool safe_p = true;
+
+      if (str->accs)
+       htab_traverse (str->accs, safe_cond_expr_check, &safe_p);
+      if (!safe_p)
+       remove_structure (i);
+      else
+       i++;
+    }
 }
 
 /* We exclude from non-field accesses of the structure 
@@ -3539,7 +3638,7 @@ collect_accesses_in_func (struct function *fn)
 /* This function summarizes counts of the fields into the structure count.  */
 
 static void
-sum_counts (d_str str, gcov_type *hotest)
+sum_counts (d_str str, gcov_type *hottest)
 {
   int i;
       
@@ -3550,7 +3649,7 @@ sum_counts (d_str str, gcov_type *hotest)
        {
          fprintf (dump_file, "\nCounter of field \"");
          print_generic_expr (dump_file, str->fields[i].decl, 0);
-         fprintf (dump_file, "\" is " HOST_WIDE_INT_PRINT_DEC, 
+         fprintf (dump_file, "\" is " HOST_WIDEST_INT_PRINT_DEC, 
                   str->fields[i].count);
        }
       str->count += str->fields[i].count;
@@ -3560,11 +3659,11 @@ sum_counts (d_str str, gcov_type *hotest)
     {
       fprintf (dump_file, "\nCounter of struct \"");
       print_generic_expr (dump_file, str->decl, 0);
-      fprintf (dump_file, "\" is " HOST_WIDE_INT_PRINT_DEC, str->count);
+      fprintf (dump_file, "\" is " HOST_WIDEST_INT_PRINT_DEC, str->count);
     }
 
-  if (str->count > *hotest)
-    *hotest = str->count;
+  if (str->count > *hottest)
+    *hottest = str->count;
 }
 
 /* This function peels the field into separate structure if it's
@@ -3627,7 +3726,7 @@ do_reorg_1 (void)
        pop_cfun ();
       }
 
-  cfun = NULL;
+  set_cfun (NULL);
 }
 
 /* This function creates new global struct variables.
@@ -3681,8 +3780,17 @@ dump_new_types (void)
           " this optimization:\n");
 
   for (i = 0; VEC_iterate (structure, structures, i, str); i++)
-    for (j = 0; VEC_iterate (tree, str->new_types, j, type); j++)
-      dump_struct_type (type, 2, 0); 
+    {
+      if (dump_file)
+       {
+         fprintf (dump_file, "\nFor type ");
+         dump_struct_type (str->decl, 2, 0);
+         fprintf (dump_file, "\nthe number of new types is %d\n",
+                  VEC_length (tree, str->new_types));
+       }      
+      for (j = 0; VEC_iterate (tree, str->new_types, j, type); j++)
+       dump_struct_type (type, 2, 0); 
+    }
 }
 
 /* This function creates new types to replace old structure types.  */
@@ -3742,13 +3850,6 @@ collect_structures (void)
 
   remove_unsuitable_types (unsuitable_types);
   VEC_free (tree, heap, unsuitable_types);
-
-  if (!VEC_length (structure, structures))
-    {
-      if (dump_file)
-       fprintf (dump_file, "\nNo structures to transform. Exiting...");
-      return;
-    }
 }
 
 /* Collect structure allocation sites. In case of arrays
@@ -3802,18 +3903,29 @@ collect_data_accesses (void)
 static void
 exclude_cold_structs (void)
 {
-  gcov_type hotest = 0;
+  gcov_type hottest = 0;
   unsigned i;
   d_str str;
 
   /* We summarize counts of fields of a structure into the structure count.  */
   for (i = 0; VEC_iterate (structure, structures, i, str); i++)
-    sum_counts (str, &hotest);
+    sum_counts (str, &hottest);
 
   /* Remove cold structures from structures vector.  */
-  for (i = 0; VEC_iterate (structure, structures, i, str); i++)
-    if (str->count * 100 < (hotest * STRUCT_REORG_COLD_STRUCT_RATIO))
-      remove_structure (i);
+  i = 0;
+  while (VEC_iterate (structure, structures, i, str))
+    if (str->count * 100 < (hottest * STRUCT_REORG_COLD_STRUCT_RATIO))
+      {
+       if (dump_file)
+         {
+           fprintf (dump_file, "\nThe structure ");
+           print_generic_expr (dump_file, str->decl, 0);
+           fprintf (dump_file, " is cold.");
+         }
+       remove_structure (i);
+      }
+    else
+      i++;
 }
 
 /* This function decomposes original structure into substructures, 
@@ -3838,7 +3950,19 @@ do_reorg (void)
 {
   /* Check that there is a work to do.  */
   if (!VEC_length (structure, structures))
-    return;
+    {
+      if (dump_file)
+       fprintf (dump_file, "\nNo structures to transform. Exiting...");
+      return;
+    }
+  else
+    {
+      if (dump_file)
+       {
+         fprintf (dump_file, "\nNumber of structures to transform is %d",
+                  VEC_length (structure, structures));
+       }
+    }
 
   /* Generate new types.  */
   create_new_types ();