mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-13 22:03:43 +08:00
Extend special_memory_constraint.
For operand with special_memory_constraint, there could be a wrapper for memory_operand. Extract mem for operand for conditional judgement like MEM_P, also for record_address_regs. gcc/ChangeLog: PR target/87767 * ira-costs.c (record_operand_costs): Extract memory operand from recog_data.operand[i] for record_address_regs. (record_reg_classes): Extract memory operand from OP for conditional judgement MEM_P. * ira.c (ira_setup_alts): Ditto. * lra-constraints.c (extract_mem_from_operand): New function. (satisfies_memory_constraint_p): Extract memory operand from OP for decompose_mem_address, return false when there's no memory operand inside OP. (process_alt_operands): Remove MEM_P (op) since it would be judged in satisfies_memory_constraint_p. * recog.c (asm_operand_ok): Extract memory operand from OP for judgement of memory_operand (OP, VOIDmode). (constrain_operands): Don't unwrapper unary operator when there's memory operand inside. * rtl.h (extract_mem_from_operand): New decl.
This commit is contained in:
parent
76835dca95
commit
4de7b01003
@ -781,7 +781,8 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
|
|||||||
|
|
||||||
case CT_SPECIAL_MEMORY:
|
case CT_SPECIAL_MEMORY:
|
||||||
insn_allows_mem[i] = allows_mem[i] = 1;
|
insn_allows_mem[i] = allows_mem[i] = 1;
|
||||||
if (MEM_P (op) && constraint_satisfied_p (op, cn))
|
if (MEM_P (extract_mem_from_operand (op))
|
||||||
|
&& constraint_satisfied_p (op, cn))
|
||||||
win = 1;
|
win = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1397,15 +1398,16 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
|
|||||||
commutative. */
|
commutative. */
|
||||||
for (i = 0; i < recog_data.n_operands; i++)
|
for (i = 0; i < recog_data.n_operands; i++)
|
||||||
{
|
{
|
||||||
|
rtx op_mem = extract_mem_from_operand (recog_data.operand[i]);
|
||||||
memcpy (op_costs[i], init_cost, struct_costs_size);
|
memcpy (op_costs[i], init_cost, struct_costs_size);
|
||||||
|
|
||||||
if (GET_CODE (recog_data.operand[i]) == SUBREG)
|
if (GET_CODE (recog_data.operand[i]) == SUBREG)
|
||||||
recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
|
recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
|
||||||
|
|
||||||
if (MEM_P (recog_data.operand[i]))
|
if (MEM_P (op_mem))
|
||||||
record_address_regs (GET_MODE (recog_data.operand[i]),
|
record_address_regs (GET_MODE (op_mem),
|
||||||
MEM_ADDR_SPACE (recog_data.operand[i]),
|
MEM_ADDR_SPACE (op_mem),
|
||||||
XEXP (recog_data.operand[i], 0),
|
XEXP (op_mem, 0),
|
||||||
0, MEM, SCRATCH, frequency * 2);
|
0, MEM, SCRATCH, frequency * 2);
|
||||||
else if (constraints[i][0] == 'p'
|
else if (constraints[i][0] == 'p'
|
||||||
|| (insn_extra_address_constraint
|
|| (insn_extra_address_constraint
|
||||||
|
@ -1868,7 +1868,7 @@ ira_setup_alts (rtx_insn *insn)
|
|||||||
|
|
||||||
case CT_MEMORY:
|
case CT_MEMORY:
|
||||||
case CT_SPECIAL_MEMORY:
|
case CT_SPECIAL_MEMORY:
|
||||||
if (MEM_P (op))
|
if (MEM_P (extract_mem_from_operand (op)))
|
||||||
goto op_success;
|
goto op_success;
|
||||||
win_p = true;
|
win_p = true;
|
||||||
break;
|
break;
|
||||||
|
@ -416,14 +416,34 @@ valid_address_p (rtx op, struct address_info *ad,
|
|||||||
return valid_address_p (ad->mode, *ad->outer, ad->as);
|
return valid_address_p (ad->mode, *ad->outer, ad->as);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For special_memory_operand, it could be false for MEM_P (op),
|
||||||
|
i.e. bcst_mem_operand in i386 backend.
|
||||||
|
Extract and return real memory operand or op. */
|
||||||
|
rtx
|
||||||
|
extract_mem_from_operand (rtx op)
|
||||||
|
{
|
||||||
|
for (rtx x = op;; x = XEXP (x, 0))
|
||||||
|
{
|
||||||
|
if (MEM_P (x))
|
||||||
|
return x;
|
||||||
|
if (GET_RTX_LENGTH (GET_CODE (x)) != 1
|
||||||
|
|| GET_RTX_FORMAT (GET_CODE (x))[0] != 'e')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return true if the eliminated form of memory reference OP satisfies
|
/* Return true if the eliminated form of memory reference OP satisfies
|
||||||
extra (special) memory constraint CONSTRAINT. */
|
extra (special) memory constraint CONSTRAINT. */
|
||||||
static bool
|
static bool
|
||||||
satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
|
satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
|
||||||
{
|
{
|
||||||
struct address_info ad;
|
struct address_info ad;
|
||||||
|
rtx mem = extract_mem_from_operand (op);
|
||||||
|
if (!MEM_P (mem))
|
||||||
|
return false;
|
||||||
|
|
||||||
decompose_mem_address (&ad, op);
|
decompose_mem_address (&ad, mem);
|
||||||
address_eliminator eliminator (&ad);
|
address_eliminator eliminator (&ad);
|
||||||
return constraint_satisfied_p (op, constraint);
|
return constraint_satisfied_p (op, constraint);
|
||||||
}
|
}
|
||||||
@ -2406,8 +2426,7 @@ process_alt_operands (int only_alternative)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_MEMORY:
|
case CT_MEMORY:
|
||||||
if (MEM_P (op)
|
if (satisfies_memory_constraint_p (op, cn))
|
||||||
&& satisfies_memory_constraint_p (op, cn))
|
|
||||||
win = true;
|
win = true;
|
||||||
else if (spilled_pseudo_p (op))
|
else if (spilled_pseudo_p (op))
|
||||||
win = true;
|
win = true;
|
||||||
@ -2448,8 +2467,7 @@ process_alt_operands (int only_alternative)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_SPECIAL_MEMORY:
|
case CT_SPECIAL_MEMORY:
|
||||||
if (MEM_P (op)
|
if (satisfies_memory_constraint_p (op, cn))
|
||||||
&& satisfies_memory_constraint_p (op, cn))
|
|
||||||
win = true;
|
win = true;
|
||||||
else if (spilled_pseudo_p (op))
|
else if (spilled_pseudo_p (op))
|
||||||
win = true;
|
win = true;
|
||||||
|
@ -1798,7 +1798,8 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
|
|||||||
case CT_MEMORY:
|
case CT_MEMORY:
|
||||||
case CT_SPECIAL_MEMORY:
|
case CT_SPECIAL_MEMORY:
|
||||||
/* Every memory operand can be reloaded to fit. */
|
/* Every memory operand can be reloaded to fit. */
|
||||||
result = result || memory_operand (op, VOIDmode);
|
result = result || memory_operand (extract_mem_from_operand (op),
|
||||||
|
VOIDmode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_ADDRESS:
|
case CT_ADDRESS:
|
||||||
@ -2584,7 +2585,9 @@ constrain_operands (int strict, alternative_mask alternatives)
|
|||||||
|
|
||||||
/* A unary operator may be accepted by the predicate, but it
|
/* A unary operator may be accepted by the predicate, but it
|
||||||
is irrelevant for matching constraints. */
|
is irrelevant for matching constraints. */
|
||||||
if (UNARY_P (op))
|
/* For special_memory_operand, there could be a memory operand inside,
|
||||||
|
and it would cause a mismatch for constraint_satisfied_p. */
|
||||||
|
if (UNARY_P (op) && op == extract_mem_from_operand (op))
|
||||||
op = XEXP (op, 0);
|
op = XEXP (op, 0);
|
||||||
|
|
||||||
if (GET_CODE (op) == SUBREG)
|
if (GET_CODE (op) == SUBREG)
|
||||||
|
@ -4324,6 +4324,7 @@ extern rtx gen_hard_reg_clobber (machine_mode, unsigned int);
|
|||||||
extern rtx get_reg_known_value (unsigned int);
|
extern rtx get_reg_known_value (unsigned int);
|
||||||
extern bool get_reg_known_equiv_p (unsigned int);
|
extern bool get_reg_known_equiv_p (unsigned int);
|
||||||
extern rtx get_reg_base_value (unsigned int);
|
extern rtx get_reg_base_value (unsigned int);
|
||||||
|
extern rtx extract_mem_from_operand (rtx);
|
||||||
|
|
||||||
#ifdef STACK_REGS
|
#ifdef STACK_REGS
|
||||||
extern int stack_regs_mentioned (const_rtx insn);
|
extern int stack_regs_mentioned (const_rtx insn);
|
||||||
|
Loading…
Reference in New Issue
Block a user