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: Don't remove no-op instructions in final_scan_insn


Richard Henderson <rth@redhat.com> writes:

> On Tue, Mar 22, 2005 at 02:05:07PM -0500, Ian Lance Taylor wrote:
> > Other processors do similar packing tricks, of course.  How do they
> > get away with it?
> 
> By issuing nop instructions that aren't moves.  E.g.
> 
> (define_insn "nop_f"
>   [(const_int 3)]
>   ""
>   "nop.f 0"
>   [(set_attr "itanium_class" "nop_f")])
> 
> Which is also gross, I admit.

No, I know that.  The problem I was thinking of is that they do their
computations based on the existing instruction stream, and then nop
moves are stripped by final.  For example, in the MIPS machine
dependent reorg pass, if TARGET_EXPLICIT_RELOCS, the MIPS backend
inserts explicit nops to avoid load delay hazards.  This happens even
when not optimizing.  If there were any no-op moves at that point, the
computations would be wrong, because those instructions would be
stripped by final_scan_insn thus reducing the number of expected
instruction cycles.  The reason it is not a problem is that the MIPS
reorg pass calls split_all_insns_noflow, and that discards the no-op
moves before the hazard avoidance code sees them.  It is this subtle
dependence on the behaviour of split_all_insns_noflow to avoid the
issue in final_scan_insn which I would like to fix.

> > 	* final.c (final_scan_insn): Don't remove no-op instructions.
> > 	* reload1.c (reload): Remove simple no-op instructions even when
> > 	not optimizing.
> 
> Should be ok for -O0.  I'd look to see that we catch nop moves that 
> might be emitted by post-reload splitters though.  I could also imagine
> reg-reg nop moves being created by the regrename pass.  Which leaves 
> us with a potential cleanup point just before rest_of_handle_sched2.

My patch changes nothing in between regrename and sched2, since final
of course happens after that.  sched2 will already clean up any no-op
moves generated by regregname, because rest_of_handle_sched2 calls
split_all_insns, which discards no-op moves.

We presumably don't care that much when not optimizing--that is, we
don't need to strip out every single no-op move.  So the issue is that
happens when we are optimizing.  In that case the post-reload
splitters will be run:
  * by rest_of_handle_flow2 (always when optimizing)
  * by rest_of_handle_sched2 (if INSN_SCHEDULING and
    flag_schedule_insns_after_reload, normally set at -O2)
  * by rest_of_handle_stack_regs (if STACK_REGS is defined, i.e., x86)
  * at the end of rest_of_compilation (if there is an attribute named
    "length", and STACK_REGS is not defined).

Since rest_of_handle_flow2 will always run the splitters when
optimizing, any no-op moves created by the postreload splitters, or
for that matter by regregname, will certainly be cleaned up by the
call to split_all_insns_noflow at the end of rest_of_compilation,
which happens if there is an attribute named "length".  At present the
following targets do not define such an attribute: c4x, cris, d30v,
dsp16xx, i370, i860, i960, ia64, m68hc11, m68k, mmix, mn10300, ns32k,
vax.  In other words, every primary target does define an attribute
named "length", as does every secondary target except
ia64-unknown-linux-gnu.  So we already know for sure that we will not
introduce any new no-op moves on any primary platforms.  (The case of
STACK_REGS being defined is sure to remove no-op moves created by
postreload splitters because rest_of_handle_stack_regs will call
split_all_insns).

We can be sure that we will not introduce any new no-op moves when
optimizing on all platforms if we make the call to
split_all_insns_noflow unconditional except for STACK_REGS.  We know
that that will not slow down the compiler on any primary platform,
because the call is already being made on those platforms.

Would you like to me to commit the appended patch along with the patch
to move no-op move detection from final to reload?

Ian

Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.75
diff -u -r2.75 passes.c
--- passes.c	21 Mar 2005 18:49:23 -0000	2.75
+++ passes.c	23 Mar 2005 14:49:17 -0000
@@ -1738,7 +1738,7 @@
     rest_of_handle_delay_slots ();
 #endif
 
-#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
+#ifndef STACK_REGS
   timevar_push (TV_SHORTEN_BRANCH);
   split_all_insns_noflow ();
   timevar_pop (TV_SHORTEN_BRANCH);


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