This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils 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]

[binutils-gdb] Optimize branches to non-weak symbols with visibility


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b084df0b8d1262fb1e969c74bcc5c61e262a6199

commit b084df0b8d1262fb1e969c74bcc5c61e262a6199
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu May 7 09:13:39 2015 -0700

    Optimize branches to non-weak symbols with visibility
    
    Branches to global non-weak symbols defined in the same segment with
    non-default visibility can be optimized the same way as branches to
    local symbols.
    
    gas/
    
    	* config/tc-i386.c (elf_symbol_resolved_in_segment_p): New.
    	(md_estimate_size_before_relax): Use it.
    
    gas/testsuite/
    
    	* gas/i386/i386.exp: Run relax-3 and x86-64-relax-2.
    	* gas/i386/relax-3.d: New file.
    	* gas/i386/relax-3.s: Likewise.
    	* gas/i386/x86-64-relax-2.d: Likewise.

Diff:
---
 gas/ChangeLog                           |  5 +++++
 gas/config/tc-i386.c                    | 24 ++++++++++++++++----
 gas/testsuite/ChangeLog                 |  7 ++++++
 gas/testsuite/gas/i386/i386.exp         |  4 ++++
 gas/testsuite/gas/i386/relax-3.d        | 30 +++++++++++++++++++++++++
 gas/testsuite/gas/i386/relax-3.s        | 39 +++++++++++++++++++++++++++++++++
 gas/testsuite/gas/i386/x86-64-relax-2.d | 32 +++++++++++++++++++++++++++
 7 files changed, 137 insertions(+), 4 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7f42a64..9758e72 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2015-05-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* config/tc-i386.c (elf_symbol_resolved_in_segment_p): New.
