OSDN Git Service

* config/bfin/bfin.md (UNSPEC_NOP): New constant.
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Jun 2007 14:35:13 +0000 (14:35 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Jun 2007 14:35:13 +0000 (14:35 +0000)
(forced_nop): New pattern.
* config/bfin/bfin.c: Include "df.h".
(add_to_reg): Use df_regs_ever_live_p instead of regs_ever_live.
(bfin_discover_loop): Use df_get_live_in instead of
global_live_at_start.
(bfin_reorder_loops): Pass 0 to cfg_layout_initialize.  Call
df_analyze when done.
(gen_one_bundle): Don't generate SEQUENCE insns, just put modes on
the insns.  Use QImode for the final insn in a bundle.  Call
df_insn_rescan on generated NOPs; use gen_forced_nop instead of
gen_nop.
(reorder_var_tracking_notes): New function.
(bfin_reorg): Pass no argument to split_all_insns.  Don't call
update_life_info.  Call df_analyze after scheduling and bundle
generation.  Call reorder_var_tracking_notes if generating these notes.
Call df_finish_pass at the end.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125648 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/bfin/bfin.c
gcc/config/bfin/bfin.md

index 0cf6938..8d476fd 100644 (file)
@@ -1,3 +1,23 @@
+2007-06-12  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * config/bfin/bfin.md (UNSPEC_NOP): New constant.
+       (forced_nop): New pattern.
+       * config/bfin/bfin.c: Include "df.h".
+       (add_to_reg): Use df_regs_ever_live_p instead of regs_ever_live.
+       (bfin_discover_loop): Use df_get_live_in instead of
+       global_live_at_start.
+       (bfin_reorder_loops): Pass 0 to cfg_layout_initialize.  Call
+       df_analyze when done.
+       (gen_one_bundle): Don't generate SEQUENCE insns, just put modes on
+       the insns.  Use QImode for the final insn in a bundle.  Call
+       df_insn_rescan on generated NOPs; use gen_forced_nop instead of
+       gen_nop.
+       (reorder_var_tracking_notes): New function.
+       (bfin_reorg): Pass no argument to split_all_insns.  Don't call
+       update_life_info.  Call df_analyze after scheduling and bundle
+       generation.  Call reorder_var_tracking_notes if generating these notes.
+       Call df_finish_pass at the end.
+
 2007-06-12  Dirk Mueller  <dmueller@suse.de>
 
        * trans-stmt.c (gfc_trans_call): fix gcc_assert to
index 26fbc6c..968735f 100644 (file)
@@ -54,6 +54,7 @@
 #include "basic-block.h"
 #include "cfglayout.h"
 #include "timevar.h"
+#include "df.h"
 
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
@@ -604,7 +605,7 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame, int epilogue_p)
        {
          int i;
          for (i = REG_P0; i <= REG_P5; i++)
-           if ((regs_ever_live[i] && ! call_used_regs[i])
+           if ((df_regs_ever_live_p (i) && ! call_used_regs[i])
                || (!TARGET_FDPIC
                    && i == PIC_OFFSET_TABLE_REGNUM
                    && (current_function_uses_pic_offset_table
@@ -3745,7 +3746,7 @@ bfin_discover_loop (loop_info loop, basic_block tail_bb, rtx tail_insn)
          FOR_EACH_EDGE (e, ei, bb->succs)
            {
              basic_block succ = EDGE_SUCC (bb, ei.index)->dest;
-             if (!REGNO_REG_SET_P (succ->il.rtl->global_live_at_start,
+             if (!REGNO_REG_SET_P (df_get_live_in (succ),
                                    REGNO (loop->iter_reg)))
                continue;
              if (!VEC_space (basic_block, works, 1))
@@ -3974,7 +3975,7 @@ bfin_reorder_loops (loop_info loops, FILE *dump_file)
 
   FOR_EACH_BB (bb)
     bb->aux = NULL;
-  cfg_layout_initialize (CLEANUP_UPDATE_LIFE);
+  cfg_layout_initialize (0);
 
   for (loop = loops; loop; loop = loop->next)
     {
@@ -4026,6 +4027,7 @@ bfin_reorder_loops (loop_info loops, FILE *dump_file)
        bb->aux = NULL;
     }
   cfg_layout_finalize ();
+  df_analyze ();
 }
 
 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
@@ -4087,7 +4089,7 @@ bfin_reorg_loops (FILE *dump_file)
 static bool
 gen_one_bundle (rtx slot[3])
 {
-  rtx bundle;
+  rtx bundle, insn;
 
   gcc_assert (slot[1] != NULL_RTX);
 
@@ -4116,9 +4118,15 @@ gen_one_bundle (rtx slot[3])
     }
 
   if (slot[0] == NULL_RTX)
-    slot[0] = emit_insn_before (gen_mnop (), slot[1]);
+    {
+      slot[0] = emit_insn_before (gen_mnop (), slot[1]);
+      df_insn_rescan (slot[0]);
+    }
   if (slot[2] == NULL_RTX)
-    slot[2] = emit_insn_after (gen_nop (), slot[1]);
+    {
+      slot[2] = emit_insn_after (gen_forced_nop (), slot[1]);
+      df_insn_rescan (slot[2]);
+    }
 
   /* Avoid line number information being printed inside one bundle.  */
   if (INSN_LOCATOR (slot[1])
@@ -4131,17 +4139,8 @@ gen_one_bundle (rtx slot[3])
   /* Terminate them with "|| " instead of ";" in the output.  */
   PUT_MODE (slot[0], SImode);
   PUT_MODE (slot[1], SImode);
-
-  /* This is a cheat to avoid emit_insn's special handling of SEQUENCEs.
-     Generating a PARALLEL first and changing its code later is the
-     easiest way to emit a SEQUENCE insn.  */
-  bundle = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, slot[0], slot[1], slot[2]));
-  emit_insn_before (bundle, slot[0]);
-  remove_insn (slot[0]);
-  remove_insn (slot[1]);
-  remove_insn (slot[2]);
-  PUT_CODE (bundle, SEQUENCE);
-  
+  /* Terminate the bundle, for the benefit of reorder_var_tracking_notes.  */
+  PUT_MODE (slot[2], QImode);
   return true;
 }
 
@@ -4199,6 +4198,7 @@ bfin_gen_bundles (void)
                    {
                      SET_SRC (pat) = XVECEXP (SET_SRC (pat), 0, 0);
                      INSN_CODE (slot[0]) = -1;
+                     df_insn_rescan (slot[0]);
                    }
                }
              n_filled = 0;
@@ -4209,6 +4209,58 @@ bfin_gen_bundles (void)
        }
     }
 }
+
+/* Ensure that no var tracking notes are emitted in the middle of a
+   three-instruction bundle.  */
+
+static void
+reorder_var_tracking_notes (void)
+{
+  basic_block bb;
+  FOR_EACH_BB (bb)
+    {
+      rtx insn, next;
+      rtx queue = NULL_RTX;
+      bool in_bundle = false;
+
+      for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = next)
+       {
+         next = NEXT_INSN (insn);
+
+         if (INSN_P (insn))
+           {
+             /* Emit queued up notes at the last instruction of a bundle.  */
+             if (GET_MODE (insn) == QImode)
+               {
+                 while (queue)
+                   {
+                     rtx next_queue = PREV_INSN (queue);
+                     PREV_INSN (NEXT_INSN (insn)) = queue;
+                     NEXT_INSN (queue) = NEXT_INSN (insn);
+                     NEXT_INSN (insn) = queue;
+                     PREV_INSN (queue) = insn;
+                     queue = next_queue;
+                   }
+                 in_bundle = false;
+               }
+             else if (GET_MODE (insn) == SImode)
+               in_bundle = true;
+           }
+         else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
+           {
+             if (in_bundle)
+               {
+                 rtx prev = PREV_INSN (insn);
+                 PREV_INSN (next) = prev;
+                 NEXT_INSN (prev) = next;
+
+                 PREV_INSN (insn) = queue;
+                 queue = insn;
+               }
+           }
+       }
+    }
+}
 \f
 /* Return an insn type for INSN that can be used by the caller for anomaly
    workarounds.  This differs from plain get_attr_type in that it handles
@@ -4290,11 +4342,9 @@ bfin_reorg (void)
   if (bfin_flag_schedule_insns2)
     {
       splitting_for_sched = 1;
-      split_all_insns (0);
+      split_all_insns ();
       splitting_for_sched = 0;
 
-      update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES);
-
       timevar_push (TV_SCHED2);
       schedule_insns ();
       timevar_pop (TV_SCHED2);
@@ -4304,6 +4354,8 @@ bfin_reorg (void)
       bfin_gen_bundles ();
     }
 
+  df_analyze ();
+
   /* Doloop optimization */
   if (cfun->machine->has_hardware_loops)
     bfin_reorg_loops (dump_file);
@@ -4451,8 +4503,10 @@ bfin_reorg (void)
     {
       timevar_push (TV_VAR_TRACKING);
       variable_tracking_main ();
+      reorder_var_tracking_notes ();
       timevar_pop (TV_VAR_TRACKING);
     }
+  df_finish_pass ();
 }
 \f
 /* Handle interrupt_handler, exception_handler and nmi_handler function
index d447825..1fafa88 100644 (file)
    (UNSPEC_FUNCDESC_GOT17M4 9)
    (UNSPEC_LSETUP_END 10)
    ;; Distinguish a 32-bit version of an insn from a 16-bit version.
-   (UNSPEC_32BIT 11)])
+   (UNSPEC_32BIT 11)
+   (UNSPEC_NOP 12)])
 
 (define_constants
   [(UNSPEC_VOLATILE_EH_RETURN 0)
   ""
   "nop;")
 
+;; A nop which stays there when emitted.
+(define_insn "forced_nop"
+  [(unspec [(const_int 0)] UNSPEC_NOP)]
+  ""
+  "nop;")
+
 (define_insn "mnop"
   [(unspec [(const_int 0)] UNSPEC_32BIT)]
   ""