re PR tree-optimization/42706 (ICE in gimple_op, at gimple.h:1634, (IPA SRA))

2010-01-14  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/42706
	* tree-sra.c (encountered_recursive_call): New variable.
	(encountered_unchangable_recursive_call): Likewise.
	(sra_initialize): Initialize both new variables.
	(callsite_has_enough_arguments_p): New function.
	(scan_function): Call decl and flags check only for IPA-SRA, check
	whether there is a recursive call and whether it has enough arguments.
	(all_callers_have_enough_arguments_p): New function.
	(convert_callers): Look for recursive calls only when
	encountered_recursive_call is set.
	(ipa_early_sra): Bail out either if
	!all_callers_have_enough_arguments_p or
	encountered_unchangable_recursive_call.

	* testsuite/gcc.dg/ipa/pr42706.c: New testcase.

From-SVN: r155911
This commit is contained in:
Martin Jambor 2010-01-14 19:00:34 +01:00 committed by Martin Jambor
parent 7767706d58
commit 2f3cdcf502
4 changed files with 115 additions and 6 deletions

View File

@ -1,3 +1,19 @@
2010-01-14 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/42706
* tree-sra.c (encountered_recursive_call): New variable.
(encountered_unchangable_recursive_call): Likewise.
(sra_initialize): Initialize both new variables.
(callsite_has_enough_arguments_p): New function.
(scan_function): Call decl and flags check only for IPA-SRA, check
whether there is a recursive call and whether it has enough arguments.
(all_callers_have_enough_arguments_p): New function.
(convert_callers): Look for recursive calls only when
encountered_recursive_call is set.
(ipa_early_sra): Bail out either if
!all_callers_have_enough_arguments_p or
encountered_unchangable_recursive_call.
2010-01-14 Alexander Monakov <amonakov@ispras.ru>
* sel-sched.c: Add 2010 to copyright years.

View File

@ -1,3 +1,8 @@
2010-01-14 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/42706
* gcc.dg/ipa/pr42706.c: New testcase.
2010-01-14 H.J. Lu <hongjiu.lu@intel.com>
* g++.dg/graphite/pr42681.C (size_t): Use __SIZE_TYPE__.
@ -5,7 +10,7 @@
2010-01-14 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/42714
* gcc/testsuite/g++.dg/torture/pr42714.C: New test.
* g++.dg/torture/pr42714.C: New test.
2010-01-14 Alexander Monakov <amonakov@ispras.ru>

View File

@ -0,0 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fno-early-inlining -fipa-sra" } */
struct S
{
float red;
int green;
void *blue;
};
extern int gi;
static int foo ();
int
bar (void)
{
foo ();
return 0;
}
static int
foo (struct S s)
{
gi = s.green;
return 0;
}

View File

@ -258,6 +258,13 @@ static int func_param_count;
__builtin_apply_args. */
static bool encountered_apply_args;
/* Set by scan_function when it finds a recursive call. */
static bool encountered_recursive_call;
/* Set by scan_function when it finds a recursive call with less actual
arguments than formal parameters.. */
static bool encountered_unchangable_recursive_call;
/* This is a table in which for each basic block and parameter there is a
distance (offset + size) in that parameter which is dereferenced and
accessed in that BB. */
@ -545,6 +552,8 @@ sra_initialize (void)
base_access_vec = pointer_map_create ();
memset (&sra_stats, 0, sizeof (sra_stats));
encountered_apply_args = false;
encountered_recursive_call = false;
encountered_unchangable_recursive_call = false;
}
/* Hook fed to pointer_map_traverse, deallocate stored vectors. */
@ -944,6 +953,14 @@ asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
return false;
}
/* Return true iff callsite CALL has at least as many actual arguments as there
are formal parameters of the function currently processed by IPA-SRA. */
static inline bool
callsite_has_enough_arguments_p (gimple call)
{
return gimple_call_num_args (call) >= (unsigned) func_param_count;
}
/* Scan function and look for interesting statements. Return true if any has
been found or processed, as indicated by callbacks. SCAN_EXPR is a callback
@ -1014,15 +1031,24 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
any |= scan_expr (argp, &gsi, false, data);
}
if (analysis_stage)
if (analysis_stage && sra_mode == SRA_MODE_EARLY_IPA)
{
tree dest = gimple_call_fndecl (stmt);
int flags = gimple_call_flags (stmt);
if (dest
&& DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
encountered_apply_args = true;
if (dest)
{
if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
encountered_apply_args = true;
if (cgraph_get_node (dest)
== cgraph_get_node (current_function_decl))
{
encountered_recursive_call = true;
if (!callsite_has_enough_arguments_p (stmt))
encountered_unchangable_recursive_call = true;
}
}
if (final_bbs
&& (flags & (ECF_CONST | ECF_PURE)) == 0)
@ -3780,6 +3806,21 @@ sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
}
}
/* Return true iff all callers have at least as many actual arguments as there
are formal parameters in the current function. */
static bool
all_callers_have_enough_arguments_p (struct cgraph_node *node)
{
struct cgraph_edge *cs;
for (cs = node->callers; cs; cs = cs->next_caller)
if (!callsite_has_enough_arguments_p (cs->call_stmt))
return false;
return true;
}
/* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
static void
@ -3815,6 +3856,10 @@ convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
BITMAP_FREE (recomputed_callers);
current_function_decl = old_cur_fndecl;
if (!encountered_recursive_call)
return;
FOR_EACH_BB (this_block)
{
gimple_stmt_iterator gsi;
@ -3927,6 +3972,14 @@ ipa_early_sra (void)
goto simple_out;
}
if (!all_callers_have_enough_arguments_p (node))
{
if (dump_file)
fprintf (dump_file, "There are callers with insufficient number of "
"arguments.\n");
goto simple_out;
}
bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
func_param_count
* last_basic_block_for_function (cfun));
@ -3941,6 +3994,14 @@ ipa_early_sra (void)
goto out;
}
if (encountered_unchangable_recursive_call)
{
if (dump_file)
fprintf (dump_file, "Function calls itself with insufficient "
"number of arguments.\n");
goto out;
}
adjustments = analyze_all_param_acesses ();
if (!adjustments)
goto out;