diff mbox series

[1/2] Move out increase_alignment into ipa-increase-alignment.cc

Message ID 20200327180656.83131-1-kito.cheng@sifive.com
State New
Headers show
Series [1/2] Move out increase_alignment into ipa-increase-alignment.cc | expand

Commit Message

Kito Cheng March 27, 2020, 6:06 p.m. UTC
- This patch is prepare for add more logic into increase_alignment
   pass, which is not related to vectorization.

gcc/ChangeLog

	* Makefile.in (OBJS): Add ipa-increase-alignment.o.
	* tree-vectorizer.c (get_vec_alignment_for_type): Moved to
	ipa-increase-alignment.cc.
	(type_align_map): Ditto.
	(get_vec_alignment_for_array_type): Ditto.
	(get_vec_alignment_for_record_type): Ditto.
	(increase_alignment): Ditto.
	(pass_data_ipa_increase_alignment): Ditto.
	(pass_ipa_increase_alignment): Ditto.
	(make_pass_ipa_increase_alignment): Ditto.
	* ipa-increase-alignment.cc (get_vec_alignment_for_type) Moved
	from ipa-increase-alignment.cc.
	(type_align_map): Ditto.
	(get_vec_alignment_for_array_type): Ditto.
	(get_vec_alignment_for_record_type): Ditto.
	(increase_alignment): Ditto.
	(pass_data_ipa_increase_alignment): Ditto.
	(pass_ipa_increase_alignment): Ditto.
	(make_pass_ipa_increase_alignment): Ditto.
---
 gcc/Makefile.in               |   1 +
 gcc/ipa-increase-alignment.cc | 223 ++++++++++++++++++++++++++++++++++
 gcc/tree-vectorizer.c         | 189 ----------------------------
 3 files changed, 224 insertions(+), 189 deletions(-)
 create mode 100644 gcc/ipa-increase-alignment.cc
diff mbox series

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index fa9923bb270..2c11252911c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1408,6 +1408,7 @@  OBJS = \
 	ipa-inline.o \
 	ipa-comdats.o \
 	ipa-visibility.o \
+	ipa-increase-alignment.o \
 	ipa-inline-analysis.o \
 	ipa-inline-transform.o \
 	ipa-predicate.o \
