]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
-fuse-caller-save - Support in lra
authorTom de Vries <tom@codesourcery.com>
Fri, 30 May 2014 08:43:05 +0000 (08:43 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Fri, 30 May 2014 08:43:05 +0000 (08:43 +0000)
2014-05-30  Tom de Vries  <tom@codesourcery.com>

* lra-int.h (struct lra_reg): Add field actual_call_used_reg_set.
* lra.c (initialize_lra_reg_info_element): Add init of
actual_call_used_reg_set field.
(lra): Call lra_create_live_ranges before lra_inheritance for
-fuse-caller-save.
* lra-assigns.c (lra_assign): Allow call_used_regs to cross calls for
-fuse-caller-save.
* lra-constraints.c (need_for_call_save_p): Use actual_call_used_reg_set
instead of call_used_reg_set for -fuse-caller-save.
* lra-lives.c (process_bb_lives): Calculate actual_call_used_reg_set.

From-SVN: r211074

gcc/ChangeLog
gcc/lra-assigns.c
gcc/lra-constraints.c
gcc/lra-int.h
gcc/lra-lives.c
gcc/lra.c

index e9046bc8efea0f764cf6ce57e971bc2f26a24877..4dc8b7ac6b4447cc17d1d3aad0972f685df4f66c 100644 (file)
@@ -1,3 +1,16 @@
+2014-05-30  Tom de Vries  <tom@codesourcery.com>
+
+       * lra-int.h (struct lra_reg): Add field actual_call_used_reg_set.
+       * lra.c (initialize_lra_reg_info_element): Add init of
+       actual_call_used_reg_set field.
+       (lra): Call lra_create_live_ranges before lra_inheritance for
+       -fuse-caller-save.
+       * lra-assigns.c (lra_assign): Allow call_used_regs to cross calls for
+       -fuse-caller-save.
+       * lra-constraints.c (need_for_call_save_p): Use actual_call_used_reg_set
+       instead of call_used_reg_set for -fuse-caller-save.
+       * lra-lives.c (process_bb_lives): Calculate actual_call_used_reg_set.
+
 2014-05-30  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/thumb2.md (*thumb2_movhi_insn): Set type of movw
index f7bb86b2160adc8173a4733f272f779bdffa7d6c..03c2506d826a56ba9abaf69ea0b89fe038c1c911 100644 (file)
@@ -1460,12 +1460,13 @@ lra_assign (void)
   create_live_range_start_chains ();
   setup_live_pseudos_and_spill_after_risky_transforms (&all_spilled_pseudos);
 #ifdef ENABLE_CHECKING
-  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
-    if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
-       && lra_reg_info[i].call_p
-       && overlaps_hard_reg_set_p (call_used_reg_set,
-                                   PSEUDO_REGNO_MODE (i), reg_renumber[i]))
-      gcc_unreachable ();
+  if (!flag_use_caller_save)
+    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+      if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
+         && lra_reg_info[i].call_p
+         && overlaps_hard_reg_set_p (call_used_reg_set,
+                                     PSEUDO_REGNO_MODE (i), reg_renumber[i]))
+       gcc_unreachable ();
 #endif
   /* Setup insns to process on the next constraint pass.  */
   bitmap_initialize (&changed_pseudo_bitmap, &reg_obstack);
index 69ffdcd454f95d42087eba2311e3a7fe6b02a9db..147f1214a8dfa4f7781128420ac7e69ad2505d5d 100644 (file)
@@ -4622,7 +4622,10 @@ need_for_call_save_p (int regno)
   lra_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0);
   return (usage_insns[regno].calls_num < calls_num
          && (overlaps_hard_reg_set_p
-             (call_used_reg_set,
+             ((flag_use_caller_save &&
+               ! hard_reg_set_empty_p (lra_reg_info[regno].actual_call_used_reg_set))
+              ? lra_reg_info[regno].actual_call_used_reg_set
+              : call_used_reg_set,
               PSEUDO_REGNO_MODE (regno), reg_renumber[regno])
              || HARD_REGNO_CALL_PART_CLOBBERED (reg_renumber[regno],
                                                 PSEUDO_REGNO_MODE (regno))));
index 41c98492973950f7b232071f2d15ab2c9a22e2d4..3c8973479fdb3af0f81a2cbacbd132945703e6c0 100644 (file)
@@ -77,6 +77,10 @@ struct lra_reg
   /* The following fields are defined only for pseudos.         */
   /* Hard registers with which the pseudo conflicts.  */
   HARD_REG_SET conflict_hard_regs;
+  /* Call used registers with which the pseudo conflicts, taking into account
+     the registers used by functions called from calls which cross the
+     pseudo.  */
+  HARD_REG_SET actual_call_used_reg_set;
   /* We assign hard registers to reload pseudos which can occur in few
      places.  So two hard register preferences are enough for them.
      The following fields define the preferred hard registers. If
index 8444adee6d8d3d11080c1a2b2fcad8c759f4a8df..26ba0d259c0e5b324aa4cb7c55ff8a85fc0c7a7d 100644 (file)
@@ -624,6 +624,17 @@ process_bb_lives (basic_block bb, int &curr_point)
 
       if (call_p)
        {
+         if (flag_use_caller_save)
+           {
+             HARD_REG_SET this_call_used_reg_set;
+             get_call_reg_set_usage (curr_insn, &this_call_used_reg_set,
+                                     call_used_reg_set);
+
+             EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
+               IOR_HARD_REG_SET (lra_reg_info[j].actual_call_used_reg_set,
+                                 this_call_used_reg_set);
+           }
+
          sparseset_ior (pseudos_live_through_calls,
                         pseudos_live_through_calls, pseudos_live);
          if (cfun->has_nonlocal_label
index ecec8908ca9f3123ec7419a0381cba837284697d..d199a813fbea9c78c2f3742f6692014cf7768c28 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -1427,6 +1427,7 @@ initialize_lra_reg_info_element (int i)
   lra_reg_info[i].no_stack_p = false;
 #endif
   CLEAR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs);
+  CLEAR_HARD_REG_SET (lra_reg_info[i].actual_call_used_reg_set);
   lra_reg_info[i].preferred_hard_regno1 = -1;
   lra_reg_info[i].preferred_hard_regno2 = -1;
   lra_reg_info[i].preferred_hard_regno_profit1 = 0;
@@ -2344,7 +2345,18 @@ lra (FILE *f)
          lra_eliminate (false, false);
          /* Do inheritance only for regular algorithms.  */
          if (! lra_simple_p)
-           lra_inheritance ();
+           {
+             if (flag_use_caller_save)
+               {
+                 if (live_p)
+                   lra_clear_live_ranges ();
+                 /* As a side-effect of lra_create_live_ranges, we calculate
+                    actual_call_used_reg_set,  which is needed during
+                    lra_inheritance.  */
+                 lra_create_live_ranges (true);
+               }
+             lra_inheritance ();
+           }
          if (live_p)
            lra_clear_live_ranges ();
          /* We need live ranges for lra_assign -- so build them.  */