===================================================================
@@ -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 @@ #define this_target_recog (&default_targ
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 ();
===================================================================
@@ -155,8 +155,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;
}
@@ -360,7 +361,7 @@ insn_invalid_p (rtx_insn *insn, bool in_
{
extract_insn (insn);
- if (! constrain_operands (1))
+ if (! constrain_operands (1, get_preferred_alternatives (insn)))
return 1;
}
@@ -2159,6 +2160,21 @@ get_preferred_alternatives (rtx_insn *in
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,
@@ -2199,7 +2215,7 @@ extract_insn_cached (rtx_insn *insn)
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);
}
@@ -2210,16 +2226,17 @@ extract_constrain_insn_cached (rtx_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;
}
@@ -2495,7 +2512,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.
@@ -2527,7 +2545,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];
@@ -2554,7 +2572,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;
@@ -2836,7 +2854,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;
}
===================================================================
@@ -138,15 +138,17 @@ reg_save_code (int reg, enum machine_mod
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)
===================================================================
@@ -1760,7 +1760,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);
}
===================================================================
@@ -1003,10 +1003,11 @@ eliminate_partially_redundant_load (basi
/* Make sure we can generate a move from register avail_reg to
dest. */
- extract_insn (as_a <rtx_insn *> (
- gen_move_insn (copy_rtx (dest),
- copy_rtx (avail_reg))));
- if (! constrain_operands (1)
+ rtx_insn *move = as_a <rtx_insn *>
+ (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))
{
===================================================================
@@ -762,7 +762,8 @@ combine_reaching_defs (ext_cand *cand, c
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;
@@ -812,7 +813,7 @@ combine_reaching_defs (ext_cand *cand, c
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;
}
===================================================================
@@ -913,7 +913,7 @@ can_reload_into (rtx in, int regno, enum
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;
===================================================================
@@ -1257,7 +1257,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,
"%<asm%> operand has impossible constraints");
@@ -4709,7 +4709,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,
"%<asm%> operand requires "
@@ -4792,7 +4794,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
@@ -5719,7 +5722,7 @@ gen_reload_chain_without_interm_reg_p (i
/* 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);
@@ -7389,7 +7392,7 @@ emit_input_reload_insns (struct insn_cha
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
@@ -8576,7 +8579,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;
}
@@ -9213,7 +9216,7 @@ inc_for_reload (rtx reloadreg, rtx in, r
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
===================================================================
@@ -2764,7 +2764,8 @@ fill_slots_from_thread (rtx_insn *insn,
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;
===================================================================
@@ -25300,7 +25300,7 @@ ix86_attr_length_address_default (rtx_in
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];
===================================================================
@@ -9199,8 +9199,10 @@ pa_can_combine_p (rtx_insn *new_rtx, rtx
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)
===================================================================
@@ -2165,7 +2165,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");
@@ -2194,7 +2194,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;
===================================================================
@@ -1567,7 +1567,7 @@ (define_peephole2
(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
@@ -1594,14 +1594,16 @@ (define_peephole2
/* ??? 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:
===================================================================
@@ -2929,7 +2929,7 @@ final_scan_insn (rtx_insn *insn, FILE *f
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