diff --git a/gcc/ipa-increase-alignment.cc b/gcc/ipa-increase-alignment.cc
new file mode 100644
index 00000000000..6e34124bc03
--- /dev/null
+++ b/gcc/ipa-increase-alignment.cc
@@ -0,0 +1,223 @@ 
+/* Increase alignment
+   Copyright (C) 2003-2020 Free Software Foundation, Inc.
+   Contributed by Dorit Naishlos <dorit@il.ibm.com>
+
+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
+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
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "tree.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "fold-const.h"
+#include "gimple-iterator.h"
+#include "tree-cfg.h"
+#include "cfgloop.h"
+#include "tree-vectorizer.h"
+#include "tm_p.h"
+
+/* Increase alignment of global arrays to improve vectorization potential.
+   TODO:
+   - Consider also structs that have an array field.
+   - Use ipa analysis to prune arrays that can't be vectorized?
+     This should involve global alignment analysis and in the future also
+     array padding.  */
+
+static unsigned get_vec_alignment_for_type (tree);
+static hash_map<tree, unsigned> *type_align_map;
+
+/* Return alignment of array's vector type corresponding to scalar type.
+   0 if no vector type exists.  */
+static unsigned
+get_vec_alignment_for_array_type (tree type)
+{
+  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+  poly_uint64 array_size, vector_size;
+
+  tree scalar_type = strip_array_types (type);
+  tree vectype = get_related_vectype_for_scalar_type (VOIDmode, scalar_type);
+  if (!vectype
+      || !poly_int_tree_p (TYPE_SIZE (type), &array_size)
+      || !poly_int_tree_p (TYPE_SIZE (vectype), &vector_size)
+      || maybe_lt (array_size, vector_size))
+    return 0;
+
+  return TYPE_ALIGN (vectype);
+}
+
+/* Return alignment of field having maximum alignment of vector type
+   corresponding to it's scalar type. For now, we only consider fields whose
+   offset is a multiple of it's vector alignment.
+   0 if no suitable field is found.  */
+static unsigned
+get_vec_alignment_for_record_type (tree type)
+{
+  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+
+  unsigned max_align = 0, alignment;
+  HOST_WIDE_INT offset;
+  tree offset_tree;
+
+  if (TYPE_PACKED (type))
+    return 0;
+
+  unsigned *slot = type_align_map->get (type);
+  if (slot)
+    return *slot;
+
+  for (tree field = first_field (type);
+       field != NULL_TREE;
+       field = DECL_CHAIN (field))
+    {
+      /* Skip if not FIELD_DECL or if alignment is set by user.  */
+      if (TREE_CODE (field) != FIELD_DECL
+	  || DECL_USER_ALIGN (field)
+	  || DECL_ARTIFICIAL (field))
+	continue;
+
+      /* We don't need to process the type further if offset is variable,
+	 since the offsets of remaining members will also be variable.  */
+      if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST
+	  || TREE_CODE (DECL_FIELD_BIT_OFFSET (field)) != INTEGER_CST)
+	break;
+
+      /* Similarly stop processing the type if offset_tree
+	 does not fit in unsigned HOST_WIDE_INT.  */
+      offset_tree = bit_position (field);
+      if (!tree_fits_uhwi_p (offset_tree))
+	break;
+
+      offset = tree_to_uhwi (offset_tree);
+      alignment = get_vec_alignment_for_type (TREE_TYPE (field));
+
+      /* Get maximum alignment of vectorized field/array among those members
+	 whose offset is multiple of the vector alignment.  */
+      if (alignment
+	  && (offset % alignment == 0)
+	  && (alignment > max_align))
+	max_align = alignment;
+    }
+
+  type_align_map->put (type, max_align);
+  return max_align;
+}
+
+/* Return alignment of vector type corresponding to decl's scalar type
+   or 0 if it doesn't exist or the vector alignment is lesser than
+   decl's alignment.  */
+static unsigned
+get_vec_alignment_for_type (tree type)
+{
+  if (type == NULL_TREE)
+    return 0;
+
+  gcc_assert (TYPE_P (type));
+
+  static unsigned alignment = 0;
+  switch (TREE_CODE (type))
+    {
+      case ARRAY_TYPE:
+	alignment = get_vec_alignment_for_array_type (type);
+	break;
+      case RECORD_TYPE:
+	alignment = get_vec_alignment_for_record_type (type);
+	break;
+      default:
+	alignment = 0;
+	break;
+    }
+
+  return (alignment > TYPE_ALIGN (type)) ? alignment : 0;
+}
+
+/* Entry point to increase_alignment pass.  */
+static unsigned int
+increase_alignment (void)
+{
+  varpool_node *vnode;
+
+  vect_location = dump_user_location_t ();
+  type_align_map = new hash_map<tree, unsigned>;
+
+  /* Increase the alignment of all global arrays for vectorization.  */
+  FOR_EACH_DEFINED_VARIABLE (vnode)
+    {
+      tree decl = vnode->decl;
+      unsigned int alignment;
+
+      if ((decl_in_symtab_p (decl)
+	  && !symtab_node::get (decl)->can_increase_alignment_p ())
+	  || DECL_USER_ALIGN (decl) || DECL_ARTIFICIAL (decl))
+	continue;
+
+      alignment = get_vec_alignment_for_type (TREE_TYPE (decl));
+      if (alignment && vect_can_force_dr_alignment_p (decl, alignment))
+        {
+	  vnode->increase_alignment (alignment);
+	  if (dump_enabled_p ())
+	    dump_printf (MSG_NOTE, "Increasing alignment of decl: %T\n", decl);
+        }
+    }
+
+  delete type_align_map;
+  return 0;
+}
+
+
+namespace {
+
+const pass_data pass_data_ipa_increase_alignment =
+{
+  SIMPLE_IPA_PASS, /* type */
+  "increase_alignment", /* name */
+  OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
+  TV_IPA_OPT, /* tv_id */
+  0, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_ipa_increase_alignment : public simple_ipa_opt_pass
+{
+public:
+  pass_ipa_increase_alignment (gcc::context *ctxt)
+    : simple_ipa_opt_pass (pass_data_ipa_increase_alignment, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual bool gate (function *)
+    {
+      return flag_section_anchors && flag_tree_loop_vectorize;
+    }
+
+  virtual unsigned int execute (function *) { return increase_alignment (); }
+
+}; // class pass_ipa_increase_alignment
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_increase_alignment (gcc::context *ctxt)
+{
+  return new pass_ipa_increase_alignment (ctxt);
+}
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 8f9444d58a3..e9caf91e174 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -1340,195 +1340,6 @@  make_pass_slp_vectorize (gcc::context *ctxt)
   return new pass_slp_vectorize (ctxt);
 }
 
-
-/* Increase alignment of global arrays to improve vectorization potential.
-   TODO:
-   - Consider also structs that have an array field.
-   - Use ipa analysis to prune arrays that can't be vectorized?
-     This should involve global alignment analysis and in the future also
-     array padding.  */
-
-static unsigned get_vec_alignment_for_type (tree);
-static hash_map<tree, unsigned> *type_align_map;
-
-/* Return alignment of array's vector type corresponding to scalar type.
-   0 if no vector type exists.  */
-static unsigned
-get_vec_alignment_for_array_type (tree type) 
-{
-  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
-  poly_uint64 array_size, vector_size;
-
-  tree scalar_type = strip_array_types (type);
-  tree vectype = get_related_vectype_for_scalar_type (VOIDmode, scalar_type);
-  if (!vectype
-      || !poly_int_tree_p (TYPE_SIZE (type), &array_size)
-      || !poly_int_tree_p (TYPE_SIZE (vectype), &vector_size)
-      || maybe_lt (array_size, vector_size))
-    return 0;
-
-  return TYPE_ALIGN (vectype);
-}
-
-/* Return alignment of field having maximum alignment of vector type
-   corresponding to it's scalar type. For now, we only consider fields whose
-   offset is a multiple of it's vector alignment.
-   0 if no suitable field is found.  */
-static unsigned
-get_vec_alignment_for_record_type (tree type) 
-{
-  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
-
-  unsigned max_align = 0, alignment;
-  HOST_WIDE_INT offset;
-  tree offset_tree;
-
-  if (TYPE_PACKED (type))
-    return 0;
-
-  unsigned *slot = type_align_map->get (type);
-  if (slot)
-    return *slot;
-
-  for (tree field = first_field (type);
-       field != NULL_TREE;
-       field = DECL_CHAIN (field))
-    {
-      /* Skip if not FIELD_DECL or if alignment is set by user.  */ 
-      if (TREE_CODE (field) != FIELD_DECL
-	  || DECL_USER_ALIGN (field)
-	  || DECL_ARTIFICIAL (field))
-	continue;
-
-      /* We don't need to process the type further if offset is variable,
-	 since the offsets of remaining members will also be variable.  */
-      if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST
-	  || TREE_CODE (DECL_FIELD_BIT_OFFSET (field)) != INTEGER_CST)
-	break;
-
-      /* Similarly stop processing the type if offset_tree
-	 does not fit in unsigned HOST_WIDE_INT.  */
-      offset_tree = bit_position (field);
-      if (!tree_fits_uhwi_p (offset_tree))
-	break;
-
-      offset = tree_to_uhwi (offset_tree); 
-      alignment = get_vec_alignment_for_type (TREE_TYPE (field));
-
-      /* Get maximum alignment of vectorized field/array among those members
-	 whose offset is multiple of the vector alignment.  */ 
-      if (alignment
-	  && (offset % alignment == 0)
-	  && (alignment > max_align))
-	max_align = alignment;
-    }
-
-  type_align_map->put (type, max_align);
-  return max_align;
-}
-
-/* Return alignment of vector type corresponding to decl's scalar type
-   or 0 if it doesn't exist or the vector alignment is lesser than
-   decl's alignment.  */
-static unsigned
-get_vec_alignment_for_type (tree type)
-{
-  if (type == NULL_TREE)
-    return 0;
-
-  gcc_assert (TYPE_P (type));
-
-  static unsigned alignment = 0;
-  switch (TREE_CODE (type))
-    {
-      case ARRAY_TYPE:
-	alignment = get_vec_alignment_for_array_type (type);
-	break;
-      case RECORD_TYPE:
-	alignment = get_vec_alignment_for_record_type (type);
-	break;
-      default:
-	alignment = 0;
-	break;
-    }
-
-  return (alignment > TYPE_ALIGN (type)) ? alignment : 0;
-}
-
-/* Entry point to increase_alignment pass.  */
-static unsigned int
-increase_alignment (void)
-{
-  varpool_node *vnode;
-
-  vect_location = dump_user_location_t ();
-  type_align_map = new hash_map<tree, unsigned>;
-
-  /* Increase the alignment of all global arrays for vectorization.  */
-  FOR_EACH_DEFINED_VARIABLE (vnode)
-    {
-      tree decl = vnode->decl;
-      unsigned int alignment;
-
-      if ((decl_in_symtab_p (decl)
-	  && !symtab_node::get (decl)->can_increase_alignment_p ())
-	  || DECL_USER_ALIGN (decl) || DECL_ARTIFICIAL (decl))
-	continue;
-
-      alignment = get_vec_alignment_for_type (TREE_TYPE (decl));
-      if (alignment && vect_can_force_dr_alignment_p (decl, alignment))
-        {
-	  vnode->increase_alignment (alignment);
-	  if (dump_enabled_p ())
-	    dump_printf (MSG_NOTE, "Increasing alignment of decl: %T\n", decl);
-        }
-    }
-
-  delete type_align_map;
-  return 0;
-}
-
-
-namespace {
-
-const pass_data pass_data_ipa_increase_alignment =
-{
-  SIMPLE_IPA_PASS, /* type */
-  "increase_alignment", /* name */
-  OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
-  TV_IPA_OPT, /* tv_id */
-  0, /* properties_required */
-  0, /* properties_provided */
-  0, /* properties_destroyed */
-  0, /* todo_flags_start */
-  0, /* todo_flags_finish */
-};
-
-class pass_ipa_increase_alignment : public simple_ipa_opt_pass
-{
-public:
-  pass_ipa_increase_alignment (gcc::context *ctxt)
-    : simple_ipa_opt_pass (pass_data_ipa_increase_alignment, ctxt)
-  {}
-
-  /* opt_pass methods: */
-  virtual bool gate (function *)
-    {
-      return flag_section_anchors && flag_tree_loop_vectorize;
-    }
-
-  virtual unsigned int execute (function *) { return increase_alignment (); }
-
-}; // class pass_ipa_increase_alignment
-
-} // anon namespace
-
-simple_ipa_opt_pass *
-make_pass_ipa_increase_alignment (gcc::context *ctxt)
-{
-  return new pass_ipa_increase_alignment (ctxt);
-}
-
 /* If the condition represented by T is a comparison or the SSA name
    result of a comparison, extract the comparison's operands.  Represent
    T as NE_EXPR <T, 0> otherwise.  */