This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][1/3] Target independent changes to support ColdFire scheduling


Hello Vladimir,

This is the first patch to add support for ColdFire scheduling.

Prologue: All ColdFire cores have two pipelines decoupled by instruction
buffer: first pipeline prefetches instruction words any cycle when
memory bus is available and puts them into buffer.  Second pipeline
takes instruction words from the buffer, decodes and executes them.

This patch adds two new hooks that help accurately model this behavior. Every cycle we check if memory unit is busy and, if not, increase the
number of prefetched instruction words. Thus we don't issue an
instruction which doesn't have all its words ready.


Second thing in this patch is a new DFA interface function that helps in
development and debugging of DFA description: it provides information on
the insns, that don't have DFA reservations assigned.

The patch was bootstrapped and regtested on x86_64-linux-gnu.

OK for trunk?

2007-08-07  Maxim Kuvyrkov  <maxim@codesourcery.com>

	* target.h (struct gcc_target.sched: dfa_pre_advance_cycle,
	dfa_post_advance_cycle): New scheduler hooks.
	* target-def.h (TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE,
	TARGET_SCHED_DFA_POST_ADVANCE_CYCLE): New macros to initialize
	new hooks.
	(TARGET_SCHED): Use them.
	* doc/tm.texi (TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE,
	TARGET_SCHED_DFA_POST_ADVANCE_CYCLE): Document new hooks.
	* haifa-sched.c (advance_one_cycle): Invoke new hooks.

	* genautomata.c (insn_has_dfa_reservation_p): New DFA interface
	function to facilitate debugging.
	(INSN_HAS_DFA_RESERVATION_P_FUNC_NAME): New macro.
	(output_insn_has_dfa_reservation_p): New static function to output
	insn_has_dfa_reservation_p ().
	(write_automata): Use it.
	* genattr.c (main): Output declaration for
	insn_has_dfa_reservation_p ().
	
Index: target.h
===================================================================
--- target.h	(revision 178501)
+++ target.h	(working copy)
@@ -273,6 +273,13 @@ struct gcc_target
     void (* init_dfa_post_cycle_insn) (void);
     rtx (* dfa_post_cycle_insn) (void);
 
+    /* The values of the following two members are pointers to
+       functions used to simplify the automaton descriptions.
+       dfa_pre_advance_cycle and dfa_post_advance_cycle are getting called
+       immediatelly before and after cycle is advanced.  */
+    void (* dfa_pre_advance_cycle) (void);
+    void (* dfa_post_advance_cycle) (void);
+
     /* The following member value is a pointer to a function returning value
        which defines how many insns in queue `ready' will we try for
        multi-pass scheduling.  If the member value is nonzero and the
Index: target-def.h
===================================================================
--- target-def.h	(revision 178501)
+++ target-def.h	(working copy)
@@ -296,6 +296,8 @@ Foundation, 51 Franklin Street, Fifth Fl
 #define TARGET_SCHED_DFA_PRE_CYCLE_INSN 0
 #define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN 0
 #define TARGET_SCHED_DFA_POST_CYCLE_INSN 0
+#define TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE 0
+#define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE 0
 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD 0
 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD 0
 #define TARGET_SCHED_DFA_NEW_CYCLE 0
@@ -324,7 +326,9 @@ Foundation, 51 Franklin Street, Fifth Fl
    TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN,			\
    TARGET_SCHED_DFA_PRE_CYCLE_INSN,				\
    TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN,			\
-   TARGET_SCHED_DFA_POST_CYCLE_INSN,				\
+   TARGET_SCHED_DFA_POST_CYCLE_INSN,			        \
+   TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE,                          \
+   TARGET_SCHED_DFA_POST_ADVANCE_CYCLE,                         \
    TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD,		\
    TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD,	\
    TARGET_SCHED_DFA_NEW_CYCLE,					\
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 178501)
+++ doc/tm.texi	(working copy)
@@ -6022,6 +6022,20 @@ The hook is analogous to @samp{TARGET_SC
 used to initialize data used by the previous hook.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_SCHED_DFA_PRE_CYCLE_ADVANCE (void)
+The hook to notify target that the current simulated cycle is about to finish.
+The hook is analogous to @samp{TARGET_SCHED_DFA_PRE_CYCLE_ADVANCE} but used
+to change the state in more complicated situations - e.g. when advancing
+state on a single insn is not enough.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_SCHED_DFA_POST_CYCLE_ADVANCE (void)
+The hook to notify target that new simulated cycle has just started.
+The hook is analogous to @samp{TARGET_SCHED_DFA_POST_CYCLE_ADVANCE} but used
+to change the state in more complicated situations - e.g. when advancing
+state on a single insn is not enough.
+@end deftypefn
+
 @deftypefn {Target Hook} int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD (void)
 This hook controls better choosing an insn from the ready insn queue
 for the @acronym{DFA}-based insn scheduler.  Usually the scheduler
Index: haifa-sched.c
===================================================================
--- haifa-sched.c	(revision 178501)
+++ haifa-sched.c	(working copy)
@@ -1118,6 +1118,9 @@ adjust_priority (rtx prev)
 HAIFA_INLINE static void
 advance_one_cycle (void)
 {
+  if (targetm.sched.dfa_pre_advance_cycle)
+    targetm.sched.dfa_pre_advance_cycle ();
+
   if (targetm.sched.dfa_pre_cycle_insn)
     state_transition (curr_state,
 		      targetm.sched.dfa_pre_cycle_insn ());
@@ -1127,6 +1130,9 @@ advance_one_cycle (void)
   if (targetm.sched.dfa_post_cycle_insn)
     state_transition (curr_state,
 		      targetm.sched.dfa_post_cycle_insn ());
+
+  if (targetm.sched.dfa_post_advance_cycle)
+    targetm.sched.dfa_post_advance_cycle ();
 }
 
 /* Clock at which the previous instruction was issued.  */
