re PR debug/66691 (ICE on valid code at -O3 with -g enabled in simplify_subreg, at...
[gcc.git] / gcc / ipa-icf.c
index 207a00d53de0a651ae03aa273f6ec8ad194bee89..691c90d59d55510934ddedf8a1387027abbfcb89 100644 (file)
@@ -55,13 +55,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include <list>
 #include "coretypes.h"
-#include "hash-set.h"
-#include "vec.h"
-#include "input.h"
 #include "alias.h"
 #include "symtab.h"
 #include "options.h"
-#include "inchash.h"
 #include "tree.h"
 #include "fold-const.h"
 #include "predict.h"
@@ -74,12 +70,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
 #include "gimple-expr.h"
-#include "is-a.h"
 #include "gimple.h"
-#include "hashtab.h"
 #include "rtl.h"
 #include "flags.h"
-#include "statistics.h"
 #include "insn-config.h"
 #include "expmed.h"
 #include "dojump.h"
@@ -98,9 +91,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dfa.h"
 #include "tree-pass.h"
 #include "gimple-pretty-print.h"
-#include "hash-map.h"
-#include "plugin-api.h"
-#include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
 #include "symbol-summary.h"
@@ -108,7 +98,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-inline.h"
 #include "cfgloop.h"
 #include "except.h"
-#include "hash-table.h"
 #include "coverage.h"
 #include "attribs.h"
 #include "print-tree.h"
@@ -268,7 +257,6 @@ sem_item::target_supports_symbol_aliases_p (void)
 sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack),
   m_checker (NULL), m_compared_func (NULL)
 {
-  arg_types.create (0);
   bb_sizes.create (0);
   bb_sorted.create (0);
 }
@@ -280,7 +268,6 @@ sem_function::sem_function (cgraph_node *node, hashval_t hash,
   sem_item (FUNC, node, hash, stack),
   m_checker (NULL), m_compared_func (NULL)
 {
-  arg_types.create (0);
   bb_sizes.create (0);
   bb_sorted.create (0);
 }
@@ -290,7 +277,6 @@ sem_function::~sem_function ()
   for (unsigned i = 0; i < bb_sorted.length (); i++)
     delete (bb_sorted[i]);
 
-  arg_types.release ();
   bb_sizes.release ();
   bb_sorted.release ();
 }
@@ -590,6 +576,30 @@ sem_function::param_used_p (unsigned int i)
   return ipa_is_param_used (IPA_NODE_REF (get_node ()), i);
 }
 
+/* Perform additional check needed to match types function parameters that are
+   used.  Unlike for normal decls it matters if type is TYPE_RESTRICT and we
+   make an assumption that REFERENCE_TYPE parameters are always non-NULL.  */
+
+bool
+sem_function::compatible_parm_types_p (tree parm1, tree parm2)
+{
+  /* Be sure that parameters are TBAA compatible.  */
+  if (!func_checker::compatible_types_p (parm1, parm2))
+    return return_false_with_msg ("parameter type is not compatible");
+
+  if (POINTER_TYPE_P (parm1)
+      && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2)))
+    return return_false_with_msg ("argument restrict flag mismatch");
+
+  /* nonnull_arg_p implies non-zero range to REFERENCE types.  */
+  if (POINTER_TYPE_P (parm1)
+      && TREE_CODE (parm1) != TREE_CODE (parm2)
+      && opt_for_fn (decl, flag_delete_null_pointer_checks))
+    return return_false_with_msg ("pointer wrt reference mismatch");
+
+  return true;
+}
+
 /* Fast equality function based on knowledge known in WPA.  */
 
 bool
