#include <string.h>
#include <assert.h>
+#include "debug.h"
#include "iroptimize.h"
#include "scalar_replace.h"
#include "array.h"
#include "irhooks.h"
#include "xmalloc.h"
+DEBUG_ONLY(static firm_dbg_module_t *dbg);
+
/**
* the environment for collecting data
*/
exchange(p, new_r_Bad(irg));
/* we might generate an endless loop, so add
- * the block to the keep-alive list */
+ * the block to the keep-alive list */
add_End_keepalive(get_irg_end(irg), block);
}
* @return non-zero if it's ok to do tail recursion
*/
static int check_lifetime_of_locals(ir_graph *irg) {
- ir_node *irg_frame = get_irg_frame(irg);
+ ir_node *irg_frame, *irg_val_param_base;
int i;
- if (get_irg_outs_state(irg) != outs_consistent)
- compute_irg_outs(irg);
-
+ irg_frame = get_irg_frame(irg);
for (i = get_irn_n_outs(irg_frame) - 1; i >= 0; --i) {
ir_node *succ = get_irn_out(irg_frame, i);
if (is_Sel(succ) && is_address_taken(succ))
return 0;
}
+
+ /* Check if we have compound arguments.
+ For now, we cannot handle them, */
+ irg_val_param_base = get_irg_value_param_base(irg);
+ if (get_irn_n_outs(irg_val_param_base) > 0)
+ return 0;
+
return 1;
}
ir_node *rets = NULL;
ir_type *mtd_type, *call_type;
- if (! get_opt_tail_recursion() || ! get_opt_optimize())
- return 0;
+ assure_irg_outs(irg);
if (! check_lifetime_of_locals(irg))
return 0;
if (! is_Call(call))
continue;
+ /* the call must be in the same block as the return */
+ if (get_nodes_block(call) != get_nodes_block(ret))
+ continue;
+
/* check if it's a recursive call */
call_ptr = get_Call_ptr(call);
- if (get_irn_op(call_ptr) != op_SymConst)
- continue;
-
- if (get_SymConst_kind(call_ptr) != symconst_addr_ent)
+ if (! is_SymConst(call_ptr) || get_SymConst_kind(call_ptr) != symconst_addr_ent)
continue;
ent = get_SymConst_entity(call_ptr);
continue;
/*
- * Check, that the types match. At least in C
- * this might fail.
- */
+ * Check, that the types match. At least in C
+ * this might fail.
+ */
mtd_type = get_entity_type(ent);
call_type = get_Call_type(call);
dump_type(mtd_type);
dump_type(call_type);
#endif
- return 0;
+ continue;
}
/* here, we have found a call */
if (! n_tail_calls)
return 0;
- if (get_opt_tail_recursion_verbose() && get_firm_verbosity() > 1)
- printf(" Performing tail recursion for graph %s and %d Calls\n",
- get_entity_ld_name(get_irg_entity(irg)), n_tail_calls);
+ DB((dbg, LEVEL_2, " Performing tail recursion for graph %s and %d Calls\n",
+ get_entity_ld_name(get_irg_entity(irg)), n_tail_calls));
hook_tail_rec(irg, n_tail_calls);
do_opt_tail_rec(irg, rets, n_tail_calls);
int n_opt_applications = 0;
ir_graph *irg;
- if (! get_opt_tail_recursion() || ! get_opt_optimize())
- return;
+ FIRM_DBG_REGISTER(dbg, "firm.opt.tailrec");
for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
irg = get_irp_irg(i);
+ current_ir_graph = irg;
+
if (opt_tail_rec_irg(irg))
++n_opt_applications;
}
- if (get_opt_tail_recursion_verbose())
- printf("Performed tail recursion for %d of %d graphs\n", n_opt_applications, get_irp_n_irgs());
+ DB((dbg, LEVEL_1, "Performed tail recursion for %d of %d graphs\n",
+ n_opt_applications, get_irp_n_irgs()));
}