On Sat, Nov 5, 2011 at 07:02, Iain Sandoe
<[email protected]> 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