aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Belevantsev <abel@ispras.ru>2007-06-13 14:50:04 +0000
committerAndrey Belevantsev <abel@ispras.ru>2007-06-13 14:50:04 +0000
commit84b71d93826e760129a8e88644960021e76074ee (patch)
tree15771856a9f66e678a85c18348ecc83fef446056
parentfb9c54c4d42c917e9c890bd605dd2b556ad54448 (diff)
* common.opt (fsel-sched-substitute-inside-insn-group): New flag.
* sel-sched.c (moveup_rhs_inside_insn_group): New. (moveup_rhs): Add inside_insn_group parameter. When it is true, use the above function. Kill unneeded comment. (moveup_set_rhs): Add inside_insn_group parameter. Pass it to moveup_rhs. (equal_after_moveup_path_p_1): Call moveup_rhs with inside_insn_group set to true. (compute_av_set): Call moveup_set_rhs with inside_insn_group == false. (find_used_regs_1): Tidy. (generate_bookkeeping_insn): Kill #if 0'd code. (fill_insns): Add to rhs_seq expressions from boundaries' av sets instead of rhs_vliw. Put correct register in them. Fix comment. Take pattern for the final insn to schedule from rhs_vliw. Move comment before 'if'. Kill unneeded scope. (sel_region_init): Enable moveup_set_path when the user requested substitution inside insn groups. (sel_global_init): Do not pipeline outer loops when the user doesn't permit any kind of pipelining. * sel-sched-ir.c: Include sel-sched-dump.h. Use again sel_print_insn as a debug hook. (RHS_DEST): New macro. * sel-sched-dump.c (sel_print_insn): Resurrect. Fix it to not segfault, use new macros. * sched-vis.c (dump_insn_slim_1): Pass 1 instead of 0 to print_insn. * config/ia64/ia64.opt (msched-spec-verbose, msched-prefer-non-data-spec-insns, msched-prefer-non-control-spec-insns, msched-count-spec-in-critical-path, msel-sched-renaming, msel-sched-substitution, msel-sched-data-spec, msel-sched-control-spec, msel-sched-dont-check-control-spec): Use Target Report Var instead of Common Report Var. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/sel-sched-branch@125678 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/config/ia64/ia64.opt20
-rw-r--r--gcc/sched-vis.c2
-rw-r--r--gcc/sel-sched-dump.c8
-rw-r--r--gcc/sel-sched-ir.c4
-rw-r--r--gcc/sel-sched-ir.h2
-rw-r--r--gcc/sel-sched.c134
7 files changed, 121 insertions, 53 deletions
diff --git a/gcc/common.opt b/gcc/common.opt
index 37b0dc480d2..a4afa75675a 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -850,6 +850,10 @@ fsel-sched-substitution
Common Report Var(flag_sel_sched_substitution) Init(0)
Perform substitution in selective scheduling
+fsel-sched-substitute-inside-insn-group
+Common Report Var(flag_sel_sched_substitute_inside_insn_group) Init(1)
+Perform substitution inside an instruction group
+
fsel-sched-verbose
Common Report Var(flag_sel_sched_verbose) Init(0)
Be verbose when running selective scheduling
diff --git a/gcc/config/ia64/ia64.opt b/gcc/config/ia64/ia64.opt
index 91c88da5849..1b104af1a50 100644
--- a/gcc/config/ia64/ia64.opt
+++ b/gcc/config/ia64/ia64.opt
@@ -129,19 +129,19 @@ Target Report Var(mflag_sched_spec_control_ldc) Init(0)
Use simple data speculation check for control speculation
msched-spec-verbose
-Common Report Var(mflag_sched_spec_verbose) Init(0)
-Print information about speculative motions.
+Target Report Var(mflag_sched_spec_verbose) Init(0)
+Print information about speculative motions
msched-prefer-non-data-spec-insns
-Common Report Var(mflag_sched_prefer_non_data_spec_insns) Init(0)
+Target Report Var(mflag_sched_prefer_non_data_spec_insns) Init(0)
If set, data speculative instructions will be chosen for schedule only if there are no other choices at the moment
msched-prefer-non-control-spec-insns
-Common Report Var(mflag_sched_prefer_non_control_spec_insns) Init(0)
+Target Report Var(mflag_sched_prefer_non_control_spec_insns) Init(0)
If set, control speculative instructions will be chosen for schedule only if there are no other choices at the moment
msched-count-spec-in-critical-path
-Common Report Var(mflag_sched_count_spec_in_critical_path) Init(0)
+Target Report Var(mflag_sched_count_spec_in_critical_path) Init(0)
Count speculative dependencies while calculating priority of instructions
msched-stop-bits-after-every-cycle
@@ -153,23 +153,23 @@ Target Report Var(mflag_sched_fp_mem_deps_zero_cost) Init(1)
Assume that floating-point stores and loads are not likely to cause conflict when placed into one instruction group
msel-sched-renaming
-Common Report Var(mflag_sel_sched_renaming) Init(1)
+Target Report Var(mflag_sel_sched_renaming) Init(1)
Do register renaming in selective scheduling
msel-sched-substitution
-Common Report Var(mflag_sel_sched_substitution) Init(1)
+Target Report Var(mflag_sel_sched_substitution) Init(1)
Perform substitution in selective scheduling
msel-sched-data-spec
-Common Report Var(mflag_sel_sched_data_spec) Init(0)
+Target Report Var(mflag_sel_sched_data_spec) Init(0)
Perform data speculation in selective scheduling
msel-sched-control-spec
-Common Report Var(mflag_sel_sched_control_spec) Init(1)
+Target Report Var(mflag_sel_sched_control_spec) Init(1)
Perform control speculation in selective scheduling
msel-sched-dont-check-control-spec
-Common Report Var(mflag_sel_sched_dont_check_control_spec) Init(0)
+Target Report Var(mflag_sel_sched_dont_check_control_spec) Init(0)
Don't generate checks for control speculation in selective scheduling
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/sched-vis.c b/gcc/sched-vis.c
index e82023fca24..427a3daaf6b 100644
--- a/gcc/sched-vis.c
+++ b/gcc/sched-vis.c
@@ -694,7 +694,7 @@ dump_insn_slim_1 (FILE *f, rtx x)
{
char t[BUF_LEN + 32];
- print_insn (t, x, 0);
+ print_insn (t, x, 1);
fputs (t, f);
}
diff --git a/gcc/sel-sched-dump.c b/gcc/sel-sched-dump.c
index 790674d4bfc..95475cacc8b 100644
--- a/gcc/sel-sched-dump.c
+++ b/gcc/sel-sched-dump.c
@@ -673,7 +673,6 @@ dump_hard_reg_set (const char *prefix, HARD_REG_SET set)
}
}
-#if 0
/* Pretty print INSN. This is used as a hook. */
const char *
sel_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
@@ -682,14 +681,14 @@ sel_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
/* '+' before insn means it is a new cycle start and it's not been
scheduled yet. '>' - has been scheduled. */
- if (s_i_d && INSN_UID (insn) < sel_max_uid && INSN_VI (insn))
+ if (s_i_d && INSN_LUID (insn) > 0)
if (GET_MODE (insn) == TImode)
sprintf (buf, "%s %4d",
- (VINSN_SCHED_TIMES (INSN_VI (insn)) > 0) ? "> " : "< ",
+ INSN_SCHED_TIMES (insn) > 0 ? "> " : "< ",
INSN_UID (insn));
else
sprintf (buf, "%s %4d",
- VINSN_SCHED_TIMES (INSN_VI (insn)) > 0 ? "! " : " ",
+ INSN_SCHED_TIMES (insn) > 0 ? "! " : " ",
INSN_UID (insn));
else
if (GET_MODE (insn) == TImode)
@@ -699,7 +698,6 @@ sel_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
return buf;
}
-#endif
/* Functions for pretty printing of CFG. */
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 7e59d264c8e..05fa2c859d1 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -53,6 +53,8 @@
#ifdef INSN_SCHEDULING
#include "sel-sched-ir.h"
+/* We don't have to use it except for sel_print_insn. */
+#include "sel-sched-dump.h"
/* A structure used to hold various parameters of insn initialization. */
struct _insn_init insn_init;
@@ -3792,7 +3794,7 @@ static struct haifa_sched_info sched_sel_haifa_sched_info =
NULL, /* schedule_more_p */
NULL, /* new_ready */
NULL, /* rgn_rank */
- NULL, /* rgn_print_insn */
+ sel_print_insn, /* rgn_print_insn */
contributes_to_priority,
NULL, NULL,
diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h
index 0a6b6928fdf..d66049f3c1c 100644
--- a/gcc/sel-sched-ir.h
+++ b/gcc/sel-sched-ir.h
@@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
/* For reg_note. */
#include "rtl.h"
#include "ggc.h"
+#include "bitmap.h"
#include "sched-int.h"
#include "sched-rgn.h"
#include "cfgloop.h"
@@ -133,6 +134,7 @@ typedef expr_t rhs_t;
#define RHS_PATTERN(RHS) (VINSN_PATTERN (RHS_VINSN (RHS)))
#define RHS_SPEC(RHS) ((RHS)->spec)
#define RHS_PRIORITY(RHS) ((RHS)->priority)
+#define RHS_DEST(RHS) (VINSN_LHS (RHS_VINSN (RHS)))
#define RHS_SCHED_TIMES(RHS) ((RHS)->sched_times)
/* Insn definition for list of original insns in find_used_regs. */
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index a02c52fbfc3..bc33489cbff 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -1533,16 +1533,74 @@ un_speculate (av_set_t *avp, insn_t insn)
/* Moveup_* helpers for code motion and computing av sets. */
+/* Propagates INSN_TO_MOVE_UP inside an insn group through THROUGH_INSN.
+ The difference from the below function is that only substitution is
+ performed. */
+static enum MOVEUP_RHS_CODE
+moveup_rhs_inside_insn_group (rhs_t insn_to_move_up, insn_t through_insn)
+{
+ vinsn_t vi = RHS_VINSN (insn_to_move_up);
+ insn_t insn = VINSN_INSN (vi);
+ ds_t *has_dep_p;
+ ds_t full_ds;
+
+ full_ds = has_dependence_p (insn_to_move_up, through_insn, &has_dep_p);
+
+ if (full_ds == 0)
+ return MOVEUP_RHS_SAME;
+
+ /* Substitution is the only cure in this case. */
+ if (has_dep_p[DEPS_IN_RHS])
+ {
+ /* Can't substitute UNIQUE VINSNs. */
+ gcc_assert (!VINSN_UNIQUE_P (vi));
+
+ if (flag_sel_sched_substitution
+ && insn_eligible_for_subst_p (through_insn))
+ {
+ /* Substitute in vinsn. */
+ line_start ();
+ print ("Substituting in moveup_rhs inside insn group:\nBefore: ");
+ sel_print_rtl (insn);
+ print (" Moving through: ");
+ sel_print_rtl (through_insn);
+ print (" After: ");
+
+ if (substitute_reg_in_rhs (insn_to_move_up, through_insn))
+ {
+ sel_print_rtl (insn);
+ line_finish ();
+
+ return MOVEUP_RHS_CHANGED;
+ }
+ else
+ print (" Can't move up due to architecture constraints.\n");
+
+ line_finish ();
+ }
+ }
+
+ return MOVEUP_RHS_NULL;
+}
+
/* Modifies INSN_TO_MOVE_UP so it can be moved through the THROUGH_INSN,
- performing necessary transformations. */
+ performing necessary transformations. When INSIDE_INSN_GROUP,
+ permit all dependencies except true ones, and try to remove those
+ too via forward substitution. All cases when a non-eliminable
+ non-zero cost dependency exists inside an insn group will be fixed
+ in tick_check_p instead. */
static enum MOVEUP_RHS_CODE
-moveup_rhs (rhs_t insn_to_move_up, insn_t through_insn)
+moveup_rhs (rhs_t insn_to_move_up, insn_t through_insn, bool inside_insn_group)
{
vinsn_t vi = RHS_VINSN (insn_to_move_up);
insn_t insn = VINSN_INSN (vi);
ds_t *has_dep_p;
ds_t full_ds;
+ /* When inside_insn_group, delegate to the helper. */
+ if (inside_insn_group)
+ return moveup_rhs_inside_insn_group (insn_to_move_up, through_insn);
+
if (VINSN_UNIQUE_P (vi))
{
if (/* Don't move branches for now. */
@@ -1605,17 +1663,6 @@ moveup_rhs (rhs_t insn_to_move_up, insn_t through_insn)
if (has_dep_p[DEPS_IN_LHS] && !EXPR_SEPARABLE_P (insn_to_move_up))
return MOVEUP_RHS_NULL;
- /* If dependency is in lhs, it affects only those insns that are
- not RHS_SCHEDULE_AS_RHS, so they couldn't be moved.
- Rhses can be moved up through the anti or output dependence
- without any change:
-
- Ex. 1: Ex. 2:
- y = x; y = x;
- x = z*2; y = z*2;
-
- z*2 can be easily lifted above the y=x assignment. */
-
/* At this point we have either separable insns, that will be lifted
up only as RHSes, or non-separable insns with no dependency in lhs.
If dependency is in RHS, then try perform substitution and move up
@@ -1681,10 +1728,11 @@ moveup_rhs (rhs_t insn_to_move_up, insn_t through_insn)
return MOVEUP_RHS_CHANGED;
}
+
/* Moves an av set AVP up through INSN, performing necessary
transformations. */
static void
-moveup_set_rhs (av_set_t *avp, insn_t insn)
+moveup_set_rhs (av_set_t *avp, insn_t insn, bool inside_insn_group)
{
av_set_iterator i;
rhs_t rhs;
@@ -1697,7 +1745,7 @@ moveup_set_rhs (av_set_t *avp, insn_t insn)
line_start ();
dump_rhs (rhs);
- switch (moveup_rhs (rhs, insn))
+ switch (moveup_rhs (rhs, insn, inside_insn_group))
{
case MOVEUP_RHS_NULL:
av_set_iter_remove (&i);
@@ -1746,7 +1794,7 @@ moveup_set_path_1 (av_set_t *avp, ilist_t path)
if (ILIST_NEXT (path))
moveup_set_path_1 (avp, ILIST_NEXT (path));
- moveup_set_rhs (avp, ILIST_INSN (path));
+ moveup_set_rhs (avp, ILIST_INSN (path), true);
}
/* Moves AVP set along PATH. */
@@ -1780,7 +1828,7 @@ equal_after_moveup_path_p_1 (rhs_t rhs, ilist_t path)
res = true;
if (res)
- res = (moveup_rhs (rhs, ILIST_INSN (path)) != MOVEUP_RHS_NULL);
+ res = (moveup_rhs (rhs, ILIST_INSN (path), true) != MOVEUP_RHS_NULL);
return res;
}
@@ -1961,7 +2009,6 @@ compute_av_set (insn_t insn, ilist_t p, int ws, bool unique_p)
free (succs);
ilist_remove (&p);
- /* Debug output. */
line_start ();
print ("av_succs (%d): ", INSN_UID (insn));
dump_av_set (av1);
@@ -1973,8 +2020,8 @@ compute_av_set (insn_t insn, ilist_t p, int ws, bool unique_p)
expr_t expr;
vinsn_t vi = INSN_VI (insn);
- moveup_set_rhs (&av1, insn);
-
+ moveup_set_rhs (&av1, insn, false);
+
expr = av_set_lookup (av1, vi);
if (expr != NULL)
@@ -2253,6 +2300,7 @@ find_used_regs_1 (insn_t insn, av_set_t orig_ops, ilist_t path,
}
orig_ops = av_set_copy (orig_ops);
+
/* If we've found valid av set, then filter the orig_ops set. */
if (INSN_AV_VALID_P (insn))
{
@@ -3252,10 +3300,7 @@ generate_bookkeeping_insn (rhs_t c_rhs, insn_t join_point, edge e1, edge e2)
/* We do not split header. */
gcc_assert (bb != current_loop_nest->header);
-#if 0
- /* We do not redirect a latch edge. */
- gcc_assert (e1 != loop_latch_edge (current_loop_nest));
-#endif
+
/* We do not redirect the only edge to the latch block. */
gcc_assert (e1->dest != latch
|| !single_pred_p (latch)
@@ -3498,18 +3543,24 @@ fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp)
{
gcc_assert (first_p);
first_p = false;
- /*av_set_add (&rhs_seq, rhs);*/
+
+ /* The sequential expression has the right form to pass
+ to move_op except when renaming happened. Put the
+ correct register in RHS then. */
+ if (EXPR_SEPARABLE_P (rhs) && REG_P (EXPR_LHS (rhs))
+ && rhs_dest_regno (rhs) != rhs_dest_regno (rhs_vliw))
+ replace_dest_with_reg_in_rhs (rhs, EXPR_LHS (rhs_vliw));
+
+ av_set_add (&rhs_seq, rhs);
}
}
- av_set_add (&rhs_seq, rhs_vliw);
-
line_start ();
print ("rhs_seq: ");
dump_av_set (rhs_seq);
line_finish ();
- /* Move choosen insn. */
+ /* Move chosen insn. */
{
insn_t place_to_insert;
insn_t new_bb_head = NULL_RTX;
@@ -3546,6 +3597,12 @@ fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp)
scheduling. */
gcc_assert (b);
+ /* We want to use a pattern from rhs_vliw, because it could've
+ been substituted, and the rest of data from rhs_seq. */
+ if (! rtx_equal_p (EXPR_PATTERN (rhs_vliw),
+ EXPR_PATTERN (c_rhs)))
+ change_vinsn_in_expr (c_rhs, EXPR_VINSN (rhs_vliw));
+
/* Find a place for C_RHS to schedule.
We want to have an invariant that only insns that are
sel_bb_header_p () have a valid LV_SET. But, in the same time,
@@ -3634,8 +3691,8 @@ fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp)
new_bb_head = insn;
}
+ /* Initialize LV_SET of the bb header. */
if (new_bb_head != NULL_RTX)
- /* Initialize LV_SET of the bb header. */
{
/* !!! TODO: We should replace all occurencies of
LV_SET_VALID_P () with LV_SET () != NULL. Overwise it is
@@ -4079,12 +4136,10 @@ move_op (insn_t insn, av_set_t orig_ops, ilist_t path, edge e1, edge e2,
if (b)
{
- {
- enum MOVEUP_RHS_CODE res;
-
- res = moveup_rhs (x, insn);
- gcc_assert (res != MOVEUP_RHS_NULL);
- }
+ enum MOVEUP_RHS_CODE res;
+
+ res = moveup_rhs (x, insn, false);
+ gcc_assert (res != MOVEUP_RHS_NULL);
if (!c_rhs_inited_p)
{
@@ -4428,7 +4483,8 @@ sel_region_init (int rgn)
/* We don't need the semantics of moveup_set_path, because filtering of
dependencies inside a sched group is handled by tick_check_p and
the target. */
- enable_moveup_set_path_p = 0;
+ enable_moveup_set_path_p
+ = flag_sel_sched_substitute_inside_insn_group != 0;
/* We need to treat insns as RHSes only when renaming is enabled. */
enable_schedule_as_rhs_p = (flag_sel_sched_renaming != 0);
@@ -5170,6 +5226,12 @@ sel_sched_region (int rgn)
static void
sel_global_init (void)
{
+ /* Pipelining outer loops is only possible when general pipelining
+ capabilities are requested.
+ FIXME: move this in opts.c. */
+ if (!flag_sel_sched_pipelining)
+ flag_sel_sched_pipelining_outer_loops = 0;
+
if (flag_sel_sched_pipelining_outer_loops)
pipeline_outer_loops_init ();