OSDN Git Service

Backported from mainline
[pf3gnuchains/gcc-fork.git] / gcc / tree-vectorizer.c
index 0636c6a..d76fe0c 100644 (file)
@@ -1,7 +1,7 @@
 /* Vectorizer
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-   Foundation, Inc.
-   Contributed by Dorit Naishlos <dorit@il.ibm.com> 
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
+   Contributed by Dorit Naishlos <dorit@il.ibm.com>
 
 This file is part of GCC.
 
@@ -21,21 +21,21 @@ along with GCC; see the file COPYING3.  If not see
 
 /* Loop and basic block vectorizer.
 
-  This file contains drivers for the three vectorizers: 
-  (1) loop vectorizer (inter-iteration parallelism), 
+  This file contains drivers for the three vectorizers:
+  (1) loop vectorizer (inter-iteration parallelism),
   (2) loop-aware SLP (intra-iteration parallelism) (invoked by the loop
       vectorizer)
   (3) BB vectorizer (out-of-loops), aka SLP
-  
+
   The rest of the vectorizer's code is organized as follows:
-  - tree-vect-loop.c - loop specific parts such as reductions, etc. These are 
-    used by drivers (1) and (2). 
-  - tree-vect-loop-manip.c - vectorizer's loop control-flow utilities, used by 
-    drivers (1) and (2). 
-  - tree-vect-slp.c - BB vectorization specific analysis and transformation, 
+  - tree-vect-loop.c - loop specific parts such as reductions, etc. These are
+    used by drivers (1) and (2).
+  - tree-vect-loop-manip.c - vectorizer's loop control-flow utilities, used by
+    drivers (1) and (2).
+  - tree-vect-slp.c - BB vectorization specific analysis and transformation,
     used by drivers (2) and (3).
   - tree-vect-stmts.c - statements analysis and transformation (used by all).
-  - tree-vect-data-refs.c - vectorizer specific data-refs analysis and 
+  - tree-vect-data-refs.c - vectorizer specific data-refs analysis and
     manipulations (used by all).
   - tree-vect-patterns.c - vectorizable code patterns detector (used by all)
 
@@ -61,50 +61,30 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "ggc.h"
 #include "tree.h"
-#include "diagnostic.h"
+#include "tree-pretty-print.h"
 #include "tree-flow.h"
 #include "tree-dump.h"
 #include "cfgloop.h"
 #include "cfglayout.h"
 #include "tree-vectorizer.h"
 #include "tree-pass.h"
+#include "timevar.h"
 
 /* vect_dump will be set to stderr or dump_file if exist.  */
 FILE *vect_dump;
 
-/* vect_verbosity_level set to an invalid value 
+/* vect_verbosity_level set to an invalid value
    to mark that it's uninitialized.  */
-enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
-
-/* Loop location.  */
-LOC vect_loop_location;
+static enum vect_verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
 
-/* Bitmap of virtual variables to be renamed.  */
-bitmap vect_memsyms_to_rename;
+/* Loop or bb location.  */
+LOC vect_location;
 
 /* Vector mapping GIMPLE stmt to stmt_vec_info. */
 VEC(vec_void_p,heap) *stmt_vec_info_vec;
 
 \f
 
-/* Function vect_set_verbosity_level.
-
-   Called from toplev.c upon detection of the
-   -ftree-vectorizer-verbose=N option.  */
-
-void
-vect_set_verbosity_level (const char *val)
-{
-   unsigned int vl;
-
-   vl = atoi (val);
-   if (vl < MAX_VERBOSITY_LEVEL)
-     vect_verbosity_level = vl;
-   else
-     vect_verbosity_level = MAX_VERBOSITY_LEVEL - 1;
-}
-
-
 /* Function vect_set_dump_settings.
 
    Fix the verbosity level of the vectorizer if the
@@ -115,24 +95,40 @@ vect_set_verbosity_level (const char *val)
    print to stderr, otherwise print to the dump file.  */
 
 static void
