diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ab06c099df..c946bbad68e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2019-07-31 Richard Sandiford + + * lra-int.h (lra_operand_data): Remove early_clobber field. + (lra_insn_reg): Likewise. + * lra.c (debug_operand_data): Update accordingly. + (setup_operand_alternative): Likewise. + (new_insn_reg): Likewise. Remove early_clobber parameter. + (collect_non_operand_hard_regs): Update call accordingly. + Don't assign to lra_insn_reg::early_clobber. + (add_regs_to_insn_regno_info): Remove early_clobber parameter + and update calls to new_insn_reg. + (lra_update_insn_regno_info): Update calls accordingly. + * lra-constraints.c (update_and_check_small_class_inputs): Take the + alternative number as a parameter and test whether the operand + is earlyclobbered in that particular alternative. + (process_alt_operands): Update call accordingly. Use per-alternative + checks for earyclobber here too. + * lra-lives.c (reg_early_clobber_p): Check early_clobber_alts + against zero for IRA_UNKNOWN_ALT. + 2019-07-30 Uroš Bizjak * config/alpha/alpha.c (alpha_option_override): Quote a C type. diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index bd9f85d33cc..f2584075937 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1866,11 +1866,12 @@ prohibited_class_reg_set_mode_p (enum reg_class rclass, alternative. */ static unsigned int curr_small_class_check = 0; -/* Update number of used inputs of class OP_CLASS for operand NOP. - Return true if we have more such class operands than the number of - available regs. */ +/* Update number of used inputs of class OP_CLASS for operand NOP + of alternative NALT. Return true if we have more such class operands + than the number of available regs. */ static bool -update_and_check_small_class_inputs (int nop, enum reg_class op_class) +update_and_check_small_class_inputs (int nop, int nalt, + enum reg_class op_class) { static unsigned int small_class_check[LIM_REG_CLASSES]; static int small_class_input_nums[LIM_REG_CLASSES]; @@ -1881,7 +1882,7 @@ update_and_check_small_class_inputs (int nop, enum reg_class op_class) && hard_reg_set_intersect_p (reg_class_contents[op_class], ira_no_alloc_regs) && (curr_static_id->operand[nop].type != OP_OUT - || curr_static_id->operand[nop].early_clobber)) + || TEST_BIT (curr_static_id->operand[nop].early_clobber_alts, nalt))) { if (small_class_check[op_class] == curr_small_class_check) small_class_input_nums[op_class]++; @@ -2150,7 +2151,8 @@ process_alt_operands (int only_alternative) /* We should reject matching of an early clobber operand if the matching operand is not dying in the insn. */ - if (! curr_static_id->operand[m].early_clobber + if (!TEST_BIT (curr_static_id->operand[m] + .early_clobber_alts, nalt) || operand_reg[nop] == NULL_RTX || (find_regno_note (curr_insn, REG_DEAD, REGNO (op)) @@ -2234,7 +2236,8 @@ process_alt_operands (int only_alternative) it results in less hard regs required for the insn than a non-matching earlyclobber alternative. */ - if (curr_static_id->operand[m].early_clobber) + if (TEST_BIT (curr_static_id->operand[m] + .early_clobber_alts, nalt)) { if (lra_dump_file != NULL) fprintf @@ -2875,7 +2878,8 @@ process_alt_operands (int only_alternative) goto fail; } - if (update_and_check_small_class_inputs (nop, this_alternative)) + if (update_and_check_small_class_inputs (nop, nalt, + this_alternative)) { if (lra_dump_file != NULL) fprintf (lra_dump_file, diff --git a/gcc/lra-int.h b/gcc/lra-int.h index f8db969122a..a87a51e47a9 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -142,10 +142,6 @@ struct lra_operand_data unsigned int strict_low : 1; /* True if the operand is an operator. */ unsigned int is_operator : 1; - /* True if there is an early clobber alternative for this operand. - 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; }; @@ -164,9 +160,6 @@ struct lra_insn_reg /* True if the reg is accessed through a subreg and the subreg is just a part of the register. */ unsigned int subreg_p : 1; - /* True if there is an early clobber alternative for this - operand. */ - unsigned int early_clobber : 1; /* True if the reg is clobber highed by the operand. */ unsigned int clobber_high : 1; /* The corresponding regno of the register. */ diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 96aa7c4717b..057ef8cab4d 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -624,10 +624,10 @@ check_pseudos_live_through_calls (int regno, static inline bool reg_early_clobber_p (const struct lra_insn_reg *reg, int n_alt) { - return (reg->early_clobber - && (n_alt == LRA_UNKNOWN_ALT - || (n_alt != LRA_NON_CLOBBERED_ALT - && TEST_BIT (reg->early_clobber_alts, n_alt)))); + return (n_alt == LRA_UNKNOWN_ALT + ? reg->early_clobber_alts != 0 + : (n_alt != LRA_NON_CLOBBERED_ALT + && TEST_BIT (reg->early_clobber_alts, n_alt))); } /* Return true if call instructions CALL1 and CALL2 use ABIs that diff --git a/gcc/lra.c b/gcc/lra.c index af40f43f835..d7593998f97 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -536,16 +536,14 @@ object_allocator lra_insn_reg_pool ("insn regs"); /* Create LRA insn related info about a reference to REGNO in INSN with TYPE (in/out/inout), biggest reference mode MODE, flag that it - is reference through subreg (SUBREG_P), flag that is early - clobbered in the insn (EARLY_CLOBBER), and reference to the next + is reference through subreg (SUBREG_P), and reference to the next insn reg info (NEXT). If REGNO can be early clobbered, alternatives in which it can be early clobbered are given by EARLY_CLOBBER_ALTS. CLOBBER_HIGH marks if reference is a clobber high. */ static struct lra_insn_reg * new_insn_reg (rtx_insn *insn, int regno, enum op_type type, - machine_mode mode, - bool subreg_p, bool early_clobber, + machine_mode mode, bool subreg_p, alternative_mask early_clobber_alts, struct lra_insn_reg *next, bool clobber_high) { @@ -556,7 +554,6 @@ new_insn_reg (rtx_insn *insn, int regno, enum op_type type, && partial_subreg_p (lra_reg_info[regno].biggest_mode, mode)) lra_reg_info[regno].biggest_mode = mode; ir->subreg_p = subreg_p; - ir->early_clobber = early_clobber; ir->early_clobber_alts = early_clobber_alts; ir->clobber_high = clobber_high; ir->regno = regno; @@ -605,7 +602,7 @@ static struct lra_operand_data debug_operand_data = 0, /* early_clobber_alts */ E_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 @@ -801,7 +798,6 @@ setup_operand_alternative (lra_insn_recog_data_t data, for (i = 0; i < nop; i++) { static_data->operand[i].early_clobber_alts = 0; - static_data->operand[i].early_clobber = false; static_data->operand[i].is_address = false; if (static_data->operand[i].constraint[0] == '%') { @@ -817,7 +813,6 @@ setup_operand_alternative (lra_insn_recog_data_t data, for (j = 0; j < nalt; j++) for (i = 0; i < nop; i++, op_alt++) { - static_data->operand[i].early_clobber |= op_alt->earlyclobber; if (op_alt->earlyclobber) static_data->operand[i].early_clobber_alts |= (alternative_mask) 1 << j; static_data->operand[i].is_address |= op_alt->is_address; @@ -878,10 +873,7 @@ collect_non_operand_hard_regs (rtx_insn *insn, rtx *x, if (curr->type != type) curr->type = OP_INOUT; if (early_clobber) - { - curr->early_clobber = true; - curr->early_clobber_alts = ALL_ALTERNATIVES; - } + curr->early_clobber_alts = ALL_ALTERNATIVES; break; } if (curr == NULL) @@ -897,7 +889,6 @@ collect_non_operand_hard_regs (rtx_insn *insn, rtx *x, && regno <= LAST_STACK_REG)); #endif list = new_insn_reg (data->insn, regno, type, mode, subreg_p, - early_clobber, early_clobber ? ALL_ALTERNATIVES : 0, list, clobber_high); } @@ -1449,15 +1440,13 @@ lra_get_copy (int n) /* This page contains code dealing with info about registers in insns. */ -/* Process X of INSN recursively and add info (operand type is - given by TYPE, flag of that it is early clobber is EARLY_CLOBBER) - about registers in X to the insn DATA. If X can be early clobbered, - alternatives in which it can be early clobbered are given by - EARLY_CLOBBER_ALTS. */ +/* Process X of INSN recursively and add info (operand type is given + by TYPE) about registers in X to the insn DATA. If X can be early + clobbered, alternatives in which it can be early clobbered are given + by EARLY_CLOBBER_ALTS. */ static void add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, - rtx_insn *insn, - enum op_type type, bool early_clobber, + rtx_insn *insn, enum op_type type, alternative_mask early_clobber_alts) { int i, j, regno; @@ -1487,8 +1476,7 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn))) { data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p, - early_clobber, early_clobber_alts, - data->regs, false); + early_clobber_alts, data->regs, false); return; } else @@ -1500,15 +1488,12 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, /* The info cannot be integrated into the found structure. */ data->regs = new_insn_reg (data->insn, regno, type, mode, - subreg_p, early_clobber, - early_clobber_alts, data->regs, - false); + subreg_p, early_clobber_alts, + data->regs, false); else { if (curr->type != type) curr->type = OP_INOUT; - if (curr->early_clobber != early_clobber) - curr->early_clobber = true; curr->early_clobber_alts |= early_clobber_alts; } return; @@ -1520,23 +1505,23 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, switch (code) { case SET: - add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, false, 0); - add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, false, 0); + add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, 0); + add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, 0); break; case CLOBBER: /* We treat clobber of non-operand hard registers as early clobber. */ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT, - true, ALL_ALTERNATIVES); + ALL_ALTERNATIVES); break; case CLOBBER_HIGH: gcc_unreachable (); case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: - add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0); + add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0); break; case PRE_MODIFY: case POST_MODIFY: - add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0); - add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, false, 0); + add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0); + add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, 0); break; default: if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT) @@ -1557,12 +1542,12 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, false, 0); + add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, 0); else if (fmt[i] == 'E') { for (j = XVECLEN (x, i) - 1; j >= 0; j--) add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn, - type, false, 0); + type, 0); } } } @@ -1652,11 +1637,10 @@ lra_update_insn_regno_info (rtx_insn *insn) for (i = static_data->n_operands - 1; i >= 0; i--) add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn, static_data->operand[i].type, - static_data->operand[i].early_clobber, static_data->operand[i].early_clobber_alts); if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE) add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn, - code == USE ? OP_IN : OP_OUT, false, 0); + code == USE ? OP_IN : OP_OUT, 0); if (CALL_P (insn)) /* On some targets call insns can refer to pseudos in memory in CALL_INSN_FUNCTION_USAGE list. Process them in order to @@ -1673,7 +1657,7 @@ lra_update_insn_regno_info (rtx_insn *insn) if ((code == USE || code == CLOBBER) && MEM_P (XEXP (XEXP (link, 0), 0))) add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn, - code == USE ? OP_IN : OP_OUT, false, 0); + code == USE ? OP_IN : OP_OUT, 0); } if (NONDEBUG_INSN_P (insn)) setup_insn_reg_info (data, freq);