On Wed, Aug 05, 2015 at 01:24:20PM -0700, H.J. Lu wrote: > Since ira_implicitly_set_insn_hard_regs may be called outside of > ira-lives.c, it can't use the local variable, preferred_alternatives. > This patch adds an alternative_mask argument to > ira_implicitly_set_insn_hard_regs. > > OK for master and 5 branch if there are no regressions on Linux/x86-64? > > H.J. > --- > gcc/ > > PR rtl-optimization/67029 > * ira-color.c: Include "recog.h" before including "ira-int.h". > * target-globals.c: Likewise. > * ira-lives.c (ira_implicitly_set_insn_hard_regs): Add an > adds an alternative_mask argument and use it instead of > preferred_alternatives. > * ira.h (ira_implicitly_set_insn_hard_regs): Moved to ... > * ira-int.h (ira_implicitly_set_insn_hard_regs): Here. > * sched-deps.c: Include "ira-int.h" after including "ira.h". > (sched_analyze_insn): Update call to > ira_implicitly_set_insn_hard_regs. > * sel-sched.c: Include "ira-int.h" after including "ira.h". > (implicit_clobber_conflict_p): Update call to > ira_implicitly_set_insn_hard_regs. >
Here is a simpler patch to add preferred_alternatives to recog_data_d so that preferred_alternatives is available in recog_data_d when needed. OK for master and 5 branch if there are no regressions on Linux/x86-64? H.J. -- gcc/ PR rtl-optimization/67029 * ira-lives.c (preferred_alternatives): Removed. (check_and_make_def_conflict): Replace preferred_alternatives with recog_data.preferred_alternatives. (make_early_clobber_and_input_conflicts): Likewise. (single_reg_class): Likewise. (ira_implicitly_set_insn_hard_regs): Likewise. (process_bb_node_lives): Pass true to extract_insn. Don't set preferred_alternatives. * recog.c (extract_insn): Add an argument, preferred. Call get_preferred_alternatives to initialize preferred_alternatives if preferred is true. * recog.h (extract_insn): Add an argument, preferred, and default to false. (recog_data_d): Add preferred_alternatives. * sched-deps.c (sched_analyze_insn): Pass true to extract_insn. * sel-sched.c (implicit_clobber_conflict_p): Likewise. gcc/testsuite/ PR rtl-optimization/67029 * gcc.dg/pr67029.c: New test. --- gcc/ira-lives.c | 15 +++++---------- gcc/recog.c | 6 +++++- gcc/recog.h | 6 +++++- gcc/sched-deps.c | 2 +- gcc/sel-sched.c | 2 +- gcc/testsuite/gcc.dg/pr67029.c | 14 ++++++++++++++ 6 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr67029.c diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index 1cb05c2..aad3224 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -86,10 +86,6 @@ static int last_call_num; /* The number of last call at which given allocno was saved. */ static int *allocno_saved_at_call; -/* The value of get_preferred_alternatives for the current instruction, - supplemental to recog_data. */ -static alternative_mask preferred_alternatives; - /* Record the birth of hard register REGNO, updating hard_regs_live and hard reg conflict information for living allocnos. */ static void @@ -648,7 +644,7 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl) instruction due to the earlyclobber, reload must fix it up. */ for (alt1 = 0; alt1 < recog_data.n_alternatives; alt1++) { - if (!TEST_BIT (preferred_alternatives, alt1)) + if (!TEST_BIT (recog_data.preferred_alternatives, alt1)) continue; const operand_alternative *op_alt1 = &recog_op_alt[alt1 * n_operands]; @@ -698,7 +694,7 @@ make_early_clobber_and_input_conflicts (void) int n_operands = recog_data.n_operands; const operand_alternative *op_alt = recog_op_alt; for (alt = 0; alt < n_alternatives; alt++, op_alt += n_operands) - if (TEST_BIT (preferred_alternatives, alt)) + if (TEST_BIT (recog_data.preferred_alternatives, alt)) for (def = 0; def < n_operands; def++) { def_cl = NO_REGS; @@ -765,7 +761,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) enum constraint_num cn; cl = NO_REGS; - alternative_mask preferred = preferred_alternatives; + alternative_mask preferred = recog_data.preferred_alternatives; for (; (c = *constraints); constraints += CONSTRAINT_LEN (c, constraints)) if (c == '#') preferred &= ~ALTERNATIVE_BIT (0); @@ -854,7 +850,7 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set) mode = (GET_CODE (op) == SCRATCH ? GET_MODE (op) : PSEUDO_REGNO_MODE (regno)); cl = NO_REGS; - alternative_mask preferred = preferred_alternatives; + alternative_mask preferred = recog_data.preferred_alternatives; for (; (c = *p); p += CONSTRAINT_LEN (c, p)) if (c == '#') preferred &= ~ALTERNATIVE_BIT (0); @@ -1178,8 +1174,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) } } - extract_insn (insn); - preferred_alternatives = get_preferred_alternatives (insn); + extract_insn (insn, true); preprocess_constraints (insn); process_single_reg_class_operands (false, freq); diff --git a/gcc/recog.c b/gcc/recog.c index 120f7b9..840bf7f 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2225,7 +2225,7 @@ constrain_operands_cached (rtx_insn *insn, int strict) /* Analyze INSN and fill in recog_data. */ void -extract_insn (rtx_insn *insn) +extract_insn (rtx_insn *insn, bool preferred) { int i; int icode; @@ -2320,6 +2320,10 @@ extract_insn (rtx_insn *insn) gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES); + recog_data.preferred_alternatives = (preferred + ? get_preferred_alternatives (insn) + : 0); + recog_data.insn = NULL; which_alternative = -1; } diff --git a/gcc/recog.h b/gcc/recog.h index ce931eb..e0c946b 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -131,7 +131,7 @@ static inline int recog_memoized (rtx_insn *insn); extern void add_clobbers (rtx, int); extern int added_clobbers_hard_reg_p (int); extern void insn_extract (rtx_insn *); -extern void extract_insn (rtx_insn *); +extern void extract_insn (rtx_insn *, bool preferred = false); extern void extract_constrain_insn (rtx_insn *insn); extern void extract_constrain_insn_cached (rtx_insn *); extern void extract_insn_cached (rtx_insn *); @@ -248,6 +248,10 @@ struct recog_data_d /* True if insn is ASM_OPERANDS. */ bool is_asm; + /* Specifies whether an insn alternative is preferred by the current + target for the current size/speed optimization choice. */ + alternative_mask preferred_alternatives; + /* In case we are caching, hold insn data was generated for. */ rtx_insn *insn; }; diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 3ac66e8..f8de8b5 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -2889,7 +2889,7 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx_insn *insn) { HARD_REG_SET temp; - extract_insn (insn); + extract_insn (insn, true); preprocess_constraints (insn); ira_implicitly_set_insn_hard_regs (&temp); AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index ec2ab05..105ebd3 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -2102,7 +2102,7 @@ implicit_clobber_conflict_p (insn_t through_insn, expr_t expr) end_sequence (); /* Calculate implicit clobbers. */ - extract_insn (insn); + extract_insn (insn, true); preprocess_constraints (insn); ira_implicitly_set_insn_hard_regs (&temp); AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); diff --git a/gcc/testsuite/gcc.dg/pr67029.c b/gcc/testsuite/gcc.dg/pr67029.c new file mode 100644 index 0000000..f0023e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr67029.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { int128 && scheduling } } } */ +/* { dg-options "-O2 -fschedule-insns" } */ +/* { dg-additional-options "-fstack-protector" { target fstack_protector } } */ + +extern void fn2 (char *); +__int128 a, b; +int +fn1 (void) +{ + char e[32]; + fn2 (e); + b = 9 * (a >> 1); + return 0; +} -- 2.4.3