mirror of git://gcc.gnu.org/git/gcc.git
[AARCH64] Support tail indirect function call.
From-SVN: r210861
This commit is contained in:
parent
09af4b4c42
commit
fee9ba422f
|
|
@ -1,3 +1,17 @@
|
||||||
|
2014-05-23 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
|
* config/aarch64/predicates.md (aarch64_call_insn_operand): New
|
||||||
|
predicate.
|
||||||
|
* config/aarch64/constraints.md ("Ucs", "Usf"): New constraints.
|
||||||
|
* config/aarch64/aarch64.md (*sibcall_insn, *sibcall_value_insn):
|
||||||
|
Adjust for tailcalling through registers.
|
||||||
|
* config/aarch64/aarch64.h (enum reg_class): New caller save
|
||||||
|
register class.
|
||||||
|
(REG_CLASS_NAMES): Likewise.
|
||||||
|
(REG_CLASS_CONTENTS): Likewise.
|
||||||
|
* config/aarch64/aarch64.c (aarch64_function_ok_for_sibcall):
|
||||||
|
Allow tailcalling without decls.
|
||||||
|
|
||||||
2014-05-23 Thomas Schwinge <thomas@codesourcery.com>
|
2014-05-23 Thomas Schwinge <thomas@codesourcery.com>
|
||||||
|
|
||||||
* gimplify.c (omp_notice_variable) <case OMP_CLAUSE_DEFAULT_NONE>:
|
* gimplify.c (omp_notice_variable) <case OMP_CLAUSE_DEFAULT_NONE>:
|
||||||
|
|
|
||||||
|
|
@ -1268,18 +1268,10 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
aarch64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
|
aarch64_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
|
||||||
|
tree exp ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
/* Indirect calls are not currently supported. */
|
/* Currently, always true. */
|
||||||
if (decl == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Cannot tail-call to long-calls, since these are outside of the
|
|
||||||
range of a branch instruction (we could handle this if we added
|
|
||||||
support for indirect tail-calls. */
|
|
||||||
if (aarch64_decl_is_long_call_p (decl))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4360,6 +4352,7 @@ aarch64_class_max_nregs (reg_class_t regclass, enum machine_mode mode)
|
||||||
{
|
{
|
||||||
switch (regclass)
|
switch (regclass)
|
||||||
{
|
{
|
||||||
|
case CALLER_SAVE_REGS:
|
||||||
case POINTER_REGS:
|
case POINTER_REGS:
|
||||||
case GENERAL_REGS:
|
case GENERAL_REGS:
|
||||||
case ALL_REGS:
|
case ALL_REGS:
|
||||||
|
|
|
||||||
|
|
@ -408,6 +408,7 @@ extern unsigned long aarch64_tune_flags;
|
||||||
enum reg_class
|
enum reg_class
|
||||||
{
|
{
|
||||||
NO_REGS,
|
NO_REGS,
|
||||||
|
CALLER_SAVE_REGS,
|
||||||
GENERAL_REGS,
|
GENERAL_REGS,
|
||||||
STACK_REG,
|
STACK_REG,
|
||||||
POINTER_REGS,
|
POINTER_REGS,
|
||||||
|
|
@ -422,6 +423,7 @@ enum reg_class
|
||||||
#define REG_CLASS_NAMES \
|
#define REG_CLASS_NAMES \
|
||||||
{ \
|
{ \
|
||||||
"NO_REGS", \
|
"NO_REGS", \
|
||||||
|
"CALLER_SAVE_REGS", \
|
||||||
"GENERAL_REGS", \
|
"GENERAL_REGS", \
|
||||||
"STACK_REG", \
|
"STACK_REG", \
|
||||||
"POINTER_REGS", \
|
"POINTER_REGS", \
|
||||||
|
|
@ -433,6 +435,7 @@ enum reg_class
|
||||||
#define REG_CLASS_CONTENTS \
|
#define REG_CLASS_CONTENTS \
|
||||||
{ \
|
{ \
|
||||||
{ 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
|
{ 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
|
||||||
|
{ 0x0007ffff, 0x00000000, 0x00000000 }, /* CALLER_SAVE_REGS */ \
|
||||||
{ 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \
|
{ 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \
|
||||||
{ 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \
|
{ 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \
|
||||||
{ 0xffffffff, 0x00000000, 0x00000003 }, /* POINTER_REGS */ \
|
{ 0xffffffff, 0x00000000, 0x00000003 }, /* POINTER_REGS */ \
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,10 @@
|
||||||
(use (match_operand 2 "" ""))])]
|
(use (match_operand 2 "" ""))])]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
|
if (!REG_P (XEXP (operands[0], 0))
|
||||||
|
&& (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
|
||||||
|
XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
|
||||||
|
|
||||||
if (operands[2] == NULL_RTX)
|
if (operands[2] == NULL_RTX)
|
||||||
operands[2] = const0_rtx;
|
operands[2] = const0_rtx;
|
||||||
}
|
}
|
||||||
|
|
@ -536,31 +540,38 @@
|
||||||
(use (match_operand 3 "" ""))])]
|
(use (match_operand 3 "" ""))])]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
|
if (!REG_P (XEXP (operands[1], 0))
|
||||||
|
&& (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
|
||||||
|
XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
|
||||||
|
|
||||||
if (operands[3] == NULL_RTX)
|
if (operands[3] == NULL_RTX)
|
||||||
operands[3] = const0_rtx;
|
operands[3] = const0_rtx;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
(define_insn "*sibcall_insn"
|
(define_insn "*sibcall_insn"
|
||||||
[(call (mem:DI (match_operand:DI 0 "" "X"))
|
[(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
|
||||||
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
||||||
(return)
|
(return)
|
||||||
(use (match_operand 2 "" ""))]
|
(use (match_operand 2 "" ""))]
|
||||||
"GET_CODE (operands[0]) == SYMBOL_REF"
|
"SIBLING_CALL_P (insn)"
|
||||||
"b\\t%a0"
|
"@
|
||||||
[(set_attr "type" "branch")]
|
br\\t%0
|
||||||
|
b\\t%a0"
|
||||||
|
[(set_attr "type" "branch, branch")]
|
||||||
)
|
)
|
||||||
|
|
||||||
(define_insn "*sibcall_value_insn"
|
(define_insn "*sibcall_value_insn"
|
||||||
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
||||||
(call (mem:DI (match_operand 1 "" "X"))
|
(call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
|
||||||
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
||||||
(return)
|
(return)
|
||||||
(use (match_operand 3 "" ""))]
|
(use (match_operand 3 "" ""))]
|
||||||
"GET_CODE (operands[1]) == SYMBOL_REF"
|
"SIBLING_CALL_P (insn)"
|
||||||
"b\\t%a1"
|
"@
|
||||||
[(set_attr "type" "branch")]
|
br\\t%1
|
||||||
|
b\\t%a1"
|
||||||
|
[(set_attr "type" "branch, branch")]
|
||||||
)
|
)
|
||||||
|
|
||||||
;; Call subroutine returning any type.
|
;; Call subroutine returning any type.
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@
|
||||||
(define_register_constraint "k" "STACK_REG"
|
(define_register_constraint "k" "STACK_REG"
|
||||||
"@internal The stack register.")
|
"@internal The stack register.")
|
||||||
|
|
||||||
|
(define_register_constraint "Ucs" "CALLER_SAVE_REGS"
|
||||||
|
"@internal The caller save registers.")
|
||||||
|
|
||||||
(define_register_constraint "w" "FP_REGS"
|
(define_register_constraint "w" "FP_REGS"
|
||||||
"Floating point and SIMD vector registers.")
|
"Floating point and SIMD vector registers.")
|
||||||
|
|
||||||
|
|
@ -92,6 +95,10 @@
|
||||||
(and (match_code "const_int")
|
(and (match_code "const_int")
|
||||||
(match_test "(unsigned HOST_WIDE_INT) ival < 64")))
|
(match_test "(unsigned HOST_WIDE_INT) ival < 64")))
|
||||||
|
|
||||||
|
(define_constraint "Usf"
|
||||||
|
"@internal Usf is a symbol reference."
|
||||||
|
(match_code "symbol_ref"))
|
||||||
|
|
||||||
(define_constraint "UsM"
|
(define_constraint "UsM"
|
||||||
"@internal
|
"@internal
|
||||||
A constraint that matches the immediate constant -1."
|
A constraint that matches the immediate constant -1."
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@
|
||||||
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))
|
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(define_predicate "aarch64_call_insn_operand"
|
||||||
|
(ior (match_code "symbol_ref")
|
||||||
|
(match_operand 0 "register_operand")))
|
||||||
|
|
||||||
(define_predicate "aarch64_simd_register"
|
(define_predicate "aarch64_simd_register"
|
||||||
(and (match_code "reg")
|
(and (match_code "reg")
|
||||||
(ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
|
(ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
2014-05-23 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
|
* gcc.target/aarch64/tail_indirect_call_1.c: New.
|
||||||
|
|
||||||
2014-05-23 Paolo Carlini <paolo.carlini@oracle.com>
|
2014-05-23 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
* g++.dg/cpp1y/lambda-init9.C: New.
|
* g++.dg/cpp1y/lambda-init9.C: New.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2" } */
|
||||||
|
|
||||||
|
typedef void FP (int);
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "br" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "blr" } } */
|
||||||
|
void
|
||||||
|
f1 (FP fp, int n)
|
||||||
|
{
|
||||||
|
(fp) (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f2 (int n, FP fp)
|
||||||
|
{
|
||||||
|
(fp) (n);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue