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
This commit is contained in:
Richard Sandiford 2014-10-22 12:02:26 +00:00 committed by Richard Sandiford
parent 9840b2fa87
commit daca1a96af
15 changed files with 100 additions and 42 deletions

View File

@ -1,3 +1,28 @@
2014-10-22 Richard Sandiford <richard.sandiford@arm.com>
* 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 <richard.sandiford@arm.com> 2014-10-22 Richard Sandiford <richard.sandiford@arm.com>
* doc/md.texi: Document "preferred_for_size" and "preferred_for_speed" * doc/md.texi: Document "preferred_for_size" and "preferred_for_speed"

View File

@ -143,15 +143,17 @@ reg_save_code (int reg, enum machine_mode mode)
cached_reg_restore_code[reg][mode] = recog_memoized (restinsn); cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);
/* Now extract both insns and see if we can meet their /* 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 ok = (cached_reg_save_code[reg][mode] != -1
&& cached_reg_restore_code[reg][mode] != -1); && cached_reg_restore_code[reg][mode] != -1);
if (ok) if (ok)
{ {
extract_insn (saveinsn); extract_insn (saveinsn);
ok = constrain_operands (1); ok = constrain_operands (1, get_enabled_alternatives (saveinsn));
extract_insn (restinsn); extract_insn (restinsn);
ok &= constrain_operands (1); ok &= constrain_operands (1, get_enabled_alternatives (restinsn));
} }
if (! ok) if (! ok)

View File

@ -25467,7 +25467,7 @@ ix86_attr_length_address_default (rtx_insn *insn)
for (i = recog_data.n_operands - 1; i >= 0; --i) for (i = recog_data.n_operands - 1; i >= 0; --i)
if (MEM_P (recog_data.operand[i])) if (MEM_P (recog_data.operand[i]))
{ {
constrain_operands_cached (reload_completed); constrain_operands_cached (insn, reload_completed);
if (which_alternative != -1) if (which_alternative != -1)
{ {
const char *constraints = recog_data.constraints[i]; const char *constraints = recog_data.constraints[i];

View File

@ -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); XVECEXP (PATTERN (new_rtx), 0, 1) = PATTERN (floater);
INSN_CODE (new_rtx) = -1; INSN_CODE (new_rtx) = -1;
insn_code_number = recog_memoized (new_rtx); insn_code_number = recog_memoized (new_rtx);
basic_block bb = BLOCK_FOR_INSN (anchor);
if (insn_code_number < 0 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; return 0;
if (reversed) if (reversed)

View File

@ -2170,7 +2170,7 @@ insn_ok_now (rtx_insn *insn)
if (recog (pattern, insn, 0) > -1) if (recog (pattern, insn, 0) > -1)
{ {
extract_insn (insn); extract_insn (insn);
if (constrain_operands (1)) if (constrain_operands (1, get_preferred_alternatives (insn)))
{ {
#if DEBUG_ALLOC #if DEBUG_ALLOC
fprintf (stderr, "\033[32m"); fprintf (stderr, "\033[32m");
@ -2199,7 +2199,7 @@ insn_ok_now (rtx_insn *insn)
if (recog (pattern, insn, 0) > -1) if (recog (pattern, insn, 0) > -1)
{ {
extract_insn (insn); extract_insn (insn);
if (constrain_operands (0)) if (constrain_operands (0, get_preferred_alternatives (insn)))
{ {
cfun->machine->virt_insns_ok = 0; cfun->machine->virt_insns_ok = 0;
return false; return false;

View File

@ -1580,7 +1580,7 @@
(set (match_dup 4) (match_dup 5))] (set (match_dup 4) (match_dup 5))]
{ {
rtx set1, set2; rtx set1, set2;
rtx_insn *insn2; rtx_insn *insn1, *insn2;
rtx replacements[4]; rtx replacements[4];
/* We want to replace occurrences of operands[0] with operands[1] and /* 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 /* ??? The last insn might be a jump insn, but the generic peephole2 code
always uses emit_insn. */ always uses emit_insn. */
/* Check that we don't violate matching constraints or earlyclobbers. */ /* Check that we don't violate matching constraints or earlyclobbers. */
extract_insn (emit_insn (set1)); basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2));
if (! constrain_operands (1)) insn1 = emit_insn (set1);
extract_insn (insn1);
if (! constrain_operands (1, get_preferred_alternatives (insn1, bb)))
goto failure; goto failure;
insn2 = emit (set2); insn2 = emit (set2);
if (GET_CODE (insn2) == BARRIER) if (GET_CODE (insn2) == BARRIER)
goto failure; goto failure;
extract_insn (insn2); extract_insn (insn2);
if (! constrain_operands (1)) if (! constrain_operands (1, get_preferred_alternatives (insn2, bb)))
{ {
rtx tmp; rtx tmp;
failure: failure:

View File

@ -2934,7 +2934,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
print_rtx_head = ""; print_rtx_head = "";
} }
if (! constrain_operands_cached (1)) if (! constrain_operands_cached (insn, 1))
fatal_insn_not_found (insn); fatal_insn_not_found (insn);
/* Some target machines need to prescan each insn before /* Some target machines need to prescan each insn before

View File

@ -1765,7 +1765,9 @@ setup_prohibited_mode_move_regs (void)
if (INSN_CODE (move_insn) < 0) if (INSN_CODE (move_insn) < 0)
continue; continue;
extract_insn (move_insn); 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; continue;
CLEAR_HARD_REG_BIT (ira_prohibited_mode_move_regs[i], j); CLEAR_HARD_REG_BIT (ira_prohibited_mode_move_regs[i], j);
} }

View File

@ -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 /* Make sure we can generate a move from register avail_reg to
dest. */ dest. */
extract_insn (as_a <rtx_insn *> ( rtx_insn *move = as_a <rtx_insn *>
gen_move_insn (copy_rtx (dest), (gen_move_insn (copy_rtx (dest), copy_rtx (avail_reg)));
copy_rtx (avail_reg)))); extract_insn (move);
if (! constrain_operands (1) if (! constrain_operands (1, get_preferred_alternatives (insn,
pred_bb))
|| reg_killed_on_edge (avail_reg, pred) || reg_killed_on_edge (avail_reg, pred)
|| reg_used_on_edge (dest, pred)) || reg_used_on_edge (dest, pred))
{ {

View File

@ -160,8 +160,9 @@ check_asm_operands (rtx x)
if (reload_completed) if (reload_completed)
{ {
/* ??? Doh! We've not got the wrapping insn. Cook one up. */ /* ??? Doh! We've not got the wrapping insn. Cook one up. */
extract_insn (make_insn_raw (x)); rtx_insn *insn = make_insn_raw (x);
constrain_operands (1); extract_insn (insn);
constrain_operands (1, get_enabled_alternatives (insn));
return which_alternative >= 0; return which_alternative >= 0;
} }
@ -365,7 +366,7 @@ insn_invalid_p (rtx_insn *insn, bool in_group)
{ {
extract_insn (insn); extract_insn (insn);
if (! constrain_operands (1)) if (! constrain_operands (1, get_preferred_alternatives (insn)))
return 1; return 1;
} }
@ -2164,6 +2165,21 @@ get_preferred_alternatives (rtx_insn *insn)
return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE); 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. /* Assert that the cached boolean attributes for INSN are still accurate.
The backend is required to define these attributes in a way that only The backend is required to define these attributes in a way that only
depends on the current target (rather than operands, compiler phase, depends on the current target (rather than operands, compiler phase,
@ -2204,7 +2220,7 @@ void
extract_constrain_insn (rtx_insn *insn) extract_constrain_insn (rtx_insn *insn)
{ {
extract_insn (insn); extract_insn (insn);
if (!constrain_operands (reload_completed)) if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
fatal_insn_not_found (insn); fatal_insn_not_found (insn);
} }
@ -2215,16 +2231,17 @@ extract_constrain_insn_cached (rtx_insn *insn)
{ {
extract_insn_cached (insn); extract_insn_cached (insn);
if (which_alternative == -1 if (which_alternative == -1
&& !constrain_operands (reload_completed)) && !constrain_operands (reload_completed,
get_enabled_alternatives (insn)))
fatal_insn_not_found (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 int
constrain_operands_cached (int strict) constrain_operands_cached (rtx_insn *insn, int strict)
{ {
if (which_alternative == -1) if (which_alternative == -1)
return constrain_operands (strict); return constrain_operands (strict, get_enabled_alternatives (insn));
else else
return 1; return 1;
} }
@ -2500,7 +2517,8 @@ preprocess_constraints (rtx insn)
} }
/* Check the operands of an insn against the insn's operand constraints /* 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 The information about the insn's operands, constraints, operand modes
etc. is obtained from the global variables set up by extract_insn. etc. is obtained from the global variables set up by extract_insn.
@ -2532,7 +2550,7 @@ struct funny_match
}; };
int int
constrain_operands (int strict) constrain_operands (int strict, alternative_mask alternatives)
{ {
const char *constraints[MAX_RECOG_OPERANDS]; const char *constraints[MAX_RECOG_OPERANDS];
int matching_operands[MAX_RECOG_OPERANDS]; int matching_operands[MAX_RECOG_OPERANDS];
@ -2559,7 +2577,7 @@ constrain_operands (int strict)
int lose = 0; int lose = 0;
funny_match_index = 0; funny_match_index = 0;
if (!TEST_BIT (recog_data.enabled_alternatives, which_alternative)) if (!TEST_BIT (alternatives, which_alternative))
{ {
int i; int i;
@ -2841,7 +2859,7 @@ constrain_operands (int strict)
/* If we are about to reject this, but we are not to test strictly, /* 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. */ try a very loose test. Only return failure if it fails also. */
if (strict == 0) if (strict == 0)
return constrain_operands (-1); return constrain_operands (-1, alternatives);
else else
return 0; return 0;
} }

