[PATCH, ARM] Enable tail call optimization for long call
This patch enables tail call optimization for long call on arm. Previously we have too strict check on arm_function_ok_for_sibcall and be lack of the support on sibcall/sibcall_value expand that long call tail oppportunities are lost. OK for next next stage 1? thanks. -- Jiong gcc/ * config/arm/predicates.md (call_insn_operand): Add long_call check. * config/arm/arm.md (sibcall, sibcall_value): Force the address to reg for long_call. * config/aarch64/aarch64.c (arm_function_ok_for_sibcall): Remove long_call restriction. gcc/testsuite gcc.target/arm/tail-long-call.c: New test. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index d5f9ff3..8dcdfa8 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6087,11 +6087,6 @@ arm_function_ok_for_sibcall (tree decl, tree exp) if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl)) return false; - /* Cannot tail-call to long calls, since these are out of range of - a branch instruction. */ - if (decl && arm_is_long_call_p (decl)) -return false; - /* If we are interworking and the function is not declared static then we can't tail-call it unless we know that it exists in this compilation unit (since it might be a Thumb routine). */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 2ddda02..fe285f0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -9444,8 +9444,10 @@ "TARGET_32BIT" " { -if (!REG_P (XEXP (operands[0], 0)) - && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)) +if ((!REG_P (XEXP (operands[0], 0)) + && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) + || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF + && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0) XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); if (operands[2] == NULL_RTX) @@ -9462,8 +9464,10 @@ "TARGET_32BIT" " { -if (!REG_P (XEXP (operands[1], 0)) && - (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF)) +if ((!REG_P (XEXP (operands[1], 0)) + && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) + || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF + && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0) XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); if (operands[3] == NULL_RTX) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index ce5c9a8..3673343 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -673,5 +673,6 @@ (match_code "reg" "0"))) (define_predicate "call_insn_operand" - (ior (match_code "symbol_ref") + (ior (and (match_code "symbol_ref") + (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))")) (match_operand 0 "s_register_operand"))) diff --git a/gcc/testsuite/gcc.target/arm/tail-long-call.c b/gcc/testsuite/gcc.target/arm/tail-long-call.c new file mode 100644 index 000..9b27468 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/tail-long-call.c @@ -0,0 +1,12 @@ +/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" "-mthumb" } { "" } } */ +/* { dg-options "-O2 -march=armv5te -marm" } */ +/* { dg-final { scan-assembler "bx" } } */ +/* { dg-final { scan-assembler-not "blx" } } */ + +int lcal (int) __attribute__ ((long_call)); + +int +dec (int a) +{ + return lcal (a); +}
Re: [PATCH, ARM] Enable tail call optimization for long call
On 25/03/14 15:44, Richard Earnshaw wrote: On 24/03/14 11:26, Jiong Wang wrote: This patch enables tail call optimization for long call on arm. Previously we have too strict check on arm_function_ok_for_sibcall and be lack of the support on sibcall/sibcall_value expand that long call tail oppportunities are lost. OK for next next stage 1? I think this is OK for EABI targets (since we can rely on the linker generating the right form of interworking veneer), but I'm less certain about other systems (do we still support COFF). I think I'd prefer the patch to factor in TARGET_AAPCS_BASED and to assume that if that is true then arbitrary tail-calls are safe. Hi Richard, IMHO, this is actually a tail call optimization, we just need to make sure the register which hold the address be caller saved then it will be OK. Updated the change log to fix that "aarch64" typo. No modification on the patch, but enclose it in this reply to keep wholeness. So, is it ok for next stage-1? Thanks. -- Jiong gcc/ * config/arm/predicates.md (call_insn_operand): Add long_call check. * config/arm/arm.md (sibcall, sibcall_value): Force the address to reg for long_call. * config/arm/arm.c (arm_function_ok_for_sibcall): Remove long_call restriction. gcc/testsuite gcc.target/arm/tail-long-call.c: New test. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index d5f9ff3..8dcdfa8 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6087,11 +6087,6 @@ arm_function_ok_for_sibcall (tree decl, tree exp) if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl)) return false; - /* Cannot tail-call to long calls, since these are out of range of - a branch instruction. */ - if (decl && arm_is_long_call_p (decl)) -return false; - /* If we are interworking and the function is not declared static then we can't tail-call it unless we know that it exists in this compilation unit (since it might be a Thumb routine). */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 2ddda02..fe285f0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -9444,8 +9444,10 @@ "TARGET_32BIT" " { -if (!REG_P (XEXP (operands[0], 0)) - && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)) +if ((!REG_P (XEXP (operands[0], 0)) + && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) + || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF + && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0) XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); if (operands[2] == NULL_RTX) @@ -9462,8 +9464,10 @@ "TARGET_32BIT" " { -if (!REG_P (XEXP (operands[1], 0)) && - (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF)) +if ((!REG_P (XEXP (operands[1], 0)) + && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) + || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF + && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0) XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); if (operands[3] == NULL_RTX) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index ce5c9a8..3673343 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -673,5 +673,6 @@ (match_code "reg" "0"))) (define_predicate "call_insn_operand" - (ior (match_code "symbol_ref") + (ior (and (match_code "symbol_ref") + (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))")) (match_operand 0 "s_register_operand"))) diff --git a/gcc/testsuite/gcc.target/arm/tail-long-call.c b/gcc/testsuite/gcc.target/arm/tail-long-call.c new file mode 100644 index 000..9b27468 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/tail-long-call.c @@ -0,0 +1,12 @@ +/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" "-mthumb" } { "" } } */ +/* { dg-options "-O2 -march=armv5te -marm" } */ +/* { dg-final { scan-assembler "bx" } } */ +/* { dg-final { scan-assembler-not "blx" } } */ + +int lcal (int) __attribute__ ((long_call)); + +int +dec (int a) +{ + return lcal (a); +}
Re: [PATCH, ARM] Enable tail call optimization for long call
On Wed, Apr 2, 2014 at 12:04 PM, Jiong Wang wrote: > > On 25/03/14 15:44, Richard Earnshaw wrote: >> >> On 24/03/14 11:26, Jiong Wang wrote: >>> >>> This patch enables tail call optimization for long call on arm. >>> >>> Previously we have too strict check on arm_function_ok_for_sibcall and >>> be lack of the support on sibcall/sibcall_value expand that long call >>> tail oppportunities are lost. >>> >>> OK for next next stage 1? >>> >> I think this is OK for EABI targets (since we can rely on the linker >> generating the right form of interworking veneer), but I'm less certain >> about other systems (do we still support COFF). >> >> I think I'd prefer the patch to factor in TARGET_AAPCS_BASED and to >> assume that if that is true then arbitrary tail-calls are safe. > > > Hi Richard, > > IMHO, this is actually a tail call optimization, we just need to make sure > the register which hold the address be caller saved then it will be OK. > > Updated the change log to fix that "aarch64" typo. No modification on the > patch, but enclose it in this reply to keep wholeness. > > So, is it ok for next stage-1? > This is OK for stage1. Ramana > > Thanks. > > -- > Jiong > > > gcc/ >* config/arm/predicates.md (call_insn_operand): Add long_call check. >* config/arm/arm.md (sibcall, sibcall_value): Force the address to reg > for long_call. >* config/arm/arm.c (arm_function_ok_for_sibcall): Remove long_call > restriction. > > gcc/testsuite >gcc.target/arm/tail-long-call.c: New test.
Re: [PATCH, ARM] Enable tail call optimization for long call
> > > gcc/ > * config/arm/predicates.md (call_insn_operand): Add long_call check. > * config/arm/arm.md (sibcall, sibcall_value): Force the address to reg for > long_call. > * config/aarch64/aarch64.c (arm_function_ok_for_sibcall): Remove long_call > restriction. config/arm/arm.c :) The ARM parts are ok for stage1 if no regressions. regards Ramana > > gcc/testsuite > gcc.target/arm/tail-long-call.c: New test.
Re: [PATCH, ARM] Enable tail call optimization for long call
On 24/03/14 11:26, Jiong Wang wrote: > This patch enables tail call optimization for long call on arm. > > Previously we have too strict check on arm_function_ok_for_sibcall and > be lack of the support on sibcall/sibcall_value expand that long call tail > oppportunities are lost. > > OK for next next stage 1? > I think this is OK for EABI targets (since we can rely on the linker generating the right form of interworking veneer), but I'm less certain about other systems (do we still support COFF). I think I'd prefer the patch to factor in TARGET_AAPCS_BASED and to assume that if that is true then arbitrary tail-calls are safe. R. > thanks. > > > tail-long-call.patch > > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index d5f9ff3..8dcdfa8 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -6087,11 +6087,6 @@ arm_function_ok_for_sibcall (tree decl, tree exp) >if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl)) > return false; > > - /* Cannot tail-call to long calls, since these are out of range of > - a branch instruction. */ > - if (decl && arm_is_long_call_p (decl)) > -return false; > - >/* If we are interworking and the function is not declared static > then we can't tail-call it unless we know that it exists in this > compilation unit (since it might be a Thumb routine). */ > diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md > index 2ddda02..fe285f0 100644 > --- a/gcc/config/arm/arm.md > +++ b/gcc/config/arm/arm.md > @@ -9444,8 +9444,10 @@ >"TARGET_32BIT" >" >{ > -if (!REG_P (XEXP (operands[0], 0)) > - && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)) > +if ((!REG_P (XEXP (operands[0], 0)) > + && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) > + || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF > + && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0) > XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); > > if (operands[2] == NULL_RTX) > @@ -9462,8 +9464,10 @@ >"TARGET_32BIT" >" >{ > -if (!REG_P (XEXP (operands[1], 0)) && > - (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF)) > +if ((!REG_P (XEXP (operands[1], 0)) > + && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) > + || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF > + && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0) > XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); > > if (operands[3] == NULL_RTX) > diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md > index ce5c9a8..3673343 100644 > --- a/gcc/config/arm/predicates.md > +++ b/gcc/config/arm/predicates.md > @@ -673,5 +673,6 @@ > (match_code "reg" "0"))) > > (define_predicate "call_insn_operand" > - (ior (match_code "symbol_ref") > + (ior (and (match_code "symbol_ref") > + (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))")) > (match_operand 0 "s_register_operand"))) > diff --git a/gcc/testsuite/gcc.target/arm/tail-long-call.c > b/gcc/testsuite/gcc.target/arm/tail-long-call.c > new file mode 100644 > index 000..9b27468 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/tail-long-call.c > @@ -0,0 +1,12 @@ > +/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" > "-mthumb" } { "" } } */ > +/* { dg-options "-O2 -march=armv5te -marm" } */ > +/* { dg-final { scan-assembler "bx" } } */ > +/* { dg-final { scan-assembler-not "blx" } } */ > + > +int lcal (int) __attribute__ ((long_call)); > + > +int > +dec (int a) > +{ > + return lcal (a); > +} >
Re: [PATCH, ARM] Enable tail call optimization for long call
On 24 March 2014 11:26, Jiong Wang wrote: > gcc/ > * config/arm/predicates.md (call_insn_operand): Add long_call check. > * config/arm/arm.md (sibcall, sibcall_value): Force the address to reg for > long_call. > * config/aarch64/aarch64.c (arm_function_ok_for_sibcall): Remove long_call > restriction. aarch64 -> arm /Marcus