It was about 9 months since I checked LRA for s390 last time. No wonder, that it is completely broken. The following patch at least permits to build s390 GCC with LRA.

The patch was successfully bootstrapped on x864/x86-64, ppc64, and ia64.

Committed as rev. 196553.

2013-03-08  Vladimir Makarov  <vmaka...@redhat.com>

        * lra-constraints.c (process_alt_operands): Don't penalize
        alternative of move insn which is an elimination result.
        (process_address): Use EXTRA_CONSTRAINT_STR for validation of
        extra address constraints.
        * lra-eliminations.c (eliminate_regs_in_insn): Make return earlier
        if there are no operand changes.
        * lra-spills.c (lra_final_code_change): Skip subreg change for
        operators.

Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 196509)
+++ lra-constraints.c   (working copy)
@@ -2068,7 +2068,11 @@ process_alt_operands (int only_alternati
                                         no_subreg_reg_operand[1])
                      || (targetm.preferred_reload_class
                          (no_subreg_reg_operand[1],
-                          (enum reg_class) curr_alt[1]) != NO_REGS)))))
+                          (enum reg_class) curr_alt[1]) != NO_REGS))
+                 /* If it is a result of recent elimination in move
+                    insn we can transform it into an add still by
+                    using this alternative.  */
+                 && GET_CODE (no_subreg_reg_operand[1]) != PLUS)))
        /* We have a move insn and a new reload insn will be similar
           to the current insn.  We should avoid such situation as it
           results in LRA cycling.  */
@@ -2444,6 +2448,15 @@ process_address (int nop, rtx *before, r
       && process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS))
     change_p = true;
 
+#ifdef EXTRA_CONSTRAINT_STR
+  /* Target hooks sometimes reject extra constraint addresses -- use
+     EXTRA_CONSTRAINT_STR for the validation.  */
+  if (constraint[0] != 'p'
+      && EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint)
+      && EXTRA_CONSTRAINT_STR (op, constraint[0], constraint))
+    return change_p;
+#endif
+
   /* There are three cases where the shape of *AD.INNER may now be invalid:
 
      1) the original address was valid, but either elimination or
Index: lra-eliminations.c
===================================================================
--- lra-eliminations.c  (revision 196509)
+++ lra-eliminations.c  (working copy)
@@ -977,6 +977,9 @@ eliminate_regs_in_insn (rtx insn, bool r
        }
     }
 
+  if (! validate_p)
+    return;
+
   /* Substitute the operands; the new values are in the substed_operand
      array.  */
   for (i = 0; i < static_id->n_operands; i++)
@@ -984,16 +987,13 @@ eliminate_regs_in_insn (rtx insn, bool r
   for (i = 0; i < static_id->n_dups; i++)
     *id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]];
 
-  if (validate_p)
-    {
-      /* If we had a move insn but now we don't, re-recognize it.
-        This will cause spurious re-recognition if the old move had a
-        PARALLEL since the new one still will, but we can't call
-        single_set without having put new body into the insn and the
-        re-recognition won't hurt in this rare case.  */
-      id = lra_update_insn_recog_data (insn);
-      static_id = id->insn_static_data;
-    }
+  /* If we had a move insn but now we don't, re-recognize it.
+     This will cause spurious re-recognition if the old move had a
+     PARALLEL since the new one still will, but we can't call
+     single_set without having put new body into the insn and the
+     re-recognition won't hurt in this rare case.  */
+  id = lra_update_insn_recog_data (insn);
+  static_id = id->insn_static_data;
 }
 
 /* Spill pseudos which are assigned to hard registers in SET.  Add
Index: lra-spills.c
===================================================================
--- lra-spills.c        (revision 196509)
+++ lra-spills.c        (working copy)
@@ -644,10 +644,12 @@ lra_final_code_change (void)
            }
 
          lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+         struct lra_static_insn_data *static_id = id->insn_static_data;
          bool insn_change_p = false;
 
          for (i = id->insn_static_data->n_operands - 1; i >= 0; i--)
-           if (alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn)))
+           if ((DEBUG_INSN_P (insn) || ! static_id->operand[i].is_operator)
+               && alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn)))
              {
                lra_update_dup (id, i);
                insn_change_p = true;

Reply via email to