View File

@ -95,8 +95,8 @@ extern void confirm_change_group (void);
extern int apply_change_group (void); extern int apply_change_group (void);
extern int num_validated_changes (void); extern int num_validated_changes (void);
extern void cancel_changes (int); extern void cancel_changes (int);
extern int constrain_operands (int); extern int constrain_operands (int, alternative_mask);
extern int constrain_operands_cached (int); extern int constrain_operands_cached (rtx_insn *, int);
extern int memory_address_addr_space_p (enum machine_mode, rtx, addr_space_t); extern int memory_address_addr_space_p (enum machine_mode, rtx, addr_space_t);
#define memory_address_p(mode,addr) \ #define memory_address_p(mode,addr) \
memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC) 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_enabled_alternatives (rtx_insn *);
alternative_mask get_preferred_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 *); bool check_bool_attrs (rtx_insn *);
void recog_init (); void recog_init ();

View File

@ -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 This is merely to keep the test for safety and updating the insn
stream simple. Also ensure that within the block the candidate stream simple. Also ensure that within the block the candidate
follows the defining insn. */ 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)) || DF_INSN_LUID (def_insn) > DF_INSN_LUID (cand->insn))
return false; return false;
@ -817,7 +818,7 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
if (recog_memoized (insn) == -1) if (recog_memoized (insn) == -1)
return false; return false;
extract_insn (insn); extract_insn (insn);
if (!constrain_operands (1)) if (!constrain_operands (1, get_preferred_alternatives (insn, bb)))
return false; return false;
} }

