From daca1a96afae35e1a2f39b91f014c2f414f70c5f Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 22 Oct 2014 12:02:26 +0000 Subject: [PATCH] recog.h (constrain_operands): Add an alternative_mask parameter. gcc/ * recog.h (constrain_operands): Add an alternative_mask parameter. (constrain_operands_cached): Likewise. (get_preferred_alternatives): Declare new form. * recog.c (get_preferred_alternatives): New bb-taking instance. (constrain_operands): Take the set of available alternatives as a parameter. (check_asm_operands, insn_invalid_p, extract_constrain_insn) (extract_constrain_insn_cached): Update calls to constrain_operands. * caller-save.c (reg_save_code): Likewise. * ira.c (setup_prohibited_mode_move_regs): Likewise. * postreload-gcse.c (eliminate_partially_redundant_load): Likewise. * ree.c (combine_reaching_defs): Likewise. * reload.c (can_reload_into): Likewise. * reload1.c (reload, reload_as_needed, inc_for_reload): Likewise. (gen_reload_chain_without_interm_reg_p, emit_input_reload_insns) (emit_insn_if_valid_for_reload): Likewise. * reorg.c (fill_slots_from_thread): Likewise. * config/i386/i386.c (ix86_attr_length_address_default): Likewise. * config/pa/pa.c (pa_can_combine_p): Likewise. * config/rl78/rl78.c (insn_ok_now): Likewise. * config/sh/sh.md (define_peephole2): Likewise. * final.c (final_scan_insn): Update call to constrain_operands_cached. From-SVN: r216555 --- gcc/ChangeLog | 25 +++++++++++++++++++++++++ gcc/caller-save.c | 8 +++++--- gcc/config/i386/i386.c | 2 +- gcc/config/pa/pa.c | 4 +++- gcc/config/rl78/rl78.c | 4 ++-- gcc/config/sh/sh.md | 10 ++++++---- gcc/final.c | 2 +- gcc/ira.c | 4 +++- gcc/postreload-gcse.c | 9 +++++---- gcc/recog.c | 42 ++++++++++++++++++++++++++++++------------ gcc/recog.h | 5 +++-- gcc/ree.c | 5 +++-- gcc/reload.c | 2 +- gcc/reload1.c | 17 ++++++++++------- gcc/reorg.c | 3 ++- 15 files changed, 100 insertions(+), 42 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3d8f810741..107afeea416 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2014-10-22 Richard Sandiford + + * recog.h (constrain_operands): Add an alternative_mask parameter. + (constrain_operands_cached): Likewise. + (get_preferred_alternatives): Declare new form. + * recog.c (get_preferred_alternatives): New bb-taking instance. + (constrain_operands): Take the set of available alternatives as + a parameter. + (check_asm_operands, insn_invalid_p, extract_constrain_insn) + (extract_constrain_insn_cached): Update calls to constrain_operands. + * caller-save.c (reg_save_code): Likewise. + * ira.c (setup_prohibited_mode_move_regs): Likewise. + * postreload-gcse.c (eliminate_partially_redundant_load): Likewise. + * ree.c (combine_reaching_defs): Likewise. + * reload.c (can_reload_into): Likewise. + * reload1.c (reload, reload_as_needed, inc_for_reload): Likewise. + (gen_reload_chain_without_interm_reg_p, emit_input_reload_insns) + (emit_insn_if_valid_for_reload): Likewise. + * reorg.c (fill_slots_from_thread): Likewise. + * config/i386/i386.c (ix86_attr_length_address_default): Likewise. + * config/pa/pa.c (pa_can_combine_p): Likewise. + * config/rl78/rl78.c (insn_ok_now): Likewise. + * config/sh/sh.md (define_peephole2): Likewise. + * final.c (final_scan_insn): Update call to constrain_operands_cached. + 2014-10-22 Richard Sandiford * doc/md.texi: Document "preferred_for_size" and "preferred_for_speed" diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 53d312f5459..8d38eabf701 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -143,15 +143,17 @@ reg_save_code (int reg, enum machine_mode mode) cached_reg_restore_code[reg][mode] = recog_memoized (restinsn); /* Now extract both insns and see if we can meet their - constraints. */ + constraints. We don't know here whether the save and restore will + be in size- or speed-tuned code, so just use the set of enabled + alternatives. */ ok = (cached_reg_save_code[reg][mode] != -1 && cached_reg_restore_code[reg][mode] != -1); if (ok) { extract_insn (saveinsn); - ok = constrain_operands (1); + ok = constrain_operands (1, get_enabled_alternatives (saveinsn)); extract_insn (restinsn); - ok &= constrain_operands (1); + ok &= constrain_operands (1, get_enabled_alternatives (restinsn)); } if (! ok) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 65b31734d39..ec3e056a3d2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25467,7 +25467,7 @@ ix86_attr_length_address_default (rtx_insn *insn) for (i = recog_data.n_operands - 1; i >= 0; --i) if (MEM_P (recog_data.operand[i])) { - constrain_operands_cached (reload_completed); + constrain_operands_cached (insn, reload_completed); if (which_alternative != -1) { const char *constraints = recog_data.constraints[i]; diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 4584ec266a4..05131d493f9 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -9064,8 +9064,10 @@ pa_can_combine_p (rtx_insn *new_rtx, rtx_insn *anchor, rtx_insn *floater, XVECEXP (PATTERN (new_rtx), 0, 1) = PATTERN (floater); INSN_CODE (new_rtx) = -1; insn_code_number = recog_memoized (new_rtx); + basic_block bb = BLOCK_FOR_INSN (anchor); if (insn_code_number < 0 - || (extract_insn (new_rtx), ! constrain_operands (1))) + || (extract_insn (new_rtx), + !constrain_operands (1, get_preferred_alternatives (new_rtx, bb))) return 0; if (reversed) diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index e8f72abdfe9..f2419ba6226 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -2170,7 +2170,7 @@ insn_ok_now (rtx_insn *insn) if (recog (pattern, insn, 0) > -1) { extract_insn (insn); - if (constrain_operands (1)) + if (constrain_operands (1, get_preferred_alternatives (insn))) { #if DEBUG_ALLOC fprintf (stderr, "\033[32m"); @@ -2199,7 +2199,7 @@ insn_ok_now (rtx_insn *insn) if (recog (pattern, insn, 0) > -1) { extract_insn (insn); - if (constrain_operands (0)) + if (constrain_operands (0, get_preferred_alternatives (insn))) { cfun->machine->virt_insns_ok = 0; return false; diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 675017c2c97..b48be1092a3 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -1580,7 +1580,7 @@ (set (match_dup 4) (match_dup 5))] { rtx set1, set2; - rtx_insn *insn2; + rtx_insn *insn1, *insn2; rtx replacements[4]; /* We want to replace occurrences of operands[0] with operands[1] and @@ -1607,14 +1607,16 @@ /* ??? The last insn might be a jump insn, but the generic peephole2 code always uses emit_insn. */ /* Check that we don't violate matching constraints or earlyclobbers. */ - extract_insn (emit_insn (set1)); - if (! constrain_operands (1)) + basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2)); + insn1 = emit_insn (set1); + extract_insn (insn1); + if (! constrain_operands (1, get_preferred_alternatives (insn1, bb))) goto failure; insn2 = emit (set2); if (GET_CODE (insn2) == BARRIER) goto failure; extract_insn (insn2); - if (! constrain_operands (1)) + if (! constrain_operands (1, get_preferred_alternatives (insn2, bb))) { rtx tmp; failure: diff --git a/gcc/final.c b/gcc/final.c index 5ce87c7dd2b..c3dc7a5d78c 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -2934,7 +2934,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, print_rtx_head = ""; } - if (! constrain_operands_cached (1)) + if (! constrain_operands_cached (insn, 1)) fatal_insn_not_found (insn); /* Some target machines need to prescan each insn before diff --git a/gcc/ira.c b/gcc/ira.c index 1bdc44612db..235a21171df 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1765,7 +1765,9 @@ setup_prohibited_mode_move_regs (void) if (INSN_CODE (move_insn) < 0) continue; extract_insn (move_insn); - if (! constrain_operands (1)) + /* We don't know whether the move will be in code that is optimized + for size or speed, so consider all enabled alternatives. */ + if (! constrain_operands (1, get_enabled_alternatives (move_insn))) continue; CLEAR_HARD_REG_BIT (ira_prohibited_mode_move_regs[i], j); } diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index 03b054a30cd..264e03064f8 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -1008,10 +1008,11 @@ eliminate_partially_redundant_load (basic_block bb, rtx_insn *insn, /* Make sure we can generate a move from register avail_reg to dest. */ - extract_insn (as_a ( - gen_move_insn (copy_rtx (dest), - copy_rtx (avail_reg)))); - if (! constrain_operands (1) + rtx_insn *move = as_a + (gen_move_insn (copy_rtx (dest), copy_rtx (avail_reg))); + extract_insn (move); + if (! constrain_operands (1, get_preferred_alternatives (insn, + pred_bb)) || reg_killed_on_edge (avail_reg, pred) || reg_used_on_edge (dest, pred)) { diff --git a/gcc/recog.c b/gcc/recog.c index afcab998124..5be01ccca95 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -160,8 +160,9 @@ check_asm_operands (rtx x) if (reload_completed) { /* ??? Doh! We've not got the wrapping insn. Cook one up. */ - extract_insn (make_insn_raw (x)); - constrain_operands (1); + rtx_insn *insn = make_insn_raw (x); + extract_insn (insn); + constrain_operands (1, get_enabled_alternatives (insn)); return which_alternative >= 0; } @@ -365,7 +366,7 @@ insn_invalid_p (rtx_insn *insn, bool in_group) { extract_insn (insn); - if (! constrain_operands (1)) + if (! constrain_operands (1, get_preferred_alternatives (insn))) return 1; } @@ -2164,6 +2165,21 @@ get_preferred_alternatives (rtx_insn *insn) return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE); } +/* Return the set of alternatives of INSN that are allowed by the current + target and are preferred for the size/speed optimization choice + associated with BB. Passing a separate BB is useful if INSN has not + been emitted yet or if we are considering moving it to a different + block. */ + +alternative_mask +get_preferred_alternatives (rtx_insn *insn, basic_block bb) +{ + if (optimize_bb_for_speed_p (bb)) + return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED); + else + return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE); +} + /* Assert that the cached boolean attributes for INSN are still accurate. The backend is required to define these attributes in a way that only depends on the current target (rather than operands, compiler phase, @@ -2204,7 +2220,7 @@ void extract_constrain_insn (rtx_insn *insn) { extract_insn (insn); - if (!constrain_operands (reload_completed)) + if (!constrain_operands (reload_completed, get_enabled_alternatives (insn))) fatal_insn_not_found (insn); } @@ -2215,16 +2231,17 @@ extract_constrain_insn_cached (rtx_insn *insn) { extract_insn_cached (insn); if (which_alternative == -1 - && !constrain_operands (reload_completed)) + && !constrain_operands (reload_completed, + get_enabled_alternatives (insn))) fatal_insn_not_found (insn); } -/* Do cached constrain_operands and complain about failures. */ +/* Do cached constrain_operands on INSN and complain about failures. */ int -constrain_operands_cached (int strict) +constrain_operands_cached (rtx_insn *insn, int strict) { if (which_alternative == -1) - return constrain_operands (strict); + return constrain_operands (strict, get_enabled_alternatives (insn)); else return 1; } @@ -2500,7 +2517,8 @@ preprocess_constraints (rtx insn) } /* Check the operands of an insn against the insn's operand constraints - and return 1 if they are valid. + and return 1 if they match any of the alternatives in ALTERNATIVES. + The information about the insn's operands, constraints, operand modes etc. is obtained from the global variables set up by extract_insn. @@ -2532,7 +2550,7 @@ struct funny_match }; int -constrain_operands (int strict) +constrain_operands (int strict, alternative_mask alternatives) { const char *constraints[MAX_RECOG_OPERANDS]; int matching_operands[MAX_RECOG_OPERANDS]; @@ -2559,7 +2577,7 @@ constrain_operands (int strict) int lose = 0; funny_match_index = 0; - if (!TEST_BIT (recog_data.enabled_alternatives, which_alternative)) + if (!TEST_BIT (alternatives, which_alternative)) { int i; @@ -2841,7 +2859,7 @@ constrain_operands (int strict) /* If we are about to reject this, but we are not to test strictly, try a very loose test. Only return failure if it fails also. */ if (strict == 0) - return constrain_operands (-1); + return constrain_operands (-1, alternatives); else return 0; } diff --git a/gcc/recog.h b/gcc/recog.h index fe8e0e80e92..c91f661ad56 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -95,8 +95,8 @@ extern void confirm_change_group (void); extern int apply_change_group (void); extern int num_validated_changes (void); extern void cancel_changes (int); -extern int constrain_operands (int); -extern int constrain_operands_cached (int); +extern int constrain_operands (int, alternative_mask); +extern int constrain_operands_cached (rtx_insn *, int); extern int memory_address_addr_space_p (enum machine_mode, rtx, addr_space_t); #define memory_address_p(mode,addr) \ memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC) @@ -414,6 +414,7 @@ extern struct target_recog *this_target_recog; alternative_mask get_enabled_alternatives (rtx_insn *); alternative_mask get_preferred_alternatives (rtx_insn *); +alternative_mask get_preferred_alternatives (rtx_insn *, basic_block); bool check_bool_attrs (rtx_insn *); void recog_init (); diff --git a/gcc/ree.c b/gcc/ree.c index 1ccd88ec53c..30a975c9e81 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -767,7 +767,8 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state) This is merely to keep the test for safety and updating the insn stream simple. Also ensure that within the block the candidate follows the defining insn. */ - if (BLOCK_FOR_INSN (cand->insn) != BLOCK_FOR_INSN (def_insn) + basic_block bb = BLOCK_FOR_INSN (cand->insn); + if (bb != BLOCK_FOR_INSN (def_insn) || DF_INSN_LUID (def_insn) > DF_INSN_LUID (cand->insn)) return false; @@ -817,7 +818,7 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state) if (recog_memoized (insn) == -1) return false; extract_insn (insn); - if (!constrain_operands (1)) + if (!constrain_operands (1, get_preferred_alternatives (insn, bb))) return false; } diff --git a/gcc/reload.c b/gcc/reload.c index 8e92f22084a..b8da67db3a2 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -918,7 +918,7 @@ can_reload_into (rtx in, int regno, enum machine_mode mode) if (recog_memoized (test_insn) >= 0) { extract_insn (test_insn); - r = constrain_operands (1); + r = constrain_operands (1, get_enabled_alternatives (test_insn)); } recog_data = save_recog_data; return r; diff --git a/gcc/reload1.c b/gcc/reload1.c index d706e529b88..74dee444196 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1261,7 +1261,7 @@ reload (rtx_insn *first, int global) if (asm_noperands (PATTERN (insn)) >= 0) { extract_insn (insn); - if (!constrain_operands (1)) + if (!constrain_operands (1, get_enabled_alternatives (insn))) { error_for_asm (insn, "% operand has impossible constraints"); @@ -4713,7 +4713,9 @@ reload_as_needed (int live_known) if (p != insn && INSN_P (p) && GET_CODE (PATTERN (p)) != USE && (recog_memoized (p) < 0 - || (extract_insn (p), ! constrain_operands (1)))) + || (extract_insn (p), + !(constrain_operands (1, + get_enabled_alternatives (p)))))) { error_for_asm (insn, "% operand requires " @@ -4796,7 +4798,8 @@ reload_as_needed (int live_known) if (n) { extract_insn (p); - n = constrain_operands (1); + n = constrain_operands (1, + get_enabled_alternatives (p)); } /* If the constraints were not met, then @@ -5723,7 +5726,7 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2) /* We want constrain operands to treat this insn strictly in its validity determination, i.e., the way it would after reload has completed. */ - result = constrain_operands (1); + result = constrain_operands (1, get_enabled_alternatives (insn)); } delete_insns_since (last); @@ -7393,7 +7396,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl, autoincrement addressing mode, then the resulting insn is ill-formed and we must reject this optimization. */ extract_insn (temp); - if (constrain_operands (1) + if (constrain_operands (1, get_enabled_alternatives (temp)) #ifdef AUTO_INC_DEC && ! find_reg_note (temp, REG_INC, reloadreg) #endif @@ -8580,7 +8583,7 @@ emit_insn_if_valid_for_reload (rtx pat) /* We want constrain operands to treat this insn strictly in its validity determination, i.e., the way it would after reload has completed. */ - if (constrain_operands (1)) + if (constrain_operands (1, get_enabled_alternatives (insn))) return insn; } @@ -9217,7 +9220,7 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount) if (code >= 0) { extract_insn (add_insn); - if (constrain_operands (1)) + if (constrain_operands (1, get_enabled_alternatives (add_insn))) { /* If this is a pre-increment and we have incremented the value where it lives, copy the incremented value to RELOADREG to diff --git a/gcc/reorg.c b/gcc/reorg.c index 57f32bbf787..8d69433e104 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -2769,7 +2769,8 @@ fill_slots_from_thread (rtx_insn *insn, rtx condition, rtx thread_or_return, insn); if (recog_memoized (ninsn) < 0 - || (extract_insn (ninsn), ! constrain_operands (1))) + || (extract_insn (ninsn), + !constrain_operands (1, get_preferred_alternatives (ninsn)))) { delete_related_insns (ninsn); return 0; -- 2.30.2