- added option -b omitleaffp, omitting the frame pointer in leaf routines only (allow...
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 2 Jun 2008 13:29:06 +0000 (13:29 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 2 Jun 2008 13:29:06 +0000 (13:29 +0000)
[r19928]

ir/be/be_t.h
ir/be/beabi.c
ir/be/bemain.c

index 9ecee74..7e77a11 100644 (file)
@@ -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 */
index b8225fb..512226a 100644 (file)
@@ -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);
 
index 1cff81d..1c46230 100644 (file)
@@ -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