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]

[PATCH] Fix rtl sharing bug in rs6000_frame_related (PR target/78614)


Hi!

As mentioned in the PR, the rs6000_frame_related rewrite broke rtl sharing
whose --enable-checking=rtl verification has been broken for the last 3.5
years until today.
The problem is that simplify_replace_rtx doesn't unshare everything, only
the minimum needed to replace what is needed without changing original
expression.  But as we replace something from PATTERN of the insn and
want to stick that into REG_FRAME_RELATED_EXPR note in the insn stream
next to the PATTERN, there can't be any sharing except for shareable
rtxes.

The following patch is the more memory friendly version, it marks as used
everything in the original PATTERN, then does all those
simplify_replace_rtxs that usually (with the patch I've just posted more
often) when unsharing/creating new rtxes keep the used bit unset, and
finally does copy_rtx_if_shared which should unshare only whatever
simplify_replace_rtx has not unshared.

The last hunk just removes unnecessary condition, if the condition is not
true, we return from the function already earlier and don't do any
replacements.

Markus said he has bootstrapped this patch with rtl checking on powerpc64.

Ok for trunk?

2016-11-30  Jakub Jelinek  <jakub@redhat.com>

	PR target/78614
	* config/rs6000/rs6000.c (rs6000_frame_related): Call
	set_used_flags (pat) before any simplifications.  Clear used flag on
	PARALLEL copy.  Don't guard add_reg_note call.  Call
	copy_rtx_if_shared on pat before storing it into
	REG_FRAME_RELATED_EXPR.

--- gcc/config/rs6000/rs6000.c.jj	2016-11-29 07:31:02.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2016-11-30 17:10:40.805842306 +0100
@@ -27170,6 +27170,7 @@ rs6000_frame_related (rtx_insn *insn, rt
      Call simplify_replace_rtx on the SETs rather than the whole insn
      so as to leave the other stuff alone (for example USE of r12).  */
 
+  set_used_flags (pat);
   if (GET_CODE (pat) == SET)
     {
       if (repl)
@@ -27181,6 +27182,7 @@ rs6000_frame_related (rtx_insn *insn, rt
     {
       pat = shallow_copy_rtx (pat);
       XVEC (pat, 0) = shallow_copy_rtvec (XVEC (pat, 0));
+      RTX_FLAG (pat, used) = 0;
 
       for (int i = 0; i < XVECLEN (pat, 0); i++)
 	if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
@@ -27203,8 +27205,7 @@ rs6000_frame_related (rtx_insn *insn, rt
     gcc_unreachable ();
 
   RTX_FRAME_RELATED_P (insn) = 1;
-  if (repl || reg2)
-    add_reg_note (insn, REG_FRAME_RELATED_EXPR, pat);
+  add_reg_note (insn, REG_FRAME_RELATED_EXPR, copy_rtx_if_shared (pat));
 
   return insn;
 }

	Jakub


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