Vladimir Makarov <vmaka...@redhat.com> writes: > On 12-10-16 5:21 PM, Richard Sandiford wrote: >> I realise you probably have patches pending as well, so I'm happy to >> wait until those have gone in and update. >> > You can commit it into the branch. You have to do some work for > conflict resolution (I added new helper function in > curr_insn_transformation for swapping operands) as the code was changed > a lot today.
Thanks. For the record, here's what I committed after retesting. Richard gcc/ * lra-int.h (lra_operand_data): Add is_address field. * lra.c (debug_operand_data): Initialize is_address field. (get_static_insn_data): Likewise. (setup_operand_alternative): Record is_address in operand data. (lra_set_insn_recog_data): Initialize is_address field. * lra-constraints.c (curr_operand_mode): New array. (init_curr_operand_mode): New function. (find_mode, get_op_mode): Delete. (match_reload): Use curr_operand_mode rather than get_op_mode. (process_alt_operands): Likewise. Remove VOIDmode check from CONST_OK_POOL_P check. (swap_operands): Swap the operand modes too. (curr_insn_transform): Use curr_operand_mode rather than get_op_mode. Remove VOIDmode check from CONST_OK_POOL_P check. Use swap_operands for the final swap too. (lra_constraints): Call init_curr_operand_mode. Index: gcc/lra-int.h =================================================================== --- gcc/lra-int.h 2012-10-17 09:04:35.000000000 +0100 +++ gcc/lra-int.h 2012-10-17 09:05:12.284782971 +0100 @@ -157,6 +157,8 @@ struct lra_operand_data This field is set up every time when corresponding operand_alternative in lra_static_insn_data is set up. */ unsigned int early_clobber : 1; + /* True if the operand is an address. */ + unsigned int is_address : 1; }; /* Info about register in an insn. */ Index: gcc/lra.c =================================================================== --- gcc/lra.c 2012-10-17 09:04:35.000000000 +0100 +++ gcc/lra.c 2012-10-17 09:05:12.286782972 +0100 @@ -517,7 +517,7 @@ static struct lra_operand_data debug_ope NULL, /* alternative */ VOIDmode, /* We are not interesting in the operand mode. */ OP_IN, - 0, 0, 0 + 0, 0, 0, 0 }; /* The following data are used as static insn data for all debug @@ -618,6 +618,7 @@ get_static_insn_data (int icode, int nop = (data->operand[i].constraint[0] == '=' ? OP_OUT : data->operand[i].constraint[0] == '+' ? OP_INOUT : OP_IN); + data->operand[i].is_address = false; } for (i = 0; i < ndup; i++) data->dup_num[i] = recog_data.dup_num[i]; @@ -823,6 +824,7 @@ setup_operand_alternative (lra_insn_reco break; case 'p': + static_data->operand[i].is_address = true; op_alt->is_address = 1; op_alt->cl = (reg_class_subunion[(int) op_alt->cl] [(int) base_reg_class (VOIDmode, @@ -844,6 +846,7 @@ setup_operand_alternative (lra_insn_reco } if (EXTRA_ADDRESS_CONSTRAINT (c, p)) { + static_data->operand[i].is_address = true; op_alt->is_address = 1; op_alt->cl = (reg_class_subunion @@ -1062,6 +1065,7 @@ lra_set_insn_recog_data (rtx insn) insn_static_data->operand[i].constraint = constraints[i]; insn_static_data->operand[i].strict_low = false; insn_static_data->operand[i].is_operator = false; + insn_static_data->operand[i].is_address = false; } } for (i = 0; i < insn_static_data->n_operands; i++) Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2012-10-17 09:04:35.000000000 +0100 +++ gcc/lra-constraints.c 2012-10-17 09:14:03.164753401 +0100 @@ -138,11 +138,13 @@ static int bb_reload_num; /* The current insn being processed and corresponding its data (basic - block, the insn data, and the insn static data. */ + block, the insn data, the insn static data, and the mode of each + operand). */ static rtx curr_insn; static basic_block curr_bb; static lra_insn_recog_data_t curr_id; static struct lra_static_insn_data *curr_static_id; +static enum machine_mode curr_operand_mode[MAX_RECOG_OPERANDS]; @@ -298,6 +300,27 @@ get_equiv_substitution (rtx x) gcc_unreachable (); } +/* Set up curr_operand_mode. */ +static void +init_curr_operand_mode (void) +{ + int nop = curr_static_id->n_operands; + for (int i = 0; i < nop; i++) + { + enum machine_mode mode = GET_MODE (*curr_id->operand_loc[i]); + if (mode == VOIDmode) + { + /* The .md mode for address operands is the mode of the + addressed value rather than the mode of the address itself. */ + if (curr_id->icode >= 0 && curr_static_id->operand[i].is_address) + mode = Pmode; + else + mode = curr_static_id->operand[i].mode; + } + curr_operand_mode[i] = mode; + } +} + /* The page contains code to reuse input reloads. */ @@ -870,65 +893,6 @@ #define SMALL_REGISTER_CLASS_P(C) \ (reg_class_size [(C)] == 1 \ || (reg_class_size [(C)] >= 1 && targetm.class_likely_spilled_p (C))) -/* Return mode of WHAT inside of WHERE whose mode of the context is - OUTER_MODE. If WHERE does not contain WHAT, return VOIDmode. */ -static enum machine_mode -find_mode (rtx *where, enum machine_mode outer_mode, rtx *what) -{ - int i, j; - enum machine_mode mode; - rtx x; - const char *fmt; - enum rtx_code code; - - if (where == what) - return outer_mode; - if (*where == NULL_RTX) - return VOIDmode; - x = *where; - code = GET_CODE (x); - outer_mode = GET_MODE (x); - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - { - if ((mode = find_mode (&XEXP (x, i), outer_mode, what)) != VOIDmode) - return mode; - } - else if (fmt[i] == 'E') - { - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - if ((mode = find_mode (&XVECEXP (x, i, j), outer_mode, what)) - != VOIDmode) - return mode; - } - } - return VOIDmode; -} - -/* Return mode for operand NOP of the current insn. */ -static inline enum machine_mode -get_op_mode (int nop) -{ - rtx *loc; - enum machine_mode mode; - bool md_first_p = asm_noperands (PATTERN (curr_insn)) < 0; - - /* Take mode from the machine description first. */ - if (md_first_p && (mode = curr_static_id->operand[nop].mode) != VOIDmode) - return mode; - loc = curr_id->operand_loc[nop]; - /* Take mode from the operand second. */ - mode = GET_MODE (*loc); - if (mode != VOIDmode) - return mode; - if (! md_first_p && (mode = curr_static_id->operand[nop].mode) != VOIDmode) - return mode; - /* Here is a very rare case. Take mode from the context. */ - return find_mode (&PATTERN (curr_insn), VOIDmode, loc); -} - /* If REG is a reload pseudo, try to make its class satisfying CL. */ static void narrow_reload_pseudo_class (rtx reg, enum reg_class cl) @@ -963,8 +927,8 @@ match_reload (signed char out, signed ch rtx in_rtx = *curr_id->operand_loc[ins[0]]; rtx out_rtx = *curr_id->operand_loc[out]; - outmode = get_op_mode (out); - inmode = get_op_mode (ins[0]); + outmode = curr_operand_mode[out]; + inmode = curr_operand_mode[ins[0]]; if (inmode != outmode) { if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode)) @@ -1690,7 +1654,7 @@ process_alt_operands (int only_alternati } op = no_subreg_reg_operand[nop]; - mode = get_op_mode (nop); + mode = curr_operand_mode[nop]; win = did_match = winreg = offmemok = constmemok = false; badop = true; @@ -2162,8 +2126,7 @@ process_alt_operands (int only_alternati if (CONST_POOL_OK_P (mode, op) && ((targetm.preferred_reload_class (op, this_alternative) == NO_REGS) - || no_input_reloads_p) - && get_op_mode (nop) != VOIDmode) + || no_input_reloads_p)) { const_to_mem = 1; if (! no_regs_p) @@ -2824,6 +2787,9 @@ emit_inc (enum reg_class new_rclass, rtx static inline void swap_operands (int nop) { + enum machine_mode mode = curr_operand_mode[nop]; + curr_operand_mode[nop] = curr_operand_mode[nop + 1]; + curr_operand_mode[nop + 1] = mode; rtx x = *curr_id->operand_loc[nop]; *curr_id->operand_loc[nop] = *curr_id->operand_loc[nop + 1]; *curr_id->operand_loc[nop + 1] = x; @@ -3012,20 +2978,12 @@ curr_insn_transform (void) if (goal_alt_swapped) { - rtx tem; - if (lra_dump_file != NULL) fprintf (lra_dump_file, " Commutative operand exchange in insn %u\n", INSN_UID (curr_insn)); - tem = *curr_id->operand_loc[commutative]; - *curr_id->operand_loc[commutative] - = *curr_id->operand_loc[commutative + 1]; - *curr_id->operand_loc[commutative + 1] = tem; - /* Swap the duplicates too. */ - lra_update_dup (curr_id, commutative); - lra_update_dup (curr_id, commutative + 1); + swap_operands (commutative); change_p = true; } @@ -3148,7 +3106,7 @@ curr_insn_transform (void) char c; rtx op = *curr_id->operand_loc[i]; rtx subreg = NULL_RTX; - enum machine_mode mode = get_op_mode (i); + enum machine_mode mode = curr_operand_mode[i]; if (GET_CODE (op) == SUBREG) { @@ -3160,8 +3118,7 @@ curr_insn_transform (void) if (CONST_POOL_OK_P (mode, op) && ((targetm.preferred_reload_class (op, (enum reg_class) goal_alt[i]) == NO_REGS) - || no_input_reloads_p) - && mode != VOIDmode) + || no_input_reloads_p)) { rtx tem = force_const_mem (mode, op); @@ -3255,7 +3212,7 @@ curr_insn_transform (void) enum op_type type = curr_static_id->operand[i].type; loc = curr_id->operand_loc[i]; - mode = get_op_mode (i); + mode = curr_operand_mode[i]; if (GET_CODE (*loc) == SUBREG) { reg = SUBREG_REG (*loc); @@ -3702,6 +3659,7 @@ lra_constraints (bool first_p) curr_id = lra_get_insn_recog_data (curr_insn); curr_static_id = curr_id->insn_static_data; init_curr_insn_input_reloads (); + init_curr_operand_mode (); if (curr_insn_transform ()) changed_p = true; }