RFA: Inserting NOPs for profiling.

Nick Clifton nickc@redhat.com
Fri Oct 13 17:49:00 GMT 2000


Hi Guys,

  I would like to propose a patch to fix a problem when generating NOP
  instructions for the profiling support.

  If profiling is enabled (with -pg) then GCC will emit a NOP at the
  start of the file, between the .gcc2_compiled symbol and the start
  of the first function.  This ensures that the address of the first
  function is not the same as the address of the .gcc2_compiled
  symbol, and so ensures that the profiler's output does not refer to
  the first function as if it were the .gcc2_compiled symbol.

  Unfortunately the code that is currently in GCC to generate this NOP
  does not work if the NOP pattern is a define_expand or if it is a
  define_insn which has a C body to compute the emitted assembler
  string.  In both cases the code will abort inside
  get_insn_template.  One particular case where this happens is the
  ARM port where the NOP pattern is complicated by the fact that there
  are two NOP instructions, one for ARM mode and one for Thumb mode.

  The patch solves the problem by taking the laborious approach of
  creating a dummy function, emitting a NOP insn, finalizing the insn
  sequence and then deleting the dummy function.  It works, and it
  should be safe.

  May I apply the patch ?

Cheers
	Nick

2000-10-13  Nick Clifton  <nickc@redhat.com>

	* toplev.c (compile_file): If inserting a NOP between
	.gcc2_compiled and the start of the first function, go through
	the entire processes of generating a dummy function in order
	to ensure that the NOP pattern is evaluated correctly.

Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.386
diff -p -r1.386 toplev.c
*** toplev.c	2000/10/13 06:26:29	1.386
--- toplev.c	2000/10/14 00:31:43
*************** compile_file (name)
*** 2310,2316 ****
      {
        /* It's best if we can write a nop here since some
  	 assemblers don't tolerate zeros in the text section.  */
!       output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL_PTR);
      }
  
    /* If dbx symbol table desired, initialize writing it
--- 2310,2348 ----
      {
        /* It's best if we can write a nop here since some
  	 assemblers don't tolerate zeros in the text section.  */
!       
!       /* We used to just do:
! 	 
! 	   output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL_PTR);
! 
! 	 but this does not work if the NOP pattern is a define_expand
! 	 or a define_insn that requires a valid insn.  This happens for example,
! 	 on the ARM port, where there are two nop instructions, one for ARM
! 	 mode and one for Thumb mode.  Instead we have to go through the whole
! 	 palava of creating a dummy function and then outputing it.  */
!       init_dummy_function_start (); 
!       start_sequence ();
!       
!       /* For some reason final() skips the first insn in the chain that is
! 	 passed to it, so we add a dummy note to prevent the nop from
! 	 being missed.  */
!       emit_note (0, NOTE_INSN_DELETED);
!       emit_insn (gen_nop ());
!       
!       /* FIXME - should we emit these insns if RTL debugging is enabled ?  */
! 
!       /* We call shorten_branches in order to generate the insn_addresses_
! 	 array.  This is used in final.  */
!       timevar_push (TV_SHORTEN_BRANCH);
!       shorten_branches (get_insns ());
!       timevar_pop (TV_SHORTEN_BRANCH);
!       
!       timevar_push (TV_FINAL);
!       final (get_insns (), asm_out_file, FALSE, 0);
!       timevar_pop (TV_FINAL);
!       
!       end_sequence ();
!       expand_dummy_function_end ();
      }
  
    /* If dbx symbol table desired, initialize writing it


More information about the Gcc-patches mailing list