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]

Re: [c/c++] i686 codegen bugs in tinfo2.cc


On Sun, Jan 14, 2001 at 06:02:24PM -0800, Richard Henderson wrote:
> > I'm forwarding this email from scott synder, about this bug. It seems to 
> > be relevant to this discussion...
> 
> Yes, this is the same bug.
> 
> > http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00068.html
> 
> I thought about that, but I think it would be better to emit
> one pic label thunk per section, as that is friendlier to
> --gc-sections.  I'm working on a patch for this now.

Geoff came up with a better suggestion -- use linkonce sections
so that we only get one of these thunks per dso.  This works out
fairly well.

The only irritating part is how much configury changes are
necessary to get ASM_FILE_END defined properly, given that
config/elfos.h obsconds with it.

Tested on i586-linux and i686-linux.  Built i686-cygwin and
i686-freebsd4.2 cross compilers to verify the configury.


r~


        * config/i386/i386.c (asm_output_function_prefix): Remove.
        (ix86_asm_file_end): New.
        (load_pic_register): Generate pic_label_name into a
        staticly allocated buffer.
        * config/i386/i386-protos.h: Update.
        * config/i386/i386.h (ASM_OUTPUT_FUNCTION_PREFIX): Remove.
        (ASM_FILE_END): New.
        * config/i386/i386afe.h: New file.
        * config.gcc (i?86-*-elf) [tm_file]: Use it.
        (i?86-*-{freebsd,linux*,moss*}): Likewise.
        * config/elfos.h (ASM_FILE_END): Undef before redefinition.
        * config/i386/cygwin.h (ASM_FILE_END): Likewise.
        * config/i386/osfrose.h (ASM_FILE_END): Invoke ix86_asm_file_end.
        * config/i386/sco5.h (ASM_FILE_END): Likewise.
        * config/i386/winnt.c (i386_pe_asm_file_end): Likewise.

Index: config.gcc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config.gcc,v
retrieving revision 1.20
diff -c -p -d -r1.20 config.gcc
*** config.gcc	2001/01/09 22:10:52	1.20
--- config.gcc	2001/01/15 23:31:28
*************** i370-*-linux*)
*** 979,985 ****
  	;;
  i[34567]86-*-elf*)
  	xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h"
! 	tm_file="i386/i386.h i386/att.h elfos.h i386/i386elf.h"
  	tmake_file=i386/t-i386elf
  	xmake_file=x-svr4
  	;;
--- 979,985 ----
  	;;
  i[34567]86-*-elf*)
  	xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h"
! 	tm_file="i386/i386.h i386/att.h elfos.h i386/i386afe.h i386/i386elf.h"
  	tmake_file=i386/t-i386elf
  	xmake_file=x-svr4
  	;;
*************** i[34567]86-*-freebsd[12] | i[34567]86-*-
*** 1095,1101 ****
  	tmake_file=t-freebsd
  	;;
  i[34567]86-*-freebsd*)
! 	tm_file="i386/i386.h i386/att.h svr4.h freebsd.h i386/freebsd.h i386/perform.h"
  	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  	tmake_file=t-freebsd
  	gas=yes
--- 1095,1101 ----
  	tmake_file=t-freebsd
  	;;
  i[34567]86-*-freebsd*)
! 	tm_file="i386/i386.h i386/att.h svr4.h freebsd.h i386/i386afe.h i386/freebsd.h i386/perform.h"
  	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  	tmake_file=t-freebsd
  	gas=yes
*************** i[34567]86-*-linux*libc1)	# Intel 80386'
*** 1166,1172 ****
  				# with ELF format using the
  				# GNU/Linux C library 5
  	xmake_file=x-linux	
! 	tm_file="i386/i386.h i386/att.h linux.h i386/linux.h"
  	tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff"
  	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  	gnu_ld=yes
--- 1166,1172 ----
  				# with ELF format using the
  				# GNU/Linux C library 5
  	xmake_file=x-linux	
! 	tm_file="i386/i386.h i386/att.h linux.h i386/i386afe.h i386/linux.h"
  	tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff"
  	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  	gnu_ld=yes