-vect_set_dump_settings (void)
+vect_set_dump_settings (bool slp)
 {
   vect_dump = dump_file;
 
   /* Check if the verbosity level was defined by the user:  */
-  if (vect_verbosity_level != MAX_VERBOSITY_LEVEL)
+  if (user_vect_verbosity_level != MAX_VERBOSITY_LEVEL)
     {
-      /* If there is no dump file, print to stderr.  */
-      if (!dump_file)
-        vect_dump = stderr;
-      return;
+      vect_verbosity_level = user_vect_verbosity_level;
+      /* Ignore user defined verbosity if dump flags require higher level of
+         verbosity.  */
+      if (dump_file)
+        {
+          if (((dump_flags & TDF_DETAILS)
+                && vect_verbosity_level >= REPORT_DETAILS)
+              || ((dump_flags & TDF_STATS)
+                   && vect_verbosity_level >= REPORT_UNVECTORIZED_LOCATIONS))
+            return;
+        }
+      else
+        {
+          /* If there is no dump file, print to stderr in case of loop
+             vectorization.  */
+          if (!slp)
+            vect_dump = stderr;
+
+          return;
+        }
     }
 
   /* User didn't specify verbosity level:  */
   if (dump_file && (dump_flags & TDF_DETAILS))
     vect_verbosity_level = REPORT_DETAILS;
   else if (dump_file && (dump_flags & TDF_STATS))
-    vect_verbosity_level = REPORT_UNVECTORIZED_LOOPS;
+    vect_verbosity_level = REPORT_UNVECTORIZED_LOCATIONS;
   else
     vect_verbosity_level = REPORT_NONE;
 
@@ -145,7 +141,7 @@ vect_set_dump_settings (void)
    For vectorization debug dumps.  */
 
 bool
-vect_print_dump_info (enum verbosity_levels vl)
+vect_print_dump_info (enum vect_verbosity_levels vl)
 {
   if (vl > vect_verbosity_level)
     return false;
@@ -153,21 +149,20 @@ vect_print_dump_info (enum verbosity_levels vl)
   if (!current_function_decl || !vect_dump)
     return false;
 
-  if (vect_loop_location == UNKNOWN_LOC)
+  if (vect_location == UNKNOWN_LOC)
     fprintf (vect_dump, "\n%s:%d: note: ",
             DECL_SOURCE_FILE (current_function_decl),
             DECL_SOURCE_LINE (current_function_decl));
   else
-    fprintf (vect_dump, "\n%s:%d: note: ", 
-            LOC_FILE (vect_loop_location), LOC_LINE (vect_loop_location));
+    fprintf (vect_dump, "\n%d: ", LOC_LINE (vect_location));
 
   return true;
 }
 
 
 /* Function vectorize_loops.
-   
-   Entry Point to loop vectorization phase.  */
+
+   Entry point to loop vectorization phase.  */
 
 unsigned
 vectorize_loops (void)
@@ -185,46 +180,53 @@ vectorize_loops (void)
     return 0;
 
   /* Fix the verbosity level if not defined explicitly by the user.  */
-  vect_set_dump_settings ();
-
-  /* Allocate the bitmap that records which virtual variables that 
-     need to be renamed.  */
-  vect_memsyms_to_rename = BITMAP_ALLOC (NULL);
+  vect_set_dump_settings (false);
 
   init_stmt_vec_info_vec ();
 
   /*  ----------- Analyze loops. -----------  */
 
-  /* If some loop was duplicated, it gets bigger number 
-     than all previously defined loops. This fact allows us to run 
+  /* If some loop was duplicated, it gets bigger number
+     than all previously defined loops.  This fact allows us to run
      only over initial loops skipping newly generated ones.  */
   FOR_EACH_LOOP (li, loop, 0)
     if (optimize_loop_nest_for_speed_p (loop))
       {
        loop_vec_info loop_vinfo;
 
-       vect_loop_location = find_loop_location (loop);
+       vect_location = find_loop_location (loop);
+        if (vect_location != UNKNOWN_LOC
+            && vect_verbosity_level > REPORT_NONE)
+         fprintf (vect_dump, "\nAnalyzing loop at %s:%d\n",
+            LOC_FILE (vect_location), LOC_LINE (vect_location));
+
        loop_vinfo = vect_analyze_loop (loop);
        loop->aux = loop_vinfo;
 
        if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
          continue;
 
+        if (vect_location != UNKNOWN_LOC
+            && vect_verbosity_level > REPORT_NONE)
+          fprintf (vect_dump, "\n\nVectorizing loop at %s:%d\n",
+            LOC_FILE (vect_location), LOC_LINE (vect_location));
+
        vect_transform_loop (loop_vinfo);
        num_vectorized_loops++;
       }
-  vect_loop_location = UNKNOWN_LOC;
+
+  vect_location = UNKNOWN_LOC;
 
   statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops);
