OSDN Git Service

2011-01-03 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Jan 2011 13:06:54 +0000 (13:06 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Jan 2011 13:06:54 +0000 (13:06 +0000)
PR tree-optimization/46984
* cgraph.h (cgraph_indirect_call_info): make field thunk_delta
HOST_WIDE_INT.
(cgraph_create_indirect_edge): Fixed line length.
(cgraph_indirect_call_info): Declare.
(cgraph_make_edge_direct) Update declaration.
* cgraph.c (cgraph_allocate_init_indirect_info): New function.
(cgraph_create_indirect_edge): Use it.
(cgraph_make_edge_direct): Made delta HOST_WIDE_INT.  Updated all
callees.
* cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Update for
the new thunk_delta representation.
* ipa-prop.c (ipa_make_edge_direct_to_target): Convert delta to
HOST_WIDE_INT.
(ipa_write_indirect_edge_info): Remove streaming of thunk_delta.
(ipa_read_indirect_edge_info): Likewise.
* lto-cgraph.c (output_edge_opt_summary): New function.
(output_node_opt_summary): Call it on all outgoing edges.
(input_edge_opt_summary): New function.
(input_node_opt_summary): Call it on all outgoing edges.

* testsuite/g++.dg/ipa/pr46984.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168420 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/ipa-prop.c
gcc/lto-cgraph.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr46984.C [new file with mode: 0644]

index aebe391..c908a7b 100644 (file)
@@ -1,3 +1,26 @@
+2011-01-03  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/46984
+       * cgraph.h (cgraph_indirect_call_info): make field thunk_delta
+       HOST_WIDE_INT.
+       (cgraph_create_indirect_edge): Fixed line length.
+       (cgraph_indirect_call_info): Declare.
+       (cgraph_make_edge_direct) Update declaration.
+       * cgraph.c (cgraph_allocate_init_indirect_info): New function.
+       (cgraph_create_indirect_edge): Use it.
+       (cgraph_make_edge_direct): Made delta HOST_WIDE_INT.  Updated all
+       callees.
+       * cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Update for
+       the new thunk_delta representation.
+       * ipa-prop.c (ipa_make_edge_direct_to_target): Convert delta to
+       HOST_WIDE_INT.
+       (ipa_write_indirect_edge_info): Remove streaming of thunk_delta.
+       (ipa_read_indirect_edge_info): Likewise.
+       * lto-cgraph.c (output_edge_opt_summary): New function.
+       (output_node_opt_summary): Call it on all outgoing edges.
+       (input_edge_opt_summary): New function.
+       (input_node_opt_summary): Call it on all outgoing edges.
+
 2011-01-02  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR driver/47137
index f96bd64..c8f9b04 100644 (file)
@@ -860,7 +860,7 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt)
         indirect call into a direct one.  */
       struct cgraph_node *new_callee = cgraph_node (decl);
 
-      cgraph_make_edge_direct (e, new_callee, NULL);
+      cgraph_make_edge_direct (e, new_callee, 0);
     }
 
   push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
@@ -1070,6 +1070,17 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
   return edge;
 }
 
+/* Allocate cgraph_indirect_call_info and set its fields to default values. */
+
+struct cgraph_indirect_call_info *
+cgraph_allocate_init_indirect_info (void)
+{
+  struct cgraph_indirect_call_info *ii;
+
+  ii = ggc_alloc_cleared_cgraph_indirect_call_info ();
+  ii->param_index = -1;
+  return ii;
+}
 
 /* Create an indirect edge with a yet-undetermined callee where the call
    statement destination is a formal parameter of the caller with index
@@ -1086,8 +1097,7 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
   edge->indirect_unknown_callee = 1;
   initialize_inline_failed (edge);
 
-  edge->indirect_info = ggc_alloc_cleared_cgraph_indirect_call_info ();
-  edge->indirect_info->param_index = -1;
+  edge->indirect_info = cgraph_allocate_init_indirect_info ();
   edge->indirect_info->ecf_flags = ecf_flags;
 
   edge->next_callee = caller->indirect_calls;
@@ -1195,12 +1205,12 @@ cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
 }
 
 /* Make an indirect EDGE with an unknown callee an ordinary edge leading to
-   CALLEE.  DELTA, if non-NULL, is an integer constant that is to be added to
-   the this pointer (first parameter).  */
+   CALLEE.  DELTA is an integer constant that is to be added to the this
+   pointer (first parameter) to compensate for skipping a thunk adjustment.  */
 
 void
 cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee,
