Commit 24d5b097 by Xuepeng Guo

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
parent c1cccc15
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> 2013-05-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
* config/arm/arm.c (arm_add_cfa_adjust_cfa_note): New added. * config/arm/arm.c (arm_add_cfa_adjust_cfa_note): New added.
......
...@@ -24,12 +24,13 @@ ...@@ -24,12 +24,13 @@
extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *); extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *);
extern int use_return_insn (int, rtx); extern int use_return_insn (int, rtx);
extern bool use_simple_return_p (void);
extern enum reg_class arm_regno_class (int); extern enum reg_class arm_regno_class (int);
extern void arm_load_pic_register (unsigned long); extern void arm_load_pic_register (unsigned long);
extern int arm_volatile_func (void); extern int arm_volatile_func (void);
extern void arm_expand_prologue (void); extern void arm_expand_prologue (void);
extern void arm_expand_epilogue (bool); 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 const char *arm_strip_name_encoding (const char *);
extern void arm_asm_output_labelref (FILE *, const char *); extern void arm_asm_output_labelref (FILE *, const char *);
extern void thumb2_asm_output_opcode (FILE *); extern void thumb2_asm_output_opcode (FILE *);
......
...@@ -2169,6 +2169,14 @@ arm_option_override (void) ...@@ -2169,6 +2169,14 @@ arm_option_override (void)
global_options.x_param_values, global_options.x_param_values,
global_options_set.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. */ /* Register global variables with the garbage collector. */
arm_add_gc_roots (); arm_add_gc_roots ();
} }
...@@ -2518,6 +2526,18 @@ use_return_insn (int iscond, rtx sibling) ...@@ -2518,6 +2526,18 @@ use_return_insn (int iscond, rtx sibling)
return 1; 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. */ /* Return TRUE if int I is a valid immediate ARM constant. */
int int
...@@ -24035,7 +24055,7 @@ thumb1_expand_prologue (void) ...@@ -24035,7 +24055,7 @@ thumb1_expand_prologue (void)
all we really need to check here is if single register is to be all we really need to check here is if single register is to be
returned, or multiple register return. */ returned, or multiple register return. */
void void
thumb2_expand_return (void) thumb2_expand_return (bool simple_return)
{ {
int i, num_regs; int i, num_regs;
unsigned long saved_regs_mask; unsigned long saved_regs_mask;
...@@ -24048,7 +24068,7 @@ thumb2_expand_return (void) ...@@ -24048,7 +24068,7 @@ thumb2_expand_return (void)
if (saved_regs_mask & (1 << i)) if (saved_regs_mask & (1 << i))
num_regs++; num_regs++;
if (saved_regs_mask) if (!simple_return && saved_regs_mask)
{ {
if (num_regs == 1) if (num_regs == 1)
{ {
......
...@@ -9276,17 +9276,17 @@ ...@@ -9276,17 +9276,17 @@
[(set_attr "type" "call")] [(set_attr "type" "call")]
) )
(define_expand "return" (define_expand "<return_str>return"
[(return)] [(returns)]
"(TARGET_ARM || (TARGET_THUMB2 "(TARGET_ARM || (TARGET_THUMB2
&& ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
&& !IS_STACKALIGN (arm_current_func_type ()))) && !IS_STACKALIGN (arm_current_func_type ())))
&& USE_RETURN_INSN (FALSE)" <return_cond_false>"
" "
{ {
if (TARGET_THUMB2) if (TARGET_THUMB2)
{ {
thumb2_expand_return (); thumb2_expand_return (<return_simple_p>);
DONE; DONE;
} }
} }
...@@ -9311,13 +9311,13 @@ ...@@ -9311,13 +9311,13 @@
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
(define_insn "*cond_return" (define_insn "*cond_<return_str>return"
[(set (pc) [(set (pc)
(if_then_else (match_operator 0 "arm_comparison_operator" (if_then_else (match_operator 0 "arm_comparison_operator"
[(match_operand 1 "cc_register" "") (const_int 0)]) [(match_operand 1 "cc_register" "") (const_int 0)])
(return) (returns)
(pc)))] (pc)))]
"TARGET_ARM && USE_RETURN_INSN (TRUE)" "TARGET_ARM <return_cond_true>"
"* "*
{ {
if (arm_ccfsm_state == 2) if (arm_ccfsm_state == 2)
...@@ -9325,20 +9325,21 @@ ...@@ -9325,20 +9325,21 @@
arm_ccfsm_state += 2; arm_ccfsm_state += 2;
return \"\"; 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 "conds" "use")
(set_attr "length" "12") (set_attr "length" "12")
(set_attr "type" "load1")] (set_attr "type" "load1")]
) )
(define_insn "*cond_return_inverted" (define_insn "*cond_<return_str>return_inverted"
[(set (pc) [(set (pc)
(if_then_else (match_operator 0 "arm_comparison_operator" (if_then_else (match_operator 0 "arm_comparison_operator"
[(match_operand 1 "cc_register" "") (const_int 0)]) [(match_operand 1 "cc_register" "") (const_int 0)])
(pc) (pc)
(return)))] (returns)))]
"TARGET_ARM && USE_RETURN_INSN (TRUE)" "TARGET_ARM <return_cond_true>"
"* "*
{ {
if (arm_ccfsm_state == 2) if (arm_ccfsm_state == 2)
...@@ -9346,7 +9347,8 @@ ...@@ -9346,7 +9347,8 @@
arm_ccfsm_state += 2; arm_ccfsm_state += 2;
return \"\"; 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 "conds" "use")
(set_attr "length" "12") (set_attr "length" "12")
......
...@@ -496,3 +496,11 @@ ...@@ -496,3 +496,11 @@
(define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p") (define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p")
(UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m") (UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m")
(UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")]) (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 ()")])
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> 2013-05-30 Tobias Burnus <burnus@net-b.de>
PR fortran/57458 PR fortran/57458
......
/* { dg-do compile } */
/* { dg-options "-O2 -g" } */
extern int * alloca (int);
int *p;
void
test (int a)
{
if (a > 0)
p = alloca (4);
}
/* { 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);
}
}
/* { 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 ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment