aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2014-02-07 14:52:26 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2014-02-07 14:52:26 +0000
commit177bc204a2f3a13c9fad9c8f88eb3449c8752552 (patch)
tree66c6a4c444bca952b3f996e781e0e593bbc8db05
parent0621cf3c78ee4e26cdb44bdfcb40677028280d5d (diff)
downloadgcc-177bc204a2f3a13c9fad9c8f88eb3449c8752552.zip
gcc-177bc204a2f3a13c9fad9c8f88eb3449c8752552.tar.gz
gcc-177bc204a2f3a13c9fad9c8f88eb3449c8752552.tar.bz2
gcc/
* config/s390/s390-protos.h (s390_can_use_simple_return_insn) (s390_can_use_return_insn): Declare. * config/s390/s390.h (EPILOGUE_USES): Define. * config/s390/s390.c (s390_mainpool_start): Allow two main_pool instructions. (s390_chunkify_start): Handle return JUMP_LABELs. (s390_early_mach): Emit a main_pool instruction on the entry edge. (s300_set_up_by_prologue, s390_can_use_simple_return_insn) (s390_can_use_return_insn): New functions. (s390_fix_long_loop_prediction): Handle conditional returns. (TARGET_SET_UP_BY_PROLOGUE): Define. * config/s390/s390.md (ANY_RETURN): New code iterator. (*creturn, *csimple_return, return, simple_return): New patterns. From-SVN: r207605
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/s390/s390-protos.h2
-rw-r--r--gcc/config/s390/s390.c74
-rw-r--r--gcc/config/s390/s390.h4
-rw-r--r--gcc/config/s390/s390.md24
5 files changed, 118 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0d0f887..5703bb5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,21 @@
2014-02-07 Richard Sandiford <rsandifo@linux.vnet.ibm.com>
+ * config/s390/s390-protos.h (s390_can_use_simple_return_insn)
+ (s390_can_use_return_insn): Declare.
+ * config/s390/s390.h (EPILOGUE_USES): Define.
+ * config/s390/s390.c (s390_mainpool_start): Allow two main_pool
+ instructions.
+ (s390_chunkify_start): Handle return JUMP_LABELs.
+ (s390_early_mach): Emit a main_pool instruction on the entry edge.
+ (s300_set_up_by_prologue, s390_can_use_simple_return_insn)
+ (s390_can_use_return_insn): New functions.
+ (s390_fix_long_loop_prediction): Handle conditional returns.
+ (TARGET_SET_UP_BY_PROLOGUE): Define.
+ * config/s390/s390.md (ANY_RETURN): New code iterator.
+ (*creturn, *csimple_return, return, simple_return): New patterns.
+
+2014-02-07 Richard Sandiford <rsandifo@linux.vnet.ibm.com>
+
* config/s390/s390.c (s390_restore_gprs_from_fprs): Add REG_CFA_RESTORE
notes to each restore. Also add REG_CFA_DEF_CFA when restoring %r15.
(s390_optimize_prologue): Don't clear RTX_FRAME_RELATED_P. Update the
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 72f8bb7..9bd08fa 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -36,6 +36,8 @@ extern bool s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment);
extern HOST_WIDE_INT s390_initial_elimination_offset (int, int);
extern void s390_emit_prologue (void);
extern void s390_emit_epilogue (bool);
+extern bool s390_can_use_simple_return_insn (void);
+extern bool s390_can_use_return_insn (void);
extern void s390_function_profiler (FILE *, int);
extern void s390_set_has_landing_pad_p (bool);
extern bool s390_hard_regno_mode_ok (unsigned int, enum machine_mode);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 2d6f8d0..993ed84 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6673,7 +6673,15 @@ s390_mainpool_start (void)
&& GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
&& XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
{
- gcc_assert (!pool->pool_insn);
+ /* There might be two main_pool instructions if base_reg
+ is call-clobbered; one for shrink-wrapped code and one
+ for the rest. We want to keep the first. */
+ if (pool->pool_insn)
+ {
+ insn = PREV_INSN (insn);
+ delete_insn (NEXT_INSN (insn));
+ continue;
+ }
pool->pool_insn = insn;
}
@@ -7110,7 +7118,7 @@ s390_chunkify_start (void)
if (GET_CODE (pat) == SET)
{
rtx label = JUMP_LABEL (insn);
- if (label)
+ if (label && !ANY_RETURN_P (label))
{
if (s390_find_pool (pool_list, label)
!= s390_find_pool (pool_list, insn))
@@ -8635,6 +8643,11 @@ s390_early_mach (void)
/* Re-compute register info. */
s390_register_info ();
+ /* If we're using a base register, ensure that it is always valid for
+ the first non-prologue instruction. */
+ if (cfun->machine->base_reg)
+ emit_insn_at_entry (gen_main_pool (cfun->machine->base_reg));
+
/* Annotate all constant pool references to let the scheduler know
they implicitly use the base register. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -9170,6 +9183,55 @@ s390_emit_epilogue (bool sibcall)
}
}
+/* Implement TARGET_SET_UP_BY_PROLOGUE. */
+
+static void
+s300_set_up_by_prologue (hard_reg_set_container *regs)
+{
+ if (cfun->machine->base_reg
+ && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
+ SET_HARD_REG_BIT (regs->set, REGNO (cfun->machine->base_reg));
+}
+
+/* Return true if the function can use simple_return to return outside
+ of a shrink-wrapped region. At present shrink-wrapping is supported
+ in all cases. */
+
+bool
+s390_can_use_simple_return_insn (void)
+{
+ return true;
+}
+
+/* Return true if the epilogue is guaranteed to contain only a return
+ instruction and if a direct return can therefore be used instead.
+ One of the main advantages of using direct return instructions
+ is that we can then use conditional returns. */
+
+bool
+s390_can_use_return_insn (void)
+{
+ int i;
+
+ if (!reload_completed)
+ return false;
+
+ if (crtl->profile)
+ return false;
+
+ if (TARGET_TPF_PROFILING)
+ return false;
+
+ for (i = 0; i < 16; i++)
+ if (cfun_gpr_save_slot (i))
+ return false;
+
+ if (cfun->machine->base_reg
+ && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
+ return false;
+
+ return cfun_frame_layout.frame_size == 0;
+}
/* Return the size in bytes of a function argument of
type TYPE and/or mode MODE. At least one of TYPE or
@@ -11019,6 +11081,11 @@ s390_fix_long_loop_prediction (rtx insn)
|| GET_CODE (SET_SRC(set)) != IF_THEN_ELSE)
return false;
+ /* Skip conditional returns. */
+ if (ANY_RETURN_P (XEXP (SET_SRC (set), 1))
+ && XEXP (SET_SRC (set), 2) == pc_rtx)
+ return false;
+
label_ref = (GET_CODE (XEXP (SET_SRC (set), 1)) == LABEL_REF ?
XEXP (SET_SRC (set), 1) : XEXP (SET_SRC (set), 2));
@@ -12163,6 +12230,9 @@ s390_option_override (void)
#undef TARGET_CAN_INLINE_P
#define TARGET_CAN_INLINE_P s390_can_inline_p
+#undef TARGET_SET_UP_BY_PROLOGUE
+#define TARGET_SET_UP_BY_PROLOGUE s300_set_up_by_prologue
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h"
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 9099fc8..2f2139e 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -878,6 +878,10 @@ do { \
fputc ('\n', (FILE)); \
} while (0)
+/* Mark the return register as used by the epilogue so that we can
+ use it in unadorned (return) and (simple_return) instructions. */
+#define EPILOGUE_USES(REGNO) ((REGNO) == RETURN_REGNUM)
+
#undef ASM_OUTPUT_FUNCTION_LABEL
#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \
s390_asm_output_function_label (FILE, NAME, DECL)
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 3f86304..76902b5 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -598,6 +598,9 @@
;; In place of GET_MODE_BITSIZE (<MODE>mode)
(define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
+;; Allow return and simple_return to be defined from a single template.
+(define_code_iterator ANY_RETURN [return simple_return])
+
;;
;;- Compare instructions.
;;
@@ -8079,6 +8082,18 @@
(set_attr "type" "branch")
(set_attr "atype" "agen")])
+;; A conditional return instruction.
+(define_insn "*c<code>"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
+ (ANY_RETURN)
+ (pc)))]
+ "s390_can_use_<code>_insn ()"
+ "b%C0r\t%%r14"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
;;
;;- Negated conditional jump instructions.
@@ -9674,6 +9689,15 @@
""
"s390_emit_epilogue (true); DONE;")
+;; A direct return instruction, without using an epilogue.
+(define_insn "<code>"
+ [(ANY_RETURN)]
+ "s390_can_use_<code>_insn ()"
+ "br\t%%r14"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
+
(define_insn "*return"
[(return)
(use (match_operand 0 "register_operand" "a"))]