+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.
__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. */
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. */
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
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)
}
}
+/* 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
BITMAP_FREE (recomputed_callers);
current_function_decl = old_cur_fndecl;
+
+ if (!encountered_recursive_call)
+ return;
+
FOR_EACH_BB (this_block)
{
gimple_stmt_iterator gsi;
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));
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;