-                        tree delta)
+                        HOST_WIDE_INT delta)
 {
   edge->indirect_unknown_callee = 0;
   edge->indirect_info->thunk_delta = delta;
index 69bc79c..33b3167 100644 (file)
@@ -386,11 +386,11 @@ struct GTY(()) cgraph_indirect_call_info
   HOST_WIDE_INT anc_offset;
   /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set).  */
   HOST_WIDE_INT otr_token;
+  /* Delta by which must be added to this parameter to compensate for a skipped
+     this adjusting thunk.  */
+  HOST_WIDE_INT thunk_delta;
   /* Type of the object from OBJ_TYPE_REF_OBJECT. */
   tree otr_type;
-  /* Delta by which must be added to this parameter.  For polymorphic calls
-     only.  */
-  tree thunk_delta;
   /* Index of the parameter that is called.  */
   int param_index;
   /* ECF flags determined from the caller.  */
@@ -549,8 +549,9 @@ void cgraph_node_remove_callees (struct cgraph_node *node);
 struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
                                        struct cgraph_node *,
                                        gimple, gcov_type, int, int);
-struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, int,
-                                                gcov_type, int, int);
+struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple,
+                                                int, gcov_type, int, int);
+struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
 struct cgraph_node * cgraph_get_node (const_tree);
 struct cgraph_node * cgraph_get_node_or_alias (const_tree);
 struct cgraph_node * cgraph_node (tree);
@@ -578,7 +579,8 @@ struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type, i
                                        int, bool, VEC(cgraph_edge_p,heap) *);
 
 void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
-void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *, tree);
+void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *,
+                             HOST_WIDE_INT);
 
 struct cgraph_asm_node *cgraph_add_asm_node (tree);
 
index 013cf63..36ba75a 100644 (file)
@@ -2168,22 +2168,20 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
        }
     }
 
-  if (e->indirect_info && e->indirect_info->thunk_delta
-      && integer_nonzerop (e->indirect_info->thunk_delta)
+  if (e->indirect_info &&
+      e->indirect_info->thunk_delta != 0
       && (!e->callee->clone.combined_args_to_skip
          || !bitmap_bit_p (e->callee->clone.combined_args_to_skip, 0)))
     {
       if (cgraph_dump_file)
-       {
-         fprintf (cgraph_dump_file, "          Thunk delta is ");
-         print_generic_expr (cgraph_dump_file,
-                             e->indirect_info->thunk_delta, 0);
-         fprintf (cgraph_dump_file, "\n");
-       }
+       fprintf (cgraph_dump_file, "          Thunk delta is "
+                HOST_WIDE_INT_PRINT_DEC "\n", e->indirect_info->thunk_delta);
       gsi = gsi_for_stmt (e->call_stmt);
       gsi_computed = true;
-      gimple_adjust_this_by_delta (&gsi, e->indirect_info->thunk_delta);
-      e->indirect_info->thunk_delta = NULL_TREE;
+      gimple_adjust_this_by_delta (&gsi,
+                                  build_int_cst (sizetype,
+                                              e->indirect_info->thunk_delta));
+      e->indirect_info->thunk_delta = 0;
     }
 
   if (e->callee->clone.combined_args_to_skip)
index b6e3f37..f85a4ff 100644 (file)
@@ -1483,7 +1483,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, tree delta)
     return NULL;
   ipa_check_create_node_params ();
 
-  cgraph_make_edge_direct (ie, callee, delta);
+  cgraph_make_edge_direct (ie, callee, delta ? tree_low_cst (delta, 0) : 0);
   if (dump_file)
     {
       fprintf (dump_file, "ipa-prop: Discovered %s call to a known target "
@@ -2549,7 +2549,6 @@ ipa_write_indirect_edge_info (struct output_block *ob,
     {
       lto_output_sleb128_stream (ob->main_stream, ii->otr_token);
       lto_output_tree (ob, ii->otr_type, true);
-      lto_output_tree (ob, ii->thunk_delta, true);
     }
 }
 
@@ -2572,7 +2571,6 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
     {
       ii->otr_token = (HOST_WIDE_INT) lto_input_sleb128 (ib);
       ii->otr_type = lto_input_tree (ib, data_in);
-      ii->thunk_delta = lto_input_tree (ib, data_in);
     }
 }
 
index 76597a0..96697e4 100644 (file)
@@ -1605,6 +1605,18 @@ output_cgraph_opt_summary_p (struct cgraph_node *node)
           || node->clone.combined_args_to_skip);
 }
 
