On Sat, Nov 5, 2011 at 07:02, Iain Sandoe
<develo...@sandoe-acoustics.co.uk> wrote:
>
> On 28 Oct 2011, at 13:57, Richard Guenther wrote:
>
>>
>> We fail to keep the cannot-inline flag up-to-date when turning
>> indirect to direct calls.  The following patch arranges to do
>> this during statement folding (which should always be called
>> when that happens).  It also makes sure to copy the updated flag
>> to the edge when iterating early inlining.
>
> This: http://gcc.gnu.org/ml/gcc-cvs/2011-11/msg00046.html
>
> regresses:
> acats/c740203a (x86-64-darwin10)
> gnat/aliasing3.adb  (m64 i486-darwin9 and x86-64-darwin10)
> ... don't know about other platforms at present.

I am also seeing a regression in some C++ code, specifically, this
call to gimple_call_set_cannot_inline() is not updating the
call_stmt_cannot_inline_p field in the corresponding call graph edge

!   if (callee
!       && !gimple_check_call_matching_types (stmt, callee))
!     gimple_call_set_cannot_inline (stmt, true);

In this code I'm trying to build, we fail the assertion in can_inline_edge_p:

  /* Be sure that the cannot_inline_p flag is up to date.  */
  gcc_checking_assert (!e->call_stmt
                       || (gimple_call_cannot_inline_p (e->call_stmt)
                           == e->call_stmt_cannot_inline_p)

because gimple_fold_call did not update the inline flag on the edge.

I grepped for calls to gimple_call_set_cannot_inline() and we don't
always bother to update the corresponding edge.  I think the safest
approach here would be to make sure that we always do (patch below).

Thoughts?


Diego.

diff --git a/gcc/gimple.c b/gcc/gimple.c
index 071c651..e2b082a 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -5558,4 +5558,31 @@ gimple_asm_clobbers_memory_p (const_gimple stmt)

   return false;
 }
+
+
+/* Set the inlinable status of GIMPLE_CALL S to INLINABLE_P.  */
+
+void
+gimple_call_set_cannot_inline (gimple s, bool inlinable_p)
+{
+  bool prev_inlinable_p;
+
+  GIMPLE_CHECK (s, GIMPLE_CALL);
+
+  prev_inlinable_p = gimple_call_cannot_inline_p (s);
+
+  if (inlinable_p)
+    s->gsbase.subcode |= GF_CALL_CANNOT_INLINE;
+  else
+    s->gsbase.subcode &= ~GF_CALL_CANNOT_INLINE;
+
+  if (prev_inlinable_p != inlinable_p)
+    {
+      struct cgraph_node *n = cgraph_get_node (current_function_decl);
+      struct cgraph_edge *e = cgraph_edge (n, s);
+      if (e)
+       e->call_stmt_cannot_inline_p = inlinable_p;
+    }
+}
+
 #include "gt-gimple.h"
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 8536c70..df31bf3 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1035,6 +1035,7 @@ extern bool walk_stmt_load_store_ops (gimple, void *,
 extern bool gimple_ior_addresses_taken (bitmap, gimple);
 extern bool gimple_call_builtin_p (gimple, enum built_in_function);
 extern bool gimple_asm_clobbers_memory_p (const_gimple);
+extern void gimple_call_set_cannot_inline (gimple, bool);

 /* In gimplify.c  */
 extern tree create_tmp_var_raw (tree, const char *);
@@ -2343,19 +2344,6 @@ gimple_call_tail_p (gimple s)
 }


-/* Set the inlinable status of GIMPLE_CALL S to INLINABLE_P.  */
-
-static inline void
-gimple_call_set_cannot_inline (gimple s, bool inlinable_p)
-{
-  GIMPLE_CHECK (s, GIMPLE_CALL);
-  if (inlinable_p)
-    s->gsbase.subcode |= GF_CALL_CANNOT_INLINE;
-  else
-    s->gsbase.subcode &= ~GF_CALL_CANNOT_INLINE;
-}
-
-
 /* Return true if GIMPLE_CALL S cannot be inlined.  */

 static inline bool

Reply via email to