diff options
author | Andrey Belevantsev <abel@ispras.ru> | 2007-06-13 14:50:04 +0000 |
---|---|---|
committer | Andrey Belevantsev <abel@ispras.ru> | 2007-06-13 14:50:04 +0000 |
commit | 84b71d93826e760129a8e88644960021e76074ee (patch) | |
tree | 15771856a9f66e678a85c18348ecc83fef446056 | |
parent | fb9c54c4d42c917e9c890bd605dd2b556ad54448 (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.opt | 4 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.opt | 20 | ||||
-rw-r--r-- | gcc/sched-vis.c | 2 | ||||
-rw-r--r-- | gcc/sel-sched-dump.c | 8 | ||||
-rw-r--r-- | gcc/sel-sched-ir.c | 4 | ||||
-rw-r--r-- | gcc/sel-sched-ir.h | 2 | ||||
-rw-r--r-- | gcc/sel-sched.c | 134 |
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 (); |