This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, rs6000] Fix PR88845: ICE in lra_set_insn_recog_data


On 3/4/19 1:27 PM, Segher Boessenkool wrote:
>> +      /* If LRA is generating a direct move from a GPR to a FPR,
>> +	 then the splitter is going to need a scratch register.  */
>> +      rtx insn = gen_movsf_from_si_internal (operands[0], operands[1]);
>> +      XEXP (XVECEXP (insn, 0, 1), 0) = gen_reg_rtx (DImode);
>> +      emit_insn (insn);
>> +      DONE;
> 
> This part isn't so great, needing detailed knowledge of the RTL generated
> by some other pattern.  Maybe there already exists some function that
> generates a register for every scratch in an insn, or you can make such
> a function?

A function that updates one insn does not exist.  There is remove_scratches(),
but that works on the entire cfg.  As part of my earlier attempts, I did split
remove_scratches() into a function that traverses the cfg and another that
replaces the scratches in one insn.  I've included it below.  I went with the
current patch, because that doesn't touch anything outside of the port.
If you prefer the patch below, we can go with that instead.  Let me know which
you prefer.


>> +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
>> +/* { dg-options "-mcpu=power8 -O2" } */
> 
> These two lines should now be just
> 
> /* { dg-options "-mdejagnu-cpu=power8 -O2" } */

Ok, will update that.

Peter



Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 269028)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -9887,7 +9887,7 @@ valid_sf_si_move (rtx dest, rtx src, mac
 static bool
 rs6000_emit_move_si_sf_subreg (rtx dest, rtx source, machine_mode mode)
 {
-  if (TARGET_DIRECT_MOVE_64BIT && !lra_in_progress && !reload_completed
+  if (TARGET_DIRECT_MOVE_64BIT && !reload_completed
       && (!SUBREG_P (dest) || !sf_subreg_operand (dest, mode))
       && SUBREG_P (source) && sf_subreg_operand (source, mode))
     {
@@ -9902,7 +9902,9 @@ rs6000_emit_move_si_sf_subreg (rtx dest,
 
       if (mode == SFmode && inner_mode == SImode)
 	{
-	  emit_insn (gen_movsf_from_si (dest, inner_source));
+	  rtx_insn *insn = emit_insn (gen_movsf_from_si (dest, inner_source));
+	  if (lra_in_progress)
+	    remove_scratches_1 (insn);
 	  return true;
 	}
     }

Index: gcc/lra.c
===================================================================
--- gcc/lra.c	(revision 269028)
+++ gcc/lra.c	(working copy)
@@ -2077,7 +2077,40 @@ lra_register_new_scratch_op (rtx_insn *i
   add_reg_note (insn, REG_UNUSED, op);
 }
 
-/* Change scratches onto pseudos and save their location.  */
+/* Change INSN's scratches into pseudos and save their location.  */
+void
+remove_scratches_1 (rtx_insn *insn)
+{
+  int i;
+  bool insn_changed_p;
+  rtx reg;
+  lra_insn_recog_data_t id;
+  struct lra_static_insn_data *static_id;
+
+  id = lra_get_insn_recog_data (insn);
+  static_id = id->insn_static_data;
+  insn_changed_p = false;
+  for (i = 0; i < static_id->n_operands; i++)
+    if (GET_CODE (*id->operand_loc[i]) == SCRATCH
+	&& GET_MODE (*id->operand_loc[i]) != VOIDmode)
+      {
+	insn_changed_p = true;
+	*id->operand_loc[i] = reg
+	  = lra_create_new_reg (static_id->operand[i].mode,
+				*id->operand_loc[i], ALL_REGS, NULL);
+	lra_register_new_scratch_op (insn, i, id->icode);
+	if (lra_dump_file != NULL)
+	  fprintf (lra_dump_file,
+		   "Removing SCRATCH in insn #%u (nop %d)\n",
+		   INSN_UID (insn), i);
+      }
+  if (insn_changed_p)
+    /* Because we might use DF right after caller-saves sub-pass
+       we need to keep DF info up to date.  */
+    df_insn_rescan (insn);
+}
+
+/* Change scratches into pseudos and save their location.  */
 static void
 remove_scratches (void)
 {
@@ -2095,29 +2128,7 @@ remove_scratches (void)
   FOR_EACH_BB_FN (bb, cfun)
     FOR_BB_INSNS (bb, insn)
     if (INSN_P (insn))
-      {
-	id = lra_get_insn_recog_data (insn);
-	static_id = id->insn_static_data;
-	insn_changed_p = false;
-	for (i = 0; i < static_id->n_operands; i++)
-	  if (GET_CODE (*id->operand_loc[i]) == SCRATCH
-	      && GET_MODE (*id->operand_loc[i]) != VOIDmode)
-	    {
-	      insn_changed_p = true;
-	      *id->operand_loc[i] = reg
-		= lra_create_new_reg (static_id->operand[i].mode,
-				      *id->operand_loc[i], ALL_REGS, NULL);
-	      lra_register_new_scratch_op (insn, i, id->icode);
-	      if (lra_dump_file != NULL)
-		fprintf (lra_dump_file,
-			 "Removing SCRATCH in insn #%u (nop %d)\n",
-			 INSN_UID (insn), i);
-	    }
-	if (insn_changed_p)
-	  /* Because we might use DF right after caller-saves sub-pass
-	     we need to keep DF info up to date.  */
-	  df_insn_rescan (insn);
-      }
+      remove_scratches_1 (insn);
 }
 
 /* Changes pseudos created by function remove_scratches onto scratches.	 */
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	(revision 269028)
+++ gcc/rtl.h	(working copy)
@@ -4087,6 +4087,9 @@ extern rtx fis_get_condition (rtx_insn *
 extern HARD_REG_SET eliminable_regset;
 extern void mark_elimination (int, int);
 
+/* In lra.c */
+extern void remove_scratches_1 (rtx_insn *);
+
 /* In reginfo.c */
 extern int reg_classes_intersect_p (reg_class_t, reg_class_t);
 extern int reg_class_subset_p (reg_class_t, reg_class_t);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]