On 13-04-17 11:11 PM, Shiva Chen wrote:
Hi, Vladimir

Overlapped live range RTL is from line 7577 to 7597 in test2.c.209r.reload

Previous patch probably not completed.
The new patch will record lra_reg_info[i].offset as the offset from
eliminate register to the pseudo i
and keep updating when the stack has been changed.
Therefore, lra-assign could get the latest offset to identify the
pseudo content is equal or not.

  gcc/lra-assigns.c      |    6 ++++--
  gcc/lra-eliminations.c |   12 ++++++++++--
  gcc/lra-int.h          |    2 ++
  gcc/lra.c              |    5 ++++-
  4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index b204513..daf0aa9 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -448,7 +448,7 @@ find_hard_regno_for (int regno, int *cost, int
try_only_hard_regno)
    int hr, conflict_hr, nregs;
    enum machine_mode biggest_mode;
    unsigned int k, conflict_regno;
-  int val, biggest_nregs, nregs_diff;
+  int offset, val, biggest_nregs, nregs_diff;
    enum reg_class rclass;
    bitmap_iterator bi;
    bool *rclass_intersect_p;
@@ -508,9 +508,11 @@ find_hard_regno_for (int regno, int *cost, int
try_only_hard_regno)
  #endif
    sparseset_clear_bit (conflict_reload_and_inheritance_pseudos, regno);
    val = lra_reg_info[regno].val;
+  offset = lra_reg_info[regno].offset;
    CLEAR_HARD_REG_SET (impossible_start_hard_regs);
    EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
-    if (val == lra_reg_info[conflict_regno].val)
+    if ((val == lra_reg_info[conflict_regno].val)
+        && (offset == lra_reg_info[conflict_regno].offset))
        {
         conflict_hr = live_pseudos_reg_renumber[conflict_regno];
         nregs = (hard_regno_nregs[conflict_hr]
diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index 9df0bae..2d34b51 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -1046,6 +1046,7 @@ spill_pseudos (HARD_REG_SET set)
  static void
  update_reg_eliminate (bitmap insns_with_changed_offsets)
  {
+  int i;
    bool prev;
    struct elim_table *ep, *ep1;
    HARD_REG_SET temp_hard_reg_set;
@@ -1124,8 +1125,15 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
    setup_elimination_map ();
    for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
      if (elimination_map[ep->from] == ep && ep->previous_offset != ep->offset)
-      bitmap_ior_into (insns_with_changed_offsets,
-                      &lra_reg_info[ep->from].insn_bitmap);
+      {
+        bitmap_ior_into (insns_with_changed_offsets,
+                        &lra_reg_info[ep->from].insn_bitmap);
+
+       /* Update offset when the eliminate offset have been changed.  */
+        for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
+         if (lra_reg_info[i].val - 1 == ep->from)
I guess, -1 here is typo.
+           lra_reg_info[i].offset += (ep->offset - ep->previous_offset);
+      }
  }

  /* Initialize the table of hard registers to eliminate.
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index 98f2ff7..944cad1 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -116,6 +116,8 @@ struct lra_reg
    /* Value holding by register.         If the pseudos have the same value
       they do not conflict.  */
    int val;
+  /* Offset from relative eliminate register to pesudo reg.  */
+  int offset;
    /* These members are set up in lra-lives.c and updated in
       lra-coalesce.c.  */
    /* The biggest size mode in which each pseudo reg is referred in
diff --git a/gcc/lra.c b/gcc/lra.c
index 9df24b5..7a60281 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -194,7 +194,10 @@ lra_create_new_reg (enum machine_mode md_mode,
rtx original,
    new_reg
      = lra_create_new_reg_with_unique_value (md_mode, original, rclass, title);
    if (original != NULL_RTX && REG_P (original))
-    lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO (original)].val;
+    {
+      lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO (original)].val;
+      lra_reg_info[REGNO (new_reg)].offset = 0;
+    }
    return new_reg;
  }



Thanks for the dump files. They help me to understand better the situation. The patch is better but it is still incomplete. There are more places where the values are used (more places in lra-assigns.c, a few places in lra-constraints.c).

As there are many places it would be nice to have helper functions (I'd make them static inline and put them in lra-int.h):

static inline void
lra_set_up_reg_val (int regno, int val, int offset)

and

static inline bool
lra_reg_val_equal_p (int regno, int val, int offset)

and use them wherever it is possible.

So could you check all the places where .val is used, define the helper functions, and use them wherever it is possible and send me the new version of the patch. I'll approve it after some checking.

Thanks for working on this problem.  I really appreciate it.

Reply via email to