*************** i[34567]86-*-linux*)	# Intel 80386's run
*** 1179,1185 ****
  			# with ELF format using glibc 2
  			# aka GNU/Linux C library 6
  	xmake_file=x-linux
! 	tm_file="i386/i386.h i386/att.h linux.h i386/linux.h"
  	tmake_file="t-linux i386/t-crtstuff"
  	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  	gnu_ld=yes
--- 1179,1185 ----
  			# with ELF format using glibc 2
  			# aka GNU/Linux C library 6
  	xmake_file=x-linux
! 	tm_file="i386/i386.h i386/att.h linux.h i386/i386afe.h i386/linux.h"
  	tmake_file="t-linux i386/t-crtstuff"
  	extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
  	gnu_ld=yes
*************** i[34567]86-pc-msdosdjgpp*)
*** 1210,1216 ****
  	esac
  	;;
  i[34567]86-moss-msdos* | i[34567]86-*-moss*)
! 	tm_file="i386/i386.h i386/att.h linux.h i386/linux.h i386/moss.h"
  	tmake_file=t-libc-ok
  	gnu_ld=yes
  	gas=yes
--- 1210,1216 ----
  	esac
  	;;
  i[34567]86-moss-msdos* | i[34567]86-*-moss*)
! 	tm_file="i386/i386.h i386/att.h linux.h i386/i386afe.h i386/linux.h i386/moss.h"
  	tmake_file=t-libc-ok
  	gnu_ld=yes
  	gas=yes
Index: config/elfos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/elfos.h,v
retrieving revision 1.23
diff -c -p -d -r1.23 elfos.h
*** elfos.h	2000/11/27 04:25:32	1.23
--- elfos.h	2001/01/15 23:31:28
*************** Boston, MA 02111-1307, USA.  */
*** 100,105 ****
--- 100,106 ----
  
  #define IDENT_ASM_OP "\t.ident\t"
  
+ #undef ASM_FILE_END
  #define ASM_FILE_END(FILE)				\
    do							\
      {				 			\
Index: config/i386/cygwin.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/cygwin.h,v
retrieving revision 1.28
diff -c -p -d -r1.28 cygwin.h
*** cygwin.h	2000/11/10 04:10:04	1.28
--- cygwin.h	2001/01/15 23:31:29
*************** do {									\
*** 498,503 ****
--- 498,504 ----
    asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
  
  /* Output function declarations at the end of the file.  */
+ #undef ASM_FILE_END
  #define ASM_FILE_END(FILE) \
    i386_pe_asm_file_end (FILE)
  
Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386-protos.h,v
retrieving revision 1.34
diff -c -p -d -r1.34 i386-protos.h
*** i386-protos.h	2001/01/14 09:14:03	1.34
--- i386-protos.h	2001/01/15 23:31:29
*************** extern void optimization_options PARAMS 
*** 26,32 ****
  
  extern int ix86_can_use_return_insn_p PARAMS ((void));
  
! extern void asm_output_function_prefix PARAMS ((FILE *, const char *));
  extern void load_pic_register PARAMS ((void));
  extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
  extern void ix86_expand_prologue PARAMS ((void));
--- 26,32 ----
  
  extern int ix86_can_use_return_insn_p PARAMS ((void));
  
! extern void ix86_asm_file_end PARAMS ((FILE *));
  extern void load_pic_register PARAMS ((void));
  extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
  extern void ix86_expand_prologue PARAMS ((void));
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.204
diff -c -p -d -r1.204 i386.c
*** i386.c	2001/01/15 13:19:31	1.204
--- i386.c	2001/01/15 23:31:29
*************** ix86_can_use_return_insn_p ()
*** 1689,1732 ****
    return tsize == 0 && nregs == 0;
  }
  
! static const char *pic_label_name;
! static int pic_label_output;
  
  /* This function generates code for -fpic that loads %ebx with
     the return address of the caller and then returns.  */
  
  void
! asm_output_function_prefix (file, name)
       FILE *file;
-      const char *name ATTRIBUTE_UNUSED;
  {
    rtx xops[2];
-   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
- 				  || current_function_uses_const_pool);
-   xops[0] = pic_offset_table_rtx;
-   xops[1] = stack_pointer_rtx;
  
!   /* Deep branch prediction favors having a return for every call.  */
!   if (pic_reg_used && TARGET_DEEP_BRANCH_PREDICTION)
!     {
!       if (!pic_label_output)
! 	{
! 	  /* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an
! 	     internal (non-global) label that's being emitted, it didn't make
! 	     sense to have .type information for local labels.   This caused
! 	     the SCO OpenServer 5.0.4 ELF assembler grief (why are you giving
! 	     me debug info for a label that you're declaring non-global?) this
! 	     was changed to call ASM_OUTPUT_LABEL() instead.  */
  
! 	  ASM_OUTPUT_LABEL (file, pic_label_name);
  
! 	  xops[1] = gen_rtx_MEM (SImode, xops[1]);
! 	  output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
! 	  output_asm_insn ("ret", xops);
  
! 	  pic_label_output = 1;
! 	}
!     }
  }
  
  void
