aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-constraints.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r--gcc/lra-constraints.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index b5c010d..80ca1e0 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -406,8 +406,10 @@ valid_address_p (rtx op, struct address_info *ad,
address_eliminator eliminator (ad);
/* Allow a memory OP if it matches CONSTRAINT, even if CONSTRAINT is more
- forgiving than "m". */
- if (MEM_P (op)
+ forgiving than "m".
+ Need to extract memory from op for special memory constraint,
+ i.e. bcst_mem_operand in i386 backend. */
+ if (MEM_P (extract_mem_from_operand (op))
&& (insn_extra_memory_constraint (constraint)
|| insn_extra_special_memory_constraint (constraint))
&& constraint_satisfied_p (op, constraint))
@@ -2426,7 +2428,8 @@ process_alt_operands (int only_alternative)
break;
case CT_MEMORY:
- if (satisfies_memory_constraint_p (op, cn))
+ if (MEM_P (op)
+ && satisfies_memory_constraint_p (op, cn))
win = true;
else if (spilled_pseudo_p (op))
win = true;
@@ -2505,7 +2508,7 @@ process_alt_operands (int only_alternative)
while ((p += len), c);
scratch_p = (operand_reg[nop] != NULL_RTX
- && lra_former_scratch_p (REGNO (operand_reg[nop])));
+ && ira_former_scratch_p (REGNO (operand_reg[nop])));
/* Record which operands fit this alternative. */
if (win)
{
@@ -3427,13 +3430,14 @@ process_address_1 (int nop, bool check_only_p,
rtx new_reg;
HOST_WIDE_INT scale;
rtx op = *curr_id->operand_loc[nop];
+ rtx mem = extract_mem_from_operand (op);
const char *constraint = curr_static_id->operand[nop].constraint;
enum constraint_num cn = lookup_constraint (constraint);
bool change_p = false;
- if (MEM_P (op)
- && GET_MODE (op) == BLKmode
- && GET_CODE (XEXP (op, 0)) == SCRATCH)
+ if (MEM_P (mem)
+ && GET_MODE (mem) == BLKmode
+ && GET_CODE (XEXP (mem, 0)) == SCRATCH)
return false;
if (insn_extra_address_constraint (cn)
@@ -3446,12 +3450,14 @@ process_address_1 (int nop, bool check_only_p,
&& curr_static_id->operand[nop].is_address)
decompose_lea_address (&ad, curr_id->operand_loc[nop]);
/* Do not attempt to decompose arbitrary addresses generated by combine
- for asm operands with loose constraints, e.g 'X'. */
- else if (MEM_P (op)
+ for asm operands with loose constraints, e.g 'X'.
+ Need to extract memory from op for special memory constraint,
+ i.e. bcst_mem_operand in i386 backend. */
+ else if (MEM_P (mem)
&& !(INSN_CODE (curr_insn) < 0
&& get_constraint_type (cn) == CT_FIXED_FORM
&& constraint_satisfied_p (op, cn)))
- decompose_mem_address (&ad, op);
+ decompose_mem_address (&ad, mem);
else if (GET_CODE (op) == SUBREG
&& MEM_P (SUBREG_REG (op)))
decompose_mem_address (&ad, SUBREG_REG (op));
@@ -3948,10 +3954,10 @@ curr_insn_transform (bool check_only_p)
no_input_reloads_p = no_output_reloads_p = false;
goal_alt_number = -1;
change_p = sec_mem_p = false;
- /* JUMP_INSNs and CALL_INSNs are not allowed to have any output
- reloads; neither are insns that SET cc0. Insns that use CC0 are
- not allowed to have any input reloads. */
- if (JUMP_P (curr_insn) || CALL_P (curr_insn))
+ /* CALL_INSNs are not allowed to have any output reloads; neither
+ are insns that SET cc0. Insns that use CC0 are not allowed to
+ have any input reloads. */
+ if (CALL_P (curr_insn))
no_output_reloads_p = true;
if (HAVE_cc0 && reg_referenced_p (cc0_rtx, PATTERN (curr_insn)))
@@ -4098,9 +4104,18 @@ curr_insn_transform (bool check_only_p)
error_for_asm (curr_insn,
"inconsistent operand constraints in an %<asm%>");
lra_asm_error_p = true;
- /* Avoid further trouble with this insn. Don't generate use
- pattern here as we could use the insn SP offset. */
- lra_set_insn_deleted (curr_insn);
+ if (! JUMP_P (curr_insn))
+ {
+ /* Avoid further trouble with this insn. Don't generate use
+ pattern here as we could use the insn SP offset. */
+ lra_set_insn_deleted (curr_insn);
+ }
+ else
+ {
+ lra_invalidate_insn_data (curr_insn);
+ ira_nullify_asm_goto (curr_insn);
+ lra_update_insn_regno_info (curr_insn);
+ }
return true;
}
@@ -4354,8 +4369,8 @@ curr_insn_transform (bool check_only_p)
assigment pass and the scratch pseudo will be
spilled. Spilled scratch pseudos are transformed
back to scratches at the LRA end. */
- && lra_former_scratch_operand_p (curr_insn, i)
- && lra_former_scratch_p (REGNO (op)))
+ && ira_former_scratch_operand_p (curr_insn, i)
+ && ira_former_scratch_p (REGNO (op)))
{
int regno = REGNO (op);
lra_change_class (regno, NO_REGS, " Change to", true);
@@ -4376,7 +4391,7 @@ curr_insn_transform (bool check_only_p)
&& goal_alt[i] != NO_REGS && REG_P (op)
&& (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
&& regno < new_regno_start
- && ! lra_former_scratch_p (regno)
+ && ! ira_former_scratch_p (regno)
&& reg_renumber[regno] < 0
/* Check that the optional reload pseudo will be able to
hold given mode value. */