small improvements: cache different environment members in local variables
[libfirm] / ir / be / ia32 / bearch_ia32.c
index 2f39e9f..a810915 100644 (file)
@@ -210,14 +210,12 @@ ir_node *ia32_get_admissible_noreg(ia32_code_gen_t *cg, ir_node *irn, int pos) {
  * If the node returns a tuple (mode_T) then the proj's
  * will be asked for this information.
  */
-static const arch_register_req_t *ia32_get_irn_reg_req(const void *self,
-                                                       const ir_node *node,
+static const arch_register_req_t *ia32_get_irn_reg_req(const ir_node *node,
                                                                                                           int pos)
 {
        ir_mode *mode = get_irn_mode(node);
        long    node_pos;
 
-       (void)self;
        if (mode == mode_X || is_Block(node)) {
                return arch_no_register_req;
        }
@@ -253,11 +251,9 @@ static const arch_register_req_t *ia32_get_irn_reg_req(const void *self,
        return arch_no_register_req;
 }
 
-static void ia32_set_irn_reg(const void *self, ir_node *irn,
-                             const arch_register_t *reg)
+static void ia32_set_irn_reg(ir_node *irn, const arch_register_t *reg)
 {
        int    pos = 0;
-       (void) self;
 
        if (get_irn_mode(irn) == mode_X) {
                return;
@@ -278,12 +274,10 @@ static void ia32_set_irn_reg(const void *self, ir_node *irn,
        }
 }
 
-static const arch_register_t *ia32_get_irn_reg(const void *self,
-                                               const ir_node *irn)
+static const arch_register_t *ia32_get_irn_reg(const ir_node *irn)
 {
        int pos = 0;
        const arch_register_t *reg = NULL;
-       (void) self;
 
        if (is_Proj(irn)) {
 
@@ -307,9 +301,8 @@ static const arch_register_t *ia32_get_irn_reg(const void *self,
        return reg;
 }
 
-static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
+static arch_irn_class_t ia32_classify(const ir_node *irn) {
        arch_irn_class_t classification = arch_irn_class_normal;
-       (void) self;
 
        irn = skip_Proj_const(irn);
 
@@ -331,9 +324,8 @@ static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
        return classification;
 }
 
-static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
+static arch_irn_flags_t ia32_get_flags(const ir_node *irn) {
        arch_irn_flags_t flags = arch_irn_flags_none;
-       (void) self;
 
        if (is_Unknown(irn))
                return arch_irn_flags_ignore;
@@ -360,30 +352,26 @@ static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
  */
 typedef struct {
        be_abi_call_flags_bits_t flags;  /**< The call flags. */
-       const arch_isa_t *isa;           /**< The ISA handle. */
        const arch_env_t *aenv;          /**< The architecture environment. */
        ir_graph *irg;                   /**< The associated graph. */
 } ia32_abi_env_t;
 
-static ir_entity *ia32_get_frame_entity(const void *self, const ir_node *irn) {
-       (void) self;
+static ir_entity *ia32_get_frame_entity(const ir_node *irn) {
        return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL;
 }
 
-static void ia32_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent) {
-       (void) self;
+static void ia32_set_frame_entity(ir_node *irn, ir_entity *ent) {
        set_ia32_frame_ent(irn, ent);
 }
 
-static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias)
+static void ia32_set_frame_offset(ir_node *irn, int bias)
 {
-       const ia32_irn_ops_t *ops = self;
-
        if (get_ia32_frame_ent(irn) == NULL)
                return;
 
        if (is_ia32_Pop(irn) || is_ia32_PopMem(irn)) {
-               int omit_fp = be_abi_omit_fp(ops->cg->birg->abi);
+               ia32_code_gen_t *cg = ia32_current_cg;
+               int omit_fp = be_abi_omit_fp(cg->birg->abi);
                if (omit_fp) {
                        /* Pop nodes modify the stack pointer before calculating the
                         * destination address, so fix this here
@@ -394,10 +382,8 @@ static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias)
        add_ia32_am_offs_int(irn, bias);
 }
 
-static int ia32_get_sp_bias(const void *self, const ir_node *node)
+static int ia32_get_sp_bias(const ir_node *node)
 {
-       (void) self;
-
        if (is_ia32_Push(node))
                return 4;
 
@@ -417,7 +403,7 @@ static void ia32_abi_dont_save_regs(void *self, pset *s)
 {
        ia32_abi_env_t *env = self;
        if(env->flags.try_omit_fp)
-               pset_insert_ptr(s, env->isa->bp);
+               pset_insert_ptr(s, env->aenv->bp);
 }
 
 /**
@@ -433,48 +419,49 @@ static void ia32_abi_dont_save_regs(void *self, pset *s)
  */
 static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
 {
-       ia32_abi_env_t *env = self;
-       const ia32_isa_t *isa     = (ia32_isa_t *)env->isa;
-       ia32_code_gen_t *cg = isa->cg;
+       ia32_abi_env_t   *env      = self;
+       ia32_code_gen_t  *cg       = ia32_current_cg;
+       const arch_env_t *arch_env = env->aenv;
 
        if (! env->flags.try_omit_fp) {
-               ir_node *bl      = get_irg_start_block(env->irg);
-               ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
-               ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
-               ir_node *noreg = ia32_new_NoReg_gp(cg);
-               ir_node *push;
+               ir_graph *irg     =env->irg;
+               ir_node  *bl      = get_irg_start_block(irg);
+               ir_node  *curr_sp = be_abi_reg_map_get(reg_map, arch_env->sp);
+               ir_node  *curr_bp = be_abi_reg_map_get(reg_map, arch_env->bp);
+               ir_node  *noreg = ia32_new_NoReg_gp(cg);
+               ir_node  *push;
 
                /* ALL nodes representing bp must be set to ignore. */
                be_node_set_flags(get_Proj_pred(curr_bp), BE_OUT_POS(get_Proj_proj(curr_bp)), arch_irn_flags_ignore);
 
                /* push ebp */
-               push    = new_rd_ia32_Push(NULL, env->irg, bl, noreg, noreg, *mem, curr_bp, curr_sp);
-               curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
-               *mem    = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
+               push    = new_rd_ia32_Push(NULL, irg, bl, noreg, noreg, *mem, curr_bp, curr_sp);
+               curr_sp = new_r_Proj(irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
+               *mem    = new_r_Proj(irg, bl, push, mode_M, pn_ia32_Push_M);
 
                /* the push must have SP out register */
-               arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
+               arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
                set_ia32_flags(push, arch_irn_flags_ignore);
 
                /* move esp to ebp */
-               curr_bp  = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
-               be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
-               arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
+               curr_bp  = be_new_Copy(arch_env->bp->reg_class, irg, bl, curr_sp);
+               be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), arch_env->bp);
+               arch_set_irn_register(arch_env, curr_bp, arch_env->bp);
                be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
 
                /* beware: the copy must be done before any other sp use */
-               curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
-               be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
-               arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
+               curr_sp = be_new_CopyKeep_single(arch_env->sp->reg_class, irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
+               be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), arch_env->sp);
+               arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
                be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
 
-               be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
-               be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
+               be_abi_reg_map_set(reg_map, arch_env->sp, curr_sp);
+               be_abi_reg_map_set(reg_map, arch_env->bp, curr_bp);
 
-               return env->isa->bp;
+               return arch_env->bp;
        }
 
-       return env->isa->sp;
+       return arch_env->sp;
 }
 
 /**
@@ -489,17 +476,18 @@ static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap
  */
 static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
 {
-       ia32_abi_env_t *env     = self;
-       ir_node        *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
-       ir_node        *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
+       ia32_abi_env_t   *env      = self;
+       const arch_env_t *arch_env = env->aenv;
+       ir_node          *curr_sp  = be_abi_reg_map_get(reg_map, arch_env->sp);
+       ir_node          *curr_bp  = be_abi_reg_map_get(reg_map, arch_env->bp);
+       ir_graph         *irg      = env->irg;
 
        if (env->flags.try_omit_fp) {
                /* simply remove the stack frame here */
-               curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
+               curr_sp = be_new_IncSP(arch_env->sp, irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
                add_irn_dep(curr_sp, *mem);
        } else {
-               ir_mode         *mode_bp = env->isa->bp->reg_class->mode;
-               ir_graph        *irg     = current_ir_graph;
+               ir_mode *mode_bp = arch_env->bp->reg_class->mode;
 
                if (ia32_cg_config.use_leave) {
                        ir_node *leave;
@@ -518,7 +506,7 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_
 
                        /* copy ebp to esp */
                        curr_sp = be_new_Copy(&ia32_reg_classes[CLASS_ia32_gp], irg, bl, curr_bp);
-                       arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
+                       arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
                        be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
 
                        /* pop ebp */
@@ -529,12 +517,12 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_
 
                        *mem = new_r_Proj(irg, bl, pop, mode_M, pn_ia32_Pop_M);
                }
-               arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
-               arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
+               arch_set_irn_register(arch_env, curr_sp, arch_env->sp);
+               arch_set_irn_register(arch_env, curr_bp, arch_env->bp);
        }
 
-       be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
-       be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
+       be_abi_reg_map_set(reg_map, arch_env->sp, curr_sp);
+       be_abi_reg_map_set(reg_map, arch_env->bp, curr_bp);
 }
 
 /**
@@ -551,7 +539,6 @@ static void *ia32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir
        env->flags = fl.bits;
        env->irg   = irg;
        env->aenv  = aenv;
-       env->isa   = aenv->isa;
        return env;
 }
 
@@ -613,11 +600,10 @@ static ir_type *ia32_abi_get_between_type(void *self)
  *
  * @return     The estimated cycle count for this operation
  */
-static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
+static int ia32_get_op_estimated_cost(const ir_node *irn)
 {
        int            cost;
        ia32_op_type_t op_tp;
-       (void) self;
 
        if (is_Proj(irn))
                return 0;
@@ -664,13 +650,12 @@ static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
  * @param obstack   The obstack to use for allocation of the returned nodes array
  * @return          The inverse operation or NULL if operation invertible
  */
-static arch_inverse_t *ia32_get_inverse(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst) {
+static arch_inverse_t *ia32_get_inverse(const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst) {
        ir_graph *irg;
        ir_mode  *mode;
        ir_mode  *irn_mode;
        ir_node  *block, *noreg, *nomem;
        dbg_info *dbg;
-       (void) self;
 
        /* we cannot invert non-ia32 irns */
        if (! is_ia32_irn(irn))
@@ -819,11 +804,10 @@ static int ia32_is_spillmode_compatible(const ir_mode *mode, const ir_mode *spil
  * @param i      The operands position
  * @return Non-Zero if operand can be loaded
  */
-static int ia32_possible_memory_operand(const void *self, const ir_node *irn, unsigned int i) {
+static int ia32_possible_memory_operand(const ir_node *irn, unsigned int i) {
        ir_node *op = get_irn_n(irn, i);
        const ir_mode *mode = get_irn_mode(op);
        const ir_mode *spillmode = get_spill_mode(op);
-       (void) self;
 
        if (
                (i != n_ia32_binary_left && i != n_ia32_binary_right) || /* a "real" operand position must be requested */
@@ -851,12 +835,12 @@ static int ia32_possible_memory_operand(const void *self, const ir_node *irn, un
        return 1;
 }
 
-static void ia32_perform_memory_operand(const void *self, ir_node *irn,
-                                        ir_node *spill, unsigned int i)
+static void ia32_perform_memory_operand(ir_node *irn, ir_node *spill,
+                                        unsigned int i)
 {
-       const ia32_irn_ops_t *ops = self;
+       ia32_code_gen_t *cg = ia32_current_cg;
 
-       assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
+       assert(ia32_possible_memory_operand(irn, i) && "Cannot perform memory operand change");
 
        if (i == n_ia32_binary_left) {
                ia32_swap_left_right(irn);
@@ -868,7 +852,7 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn,
        set_ia32_need_stackent(irn);
 
        set_irn_n(irn, n_ia32_base, get_irg_frame(get_irn_irg(irn)));
-       set_irn_n(irn, n_ia32_binary_right, ia32_get_admissible_noreg(ops->cg, irn, n_ia32_binary_right));
+       set_irn_n(irn, n_ia32_binary_right, ia32_get_admissible_noreg(cg, irn, n_ia32_binary_right));
        set_irn_n(irn, n_ia32_mem, spill);
 
        /* immediates are only allowed on the right side */
@@ -888,7 +872,7 @@ static const be_abi_callbacks_t ia32_abi_callbacks = {
 
 /* fill register allocator interface */
 
-static const arch_irn_ops_if_t ia32_irn_ops_if = {
+static const arch_irn_ops_t ia32_irn_ops = {
        ia32_get_irn_reg_req,
        ia32_set_irn_reg,
        ia32_get_irn_reg,
@@ -904,13 +888,6 @@ static const arch_irn_ops_if_t ia32_irn_ops_if = {
        ia32_perform_memory_operand,
 };
 
-static ia32_irn_ops_t ia32_irn_ops = {
-       &ia32_irn_ops_if,
-       NULL
-};
-
-
-
 /**************************************************
  *                _                         _  __
  *               | |                       (_)/ _|
@@ -1565,14 +1542,14 @@ static const arch_code_generator_if_t ia32_code_gen_if = {
  * Initializes a IA32 code generator.
  */
 static void *ia32_cg_init(be_irg_t *birg) {
-       ia32_isa_t      *isa = (ia32_isa_t *)birg->main_env->arch_env.isa;
+       ia32_isa_t      *isa = (ia32_isa_t *)birg->main_env->arch_env;
        ia32_code_gen_t *cg  = xcalloc(1, sizeof(*cg));
 
        cg->impl      = &ia32_code_gen_if;
        cg->irg       = birg->irg;
        cg->reg_set   = new_set(ia32_cmp_irn_reg_assoc, 1024);
-       cg->arch_env  = &birg->main_env->arch_env;
        cg->isa       = isa;
+       cg->arch_env  = birg->main_env->arch_env;
        cg->birg      = birg;
        cg->blk_sched = NULL;
        cg->dump      = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
@@ -1595,8 +1572,6 @@ static void *ia32_cg_init(be_irg_t *birg) {
 
        cur_reg_set = cg->reg_set;
 
-       ia32_irn_ops.cg = cg;
-
        assert(ia32_current_cg == NULL);
        ia32_current_cg = cg;
 
@@ -1672,7 +1647,7 @@ static ia32_isa_t ia32_isa_template = {
 /**
  * Initializes the backend ISA.
  */
-static void *ia32_init(FILE *file_handle) {
+static arch_env_t *ia32_init(FILE *file_handle) {
        static int inited = 0;
        ia32_isa_t *isa;
 
@@ -1690,7 +1665,7 @@ static void *ia32_init(FILE *file_handle) {
        }
 
        ia32_register_init();
-       ia32_create_opcodes();
+       ia32_create_opcodes(&ia32_irn_ops);
 
        be_emit_init(file_handle);
        isa->regs_16bit     = pmap_create();
@@ -1724,7 +1699,7 @@ static void *ia32_init(FILE *file_handle) {
         */
        inc_master_type_visited();
 
-       return isa;
+       return &isa->arch_env;
 }
 
 
@@ -1736,7 +1711,7 @@ static void ia32_done(void *self) {
        ia32_isa_t *isa = self;
 
        /* emit now all global declarations */
-       be_gas_emit_decls(isa->arch_isa.main_env, 1);
+       be_gas_emit_decls(isa->arch_env.main_env, 1);
 
        pmap_destroy(isa->regs_16bit);
        pmap_destroy(isa->regs_8bit);
@@ -1895,25 +1870,6 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type,
        }
 }
 
-
-static const void *ia32_get_irn_ops(const arch_irn_handler_t *self,
-                                    const ir_node *irn)
-{
-       (void) self;
-       (void) irn;
-       return &ia32_irn_ops;
-}
-
-const arch_irn_handler_t ia32_irn_handler = {
-       ia32_get_irn_ops
-};
-
-const arch_irn_handler_t *ia32_get_irn_handler(const void *self)
-{
-       (void) self;
-       return &ia32_irn_handler;
-}
-
 int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn)
 {
        (void) block_env;
@@ -1944,8 +1900,8 @@ static const arch_code_generator_if_t *ia32_get_code_generator_if(void *self)
  * Returns the estimated execution time of an ia32 irn.
  */
 static sched_timestep_t ia32_sched_exectime(void *env, const ir_node *irn) {
-       const arch_env_t *arch_env = env;
-       return is_ia32_irn(irn) ? ia32_get_op_estimated_cost(arch_get_irn_ops(arch_env, irn), irn) : 1;
+       (void) env;
+       return is_ia32_irn(irn) ? ia32_get_op_estimated_cost(irn) : 1;
 }
 
 list_sched_selector_t ia32_sched_selector;
@@ -2251,7 +2207,7 @@ static lc_opt_enum_int_var_t gas_var = {
 static const lc_opt_table_entry_t ia32_options[] = {
        LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
        LC_OPT_ENT_INT("stackalign", "set stack alignment for calls",
-                      &ia32_isa_template.arch_isa.stack_alignment),
+                      &ia32_isa_template.arch_env.stack_alignment),
        LC_OPT_LAST
 };
 
@@ -2262,7 +2218,6 @@ const arch_isa_if_t ia32_isa_if = {
        ia32_get_reg_class,
        ia32_get_reg_class_for_mode,
        ia32_get_call_abi,
-       ia32_get_irn_handler,
        ia32_get_code_generator_if,
        ia32_get_list_sched_selector,
        ia32_get_ilp_sched_selector,