--- 1689,1741 ----
    return tsize == 0 && nregs == 0;
  }
  
! static char pic_label_name[32];
  
  /* This function generates code for -fpic that loads %ebx with
     the return address of the caller and then returns.  */
  
  void
! ix86_asm_file_end (file)
       FILE *file;
  {
    rtx xops[2];
  
!   if (! TARGET_DEEP_BRANCH_PREDICTION || pic_label_name[0] == 0)
!     return;
  
! #ifdef ASM_OUTPUT_SECTION_NAME
!   /* The trick here is to create a linkonce section containing the
!      pic label thunk, but to refer to it with an internal label.
!      Because the label is internal, we don't have inter-dso name
!      binding issues on hosts that don't support ".hidden".
  
!      In order to use these macros, however, we must create a fake
!      function decl.  */
!   {
!     tree decl = build_decl (FUNCTION_DECL,
! 			    get_identifier ("i686.get_pc_thunk"),
! 			    error_mark_node);
!     DECL_ONE_ONLY (decl) = 1;
!     UNIQUE_SECTION (decl, 0);
!     named_section (decl, NULL, 0);
!   }
! #else
!   text_section ();
! #endif
  
!   /* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an
!      internal (non-global) label that's being emitted, it didn't make
!      sense to have .type information for local labels.   This caused
!      the SCO OpenServer 5.0.4 ELF assembler grief (why are you giving
!      me debug info for a label that you're declaring non-global?) this
!      was changed to call ASM_OUTPUT_LABEL() instead.  */
! 
!   ASM_OUTPUT_LABEL (file, pic_label_name);
! 
!   xops[0] = pic_offset_table_rtx;
!   xops[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
!   output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
!   output_asm_insn ("ret", xops);
  }
  
  void
*************** load_pic_register ()
*** 1738,1749 ****
  
    if (TARGET_DEEP_BRANCH_PREDICTION)
      {
!       if (pic_label_name == NULL)
! 	{
! 	  char buf[32];
! 	  ASM_GENERATE_INTERNAL_LABEL (buf, "LPR", 0);
! 	  pic_label_name = ggc_strdup (buf);
! 	}
        pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name));
      }
    else
--- 1747,1754 ----
  
    if (TARGET_DEEP_BRANCH_PREDICTION)
      {
!       if (! pic_label_name[0])
! 	ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
        pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name));
      }
    else
*************** ix86_emit_save_regs ()
*** 1951,1958 ****
  void
  ix86_expand_prologue ()
  {
!   HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *) 0, (int *) 0,
! 						 (int *) 0);
    rtx insn;
    int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
  				  || current_function_uses_const_pool);
--- 1956,1963 ----
  void
  ix86_expand_prologue ()
  {
!   HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *) 0,
! 						 (int *) 0, (int *) 0);
    rtx insn;
    int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
  				  || current_function_uses_const_pool);
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.144
diff -c -p -d -r1.144 i386.h
*** i386.h	2001/01/13 08:57:29	1.144
--- i386.h	2001/01/15 23:31:29
*************** typedef struct ix86_args {
*** 1356,1368 ****
         || ! FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL)))) \
         || FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl))))))
  
! /* This macro is invoked just before the start of a function.
!    It is used here to output code for -fpic that will load the
!    return address into %ebx.  */
  
