From: Michael Beck Date: Mon, 2 Jun 2008 13:29:06 +0000 (+0000) Subject: - added option -b omitleaffp, omitting the frame pointer in leaf routines only (allow... X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=0b21c87e6264928144e034605e97be3e4d7138b4;p=libfirm - added option -b omitleaffp, omitting the frame pointer in leaf routines only (allow better debugging the -b omitfp) [r19928] --- diff --git a/ir/be/be_t.h b/ir/be/be_t.h index 9ecee74c0..7e77a11db 100644 --- a/ir/be/be_t.h +++ b/ir/be/be_t.h @@ -68,6 +68,7 @@ struct be_options_t { int timing; /**< time the backend phases */ int opt_profile; /**< instrument code for profiling */ int omit_fp; /**< try to omit the frame pointer */ + int omit_leaf_fp; /**< try to omit the frame pointer in leaf routines */ int pic; /**< create position independent code */ int gprof; /**< create gprof compatible profiling code */ int vrfy_option; /**< backend verify option */ diff --git a/ir/be/beabi.c b/ir/be/beabi.c index b8225fb2b..512226a70 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -113,9 +113,12 @@ struct _be_abi_irg_t { 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; + /* _ ____ ___ ____ _ _ _ _ / \ | __ )_ _| / ___|__ _| | | |__ __ _ ___| | _____ @@ -239,7 +242,7 @@ static be_abi_call_t *be_abi_call_new(const arch_register_class_t *cls_addr) 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; } @@ -871,10 +874,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp 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); @@ -886,7 +886,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp 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; @@ -909,7 +909,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp 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); @@ -971,10 +971,7 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp) 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); @@ -983,7 +980,7 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp) 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), @@ -1120,11 +1117,11 @@ static void process_calls_in_block(ir_node *bl, void *data) 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; @@ -1134,19 +1131,25 @@ static void process_calls_in_block(ir_node *bl, void *data) /* 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"); @@ -1158,7 +1161,7 @@ static void process_calls_in_block(ir_node *bl, void *data) /* 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, @@ -2123,7 +2126,8 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg) 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); diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 1cff81d9d..1c4623079 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -89,6 +89,7 @@ static be_options_t be_options = { 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 */ @@ -150,19 +151,20 @@ static lc_opt_enum_int_var_t sched_var = { }; 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