static heights_t *ir_heights;
-/* Flag: if set, try to omit the frame pointer if called by the backend */
+/** Flag: if set, try to omit the frame pointer in all routines. */
static int be_omit_fp = 1;
+/** Flag: if set, try to omit the frame pointer in leaf routines only. */
+static int be_omit_leaf_fp = 1;
+
/*
_ ____ ___ ____ _ _ _ _
/ \ | __ )_ _| / ___|__ _| | | |__ __ _ ___| | _____
call->cb = NULL;
call->cls_addr = cls_addr;
- call->flags.bits.try_omit_fp = be_omit_fp;
+ call->flags.bits.try_omit_fp = be_omit_fp | be_omit_leaf_fp;
return call;
}
ir_node *new_alloc, *size, *addr, *ins[2];
unsigned stack_alignment;
- if (get_Alloc_where(alloc) != stack_alloc) {
- assert(0);
- return alloc;
- }
+ assert(get_Alloc_where(alloc) == stack_alloc);
block = get_nodes_block(alloc);
irg = get_irn_irg(block);
ir_node *irn = get_edge_src_irn(edge);
assert(is_Proj(irn));
- switch(get_Proj_proj(irn)) {
+ switch (get_Proj_proj(irn)) {
case pn_Alloc_M:
alloc_mem = irn;
break;
dbg = get_irn_dbg_info(alloc);
/* we might need to multiply the size with the element size */
- if(type != get_unknown_type() && get_type_size_bytes(type) != 1) {
+ if (type != firm_unknown_type && get_type_size_bytes(type) != 1) {
tarval *tv = new_tarval_from_long(get_type_size_bytes(type),
mode_Iu);
ir_node *cnst = new_rd_Const(dbg, irg, block, mode_Iu, tv);
unsigned stack_alignment;
dbg_info *dbg;
- if (get_Free_where(free) != stack_alloc) {
- assert(0);
- return free;
- }
+ assert(get_Free_where(free) == stack_alloc);
block = get_nodes_block(free);
irg = get_irn_irg(block);
dbg = get_irn_dbg_info(free);
/* we might need to multiply the size with the element size */
- if(type != get_unknown_type() && get_type_size_bytes(type) != 1) {
+ if (type != firm_unknown_type && get_type_size_bytes(type) != 1) {
tarval *tv = new_tarval_from_long(get_type_size_bytes(type), mode_Iu);
ir_node *cnst = new_rd_Const(dbg, irg, block, mode_Iu, tv);
ir_node *mul = new_rd_Mul(dbg, irg, block, get_Free_size(free),
ir_node *irn;
int n;
- for(irn = get_irn_link(bl), n = 0; irn; irn = get_irn_link(irn), ++n)
+ for (irn = get_irn_link(bl), n = 0; irn; irn = get_irn_link(irn), ++n)
obstack_ptr_grow(&env->obst, irn);
/* If there were call nodes in the block. */
- if(n > 0) {
+ if (n > 0) {
ir_node *keep;
ir_node **nodes;
int i;
/* order the call nodes according to data dependency */
qsort(nodes, n, sizeof(nodes[0]), cmp_call_dependency);
- for(i = n - 1; i >= 0; --i) {
+ for (i = n - 1; i >= 0; --i) {
ir_node *irn = nodes[i];
DBG((env->dbg, LEVEL_3, "\tprocessing call %+F\n", irn));
- switch(get_irn_opcode(irn)) {
+ switch (get_irn_opcode(irn)) {
case iro_Call:
+ if (! be_omit_fp) {
+ /* The stack pointer will be modified due to a call. */
+ env->call->flags.bits.try_omit_fp = 0;
+ }
curr_sp = adjust_call(env, irn, curr_sp);
break;
case iro_Alloc:
- curr_sp = adjust_alloc(env, irn, curr_sp);
+ if (get_Alloc_where(irn) == stack_alloc)
+ curr_sp = adjust_alloc(env, irn, curr_sp);
break;
case iro_Free:
- curr_sp = adjust_free(env, irn, curr_sp);
+ if (get_Free_where(irn) == stack_alloc)
+ curr_sp = adjust_free(env, irn, curr_sp);
break;
default:
panic("invalid call");
/* Keep the last stack state in the block by tying it to Keep node,
* the proj from calls is already kept */
- if(curr_sp != env->init_sp
+ if (curr_sp != env->init_sp
&& !(is_Proj(curr_sp) && be_is_Call(get_Proj_pred(curr_sp)))) {
nodes[0] = curr_sp;
keep = be_new_Keep(env->arch_env->sp->reg_class,
optimization_state_t state;
unsigned *limited_bitset;
- be_omit_fp = birg->main_env->options->omit_fp;
+ be_omit_fp = birg->main_env->options->omit_fp;
+ be_omit_leaf_fp = birg->main_env->options->omit_leaf_fp;
obstack_init(&env->obst);
BE_TIME_OFF, /* no timing */
0, /* no opt profile */
0, /* try to omit frame pointer */
+ 0, /* try to omit leaf frame pointer */
0, /* create PIC code */
0, /* create gprof compatible profiling code */
BE_VRFY_WARN, /* verification level: warn */
};
static const lc_opt_table_entry_t be_main_options[] = {
- LC_OPT_ENT_STR ("config", "read another config file containing backend options", config_file, sizeof(config_file)),
- LC_OPT_ENT_ENUM_MASK("dump", "dump irg on several occasions", &dump_var),
- LC_OPT_ENT_BOOL ("omitfp", "omit frame pointer", &be_options.omit_fp),
- LC_OPT_ENT_BOOL ("pic", "create PIC code", &be_options.pic),
- LC_OPT_ENT_BOOL ("gprof", "create gprof profiling code", &be_options.gprof),
- LC_OPT_ENT_ENUM_PTR ("vrfy", "verify the backend irg", &vrfy_var),
- LC_OPT_ENT_BOOL ("time", "get backend timing statistics", &be_options.timing),
- LC_OPT_ENT_BOOL ("profile", "instrument the code for execution count profiling", &be_options.opt_profile),
- LC_OPT_ENT_ENUM_PTR ("sched", "select a scheduler", &sched_var),
- LC_OPT_ENT_STR ("os", "specify target operating system", &be_options.target_os, sizeof(be_options.target_os)),
+ LC_OPT_ENT_STR ("config", "read another config file containing backend options", config_file, sizeof(config_file)),
+ LC_OPT_ENT_ENUM_MASK("dump", "dump irg on several occasions", &dump_var),
+ LC_OPT_ENT_BOOL ("omitfp", "omit frame pointer", &be_options.omit_fp),
+ LC_OPT_ENT_BOOL ("omitleaffp", "omit frame pointer in leaf routines", &be_options.omit_leaf_fp),
+ LC_OPT_ENT_BOOL ("pic", "create PIC code", &be_options.pic),
+ LC_OPT_ENT_BOOL ("gprof", "create gprof profiling code", &be_options.gprof),
+ LC_OPT_ENT_ENUM_PTR ("vrfy", "verify the backend irg", &vrfy_var),
+ LC_OPT_ENT_BOOL ("time", "get backend timing statistics", &be_options.timing),
+ LC_OPT_ENT_BOOL ("profile", "instrument the code for execution count profiling", &be_options.opt_profile),
+ LC_OPT_ENT_ENUM_PTR ("sched", "select a scheduler", &sched_var),
+ LC_OPT_ENT_STR ("os", "specify target operating system", &be_options.target_os, sizeof(be_options.target_os)),
#ifdef FIRM_STATISTICS
- LC_OPT_ENT_BOOL ("statev", "dump statistic events", &be_options.statev),
- LC_OPT_ENT_STR ("filtev", "filter for stat events (regex if support is active", &be_options.filtev, sizeof(be_options.filtev)),
+ LC_OPT_ENT_BOOL ("statev", "dump statistic events", &be_options.statev),
+ LC_OPT_ENT_STR ("filtev", "filter for stat events (regex if support is active", &be_options.filtev, sizeof(be_options.filtev)),
#endif
#ifdef WITH_ILP