Index: genautomata.c
===================================================================
--- genautomata.c	(revision 178501)
+++ genautomata.c	(working copy)
@@ -6907,6 +6907,8 @@ output_reserved_units_table_name (FILE *
 
 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
 
+#define INSN_HAS_DFA_RESERVATION_P_FUNC_NAME "insn_has_dfa_reservation_p"
+
 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME  "dfa_clean_insn_cache"
 
 #define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache"
@@ -8394,6 +8396,42 @@ output_cpu_unit_reservation_p (void)
   fprintf (output_file, "  return 0;\n}\n\n");
 }
 
+/* The following function outputs a function to check if insn
+   has a dfa reservation.  */
+static void
+output_insn_has_dfa_reservation_p (void)
+{
+  fprintf (output_file,
+	   "bool\n%s (rtx %s ATTRIBUTE_UNUSED)\n{\n",
+           INSN_HAS_DFA_RESERVATION_P_FUNC_NAME,
+           INSN_PARAMETER_NAME);
+
+  if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
+    {
+      fprintf (output_file, "  return false;\n}\n\n");
+      return;
+    }
+
+  fprintf (output_file, "  int %s;\n\n", INTERNAL_INSN_CODE_NAME);
+
+  fprintf (output_file, "  if (%s == 0)\n    %s = %s;\n",
+	   INSN_PARAMETER_NAME,
+	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+  fprintf (output_file, "  else\n\
+    {\n\
+      %s = %s (%s);\n\
+      if (%s > %s)\n\
+        %s = %s;\n\
+    }\n\n",
+	   INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
+	       INSN_PARAMETER_NAME,
+	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
+	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+
+  fprintf (output_file, "  return %s != %s;\n}\n\n",
+	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+}
+
 /* The function outputs PHR interface functions `dfa_clean_insn_cache'
    and 'dfa_clear_single_insn_cache'.  */
 static void
@@ -9183,6 +9221,7 @@ write_automata (void)
   fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
   output_get_cpu_unit_code_func ();
   output_cpu_unit_reservation_p ();
+  output_insn_has_dfa_reservation_p ();
   fprintf (output_file, "\n#endif /* #if %s */\n\n",
 	   CPU_UNITS_QUERY_MACRO_NAME);
   output_dfa_clean_insn_cache_func ();
Index: genattr.c
===================================================================
--- genattr.c	(revision 178501)
+++ genattr.c	(working copy)
@@ -245,6 +245,9 @@ main (int argc, char **argv)
       printf ("   DFA state.  */\n");
       printf ("extern int cpu_unit_reservation_p (state_t, int);\n");
       printf ("#endif\n\n");
+      printf ("/* The following function returns true if insn\n");
+      printf ("   has a dfa reservation.  */\n");
+      printf ("extern bool insn_has_dfa_reservation_p (rtx);\n\n");
       printf ("/* Clean insn code cache.  It should be called if there\n");
       printf ("   is a chance that condition value in a\n");
       printf ("   define_insn_reservation will be changed after\n");

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]