This is a simpel and nice fix, but could suppress some CP opportunities for
self-recursive call.  Using the test case as example, the first should be a
for-all-context clone, and the call "recur_fn (i, 1, depth + 1)" is replaced 
with
a newly created recursive node. Thus, in the next round of CP iteration, the
way to do CP for the 2nd arugment "1" is blocked, because its coming edge
can not pass check by cgraph_edge_brings_value_p().

+__attribute__((noinline)) static int recur_fn (int i, int j, int depth)
+{
+   if (depth > 10)
+     return 1;
+
+   data[i + j]++;
+
+   if (depth & 3)
+     recur_fn (i, 1, depth + 1);
+   else
+     recur_fn (i, j & 1, depth + 1);
+
+   foo();
+
+   return i + j;
+}
+
+int caller (int v, int depth)
+{
+  recur_fn (1, v, depth);
+
+  return 0;
+}


>However, I believe that his approach mostly papers over a bug that
>happens earlier, specifically that cgraph_edge_brings_value_p returned
>true for the self-recursive edge from all-context clone to itself, even
>though when evaluating the second argument.  We assume that all context
>clones get at least as many constants as any other potential clone, but
>that does not work for self-recursive edges with pass-through parameters
>that that just pass along the received constant.

The following check on value in cgraph_edge_brings_value_p could ensure
whether the value can arrive the dest node or not. If the value is a constant
without source, as above example "1", this is allowed. Otherwise, code snippet
enclosed by "if (caller_info->ipcp_orig_node)" could capture for-all-context 
clone.

Thanks,
Feng

Reply via email to