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]

[COMMITTED][AArch64] Tighten direct call pattern to repair -fno-plt


James Greenhalgh writes:

> On Thu, Jul 16, 2015 at 11:21:25AM +0100, Jiong Wang wrote:
>> 
>> Jeff Law writes:
>> 
>> > On 06/23/2015 02:29 AM, Ramana Radhakrishnan wrote:
>> >
>> >>> If you try disabling the REG_EQUAL note generation [*], you'll probably find a
>> >>> performance regression on arm32 (and probably on aarch64 as well?
>> >>> we only
>> >>
>> >> IMHO disabling the REG_EQUAL note generation is the wrong way to go about this.
>> > Agreed.
>> >
>> >> Irrespective of combine, as a first step we should fix the predicates
>> >> and the call expanders to prevent this sort of replacement in the
>> >> backends. Tightening the predicates in the call patterns will achieve
>> >> the same for you and then we can investigate the use of GOT_PREL. My
>> >> recollection of this is that you need to work out when it's more
>> >> beneficial to use GOT_PREL over GOT but it's been a while since I
>> >> looked in that area.
>> > Also agreed.  This is primarily a backend issue with the call patterns.
>> >
>> > This is similar to the situation on the PA with the 32bit SOM runtime 
>> > where direct and indirect calls have different calling conventions. 
>> > Those different calling conventions combined with the early loading of 
>> > the parameter registers in effect restricts us from being able to 
>> > transform an indirect call into a direct call (combine) or vice-versa (cse).
>> >
>> > The way we handled this was to split the calls into two patterns, one 
>> > for direct one for indirect and tightening their predicates appropriately.
>> >
>> > Jeff
>> 
>> Attachment is the patch which repair -fno-plt support for AArch64.
>> 
>> aarch64_is_noplt_call_p will only be true if:
>> 
>>   * gcc is generating position independent code.
>>   * function symbol has declaration.
>>   * either -fno-plt or "(no_plt)" attribute specified.
>>   * it's a external function.
>>   
>> OK for trunk?
>
> OK.
>
> Thanks,
> James
>
>> 
>> 2015-07-16  Jiong Wang  <jiong.wang@arm.com>
>> 
>> gcc/
>>   * config/aarch64/aarch64-protos.h (aarch64_is_noplt_call_p): New
>>   declaration.
>>   * config/aarch64/aarch64.c (aarch64_is_noplt_call_p): New function.
>>   * config/aarch64/aarch64.md (call_value_symbol): Check noplt
>>   scenarios.
>>   (call_symbol): Ditto.
>> 
>> gcc/testsuite/
>>   * gcc.target/aarch64/noplt_1.c: New testcase.
>>   * gcc.target/aarch64/noplt_2.c: Ditto.
>> 
>
> ((Though do check the ChangeLog formatting when you commit :-).))

Thanks for review.

I realized I need to apply the same trick as I have done at

  https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01653.html,

then the included testcase can work well on any of tiny, small, large
model.

Committed the following patch:

commit 2bcb7473b37f9aa76e530f0a2007893489f61586
Author: jiwang <jiwang@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Aug 6 15:57:36 2015 +0000

    [AArch64] Tighten direct call pattern to repair -fno-plt
    
    2015-08-06  Jiong Wang  <jiong.wang@arm.com>
    
    gcc/
      * config/aarch64/aarch64-protos.h (aarch64_is_noplt_call_p): New declaration.
      * config/aarch64/aarch64.c (aarch64_is_noplt_call_p): New function.
      * config/aarch64/aarch64.md (call_value_symbol): Check noplt scenarios.
      (call_symbol): Likewise.
    
    gcc/testsuite/
      * gcc.target/aarch64/noplt_1.c: New testcase.
      * gcc.target/aarch64/noplt_2.c: Likewise.
    
    
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@226681 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 43df172..2b364ce 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-08-06  Jiong Wang  <jiong.wang@arm.com>
+
+	* config/aarch64/aarch64-protos.h (aarch64_is_noplt_call_p): New declaration.
+	* config/aarch64/aarch64.c (aarch64_is_noplt_call_p): New function.
+	* config/aarch64/aarch64.md (call_value_symbol): Check noplt scenarios.
+	(call_symbol): Likewise.
+
 2015-08-06  Venkataramanan Kumar  <Venkataramanan.kumar@amd.com>
 
 	* tree-vect-patterns.c (vect_recog_mult_pattern): New function
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 5d8902f..32b5d09 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -258,6 +258,7 @@ bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
 			     const struct cl_decoded_option *, location_t);
 bool aarch64_is_extend_from_extract (machine_mode, rtx, rtx);
 bool aarch64_is_long_call_p (rtx);