+/* Output optimization summary for EDGE to OB.  */
+static void
+output_edge_opt_summary (struct output_block *ob,
+                        struct cgraph_edge *edge)
+{
+  if (edge->indirect_info)
+    lto_output_sleb128_stream (ob->main_stream,
+                              edge->indirect_info->thunk_delta);
+  else
+    lto_output_sleb128_stream (ob->main_stream, 0);
+}
+
 /* Output optimization summary for NODE to OB.  */
 
 static void
@@ -1616,6 +1628,7 @@ output_node_opt_summary (struct output_block *ob,
   struct ipa_replace_map *map;
   struct bitpack_d bp;
   int i;
+  struct cgraph_edge *e;
 
   lto_output_uleb128_stream (ob->main_stream,
                             bitmap_count_bits (node->clone.args_to_skip));
@@ -1646,6 +1659,10 @@ output_node_opt_summary (struct output_block *ob,
       bp_pack_value (&bp, map->ref_p, 1);
       lto_output_bitpack (&bp);
     }
+  for (e = node->callees; e; e = e->next_callee)
+    output_edge_opt_summary (ob, e);
+  for (e = node->indirect_calls; e; e = e->next_callee)
+    output_edge_opt_summary (ob, e);
 }
 
 /* Output optimization summaries stored in callgraph.
@@ -1680,7 +1697,23 @@ output_cgraph_opt_summary (void)
   destroy_output_block (ob);
 }
 
-/* Input optimiation summary of NODE.  */
+/* Input optimisation summary of EDGE.  */
+
+static void
+input_edge_opt_summary (struct cgraph_edge *edge,
+                       struct lto_input_block *ib_main)
+{
+  HOST_WIDE_INT thunk_delta;
+  thunk_delta = lto_input_sleb128 (ib_main);
+  if (thunk_delta != 0)
+    {
+      gcc_assert (!edge->indirect_info);
+      edge->indirect_info = cgraph_allocate_init_indirect_info ();
+      edge->indirect_info->thunk_delta = thunk_delta;
+    }
+}
+
+/* Input optimisation summary of NODE.  */
 
 static void
 input_node_opt_summary (struct cgraph_node *node,
@@ -1691,6 +1724,7 @@ input_node_opt_summary (struct cgraph_node *node,
   int count;
   int bit;
   struct bitpack_d bp;
+  struct cgraph_edge *e;
 
   count = lto_input_uleb128 (ib_main);
   if (count)
@@ -1726,6 +1760,10 @@ input_node_opt_summary (struct cgraph_node *node,
       map->replace_p = bp_unpack_value (&bp, 1);
       map->ref_p = bp_unpack_value (&bp, 1);
     }
+  for (e = node->callees; e; e = e->next_callee)
+    input_edge_opt_summary (e, ib_main);
+  for (e = node->indirect_calls; e; e = e->next_callee)
+    input_edge_opt_summary (e, ib_main);
 }
 
 /* Read section in file FILE_DATA of length LEN with data DATA.  */
index df5ce01..86f8e3e 100644 (file)
@@ -1,3 +1,8 @@
+2011-01-03  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/46984
+       * g++.dg/ipa/pr46984.C: New test.
+
 2011-01-02  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/46408
diff --git a/gcc/testsuite/g++.dg/ipa/pr46984.C b/gcc/testsuite/g++.dg/ipa/pr46984.C
new file mode 100644 (file)
index 0000000..f7bb840
--- /dev/null
@@ -0,0 +1,62 @@
+// { dg-options "-O -fipa-cp -fno-early-inlining -flto" }
+// { dg-do run }
+
+extern "C" void abort ();
+
+class A
+{
+public:
+  virtual void foo () {abort();}
+};
+
+class B : public A
+{
+public:
+  int z;
+  virtual void foo () {abort();}
+};
+
+class C : public A
+{
+public:
+  void *a[32];
+  unsigned long b;
+  long c[32];
+
+  virtual void foo () {abort();}
+};
+
+class D : public C, public B
+{
+public:
+  D () : C(), B()
+  {
+    int i;
+    for (i = 0; i < 32; i++)
+      {
+       a[i] = (void *) 0;
+       c[i] = 0;
+      }
+    b = 0xaaaa;
+  }
+
+  virtual void foo ();
+};
+
+void D::foo()
+{
+  if (b != 0xaaaa)
+    abort();
+}
+
+static inline void bar (B &b)
+{
+  b.foo ();
+}
+
+int main()
+{
+  D d;
+  bar (d);
+  return 0;
+}