View File

@ -918,7 +918,7 @@ can_reload_into (rtx in, int regno, enum machine_mode mode)
if (recog_memoized (test_insn) >= 0) if (recog_memoized (test_insn) >= 0)
{ {
extract_insn (test_insn); extract_insn (test_insn);
r = constrain_operands (1); r = constrain_operands (1, get_enabled_alternatives (test_insn));
} }
recog_data = save_recog_data; recog_data = save_recog_data;
return r; return r;

View File

@ -1261,7 +1261,7 @@ reload (rtx_insn *first, int global)
if (asm_noperands (PATTERN (insn)) >= 0) if (asm_noperands (PATTERN (insn)) >= 0)
{ {
extract_insn (insn); extract_insn (insn);
if (!constrain_operands (1)) if (!constrain_operands (1, get_enabled_alternatives (insn)))
{ {
error_for_asm (insn, error_for_asm (insn,
"%<asm%> operand has impossible constraints"); "%<asm%> operand has impossible constraints");
@ -4713,7 +4713,9 @@ reload_as_needed (int live_known)
if (p != insn && INSN_P (p) if (p != insn && INSN_P (p)
&& GET_CODE (PATTERN (p)) != USE && GET_CODE (PATTERN (p)) != USE
&& (recog_memoized (p) < 0 && (recog_memoized (p) < 0
|| (extract_insn (p), ! constrain_operands (1)))) || (extract_insn (p),
!(constrain_operands (1,
get_enabled_alternatives (p))))))
{ {
error_for_asm (insn, error_for_asm (insn,
"%<asm%> operand requires " "%<asm%> operand requires "
@ -4796,7 +4798,8 @@ reload_as_needed (int live_known)
if (n) if (n)
{ {
extract_insn (p); extract_insn (p);
n = constrain_operands (1); n = constrain_operands (1,
get_enabled_alternatives (p));
} }
/* If the constraints were not met, then /* 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 /* We want constrain operands to treat this insn strictly in
its validity determination, i.e., the way it would after its validity determination, i.e., the way it would after
reload has completed. */ reload has completed. */
result = constrain_operands (1); result = constrain_operands (1, get_enabled_alternatives (insn));
} }
delete_insns_since (last); 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 autoincrement addressing mode, then the resulting insn
is ill-formed and we must reject this optimization. */ is ill-formed and we must reject this optimization. */
extract_insn (temp); extract_insn (temp);
if (constrain_operands (1) if (constrain_operands (1, get_enabled_alternatives (temp))
#ifdef AUTO_INC_DEC #ifdef AUTO_INC_DEC
&& ! find_reg_note (temp, REG_INC, reloadreg) && ! find_reg_note (temp, REG_INC, reloadreg)
#endif #endif
@ -8580,7 +8583,7 @@ emit_insn_if_valid_for_reload (rtx pat)
/* We want constrain operands to treat this insn strictly in its /* We want constrain operands to treat this insn strictly in its
validity determination, i.e., the way it would after reload has validity determination, i.e., the way it would after reload has
completed. */ completed. */
if (constrain_operands (1)) if (constrain_operands (1, get_enabled_alternatives (insn)))
return insn; return insn;
} }
@ -9217,7 +9220,7 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
if (code >= 0) if (code >= 0)
{ {
extract_insn (add_insn); 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 /* If this is a pre-increment and we have incremented the value
where it lives, copy the incremented value to RELOADREG to where it lives, copy the incremented value to RELOADREG to

View File

@ -2769,7 +2769,8 @@ fill_slots_from_thread (rtx_insn *insn, rtx condition, rtx thread_or_return,
insn); insn);
if (recog_memoized (ninsn) < 0 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); delete_related_insns (ninsn);
return 0; return 0;