@@ -602,9 +612,6 @@ sem_function::equals_wpa (sem_item *item,
 
   m_compared_func = static_cast<sem_function *> (item);
 
-  if (arg_types.length () != m_compared_func->arg_types.length ())
-    return return_false_with_msg ("different number of arguments");
-
   if (cnode->thunk.thunk_p != cnode2->thunk.thunk_p)
     return return_false_with_msg ("thunk_p mismatch");
 
@@ -693,38 +700,40 @@ sem_function::equals_wpa (sem_item *item,
     }
 
   /* Result type checking.  */
-  if (!func_checker::compatible_types_p (result_type,
-                                        m_compared_func->result_type))
+  if (!func_checker::compatible_types_p
+        (TREE_TYPE (TREE_TYPE (decl)),
+         TREE_TYPE (TREE_TYPE (m_compared_func->decl))))
     return return_false_with_msg ("result types are different");
 
   /* Checking types of arguments.  */
-  for (unsigned i = 0; i < arg_types.length (); i++)
+  tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)),
+       list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl));
+  for (unsigned i = 0; list1 && list2;
+       list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++)
     {
+      tree parm1 = TREE_VALUE (list1);
+      tree parm2 = TREE_VALUE (list2);
+
       /* This guard is here for function pointer with attributes (pr59927.c).  */
-      if (!arg_types[i] || !m_compared_func->arg_types[i])
+      if (!parm1 || !parm2)
        return return_false_with_msg ("NULL argument type");
 
-      /* We always need to match types so we are sure the callin conventions
-        are compatible.  */
-      if (!func_checker::compatible_types_p (arg_types[i],
-                                            m_compared_func->arg_types[i]))
-       return return_false_with_msg ("argument type is different");
+      /* Verify that types are compatible to ensure that both functions
+        have same calling conventions.  */
+      if (!types_compatible_p (parm1, parm2))
+       return return_false_with_msg ("parameter types are not compatible");
 
-      /* On used arguments we need to do a bit more of work.  */
       if (!param_used_p (i))
        continue;
-      if (POINTER_TYPE_P (arg_types[i])
-         && (TYPE_RESTRICT (arg_types[i])
-             != TYPE_RESTRICT (m_compared_func->arg_types[i])))
-       return return_false_with_msg ("argument restrict flag mismatch");
-      /* nonnull_arg_p implies non-zero range to REFERENCE types.  */
-      if (POINTER_TYPE_P (arg_types[i])
-         && TREE_CODE (arg_types[i])
-            != TREE_CODE (m_compared_func->arg_types[i])
-         && opt_for_fn (decl, flag_delete_null_pointer_checks))
-       return return_false_with_msg ("pointer wrt reference mismatch");
+
+      /* Perform additional checks for used parameters.  */
+      if (!compatible_parm_types_p (parm1, parm2))
+       return false;
     }
 
+  if (list1 || list2)
+    return return_false_with_msg ("Mismatched number of parameters");
+
   if (node->num_references () != item->node->num_references ())
     return return_false_with_msg ("different number of references");
 
@@ -931,11 +940,23 @@ sem_function::equals_private (sem_item *item)
                                false,
                                &refs_set,
                                &m_compared_func->refs_set);
-  for (arg1 = DECL_ARGUMENTS (decl),
-       arg2 = DECL_ARGUMENTS (m_compared_func->decl);
-       arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
-    if (!m_checker->compare_decl (arg1, arg2))
-      return return_false ();
+  arg1 = DECL_ARGUMENTS (decl);
+  arg2 = DECL_ARGUMENTS (m_compared_func->decl);
+  for (unsigned i = 0;
+       arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++)
+    {
+      if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
+       return return_false_with_msg ("argument types are not compatible");
+      if (!param_used_p (i))
+       continue;
+      /* Perform additional checks for used parameters.  */
+      if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
+       return false;
+      if (!m_checker->compare_decl (arg1, arg2))
+        return return_false ();
+    }
+  if (arg1 || arg2)
+    return return_false_with_msg ("Mismatched number of arguments");
 
   if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
     return true;
@@ -1448,8 +1469,6 @@ sem_function::init (void)
       hstate.add_flag (cnode->thunk.add_pointer_bounds_args);
       gcode_hash = hstate.end ();
     }
-
-  parse_tree_args ();
 }
 
 /* Accumulate to HSTATE a hash of expression EXP.
@@ -1700,37 +1719,6 @@ sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
   return f;
 }
 
-/* Parses function arguments and result type.  */
-
-void
-sem_function::parse_tree_args (void)
-{
-  tree result;
-
-  if (arg_types.exists ())
-    arg_types.release ();
-
-  arg_types.create (4);
-  tree fnargs = DECL_ARGUMENTS (decl);
-
-  for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
-    arg_types.safe_push (DECL_ARG_TYPE (parm));
-
-  /* Function result type.  */
-  result = DECL_RESULT (decl);
-  result_type = result ? TREE_TYPE (result) : NULL;
-
-  /* During WPA, we can get arguments by following method.  */
-  if (!fnargs)
-    {
-      tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
-      for (tree parm = type; parm; parm = TREE_CHAIN (parm))
-       arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
-
-      result_type = TREE_TYPE (TREE_TYPE (decl));
-    }
-}
-
 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
    return true if phi nodes are semantically equivalent in these blocks .  */
 
@@ -2918,8 +2906,7 @@ sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
 unsigned
 sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
 {
-  typedef hash_map <symbol_compare_collection *, vec <sem_item *>,
-    symbol_compare_hashmap_traits> subdivide_hash_map;
+  typedef hash_map <symbol_compare_hash, vec <sem_item *> > subdivide_hash_map;
 
   unsigned newly_created_classes = 0;