ipa-icf.c (sem_function::equals_wpa): Compare thunk info.
authorJan Hubicka <hubicka@ucw.cz>
Fri, 24 Apr 2015 00:58:25 +0000 (02:58 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 24 Apr 2015 00:58:25 +0000 (00:58 +0000)
* ipa-icf.c (sem_function::equals_wpa): Compare thunk info.
(sem_function::equals): IGNORED_NODES parameter is now unused;
update call of equals_private.
(sem_function::equals_private): Do not call equals_wpa; skip
gimple body matching if there is no body.
(sem_function::init): Add logic to hash tthunk info.
(sem_function::parse): Also parse thunks.
* ipa-icf.h (equals_private): Update declaration.

From-SVN: r222392

gcc/ChangeLog
gcc/ipa-icf.c
gcc/ipa-icf.h

index 44c775c8e8c74a2d4f804a6e74d1c4d5ca344915..2eaacfdfd1418577a53ef338617043f11c8f02c5 100644 (file)
@@ -1,3 +1,14 @@
+2015-04-23  Jan Hubicka  <hubicka@ucw.cz>
+
+       * ipa-icf.c (sem_function::equals_wpa): Compare thunk info.
+       (sem_function::equals): IGNORED_NODES parameter is now unused;
+       update call of equals_private.
+       (sem_function::equals_private): Do not call equals_wpa; skip
+       gimple body matching if there is no body.
+       (sem_function::init): Add logic to hash tthunk info.
+       (sem_function::parse): Also parse thunks.
+       * ipa-icf.h (equals_private): Update declaration.
+
 2015-04-23  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * config/rs6000/altivec.md (*altivec_lvx_<mode>_internal): Remove
index 5336744fc2fb2ac1ac4594caceaf4543e8979eee..ce4aca20b669461ac9c5796aeb81710d4b3e4164 100644 (file)
@@ -601,12 +601,32 @@ sem_function::equals_wpa (sem_item *item,
                          hash_map <symtab_node *, sem_item *> &ignored_nodes)
 {
   gcc_assert (item->type == FUNC);
+  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+  cgraph_node *cnode2 = dyn_cast <cgraph_node *> (item->node);
 
   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");
+
+  if (cnode->thunk.thunk_p)
+    {
+      if (cnode->thunk.fixed_offset != cnode2->thunk.fixed_offset)
+        return return_false_with_msg ("thunk fixed_offset mismatch");
+      if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value)
+        return return_false_with_msg ("thunk virtual_value mismatch");
+      if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting)
+        return return_false_with_msg ("thunk this_adjusting mismatch");
+      if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p)
+        return return_false_with_msg ("thunk virtual_offset_p mismatch");
+      if (cnode->thunk.add_pointer_bounds_args
+         != cnode2->thunk.add_pointer_bounds_args)
+        return return_false_with_msg ("thunk add_pointer_bounds_args mismatch");
+    }
+
   /* Compare special function DECL attributes.  */
   if (DECL_FUNCTION_PERSONALITY (decl)
       != DECL_FUNCTION_PERSONALITY (item->decl))
