diff options
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 55 |
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. */ |