aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2009-03-28 00:43:26 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2009-03-27 17:43:26 -0700
commit20a07f44670dc291cec862a5c688bad57e8a4266 (patch)
tree665f23f43ed41e7874cc2b369ea0e3f460aec4ba
parentb9605c6cd4ee61bec1db4883c798e526ce75d77c (diff)
downloadgcc-20a07f44670dc291cec862a5c688bad57e8a4266.zip
gcc-20a07f44670dc291cec862a5c688bad57e8a4266.tar.gz
gcc-20a07f44670dc291cec862a5c688bad57e8a4266.tar.bz2
genautomata.c: Add a new year to the copyright.
2009-03-27 Vladimir Makarov <vmakarov@redhat.com> * genautomata.c: Add a new year to the copyright. Add a new reference. (struct insn_reserv_decl): Add comments for member bypass_list. (find_bypass): Remove. (insert_bypass): New. (process_decls): Use insert_bypass. (output_internal_insn_latency_func): Output all bypasses with the same input insn in one switch case. * rtl.def (define_bypass): Describe bypass choice. * doc/md.texi (define_bypass): Ditto. From-SVN: r145152
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/doc/md.texi5
-rw-r--r--gcc/genautomata.c159
-rw-r--r--gcc/rtl.def6
4 files changed, 123 insertions, 61 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d91006b..ad0c1f0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2009-03-27 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c: Add a new year to the copyright. Add a new
+ reference.
+ (struct insn_reserv_decl): Add comments for member bypass_list.
+ (find_bypass): Remove.
+ (insert_bypass): New.
+ (process_decls): Use insert_bypass.
+ (output_internal_insn_latency_func): Output all bypasses with the
+ same input insn in one switch case.
+
+ * rtl.def (define_bypass): Describe bypass choice.
+ * doc/md.texi (define_bypass): Ditto.
+
2009-03-27 Richard Guenther <rguenther@suse.de>
* gimplify.c (mark_addressable): Export.
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index ae1c59a..18a1a4d 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -7506,6 +7506,11 @@ be ignored for this case. The additional guard is necessary to
recognize complicated bypasses, e.g.@: when the consumer is only an address
of insn @samp{store} (not a stored value).
+If there are more one bypass with the same output and input insns, the
+chosen bypass is the first bypass with a guard in description whose
+guard function returns nonzero. If there is no such bypass, then
+bypass without the guard function is chosen.
+
@findex exclusion_set
@findex presence_set
@findex final_presence_set
diff --git a/gcc/genautomata.c b/gcc/genautomata.c
index d314b8f..1d742f4 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -1,5 +1,5 @@
/* Pipeline hazard description translator.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Written by Vladimir Makarov <vmakarov@redhat.com>
@@ -22,21 +22,25 @@ along with GCC; see the file COPYING3. If not see
/* References:
- 1. Detecting pipeline structural hazards quickly. T. Proebsting,
+ 1. The finite state automaton based pipeline hazard recognizer and
+ instruction scheduler in GCC. V. Makarov. Proceedings of GCC
+ summit, 2003.
+
+ 2. Detecting pipeline structural hazards quickly. T. Proebsting,
C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
Principles of Programming Languages, pages 280--286, 1994.
This article is a good start point to understand usage of finite
state automata for pipeline hazard recognizers. But I'd
- recommend the 2nd article for more deep understanding.
+ recommend the 1st and 3rd article for more deep understanding.
- 2. Efficient Instruction Scheduling Using Finite State Automata:
+ 3. Efficient Instruction Scheduling Using Finite State Automata:
V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
article about usage of finite state automata for pipeline hazard
recognizers.
- The current implementation is different from the 2nd article in the
- following:
+ The current implementation is described in the 1st article and it
+ is different from the 3rd article in the following:
1. New operator `|' (alternative) is permitted in functional unit
reservation which can be treated deterministically and
@@ -463,7 +467,10 @@ struct insn_reserv_decl
insn. */
int insn_num;
/* The following field value is list of bypasses in which given insn
- is output insn. */
+ is output insn. Bypasses with the same input insn stay one after
+ another in the list in the same order as their occurrences in the
+ description but the bypass without a guard stays always the last
+ in a row of bypasses with the same input insn. */
struct bypass_decl *bypass_list;
/* The following fields are defined by automaton generator. */
@@ -2367,18 +2374,67 @@ add_presence_absence (unit_set_el_t dest_list,
}
-/* The function searches for bypass with given IN_INSN_RESERV in given
- BYPASS_LIST. */
-static struct bypass_decl *
-find_bypass (struct bypass_decl *bypass_list,
- struct insn_reserv_decl *in_insn_reserv)
+/* The function inserts BYPASS in the list of bypasses of the
+ corresponding output insn. The order of bypasses in the list is
+ decribed in a comment for member `bypass_list' (see above). If
+ there is already the same bypass in the list the function reports
+ this and does nothing. */
+static void
+insert_bypass (struct bypass_decl *bypass)
{
- struct bypass_decl *bypass;
-
- for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
- if (bypass->in_insn_reserv == in_insn_reserv)
- break;
- return bypass;
+ struct bypass_decl *curr, *last;
+ struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
+ struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
+
+ for (curr = out_insn_reserv->bypass_list, last = NULL;
+ curr != NULL;
+ last = curr, curr = curr->next)
+ if (curr->in_insn_reserv == in_insn_reserv)
+ {
+ if ((bypass->bypass_guard_name != NULL
+ && curr->bypass_guard_name != NULL
+ && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
+ || bypass->bypass_guard_name == curr->bypass_guard_name)
+ {
+ if (bypass->bypass_guard_name == NULL)
+ {
+ if (!w_flag)
+ error ("the same bypass `%s - %s' is already defined",
+ bypass->out_insn_name, bypass->in_insn_name);
+ else
+ warning (0, "the same bypass `%s - %s' is already defined",
+ bypass->out_insn_name, bypass->in_insn_name);
+ }
+ else if (!w_flag)
+ error ("the same bypass `%s - %s' (guard %s) is already defined",
+ bypass->out_insn_name, bypass->in_insn_name,
+ bypass->bypass_guard_name);
+ else
+ warning
+ (0, "the same bypass `%s - %s' (guard %s) is already defined",
+ bypass->out_insn_name, bypass->in_insn_name,
+ bypass->bypass_guard_name);
+ return;
+ }
+ if (curr->bypass_guard_name == NULL)
+ break;
+ if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
+ {
+ last = curr;
+ break;
+ }
+
+ }
+ if (last == NULL)
+ {
+ bypass->next = out_insn_reserv->bypass_list;
+ out_insn_reserv->bypass_list = bypass;
+ }
+ else
+ {
+ bypass->next = last->next;
+ last->next = bypass;
+ }
}
/* The function processes pipeline description declarations, checks
@@ -2391,7 +2447,6 @@ process_decls (void)
decl_t decl_in_table;
decl_t out_insn_reserv;
decl_t in_insn_reserv;
- struct bypass_decl *bypass;
int automaton_presence;
int i;
@@ -2514,36 +2569,7 @@ process_decls (void)
= DECL_INSN_RESERV (out_insn_reserv);
DECL_BYPASS (decl)->in_insn_reserv
= DECL_INSN_RESERV (in_insn_reserv);
- bypass
- = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
- DECL_BYPASS (decl)->in_insn_reserv);
- if (bypass != NULL)
- {
- if (DECL_BYPASS (decl)->latency == bypass->latency)
- {
- if (!w_flag)
- error
- ("the same bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- else
- warning
- (0, "the same bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- }
- else
- error ("bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- }
- else
- {
- DECL_BYPASS (decl)->next
- = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
- DECL_INSN_RESERV (out_insn_reserv)->bypass_list
- = DECL_BYPASS (decl);
- }
+ insert_bypass (DECL_BYPASS (decl));
}
}
}
@@ -8159,19 +8185,32 @@ output_internal_insn_latency_func (void)
(advance_cycle_insn_decl)->insn_num));
fprintf (output_file, " case %d:\n",
bypass->in_insn_reserv->insn_num);
- if (bypass->bypass_guard_name == NULL)
- fprintf (output_file, " return %d;\n",
- bypass->latency);
- else
+ for (;;)
{
- fprintf (output_file,
- " if (%s (%s, %s))\n",
- bypass->bypass_guard_name, INSN_PARAMETER_NAME,
- INSN2_PARAMETER_NAME);
- fprintf (output_file,
- " return %d;\n break;\n",
- bypass->latency);
+ if (bypass->bypass_guard_name == NULL)
+ {
+ gcc_assert (bypass->next == NULL
+ || (bypass->in_insn_reserv
+ != bypass->next->in_insn_reserv));
+ fprintf (output_file, " return %d;\n",
+ bypass->latency);
+ }
+ else
+ {
+ fprintf (output_file,
+ " if (%s (%s, %s))\n",
+ bypass->bypass_guard_name, INSN_PARAMETER_NAME,
+ INSN2_PARAMETER_NAME);
+ fprintf (output_file, " return %d;\n",
+ bypass->latency);
+ }
+ if (bypass->next == NULL
+ || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
+ break;
+ bypass = bypass->next;
}
+ if (bypass->bypass_guard_name != NULL)
+ fprintf (output_file, " break;\n");
}
fputs (" }\n break;\n", output_file);
}
diff --git a/gcc/rtl.def b/gcc/rtl.def
index 33bf6bd..662a9f0 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -1088,7 +1088,11 @@ DEF_RTL_EXPR(FINAL_ABSENCE_SET, "final_absence_set", "ss", RTX_EXTRA)
guard for the bypass. The function will get the two insns as
parameters. If the function returns zero the bypass will be
ignored for this case. Additional guard is necessary to recognize
- complicated bypasses, e.g. when consumer is load address. */
+ complicated bypasses, e.g. when consumer is load address. If there
+ are more one bypass with the same output and input insns, the
+ chosen bypass is the first bypass with a guard in description whose
+ guard function returns nonzero. If there is no such bypass, then
+ bypass without the guard function is chosen. */
DEF_RTL_EXPR(DEFINE_BYPASS, "define_bypass", "issS", RTX_EXTRA)
/* (define_automaton string) describes names of automata generated and