! #undef ASM_OUTPUT_FUNCTION_PREFIX
! #define ASM_OUTPUT_FUNCTION_PREFIX(FILE, FNNAME) \
!   asm_output_function_prefix (FILE, FNNAME)
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
     for profiling a function entry.  */
--- 1356,1366 ----
         || ! FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL)))) \
         || FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl))))))
  
! /* This macro is invoked at the end of compilation.  It is used here to
!    output code for -fpic that will load the return address into %ebx.  */
  
! #undef ASM_FILE_END
! #define ASM_FILE_END(FILE)  ix86_asm_file_end (FILE)
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
     for profiling a function entry.  */
Index: config/i386/i386afe.h
===================================================================
RCS file: i386afe.h
diff -N i386afe.h
*** /dev/null	Tue May  5 13:32:27 1998
--- i386afe.h	Mon Jan 15 15:31:29 2001
***************
*** 0 ****
--- 1,37 ----
+ /* Copyright (C) 2001 Free Software Foundation, Inc.
+ 
+ This file is part of GNU CC.
+ 
+ GNU CC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+ 
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING.  If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+ 
+ /* Irritatingly, config/elfos.h defines its own version of ASM_FILE_END,
+    conflicting with a definition which we wish to have in i386/i386.h.
+    We _really_ need to clean up the hodge-podge of random macro placement
+    in the configury...  */
+ 
+ /* This macro is invoked at the end of compilation.  It is used here to
+    output code for -fpic that will load the return address into %ebx.  */
+ 
+ #undef ASM_FILE_END
+ #define ASM_FILE_END(FILE)				\
+   do							\
+     {				 			\
+       ix86_asm_file_end (FILE);				\
+       if (!flag_no_ident)				\
+ 	fprintf ((FILE), "%s\"GCC: (GNU) %s\"\n",	\
+ 		 IDENT_ASM_OP, version_string);		\
+     }							\
+   while (0)
Index: config/i386/osfrose.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/osfrose.h,v
retrieving revision 1.16
diff -c -p -d -r1.16 osfrose.h
*** osfrose.h	2000/11/02 23:29:10	1.16
--- osfrose.h	2001/01/15 23:31:29
*************** while (0)
*** 752,763 ****
  #define SCCS_DIRECTIVE
  
  /* This says what to print at the end of the assembly file */
  #define ASM_FILE_END(STREAM)						\
  do									\
    {									\
      if (HALF_PIC_P ())							\
        HALF_PIC_FINISH (STREAM);						\
! 									\
      if (!flag_no_ident)							\
        {									\
  	char *fstart = main_input_filename;				\
--- 752,764 ----
  #define SCCS_DIRECTIVE
  
  /* This says what to print at the end of the assembly file */
+ #undef ASM_FILE_END
  #define ASM_FILE_END(STREAM)						\
  do									\
    {									\
      if (HALF_PIC_P ())							\
        HALF_PIC_FINISH (STREAM);						\
!     ix86_asm_file_end (STREAM);						\
      if (!flag_no_ident)							\
        {									\
  	char *fstart = main_input_filename;				\
Index: config/i386/sco5.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/sco5.h,v
retrieving revision 1.41
diff -c -p -d -r1.41 sco5.h
*** sco5.h	2000/12/30 17:14:52	1.41
--- sco5.h	2001/01/15 23:31:29
*************** do {									\
*** 213,218 ****
--- 213,219 ----
  #undef ASM_FILE_END
  #define ASM_FILE_END(FILE)						\
  do {									\
+      ix86_asm_file_end (FILE);						\
       if (!flag_no_ident)						\
  	fprintf ((FILE), "%s\"GCC: (GNU) %s\"\n",			\
  		 IDENT_ASM_OP, version_string);				\
Index: config/i386/winnt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/winnt.c,v
retrieving revision 1.18
diff -c -p -d -r1.18 winnt.c
*** winnt.c	2000/01/22 19:49:21	1.18
--- winnt.c	2001/01/15 23:31:29
*************** i386_pe_asm_file_end (file)
*** 592,597 ****
--- 592,599 ----
  {
    struct extern_list *p;
  
+   ix86_asm_file_end (file);
+ 
    for (p = extern_head; p != NULL; p = p->next)
      {
        tree decl;

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