Commit af2c8a96 by Jeff Law Committed by Jeff Law

rs6000-protos.h (output_probe_stack_range): Update prototype for new argument.

	* config/rs6000/rs6000-protos.h (output_probe_stack_range): Update
	prototype for new argument.
	* config/rs6000/rs6000.c (rs6000_emit_allocate_stack_1): New function,
	mostly extracted from rs6000_emit_allocate_stack.
	(rs6000_emit_probe_stack_range_stack_clash): New function.
	(rs6000_emit_allocate_stack): Call
	rs6000_emit_probe_stack_range_stack_clash as needed.
	(rs6000_emit_probe_stack_range): Add additional argument
	to call to gen_probe_stack_range{si,di}.
	(output_probe_stack_range): New.
	(output_probe_stack_range_1): Renamed from output_probe_stack_range.
	(output_probe_stack_range_stack_clash): New.
	(rs6000_emit_prologue): Emit notes into dump file as requested.
	* rs6000.md (allocate_stack): Handle -fstack-clash-protection.
	(probe_stack_range<P:mode>): Operand 0 is now early-clobbered.
	Add additional operand and pass it to output_probe_stack_range.

	* lib/target-supports.exp
	(check_effective_target_supports_stack_clash_protection): Enable for
	rs6000 and powerpc targets.

From-SVN: r253179
parent d80d5c38
2017-09-25 Jeff Law <law@redhat.com>
* config/rs6000/rs6000-protos.h (output_probe_stack_range): Update
prototype for new argument.
* config/rs6000/rs6000.c (rs6000_emit_allocate_stack_1): New function,
mostly extracted from rs6000_emit_allocate_stack.
(rs6000_emit_probe_stack_range_stack_clash): New function.
(rs6000_emit_allocate_stack): Call
rs6000_emit_probe_stack_range_stack_clash as needed.
(rs6000_emit_probe_stack_range): Add additional argument
to call to gen_probe_stack_range{si,di}.
(output_probe_stack_range): New.
(output_probe_stack_range_1): Renamed from output_probe_stack_range.
(output_probe_stack_range_stack_clash): New.
(rs6000_emit_prologue): Emit notes into dump file as requested.
* rs6000.md (allocate_stack): Handle -fstack-clash-protection.
(probe_stack_range<P:mode>): Operand 0 is now early-clobbered.
Add additional operand and pass it to output_probe_stack_range.
2017-09-25 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/82163
......@@ -128,7 +128,7 @@ extern void rs6000_emit_sISEL (machine_mode, rtx[]);
extern void rs6000_emit_sCOND (machine_mode, rtx[]);
extern void rs6000_emit_cbranch (machine_mode, rtx[]);
extern char * output_cbranch (rtx, const char *, int, rtx_insn *);
extern const char * output_probe_stack_range (rtx, rtx);
extern const char * output_probe_stack_range (rtx, rtx, rtx);
extern void rs6000_emit_dot_insn (rtx dst, rtx src, int dot, rtx ccreg);
extern bool rs6000_emit_set_const (rtx, rtx);
extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx);
......
......@@ -10250,10 +10250,20 @@
;;
;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
;; We move the back-chain and decrement the stack pointer.
;;
;; Operand1 is more naturally reg_or_short_operand. However, for a large
;; constant alloca, using that predicate will force the generic code to put
;; the constant size into a register before calling the expander.
;;
;; As a result the expander would not have the constant size information
;; in those cases and would have to generate less efficient code.
;;
;; Thus we allow reg_or_cint_operand instead so that the expander can see
;; the constant size. The value is forced into a register if necessary.
;;
(define_expand "allocate_stack"
[(set (match_operand 0 "gpc_reg_operand" "")
(minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
(minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
(set (reg 1)
(minus (reg 1) (match_dup 1)))]
""
......@@ -10263,6 +10273,15 @@
rtx neg_op0;
rtx insn, par, set, mem;
/* By allowing reg_or_cint_operand as the predicate we can get
better code for stack-clash-protection because we do not lose
size information. But the rest of the code expects the operand
to be reg_or_short_operand. If it isn't, then force it into
a register. */
rtx orig_op1 = operands[1];
if (!reg_or_short_operand (operands[1], Pmode))
operands[1] = force_reg (Pmode, operands[1]);
emit_move_insn (chain, stack_bot);
/* Check stack bounds if necessary. */
......@@ -10275,6 +10294,51 @@
emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
}
/* Allocate and probe if requested.
This may look similar to the loop we use for prologue allocations,
but it is critically different. For the former we know the loop
will iterate, but do not know that generally here. The former
uses that knowledge to rotate the loop. Combining them would be
possible with some performance cost. */
if (flag_stack_clash_protection)
{
rtx rounded_size, last_addr, residual;
HOST_WIDE_INT probe_interval;
compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
&residual, &probe_interval,
orig_op1);
/* We do occasionally get in here with constant sizes, we might
as well do a reasonable job when we obviously can. */
if (rounded_size != const0_rtx)
{
rtx loop_lab, end_loop;
bool rotated = CONST_INT_P (rounded_size);
emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
last_addr, rotated);
if (Pmode == SImode)
emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
stack_pointer_rtx,
GEN_INT (-probe_interval),
chain));
else
emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
stack_pointer_rtx,
GEN_INT (-probe_interval),
chain));
emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
last_addr, rotated);
}
/* Now handle residuals. We just have to set operands[1] correctly
and let the rest of the expander run. */
operands[1] = residual;
if (!CONST_INT_P (residual))
operands[1] = force_reg (Pmode, operands[1]);
}
if (GET_CODE (operands[1]) != CONST_INT
|| INTVAL (operands[1]) < -32767
|| INTVAL (operands[1]) > 32768)
......@@ -11413,12 +11477,13 @@
(set_attr "length" "4")])
(define_insn "probe_stack_range<P:mode>"
[(set (match_operand:P 0 "register_operand" "=r")
[(set (match_operand:P 0 "register_operand" "=&r")
(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
(match_operand:P 2 "register_operand" "r")]
(match_operand:P 2 "register_operand" "r")
(match_operand:P 3 "register_operand" "r")]
UNSPECV_PROBE_STACK_RANGE))]
""
"* return output_probe_stack_range (operands[0], operands[2]);"
"* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
[(set_attr "type" "three")])
;; Compare insns are next. Note that the RS/6000 has two types of compares,
......
2017-09-25 Jeff Law <law@redhat.com>
* lib/target-supports.exp
(check_effective_target_supports_stack_clash_protection): Enable for
rs6000 and powerpc targets.
2017-09-25 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/82163
......
......@@ -8639,12 +8639,12 @@ proc check_effective_target_autoincdec { } {
proc check_effective_target_supports_stack_clash_protection { } {
# Temporary until the target bits are fully ACK'd.
# if { [istarget aarch*-*-*]
# || [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } {
# if { [istarget aarch*-*-*] } {
# return 1
# }
if { [istarget x86_64-*-*] || [istarget i?86-*-*]
|| [istarget powerpc*-*-*] || [istarget rs6000*-*-*]
|| [istarget s390*-*-*] } {
return 1
}
......
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