+	(md_estimate_size_before_relax): Use it.
+
 2015-05-06  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
 	* config/tc-sparc.c: Typo in comment fixed.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 50f9cb4..c4ba13d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -8772,6 +8772,25 @@ i386_frag_max_var (fragS *frag)
   return TYPE_FROM_RELAX_STATE (frag->fr_subtype) == UNCOND_JUMP ? 4 : 5;
 }
 
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+static int
+elf_symbol_resolved_in_segment_p (symbolS *fr_symbol)
+{
+  /* STT_GNU_IFUNC symbol must go through PLT.  */
+  if ((symbol_get_bfdsym (fr_symbol)->flags
+       & BSF_GNU_INDIRECT_FUNCTION) != 0)
+    return 0;
+
+  if (!S_IS_EXTERNAL (fr_symbol))
+    /* Symbol may be weak or local.  */
+    return !S_IS_WEAK (fr_symbol);
+
+  /* Global symbols with default visibility in a shared library may be
+     preempted by another definition.  */
+  return ELF_ST_VISIBILITY (S_GET_OTHER (fr_symbol)) != STV_DEFAULT;
+}
+#endif
+
 /* md_estimate_size_before_relax()
 
    Called just before relax() for rs_machine_dependent frags.  The x86
@@ -8795,10 +8814,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment)
   if (S_GET_SEGMENT (fragP->fr_symbol) != segment
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       || (IS_ELF
-	  && (S_IS_EXTERNAL (fragP->fr_symbol)
-	      || S_IS_WEAK (fragP->fr_symbol)
-	      || ((symbol_get_bfdsym (fragP->fr_symbol)->flags
-		   & BSF_GNU_INDIRECT_FUNCTION))))
+	  && !elf_symbol_resolved_in_segment_p (fragP->fr_symbol))
 #endif
 #if defined (OBJ_COFF) && defined (TE_PE)
       || (OUTPUT_FLAVOR == bfd_target_coff_flavour
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 6339bff..1cfa577 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2015-05-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* gas/i386/i386.exp: Run relax-3 and x86-64-relax-2.
+	* gas/i386/relax-3.d: New file.
+	* gas/i386/relax-3.s: Likewise.
+	* gas/i386/x86-64-relax-2.d: Likewise.
+
 2015-05-06  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
 	* gas/sparc/natural-32.d: Test ldn, ldna, stn, stna, slln, srln,
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index e1fdd18..af56c26 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -394,6 +394,8 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
 	run_dump_test "size-4"
 
 	run_dump_test "note"
+
+	run_dump_test "relax-3"
     }
 
     # This is a PE specific test.
@@ -748,6 +750,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
 	run_dump_test "x86-64-size-4"
 	run_dump_test "x86-64-size-5"
 	run_list_test "x86-64-size-inval-1" "-al"
+
+	run_dump_test "x86-64-relax-2"
     }
 
     set ASFLAGS "$old_ASFLAGS"
diff --git a/gas/testsuite/gas/i386/relax-3.d b/gas/testsuite/gas/i386/relax-3.d
new file mode 100644
index 0000000..8aa94e9
--- /dev/null
+++ b/gas/testsuite/gas/i386/relax-3.d
@@ -0,0 +1,30 @@
+#objdump: -dwr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <foo>:
+[ 	]*[a-f0-9]+:	eb 1f                	jmp    21 <local>
+[ 	]*[a-f0-9]+:	eb 19                	jmp    1d <hidden_def>
+[ 	]*[a-f0-9]+:	e9 fc ff ff ff       	jmp    5 <foo\+0x5>	5: (R_386_PC)?(DISP)?32	global_def
+[ 	]*[a-f0-9]+:	e9 fc ff ff ff       	jmp    a <foo\+0xa>	a: (R_386_PC)?(DISP)?32	weak_def
+[ 	]*[a-f0-9]+:	e9 fc ff ff ff       	jmp    f <foo\+0xf>	f: (R_386_PC)?(DISP)?32	weak_hidden_undef
+[ 	]*[a-f0-9]+:	e9 fc ff ff ff       	jmp    14 <foo\+0x14>	14: (R_386_PC)?(DISP)?32	weak_hidden_def
+[ 	]*[a-f0-9]+:	e9 fc ff ff ff       	jmp    19 <foo\+0x19>	19: (R_386_PC)?(DISP)?32	hidden_undef
+
+0+1d <hidden_def>:
+[ 	]*[a-f0-9]+:	c3                   	ret    
+
+0+1e <weak_hidden_def>:
+[ 	]*[a-f0-9]+:	c3                   	ret    
+
+0+1f <global_def>:
+[ 	]*[a-f0-9]+:	c3                   	ret    
+
+0+20 <weak_def>:
+[ 	]*[a-f0-9]+:	c3                   	ret    
+
+0+21 <local>:
+[ 	]*[a-f0-9]+:	c3                   	ret    
+#pass
diff --git a/gas/testsuite/gas/i386/relax-3.s b/gas/testsuite/gas/i386/relax-3.s
new file mode 100644
index 0000000..ab52185
--- /dev/null
+++ b/gas/testsuite/gas/i386/relax-3.s
@@ -0,0 +1,39 @@
+	.text
+	.global foo
+foo:
+	jmp local
+	jmp hidden_def
+	jmp global_def
+	jmp weak_def
+	jmp weak_hidden_undef
+	jmp weak_hidden_def
+	jmp hidden_undef
+
+	.hidden hidden_undef
+
+	.global hidden_def
+	.hidden hidden_def
+hidden_def:
+	ret
+
+	.global weak_hidden_def
+	.hidden weak_hidden_def
+	.weak weak_hidden_def
+weak_hidden_def:
+	ret
+
+	.global global_def
+global_def:
+	ret
+
+	.global weak_def
+	.weak weak_def
+weak_def:
+	ret
+
+local:
+	ret
+
+	.global weak_hidden_undef
+	.weak weak_hidden_undef
+	.hidden weak_hidden_undef
diff --git a/gas/testsuite/gas/i386/x86-64-relax-2.d b/gas/testsuite/gas/i386/x86-64-relax-2.d
new file mode 100644
index 0000000..7b0bd56
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-relax-2.d
@@ -0,0 +1,32 @@
+#source: relax-3.s
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <foo>:
+[ 	]*[a-f0-9]+:	eb 1f                	jmp    21 <local>
+[ 	]*[a-f0-9]+:	eb 19                	jmp    1d <hidden_def>
+[ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   9 <foo\+0x9>	5: R_X86_64_PC32	global_def-0x4
+[ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   e <foo\+0xe>	a: R_X86_64_PC32	weak_def-0x4
+[ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   13 <foo\+0x13>	f: R_X86_64_PC32	weak_hidden_undef-0x4
+[ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   18 <foo\+0x18>	14: R_X86_64_PC32	weak_hidden_def-0x4
+[ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   1d <hidden_def>	19: R_X86_64_PC32	hidden_undef-0x4
+
+0+1d <hidden_def>:
+[ 	]*[a-f0-9]+:	c3                   	retq   
+
+0+1e <weak_hidden_def>:
+[ 	]*[a-f0-9]+:	c3                   	retq   
+
+0+1f <global_def>:
+[ 	]*[a-f0-9]+:	c3                   	retq   
+
+0+20 <weak_def>:
+[ 	]*[a-f0-9]+:	c3                   	retq   
+
+0+21 <local>:
+[ 	]*[a-f0-9]+:	c3                   	retq   
+#pass


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