-  if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS)
-      || (vect_print_dump_info (REPORT_VECTORIZED_LOOPS)
-         && num_vectorized_loops > 0))
+  if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)
+      || (num_vectorized_loops > 0
+         && vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS)))
     fprintf (vect_dump, "vectorized %u loops in function.\n",
             num_vectorized_loops);
 
   /*  ----------- Finalize. -----------  */
 
-  BITMAP_FREE (vect_memsyms_to_rename);
+  mark_sym_for_renaming (gimple_vop (cfun));
 
   for (i = 1; i < vect_loops_num; i++)
     {
@@ -242,7 +244,68 @@ vectorize_loops (void)
 
   return num_vectorized_loops > 0 ? TODO_cleanup_cfg : 0;
 }
+
+
+/*  Entry point to basic block SLP phase.  */
+
+static unsigned int
+execute_vect_slp (void)
+{
+  basic_block bb;
+
+  /* Fix the verbosity level if not defined explicitly by the user.  */
+  vect_set_dump_settings (true);
+
+  init_stmt_vec_info_vec ();
+
+  FOR_EACH_BB (bb)
+    {
+      vect_location = find_bb_location (bb);
+
+      if (vect_slp_analyze_bb (bb))
+        {
+          vect_slp_transform_bb (bb);
+
+          if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
+            fprintf (vect_dump, "basic block vectorized using SLP\n");
+        }
+    }
+
+  free_stmt_vec_info_vec ();
+  return 0;
+}
+
+static bool
+gate_vect_slp (void)
+{
+  /* Apply SLP either if the vectorizer is on and the user didn't specify
+     whether to run SLP or not, or if the SLP flag was set by the user.  */
+  return ((flag_tree_vectorize != 0 && flag_tree_slp_vectorize != 0)
+          || flag_tree_slp_vectorize == 1);
+}
+
+struct gimple_opt_pass pass_slp_vectorize =
+{
+ {
+  GIMPLE_PASS,
+  "slp",                                /* name */
+  gate_vect_slp,                        /* gate */
+  execute_vect_slp,                     /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_TREE_SLP_VECTORIZATION,            /* tv_id */
+  PROP_ssa | PROP_cfg,                  /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_ggc_collect
+    | TODO_verify_ssa
+    | TODO_update_ssa
+    | TODO_verify_stmts                 /* todo_flags_finish */
+ }
+};
+
 
 /* Increase alignment of global arrays to improve vectorization potential.
    TODO:
@@ -262,11 +325,13 @@ increase_alignment (void)
        vnode = vnode->next_needed)
     {
       tree vectype, decl = vnode->decl;
+      tree t;
       unsigned int alignment;
 
-      if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
+      t = TREE_TYPE(decl);
+      if (TREE_CODE (t) != ARRAY_TYPE)
         continue;
-      vectype = get_vectype_for_scalar_type (TREE_TYPE (TREE_TYPE (decl)));
+      vectype = get_vectype_for_scalar_type (strip_array_types (t));
       if (!vectype)
         continue;
       alignment = TYPE_ALIGN (vectype);
@@ -281,6 +346,7 @@ increase_alignment (void)
             {
               fprintf (dump_file, "Increasing alignment of decl: ");
               print_generic_expr (dump_file, decl, TDF_SLIM);
+             fprintf (dump_file, "\n");
             }
         }
     }
@@ -305,7 +371,7 @@ struct simple_ipa_opt_pass pass_ipa_increase_alignment =
   NULL,                                 /* sub */
   NULL,                                 /* next */
   0,                                    /* static_pass_number */
-  0,                                    /* tv_id */
+  TV_IPA_OPT,                           /* tv_id */
   0,                                    /* properties_required */
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
@@ -313,5 +379,3 @@ struct simple_ipa_opt_pass pass_ipa_increase_alignment =
   0                                     /* todo_flags_finish */
  }
 };
-
-