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]

Don't remove no-op instructions in final_scan_insn


There is long standing code in final_scan_insn which discards
instructions which simply set a register to itself, with this comment:

	/* Don't bother outputting obvious no-ops, even without -O.
	   This optimization is fast and doesn't interfere with debugging.
	   Don't do this if the insn is in a delay slot, since this
	   will cause an improper number of delay insns to be written.  */

This code tripped me up on an uncontributed backend for a VLIW
processor when compiling without optimization, because I was doing
instruction packing which assumed that the instruction stream was no
longer going to change.  When optimizing these useless instructions
are removed earlier, but when not optimizing they can stick around
until they are removed by final_scan_insn.

Other processors do similar packing tricks, of course.  How do they
get away with it?  It turns out that split_all_insns_noflow discards
no-op instructions after reload.  And it turns out that
split_all_insns_noflow is called even when not optimizing if you
happen to have an instruction attribute named "length".

Note that you can't remove no-op instructions before reload, because
they are used as the end of a REG_NO_CONFLICT block as generated by
emit_no_conflict_block.  I think REG_NO_CONFLICT should be reworked
somehow, but I don't know how.

Anyhow, I think this kind of subtlety is unnecessary.  I don't think
that final_scan_insn should change the instruction stream in this way.
(It does change the instruction stream in the HAVE_cc0 case, and if
there are peepholes, but those cases are at least better documented.)

I propose moving the removal of simple no-op instructions to the end
of reload, where it already walks over all the instructions anyhow.
This should retain the optimization when not optimizing, and should
not have any negative affect on compilation speed.

This patch also makes a step toward removing the somewhat confusing,
and no longer necessary, prescan parameter of final_scan_insn.

Passed bootstrap and testsuite on i686-pc-linux-gnu.  OK to commit?

Ian


2005-03-22  Ian Lance Taylor  <ian@airs.com>

	* final.c (final_scan_insn): Don't remove no-op instructions.
	* reload1.c (reload): Remove simple no-op instructions even when
	not optimizing.


Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.345
diff -u -p -r1.345 final.c
--- final.c	22 Mar 2005 13:29:09 -0000	1.345
+++ final.c	22 Mar 2005 19:01:01 -0000
@@ -2267,20 +2267,6 @@ final_scan_insn (rtx insn, FILE *file, i
 	  }
 #endif
 
-#ifndef STACK_REGS
-	/* Don't bother outputting obvious no-ops, even without -O.
-	   This optimization is fast and doesn't interfere with debugging.
-	   Don't do this if the insn is in a delay slot, since this
-	   will cause an improper number of delay insns to be written.  */
-	if (final_sequence == 0
-	    && prescan >= 0
-	    && NONJUMP_INSN_P (insn) && GET_CODE (body) == SET
-	    && REG_P (SET_SRC (body))
-	    && REG_P (SET_DEST (body))
-	    && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
-	  break;
-#endif
-
 #ifdef HAVE_cc0
 	/* If this is a conditional branch, maybe modify it
 	   if the cc's are in a nonstandard state
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.463
diff -u -p -r1.463 reload1.c
--- reload1.c	7 Mar 2005 17:48:37 -0000	1.463
+++ reload1.c	22 Mar 2005 19:01:03 -0000
@@ -1174,6 +1174,19 @@ reload (rtx first, int global)
 	  replace_pseudos_in (& XEXP (PATTERN (insn), 0),
 			      VOIDmode, PATTERN (insn));
 
+	/* Discard obvious no-ops, even without -O.  This optimization
+	   is fast and doesn't interfere with debugging.  */
+	if (NONJUMP_INSN_P (insn)
+	    && GET_CODE (PATTERN (insn)) == SET
+	    && REG_P (SET_SRC (PATTERN (insn)))
+	    && REG_P (SET_DEST (PATTERN (insn)))
+	    && (REGNO (SET_SRC (PATTERN (insn)))
+		== REGNO (SET_DEST (PATTERN (insn)))))
+	  {
+	    delete_insn (insn);
+	    continue;
+	  }
+
 	pnote = &REG_NOTES (insn);
 	while (*pnote != 0)
 	  {


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