+bool aarch64_is_noplt_call_p (rtx);
 bool aarch64_label_mentioned_p (rtx);
 void aarch64_declare_function_name (FILE *, const char*, tree);
 bool aarch64_legitimate_pic_operand_p (rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 1394ed7..e991a49 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -744,6 +744,24 @@ aarch64_is_long_call_p (rtx sym)
   return aarch64_decl_is_long_call_p (SYMBOL_REF_DECL (sym));
 }
 
+/* Return true if calls to symbol-ref SYM should not go through
+   plt stubs.  */
+
+bool
+aarch64_is_noplt_call_p (rtx sym)
+{
+  const_tree decl = SYMBOL_REF_DECL (sym);
+
+  if (flag_pic
+      && decl
+      && (!flag_plt
+	  || lookup_attribute ("noplt", DECL_ATTRIBUTES (decl)))
+      && !targetm.binds_local_p (decl))
+    return true;
+
+  return false;
+}
+
 /* Return true if the offsets to a zero/sign-extract operation
    represent an expression that matches an extend operation.  The
    operands represent the paramters from
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index b7b04c4..7f99753 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -603,7 +603,8 @@
    (use (match_operand 2 "" ""))
    (clobber (reg:DI LR_REGNUM))]
   "GET_CODE (operands[0]) == SYMBOL_REF
-   && !aarch64_is_long_call_p (operands[0])"
+   && !aarch64_is_long_call_p (operands[0])
+   && !aarch64_is_noplt_call_p (operands[0])"
   "bl\\t%a0"
   [(set_attr "type" "call")]
 )
@@ -665,7 +666,8 @@
    (use (match_operand 3 "" ""))
    (clobber (reg:DI LR_REGNUM))]
   "GET_CODE (operands[1]) == SYMBOL_REF
-   && !aarch64_is_long_call_p (operands[1])"
+   && !aarch64_is_long_call_p (operands[1])
+   && !aarch64_is_noplt_call_p (operands[1])"
   "bl\\t%a1"
   [(set_attr "type" "call")]
 )
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 76afd8e..fb3bf07 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-08-06  Jiong Wang  <jiong.wang@arm.com>
+
+	* gcc.target/aarch64/noplt_1.c: New testcase.
+	* gcc.target/aarch64/noplt_2.c: Likewise.
+
 2015-08-06  Venkataramanan Kumar  <Venkataramanan.kumar@amd.com>
 
 	* gcc.dg/vect/vect-mult-pattern-1.c: New test.
diff --git a/gcc/testsuite/gcc.target/aarch64/noplt_1.c b/gcc/testsuite/gcc.target/aarch64/noplt_1.c
new file mode 100644
index 0000000..4e9bb62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/noplt_1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fpic -fno-plt" } */
+/* { dg-skip-if "-mcmodel=large, no support for -fpic" { aarch64-*-* }  { "-mcmodel=large" } { "" } } */
+
+int* bar (void) ;
+
+int
+foo (int a)
+{
+  int *b = bar ();
+  return b[a];
+}
+
+/* { dg-final { scan-assembler "#:got:" { target { aarch64_tiny || aarch64_small } } } } */
+/* { dg-final { scan-assembler "#:got_lo12:" { target aarch64_small } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/noplt_2.c b/gcc/testsuite/gcc.target/aarch64/noplt_2.c
new file mode 100644
index 0000000..718999b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/noplt_2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-skip-if "-mcmodel=large, no support for -fpic" { aarch64-*-* }  { "-mcmodel=large" } { "" } } */
+
+__attribute__ ((noplt))
+int* bar0 (void) ;
+int* bar1 (void) ;
+
+int
+foo (int a)
+{
+  int *b0 = bar0 ();
+  int *b1 = bar1 ();
+  return b0[a] + b1[a];
+}
+
+/* { dg-final { scan-assembler-times "#:got:" 1 { target { aarch64_tiny || aarch64_small } } } } */
+/* { dg-final { scan-assembler-times "#:got_lo12:" 1 { target aarch64_small } } } */

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