@@ -862,10 +882,10 @@ sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
 
 bool
 sem_function::equals (sem_item *item,
-                     hash_map <symtab_node *, sem_item *> &ignored_nodes)
+                     hash_map <symtab_node *, sem_item *> &)
 {
   gcc_assert (item->type == FUNC);
-  bool eq = equals_private (item, ignored_nodes);
+  bool eq = equals_private (item);
 
   if (m_checker != NULL)
     {
@@ -890,8 +910,7 @@ sem_function::equals (sem_item *item,
 /* Processes function equality comparison.  */
 
 bool
-sem_function::equals_private (sem_item *item,
-                             hash_map <symtab_node *, sem_item *> &ignored_nodes)
+sem_function::equals_private (sem_item *item)
 {
   if (item->type != FUNC)
     return false;
@@ -911,9 +930,6 @@ sem_function::equals_private (sem_item *item,
       || cfg_checksum != m_compared_func->cfg_checksum)
     return return_false ();
 
-  if (!equals_wpa (item, ignored_nodes))
-    return false;
-
   m_checker = new func_checker (decl, m_compared_func->decl,
                                compare_polymorphic_p (),
                                false,
@@ -925,6 +941,9 @@ sem_function::equals_private (sem_item *item,
     if (!m_checker->compare_decl (arg1, arg2))
       return return_false ();
 
+  if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
+    return true;
+
   /* Fill-up label dictionary.  */
   for (unsigned i = 0; i < bb_sorted.length (); ++i)
     {
@@ -1380,44 +1399,59 @@ sem_function::init (void)
   arg_count = count_formal_params (fndecl);
 
   edge_count = n_edges_for_fn (func);
-  cfg_checksum = coverage_compute_cfg_checksum (func);
-
-  inchash::hash hstate;
-
-  basic_block bb;
-  FOR_EACH_BB_FN (bb, func)
-  {
-    unsigned nondbg_stmt_count = 0;
+  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+  if (!cnode->thunk.thunk_p)
+    {
+      cfg_checksum = coverage_compute_cfg_checksum (func);
 
-    edge e;
-    for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
-        ei_next (&ei))
-      cfg_checksum = iterative_hash_host_wide_int (e->flags,
-                    cfg_checksum);
+      inchash::hash hstate;
 
-    for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
-        gsi_next (&gsi))
+      basic_block bb;
+      FOR_EACH_BB_FN (bb, func)
       {
-       gimple stmt = gsi_stmt (gsi);
+       unsigned nondbg_stmt_count = 0;
+
+       edge e;
+       for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
+            ei_next (&ei))
+         cfg_checksum = iterative_hash_host_wide_int (e->flags,
+                        cfg_checksum);
 
-       if (gimple_code (stmt) != GIMPLE_DEBUG
-           && gimple_code (stmt) != GIMPLE_PREDICT)
+       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+            gsi_next (&gsi))
          {
-           hash_stmt (stmt, hstate);
-           nondbg_stmt_count++;
+           gimple stmt = gsi_stmt (gsi);
+
+           if (gimple_code (stmt) != GIMPLE_DEBUG
+               && gimple_code (stmt) != GIMPLE_PREDICT)
+             {
+               hash_stmt (stmt, hstate);
+               nondbg_stmt_count++;
+             }
          }
-      }
 
-    gcode_hash = hstate.end ();
-    bb_sizes.safe_push (nondbg_stmt_count);
+       gcode_hash = hstate.end ();
+       bb_sizes.safe_push (nondbg_stmt_count);
 
-    /* Inserting basic block to hash table.  */
-    sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
-                                     EDGE_COUNT (bb->preds)
-                                     + EDGE_COUNT (bb->succs));
+       /* Inserting basic block to hash table.  */
+       sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
+                                         EDGE_COUNT (bb->preds)
+                                         + EDGE_COUNT (bb->succs));
 
-    bb_sorted.safe_push (semantic_bb);
-  }
+       bb_sorted.safe_push (semantic_bb);
+      }
+    }
+  else
+    {
+      cfg_checksum = 0;
+      inchash::hash hstate;
+      hstate.add_wide_int (cnode->thunk.fixed_offset);
+      hstate.add_wide_int (cnode->thunk.virtual_value);
+      hstate.add_flag (cnode->thunk.this_adjusting);
+      hstate.add_flag (cnode->thunk.virtual_offset_p);
+      hstate.add_flag (cnode->thunk.add_pointer_bounds_args);
+      gcode_hash = hstate.end ();
+    }
 
   parse_tree_args ();
 }
@@ -1657,9 +1691,7 @@ sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
   tree fndecl = node->decl;
   function *func = DECL_STRUCT_FUNCTION (fndecl);
 
-  /* TODO: add support for thunks.  */
-
-  if (!func || !node->has_gimple_body_p ())
+  if (!func || (!node->has_gimple_body_p () && !node->thunk.thunk_p))
     return NULL;
 
   if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
index 8ad09df4c8aec2eb4a17b9f80fea5799493e25b6..a3b9ab93678102c6c094f9d212613a256fdd6bb1 100644 (file)
@@ -380,8 +380,7 @@ private:
   bool compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2);
 
   /* Processes function equality comparison.  */
-  bool equals_private (sem_item *item,
-                      hash_map <symtab_node *, sem_item *> &ignored_nodes);
+  bool equals_private (sem_item *item);
 
   /* Returns true if tree T can be compared as a handled component.  */
   static bool icf_handled_component_p (tree t);