re PR tree-optimization/16876 (ICE on testcase with -O3 in fold-const)
2007-06-23 Richard Guenther <rguenther@suse.de> PR tree-optimization/16876 PR middle-end/29478 * tree.h (CALL_CANNOT_INLINE_P): New macro to access static_flag for CALL_EXPRs. * tree-inline.c (initialize_inlined_parameters): Do not call lang_hooks.tree_inlining.convert_parm_for_inlining. * cgraphbuild.c (initialize_inline_failed): Set inline failed reason for mismatched types. * gimplify.c (gimplify_call_expr): Verify the call expression arguments match the called function type signature. Otherwise mark the call expression to be not considered for inlining using CALL_CANNOT_INLINE_P flag. * ipa-inline.c (cgraph_mark_inline): Honor CALL_CANNOT_INLINE_P on the edges call expression. (cgraph_decide_inlining_of_small_function): Likewise. (cgraph_decide_inlining): Likewise. * c-objc-common.h (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): Remove define. * c-tree.h (c_convert_parm_for_inlining): Remove declaration. * c-typeck.c (c_convert_parm_for_inlining): Remove. * langhooks-def.h (lhd_tree_inlining_convert_parm_for_inlining): Remove declaration. (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): Remove define. * langhooks.c (lhd_tree_inlining_convert_parm_for_inlining): Remove. * langhooks.h (struct lang_hooks_for_tree_inlining): Remove convert_parm_for_inlining member. * gcc.dg/pr29254.c: The warning is bogus. * gcc.dg/warn-1.c: Likewise. * gcc.dg/assign-warn-3.c: Likewise. * gcc.dg/noncompile/pr16876.c: The testcase is bogus, remove. From-SVN: r125974
This commit is contained in:
parent
630ef467a8
commit
e36711f3cd
|
@ -1,3 +1,33 @@
|
|||
2007-06-23 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/16876
|
||||
PR middle-end/29478
|
||||
* tree.h (CALL_CANNOT_INLINE_P): New macro to access static_flag
|
||||
for CALL_EXPRs.
|
||||
* tree-inline.c (initialize_inlined_parameters): Do not call
|
||||
lang_hooks.tree_inlining.convert_parm_for_inlining.
|
||||
* cgraphbuild.c (initialize_inline_failed): Set inline failed
|
||||
reason for mismatched types.
|
||||
* gimplify.c (gimplify_call_expr): Verify the call expression
|
||||
arguments match the called function type signature. Otherwise
|
||||
mark the call expression to be not considered for inlining
|
||||
using CALL_CANNOT_INLINE_P flag.
|
||||
* ipa-inline.c (cgraph_mark_inline): Honor CALL_CANNOT_INLINE_P on the
|
||||
edges call expression.
|
||||
(cgraph_decide_inlining_of_small_function): Likewise.
|
||||
(cgraph_decide_inlining): Likewise.
|
||||
* c-objc-common.h (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
|
||||
Remove define.
|
||||
* c-tree.h (c_convert_parm_for_inlining): Remove declaration.
|
||||
* c-typeck.c (c_convert_parm_for_inlining): Remove.
|
||||
* langhooks-def.h (lhd_tree_inlining_convert_parm_for_inlining):
|
||||
Remove declaration.
|
||||
(LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): Remove define.
|
||||
* langhooks.c (lhd_tree_inlining_convert_parm_for_inlining):
|
||||
Remove.
|
||||
* langhooks.h (struct lang_hooks_for_tree_inlining): Remove
|
||||
convert_parm_for_inlining member.
|
||||
|
||||
2007-06-23 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
PR target/31152
|
||||
|
|
|
@ -89,9 +89,6 @@ extern void c_initialize_diagnostics (diagnostic_context *);
|
|||
#undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
|
||||
#define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
|
||||
c_disregard_inline_limits
|
||||
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
|
||||
c_convert_parm_for_inlining
|
||||
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
|
||||
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
|
||||
|
||||
|
|
|
@ -577,7 +577,6 @@ extern tree c_start_case (tree);
|
|||
extern void c_finish_case (tree);
|
||||
extern tree build_asm_expr (tree, tree, tree, tree, bool);
|
||||
extern tree build_asm_stmt (tree, tree);
|
||||
extern tree c_convert_parm_for_inlining (tree, tree, tree, int);
|
||||
extern int c_types_compatible_p (tree, tree);
|
||||
extern tree c_begin_compound_stmt (bool);
|
||||
extern tree c_end_compound_stmt (tree, bool);
|
||||
|
|
|
@ -4247,37 +4247,6 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
|
|||
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Convert VALUE for assignment into inlined parameter PARM. ARGNUM
|
||||
is used for error and warning reporting and indicates which argument
|
||||
is being processed. */
|
||||
|
||||
tree
|
||||
c_convert_parm_for_inlining (tree parm, tree value, tree fn, int argnum)
|
||||
{
|
||||
tree ret, type;
|
||||
|
||||
/* If FN was prototyped at the call site, the value has been converted
|
||||
already in convert_arguments.
|
||||
However, we might see a prototype now that was not in place when
|
||||
the function call was seen, so check that the VALUE actually matches
|
||||
PARM before taking an early exit. */
|
||||
if (!value
|
||||
|| (TYPE_ARG_TYPES (TREE_TYPE (fn))
|
||||
&& (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
|
||||
== TYPE_MAIN_VARIANT (TREE_TYPE (value)))))
|
||||
return value;
|
||||
|
||||
type = TREE_TYPE (parm);
|
||||
ret = convert_for_assignment (type, value,
|
||||
ic_argpass_nonproto, fn,
|
||||
fn, argnum);
|
||||
if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
|
||||
&& INTEGRAL_TYPE_P (type)
|
||||
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
|
||||
ret = default_conversion (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If VALUE is a compound expr all of whose expressions are constant, then
|
||||
return its value. Otherwise, return error_mark_node.
|
||||
|
|
|
@ -99,6 +99,8 @@ initialize_inline_failed (struct cgraph_node *node)
|
|||
"considered for inlining");
|
||||
else if (!node->local.inlinable)
|
||||
e->inline_failed = N_("function not inlinable");
|
||||
else if (CALL_CANNOT_INLINE_P (e->call_stmt))
|
||||
e->inline_failed = N_("mismatched arguments");
|
||||
else
|
||||
e->inline_failed = N_("function not considered for inlining");
|
||||
}
|
||||
|
|
|
@ -2058,7 +2058,7 @@ gimplify_arg (tree *expr_p, tree *pre_p)
|
|||
static enum gimplify_status
|
||||
gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
|
||||
{
|
||||
tree decl;
|
||||
tree decl, parms, p;
|
||||
enum gimplify_status ret;
|
||||
int i, nargs;
|
||||
|
||||
|
@ -2124,6 +2124,48 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
|
|||
|
||||
nargs = call_expr_nargs (*expr_p);
|
||||
|
||||
/* Get argument types for verification. */
|
||||
decl = get_callee_fndecl (*expr_p);
|
||||
parms = NULL_TREE;
|
||||
if (decl)
|
||||
parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
|
||||
else if (POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_FN (*expr_p))))
|
||||
parms = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (*expr_p))));
|
||||
|
||||
/* Verify if the type of the argument matches that of the function
|
||||
declaration. If we cannot verify this or there is a mismatch,
|
||||
mark the call expression so it doesn't get inlined later. */
|
||||
if (parms)
|
||||
{
|
||||
for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p))
|
||||
if (!p
|
||||
|| TREE_VALUE (p) == error_mark_node
|
||||
|| CALL_EXPR_ARG (*expr_p, i) == error_mark_node
|
||||
|| !lang_hooks.types_compatible_p
|
||||
(TREE_TYPE (CALL_EXPR_ARG (*expr_p, i)), TREE_VALUE (p)))
|
||||
{
|
||||
CALL_CANNOT_INLINE_P (*expr_p) = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (decl && DECL_ARGUMENTS (decl))
|
||||
{
|
||||
for (i = 0, p = DECL_ARGUMENTS (decl); i < nargs;
|
||||
i++, p = TREE_CHAIN (p))
|
||||
if (!p
|
||||
|| p == error_mark_node
|
||||
|| CALL_EXPR_ARG (*expr_p, i) == error_mark_node
|
||||
|| !lang_hooks.types_compatible_p
|
||||
(TREE_TYPE (CALL_EXPR_ARG (*expr_p, i)), TREE_TYPE (p)))
|
||||
{
|
||||
CALL_CANNOT_INLINE_P (*expr_p) = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nargs != 0)
|
||||
CALL_CANNOT_INLINE_P (*expr_p) = 1;
|
||||
|
||||
/* Finally, gimplify the function arguments. */
|
||||
for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
|
||||
PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
|
||||
PUSH_ARGS_REVERSED ? i-- : i++)
|
||||
|
|
|
@ -288,22 +288,21 @@ cgraph_mark_inline (struct cgraph_edge *edge)
|
|||
struct cgraph_node *to = edge->caller;
|
||||
struct cgraph_node *what = edge->callee;
|
||||
struct cgraph_edge *e, *next;
|
||||
int times = 0;
|
||||
|
||||
/* Look for all calls, mark them inline and clone recursively
|
||||
all inlined functions. */
|
||||
for (e = what->callers; e; e = next)
|
||||
{
|
||||
next = e->next_caller;
|
||||
if (e->caller == to && e->inline_failed)
|
||||
if (e->caller == to && e->inline_failed
|
||||
&& !CALL_CANNOT_INLINE_P (e->call_stmt))
|
||||
{
|
||||
cgraph_mark_inline_edge (e, true);
|
||||
if (e == edge)
|
||||
edge = next;
|
||||
times++;
|
||||
}
|
||||
}
|
||||
gcc_assert (times);
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
|
@ -885,7 +884,7 @@ cgraph_decide_inlining_of_small_functions (void)
|
|||
}
|
||||
gcc_assert (edge->aux);
|
||||
edge->aux = NULL;
|
||||
if (!edge->inline_failed)
|
||||
if (!edge->inline_failed || CALL_CANNOT_INLINE_P (edge->call_stmt))
|
||||
continue;
|
||||
|
||||
/* When not having profile info ready we don't weight by any way the
|
||||
|
@ -1076,7 +1075,7 @@ cgraph_decide_inlining (void)
|
|||
for (e = node->callers; e; e = next)
|
||||
{
|
||||
next = e->next_caller;
|
||||
if (!e->inline_failed)
|
||||
if (!e->inline_failed || CALL_CANNOT_INLINE_P (e->call_stmt))
|
||||
continue;
|
||||
if (cgraph_recursive_inlining_p (e->caller, e->callee,
|
||||
&e->inline_failed))
|
||||
|
|
|
@ -73,7 +73,6 @@ extern tree lhd_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
|
|||
extern int lhd_tree_inlining_cannot_inline_tree_fn (tree *);
|
||||
extern int lhd_tree_inlining_disregard_inline_limits (tree);
|
||||
extern int lhd_tree_inlining_auto_var_in_fn_p (tree, tree);
|
||||
extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree, int);
|
||||
extern void lhd_initialize_diagnostics (struct diagnostic_context *);
|
||||
extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
|
||||
|
||||
|
@ -145,8 +144,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
|
|||
lhd_tree_inlining_auto_var_in_fn_p
|
||||
#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P \
|
||||
hook_bool_tree_tree_false
|
||||
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
|
||||
lhd_tree_inlining_convert_parm_for_inlining
|
||||
|
||||
#define LANG_HOOKS_TREE_INLINING_INITIALIZER { \
|
||||
LANG_HOOKS_TREE_INLINING_WALK_SUBTREES, \
|
||||
|
@ -154,7 +151,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
|
|||
LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS, \
|
||||
LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P, \
|
||||
LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P, \
|
||||
LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
|
||||
}
|
||||
|
||||
#define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR lhd_callgraph_analyze_expr
|
||||
|
|
|
@ -330,18 +330,6 @@ lhd_tree_inlining_auto_var_in_fn_p (tree var, tree fn)
|
|||
|| TREE_CODE (var) == RESULT_DECL));
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.convert_parm_for_inlining performs any
|
||||
language-specific conversion before assigning VALUE to PARM. */
|
||||
|
||||
tree
|
||||
lhd_tree_inlining_convert_parm_for_inlining (tree parm ATTRIBUTE_UNUSED,
|
||||
tree value,
|
||||
tree fndecl ATTRIBUTE_UNUSED,
|
||||
int argnum ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_dump.dump_tree: Dump language-specific parts of tree
|
||||
nodes. Returns nonzero if it does not want the usual dumping of the
|
||||
second argument. */
|
||||
|
|
|
@ -42,7 +42,6 @@ struct lang_hooks_for_tree_inlining
|
|||
int (*disregard_inline_limits) (tree);
|
||||
int (*auto_var_in_fn_p) (tree, tree);
|
||||
bool (*var_mod_type_p) (tree, tree);
|
||||
tree (*convert_parm_for_inlining) (tree, tree, tree, int);
|
||||
};
|
||||
|
||||
struct lang_hooks_for_callgraph
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2007-06-23 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/16876
|
||||
PR middle-end/29478
|
||||
* gcc.dg/pr29254.c: The warning is bogus.
|
||||
* gcc.dg/warn-1.c: Likewise.
|
||||
* gcc.dg/assign-warn-3.c: Likewise.
|
||||
* gcc.dg/noncompile/pr16876.c: The testcase is bogus, remove.
|
||||
|
||||
2007-06-23 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* gcc.c-torture/execute/20070623-1.c: New.
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
/* This is valid to execute, so maybe shouldn't warn at all. */
|
||||
void f0(x) signed char *x; { }
|
||||
void g0(unsigned char *x) { f0(x); } /* { dg-warning "warning: pointer targets in passing argument 1 of 'f0' differ in signedness" } */
|
||||
void g0(unsigned char *x) { f0(x); } /* { dg-bogus "warning: pointer targets in passing argument 1 of 'f0' differ in signedness" } */
|
||||
|
||||
/* This is undefined on execution but still must compile. */
|
||||
void f1(x) int *x; { }
|
||||
void g1(unsigned int *x) { f1(x); } /* { dg-warning "warning: pointer targets in passing argument 1 of 'f1' differ in signedness" } */
|
||||
void g1(unsigned int *x) { f1(x); } /* { dg-bogus "warning: pointer targets in passing argument 1 of 'f1' differ in signedness" } */
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/* { dg-options "-O -finline-functions" } */
|
||||
|
||||
static void g();
|
||||
struct bigstack {
|
||||
char space[4096];
|
||||
};
|
||||
|
||||
|
||||
void f() {
|
||||
g(0); /* { dg-error "incompatible type for argument 1 of 'g'" } */
|
||||
}
|
||||
|
||||
static void g(struct bigstack bstack) {
|
||||
g(bstack);
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3 -Werror" } */
|
||||
/* { dg-message "warnings being treated as errors" "" {target "*-*-*"} 0 } */
|
||||
|
||||
list_compare (int * list1)
|
||||
{
|
||||
|
@ -18,5 +17,5 @@ value_compare (int * a)
|
|||
|
||||
func2 (const int * fb)
|
||||
{
|
||||
func1 ((int *) fb); /* { dg-error "discards qualifiers" } */
|
||||
func1 ((int *) fb); /* { dg-bogus "discards qualifiers" } */
|
||||
}
|
||||
|
|
|
@ -12,5 +12,5 @@ void bar (void)
|
|||
{
|
||||
void *vp;
|
||||
|
||||
foo (vp); /* { dg-warning "passing argument 1 of" } */
|
||||
foo (vp); /* { dg-bogus "passing argument 1 of" } */
|
||||
}
|
||||
|
|
|
@ -1451,7 +1451,6 @@ initialize_inlined_parameters (copy_body_data *id, tree exp,
|
|||
tree a;
|
||||
tree p;
|
||||
tree vars = NULL_TREE;
|
||||
int argnum = 0;
|
||||
call_expr_arg_iterator iter;
|
||||
tree static_chain = CALL_EXPR_STATIC_CHAIN (exp);
|
||||
|
||||
|
@ -1462,17 +1461,7 @@ initialize_inlined_parameters (copy_body_data *id, tree exp,
|
|||
equivalent VAR_DECL, appropriately initialized. */
|
||||
for (p = parms, a = first_call_expr_arg (exp, &iter); p;
|
||||
a = next_call_expr_arg (&iter), p = TREE_CHAIN (p))
|
||||
{
|
||||
tree value;
|
||||
|
||||
++argnum;
|
||||
|
||||
/* Find the initializer. */
|
||||
value = lang_hooks.tree_inlining.convert_parm_for_inlining
|
||||
(p, a, fn, argnum);
|
||||
|
||||
setup_one_parameter (id, p, value, fn, bb, &vars);
|
||||
}
|
||||
setup_one_parameter (id, p, a, fn, bb, &vars);
|
||||
|
||||
/* Initialize the static chain. */
|
||||
p = DECL_STRUCT_FUNCTION (fn)->static_chain_decl;
|
||||
|
|
|
@ -449,7 +449,10 @@ struct gimple_stmt GTY(())
|
|||
POINTER_TYPE, REFERENCE_TYPE
|
||||
MOVE_NONTEMPORAL in
|
||||
GIMPLE_MODIFY_STMT
|
||||
CASE_HIGH_SEEN in CASE_LABEL_EXPR
|
||||
CASE_HIGH_SEEN in
|
||||
CASE_LABEL_EXPR
|
||||
CALL_CANNOT_INLINE_P in
|
||||
CALL_EXPR
|
||||
|
||||
public_flag:
|
||||
|
||||
|
@ -1144,6 +1147,9 @@ extern void omp_clause_range_check_failed (const tree, const char *, int,
|
|||
#define CASE_HIGH_SEEN(NODE) \
|
||||
(CASE_LABEL_EXPR_CHECK (NODE)->base.static_flag)
|
||||
|
||||
/* Used to mark a CALL_EXPR as not suitable for inlining. */
|
||||
#define CALL_CANNOT_INLINE_P(NODE) ((NODE)->base.static_flag)
|
||||
|
||||
/* In an expr node (usually a conversion) this means the node was made
|
||||
implicitly and should not lead to any sort of warning. In a decl node,
|
||||
warnings concerning the decl should be suppressed. This is used at
|
||||
|
|
Loading…
Reference in New Issue