diff mbox

PR rtl-optimization/67029: gcc-5.2.0 unable to find a register to spill with O3 fsched-pressure fschedule-insns

Message ID 20150806023518.GA17522@intel.com
State New
Headers show

Commit Message

H.J. Lu Aug. 6, 2015, 2:35 a.m. UTC
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 mbox

Patch

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;
+}