arm-protos.h: Add and update function protos.
gcc/ChangeLog: 2013-05-30 Bernd Schmidt <bernds@codesourcery.com> Zhenqiang Chen <zhenqiang.chen@linaro.org> * config/arm/arm-protos.h: Add and update function protos. * config/arm/arm.c (use_simple_return_p): New added. (thumb2_expand_return): Check simple_return flag. * config/arm/arm.md: Add simple_return and conditional simple_return. * config/arm/iterators.md: Add iterator for return and simple_return. gcc/testsuite/ChangeLog: 2013-05-30 Zhenqiang Chen <zhenqiang.chen@linaro.org> * gcc.dg/shrink-wrap-alloca.c: New added. * gcc.dg/shrink-wrap-pretend.c: New added. * gcc.dg/shrink-wrap-sibcall.c: New added. From-SVN: r199439
This commit is contained in:
parent
c1cccc15b7
commit
24d5b0970a
9 changed files with 136 additions and 15 deletions
|
@ -1,3 +1,12 @@
|
|||
2013-05-30 Bernd Schmidt <bernds@codesourcery.com>
|
||||
Zhenqiang Chen <zhenqiang.chen@linaro.org>
|
||||
|
||||
* config/arm/arm-protos.h: Add and update function protos.
|
||||
* config/arm/arm.c (use_simple_return_p): New added.
|
||||
(thumb2_expand_return): Check simple_return flag.
|
||||
* config/arm/arm.md: Add simple_return and conditional simple_return.
|
||||
* config/arm/iterators.md: Add iterator for return and simple_return.
|
||||
|
||||
2013-05-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
|
||||
|
||||
* config/arm/arm.c (arm_add_cfa_adjust_cfa_note): New added.
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
|
||||
extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *);
|
||||
extern int use_return_insn (int, rtx);
|
||||
extern bool use_simple_return_p (void);
|
||||
extern enum reg_class arm_regno_class (int);
|
||||
extern void arm_load_pic_register (unsigned long);
|
||||
extern int arm_volatile_func (void);
|
||||
extern void arm_expand_prologue (void);
|
||||
extern void arm_expand_epilogue (bool);
|
||||
extern void thumb2_expand_return (void);
|
||||
extern void thumb2_expand_return (bool);
|
||||
extern const char *arm_strip_name_encoding (const char *);
|
||||
extern void arm_asm_output_labelref (FILE *, const char *);
|
||||
extern void thumb2_asm_output_opcode (FILE *);
|
||||
|
|
|
@ -2169,6 +2169,14 @@ arm_option_override (void)
|
|||
global_options.x_param_values,
|
||||
global_options_set.x_param_values);
|
||||
|
||||
/* Disable shrink-wrap when optimizing function for size, since it tends to
|
||||
generate additional returns. */
|
||||
if (optimize_function_for_size_p (cfun) && TARGET_THUMB2)
|
||||
flag_shrink_wrap = false;
|
||||
/* TBD: Dwarf info for apcs frame is not handled yet. */
|
||||
if (TARGET_APCS_FRAME)
|
||||
flag_shrink_wrap = false;
|
||||
|
||||
/* Register global variables with the garbage collector. */
|
||||
arm_add_gc_roots ();
|
||||
}
|
||||
|
@ -2518,6 +2526,18 @@ use_return_insn (int iscond, rtx sibling)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Return TRUE if we should try to use a simple_return insn, i.e. perform
|
||||
shrink-wrapping if possible. This is the case if we need to emit a
|
||||
prologue, which we can test by looking at the offsets. */
|
||||
bool
|
||||
use_simple_return_p (void)
|
||||
{
|
||||
arm_stack_offsets *offsets;
|
||||
|
||||
offsets = arm_get_frame_offsets ();
|
||||
return offsets->outgoing_args != 0;
|
||||
}
|
||||
|
||||
/* Return TRUE if int I is a valid immediate ARM constant. */
|
||||
|
||||
int
|
||||
|
@ -24035,7 +24055,7 @@ thumb1_expand_prologue (void)
|
|||
all we really need to check here is if single register is to be
|
||||
returned, or multiple register return. */
|
||||
void
|
||||
thumb2_expand_return (void)
|
||||
thumb2_expand_return (bool simple_return)
|
||||
{
|
||||
int i, num_regs;
|
||||
unsigned long saved_regs_mask;
|
||||
|
@ -24048,7 +24068,7 @@ thumb2_expand_return (void)
|
|||
if (saved_regs_mask & (1 << i))
|
||||
num_regs++;
|
||||
|
||||
if (saved_regs_mask)
|
||||
if (!simple_return && saved_regs_mask)
|
||||
{
|
||||
if (num_regs == 1)
|
||||
{
|
||||
|
|
|
@ -9276,17 +9276,17 @@
|
|||
[(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_expand "return"
|
||||
[(return)]
|
||||
(define_expand "<return_str>return"
|
||||
[(returns)]
|
||||
"(TARGET_ARM || (TARGET_THUMB2
|
||||
&& ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
|
||||
&& !IS_STACKALIGN (arm_current_func_type ())))
|
||||
&& USE_RETURN_INSN (FALSE)"
|
||||
<return_cond_false>"
|
||||
"
|
||||
{
|
||||
if (TARGET_THUMB2)
|
||||
{
|
||||
thumb2_expand_return ();
|
||||
thumb2_expand_return (<return_simple_p>);
|
||||
DONE;
|
||||
}
|
||||
}
|
||||
|
@ -9311,13 +9311,13 @@
|
|||
(set_attr "predicable" "yes")]
|
||||
)
|
||||
|
||||
(define_insn "*cond_return"
|
||||
(define_insn "*cond_<return_str>return"
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "arm_comparison_operator"
|
||||
[(match_operand 1 "cc_register" "") (const_int 0)])
|
||||
(return)
|
||||
(returns)
|
||||
(pc)))]
|
||||
"TARGET_ARM && USE_RETURN_INSN (TRUE)"
|
||||
"TARGET_ARM <return_cond_true>"
|
||||
"*
|
||||
{
|
||||
if (arm_ccfsm_state == 2)
|
||||
|
@ -9325,20 +9325,21 @@
|
|||
arm_ccfsm_state += 2;
|
||||
return \"\";
|
||||
}
|
||||
return output_return_instruction (operands[0], true, false, false);
|
||||
return output_return_instruction (operands[0], true, false,
|
||||
<return_simple_p>);
|
||||
}"
|
||||
[(set_attr "conds" "use")
|
||||
(set_attr "length" "12")
|
||||
(set_attr "type" "load1")]
|
||||
)
|
||||
|
||||
(define_insn "*cond_return_inverted"
|
||||
(define_insn "*cond_<return_str>return_inverted"
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "arm_comparison_operator"
|
||||
[(match_operand 1 "cc_register" "") (const_int 0)])
|
||||
(pc)
|
||||
(return)))]
|
||||
"TARGET_ARM && USE_RETURN_INSN (TRUE)"
|
||||
(returns)))]
|
||||
"TARGET_ARM <return_cond_true>"
|
||||
"*
|
||||
{
|
||||
if (arm_ccfsm_state == 2)
|
||||
|
@ -9346,7 +9347,8 @@
|
|||
arm_ccfsm_state += 2;
|
||||
return \"\";
|
||||
}
|
||||
return output_return_instruction (operands[0], true, true, false);
|
||||
return output_return_instruction (operands[0], true, true,
|
||||
<return_simple_p>);
|
||||
}"
|
||||
[(set_attr "conds" "use")
|
||||
(set_attr "length" "12")
|
||||
|
|
|
@ -496,3 +496,11 @@
|
|||
(define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p")
|
||||
(UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m")
|
||||
(UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")])
|
||||
;; Both kinds of return insn.
|
||||
(define_code_iterator returns [return simple_return])
|
||||
(define_code_attr return_str [(return "") (simple_return "simple_")])
|
||||
(define_code_attr return_simple_p [(return "false") (simple_return "true")])
|
||||
(define_code_attr return_cond_false [(return " && USE_RETURN_INSN (FALSE)")
|
||||
(simple_return " && use_simple_return_p ()")])
|
||||
(define_code_attr return_cond_true [(return " && USE_RETURN_INSN (TRUE)")
|
||||
(simple_return " && use_simple_return_p ()")])
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2013-05-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
|
||||
|
||||
* gcc.dg/shrink-wrap-alloca.c: New added.
|
||||
* gcc.dg/shrink-wrap-pretend.c: New added.
|
||||
* gcc.dg/shrink-wrap-sibcall.c: New added.
|
||||
|
||||
2013-05-30 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR fortran/57458
|
||||
|
|
13
gcc/testsuite/gcc.dg/shrink-wrap-alloca.c
Normal file
13
gcc/testsuite/gcc.dg/shrink-wrap-alloca.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -g" } */
|
||||
|
||||
extern int * alloca (int);
|
||||
|
||||
int *p;
|
||||
|
||||
void
|
||||
test (int a)
|
||||
{
|
||||
if (a > 0)
|
||||
p = alloca (4);
|
||||
}
|
36
gcc/testsuite/gcc.dg/shrink-wrap-pretend.c
Normal file
36
gcc/testsuite/gcc.dg/shrink-wrap-pretend.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -g" } */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define DEBUG_BUFFER_SIZE 80
|
||||
int unifi_debug = 5;
|
||||
|
||||
void
|
||||
unifi_trace (void* ospriv, int level, const char *fmt, ...)
|
||||
{
|
||||
static char s[DEBUG_BUFFER_SIZE];
|
||||
va_list args;
|
||||
unsigned int len;
|
||||
|
||||
if (!ospriv)
|
||||
return;
|
||||
|
||||
if (unifi_debug >= level)
|
||||
{
|
||||
va_start (args, fmt);
|
||||
len = vsnprintf (&(s)[0], (DEBUG_BUFFER_SIZE), fmt, args);
|
||||
va_end (args);
|
||||
|
||||
if (len >= DEBUG_BUFFER_SIZE)
|
||||
{
|
||||
(s)[DEBUG_BUFFER_SIZE - 2] = '\n';
|
||||
(s)[DEBUG_BUFFER_SIZE - 1] = 0;
|
||||
}
|
||||
|
||||
printf ("%s", s);
|
||||
}
|
||||
}
|
||||
|
26
gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c
Normal file
26
gcc/testsuite/gcc.dg/shrink-wrap-sibcall.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -g" } */
|
||||
|
||||
unsigned char a, b, d, f, g;
|
||||
|
||||
int test (void);
|
||||
|
||||
int
|
||||
baz (int c)
|
||||
{
|
||||
if (c == 0) return test ();
|
||||
if (b & 1)
|
||||
{
|
||||
g = 0;
|
||||
int e = (a & 0x0f) - (g & 0x0f);
|
||||
|
||||
if (!a) b |= 0x80;
|
||||
a = e + test ();
|
||||
f = g/5 + a*3879 + b *2985;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = g + a*39879 + b *25;
|
||||
}
|
||||
return test ();
|
||||
}
|
Loading…
Add table
Reference in a new issue