Hi,

As discussed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69708 and corresponding mailing list discussion, IPA CP is not detecting a jump-function with the sq function as value.


static int sq(int x) {
  return x * x;
}

static const F f = {sq};
...
dosomething (g(f, x));
...

I added a check at determine_locally_known_aggregate_parts to detect this. This fixes the testcase and passes x86-64-linux-gnu lto bootstrap and regression testing with no new regression. Does this look sensible place to fix this?

Thanks,
Kugan

gcc/ChangeLog:



2016-03-01  Kugan Vivekanandarajah  <kug...@linaro.org>



        * ipa-prop.c (determine_locally_known_aggregate_parts): Determine jump

         function for static constant initialization.

diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 72c2fed..22da097 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1562,6 +1562,57 @@ determine_locally_known_aggregate_parts (gcall *call, 
tree arg,
       jfunc->agg.by_ref = by_ref;
       build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
     }
+  else if ((TREE_CODE (arg) == VAR_DECL)
+          && is_global_var (arg))
+    {
+      /* PR69708:  Figure out aggregate jump-function with constant init
+        value.  */
+      struct ipa_known_agg_contents_list *n, **p;
+      HOST_WIDE_INT offset = 0, size, max_size;
+      varpool_node *node = varpool_node::get (arg);
+      if (node
+         && DECL_INITIAL (node->decl)
+         && TREE_READONLY (node->decl)
+         && TREE_CODE (DECL_INITIAL (node->decl)) == CONSTRUCTOR)
+       {
+         tree exp = DECL_INITIAL (node->decl);
+         unsigned HOST_WIDE_INT ix;
+         tree field, val;
+         bool reverse;
+         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), ix, field, val)
+           {
+             bool already_there = false;
+             if (!field)
+               break;
+             get_ref_base_and_extent (field, &offset, &size,
+                                      &max_size, &reverse);
+             if (max_size == -1
+                 || max_size != size)
+               break;
+             p = get_place_in_agg_contents_list (&list, offset, size,
+                                                 &already_there);
+             if (!p)
+               break;
+             n = XALLOCA (struct ipa_known_agg_contents_list);
+             n->size = size;
+             n->offset = offset;
+             if (is_gimple_ip_invariant (val))
+               {
+                 n->constant = val;
+                 const_count++;
+               }
+             else
+               n->constant = NULL_TREE;
+             n->next = *p;
+             *p = n;
+           }
+       }
+      if (const_count)
+       {
+         jfunc->agg.by_ref = by_ref;
+         build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
+       }
+    }
 }
 
 static tree

Reply via email to