diff options
author | Martin Jambor <mjambor@suse.cz> | 2010-01-14 19:00:34 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2010-01-14 19:00:34 +0100 |
commit | 2f3cdcf50295a3888012b66a52b709a7f21d2f25 (patch) | |
tree | e67d8e3c3b5b8bd2f68e5f4e63f4b36f8e354636 /gcc/tree-sra.c | |
parent | 7767706d58eecfccd3805fd9e59fdb5e3b557611 (diff) | |
download | gcc-2f3cdcf50295a3888012b66a52b709a7f21d2f25.zip gcc-2f3cdcf50295a3888012b66a52b709a7f21d2f25.tar.gz gcc-2f3cdcf50295a3888012b66a52b709a7f21d2f25.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 4797667..dd62cc5 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -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; |