Commit f758f299 by Michael Meissner Committed by Michael Meissner

re PR target/58160 (Power8 fusion support has a bug that shows up in running spec 2006)

2013-08-14  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/58160
	* config/rs6000/predicates.md (fusion_gpr_mem_load): Allow the
	memory rtx to contain ZERO_EXTEND and SIGN_EXTEND.

	* config/rs6000/rs6000-protos.h (fusion_gpr_load_p): Pass operands
	array instead of each individual operand as a separate argument.
	(emit_fusion_gpr_load): Likewise.
	(expand_fusion_gpr_load): Add new function declaration.

	* config/rs6000/rs6000.c (fusion_gpr_load_p): Change the calling
	signature to have the operands passed as an array, instead of as
	separate arguments.  Allow ZERO_EXTEND to be in the memory
	address, and also SIGN_EXTEND if -mpower8-fusion-sign.  Do not
	depend on the register live/dead flags when peepholes are run.
	(expand_fusion_gpr_load): New function to be called from the
	peephole2 pass, to change the register that addis sets to be the
	target register.
	(emit_fusion_gpr_load): Change the calling signature to have the
	operands passed as an array, instead of as separate arguments.
	Allow ZERO_EXTEND to be in the memory address, and also
	SIGN_EXTEND if -mpower8-fusion-sign.

	* config/rs6000/rs6000.md (UNSPEC_FUSION_GPR): Delete unused
	unspec enumeration.
	(power8 fusion peephole/peephole2): Rework the fusion peepholes to
	adjust the register addis loads up in the peephole2 pass.  Do not
	depend on the register live/dead state when the peephole pass is
	done.

From-SVN: r201792
parent 158f4e4f
2013-08-16 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/58160
* config/rs6000/predicates.md (fusion_gpr_mem_load): Allow the
memory rtx to contain ZERO_EXTEND and SIGN_EXTEND.
* config/rs6000/rs6000-protos.h (fusion_gpr_load_p): Pass operands
array instead of each individual operand as a separate argument.
(emit_fusion_gpr_load): Likewise.
(expand_fusion_gpr_load): Add new function declaration.
* config/rs6000/rs6000.c (fusion_gpr_load_p): Change the calling
signature to have the operands passed as an array, instead of as
separate arguments. Allow ZERO_EXTEND to be in the memory
address, and also SIGN_EXTEND if -mpower8-fusion-sign. Do not
depend on the register live/dead flags when peepholes are run.
(expand_fusion_gpr_load): New function to be called from the
peephole2 pass, to change the register that addis sets to be the
target register.
(emit_fusion_gpr_load): Change the calling signature to have the
operands passed as an array, instead of as separate arguments.
Allow ZERO_EXTEND to be in the memory address, and also
SIGN_EXTEND if -mpower8-fusion-sign.
* config/rs6000/rs6000.md (UNSPEC_FUSION_GPR): Delete unused
unspec enumeration.
(power8 fusion peephole/peephole2): Rework the fusion peepholes to
adjust the register addis loads up in the peephole2 pass. Do not
depend on the register live/dead state when the peephole pass is
done.
2013-08-16 David Malcolm <dmalcolm@redhat.com>
* gengtype.c (create_user_defined_type): Ensure that the kind
......
......@@ -1740,10 +1740,18 @@
;; Match the second insn (lbz, lhz, lwz, ld) in fusing the combination of addis
;; and loads to GPR registers on power8.
(define_predicate "fusion_gpr_mem_load"
(match_code "mem")
(match_code "mem,sign_extend,zero_extend")
{
rtx addr;
/* Handle sign/zero extend. */
if (GET_CODE (op) == ZERO_EXTEND
|| (TARGET_P8_FUSION_SIGN && GET_CODE (op) == SIGN_EXTEND))
{
op = XEXP (op, 0);
mode = GET_MODE (op);
}
if (!MEM_P (op))
return 0;
......
......@@ -73,8 +73,9 @@ extern int mems_ok_for_quad_peep (rtx, rtx);
extern bool gpr_or_gpr_p (rtx, rtx);
extern bool direct_move_p (rtx, rtx);
extern bool quad_load_store_p (rtx, rtx);
extern bool fusion_gpr_load_p (rtx, rtx, rtx, rtx, rtx);
extern const char *emit_fusion_gpr_load (rtx, rtx, rtx, rtx);
extern bool fusion_gpr_load_p (rtx *, bool);
extern void expand_fusion_gpr_load (rtx *);
extern const char *emit_fusion_gpr_load (rtx *);
extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx,
enum reg_class);
extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
......
......@@ -136,7 +136,6 @@
UNSPEC_P8V_MTVSRD
UNSPEC_P8V_XXPERMDI
UNSPEC_P8V_RELOAD_FROM_VSX
UNSPEC_FUSION_GPR
])
;;
......@@ -15775,108 +15774,38 @@
;; a GPR. The addis instruction must be adjacent to the load, and use the same
;; register that is being loaded. The fused ops must be physically adjacent.
;; GPR fusion for single word integer types
;; We use define_peephole for the actual addis/load, and the register used to
;; hold the addis value must be the same as the register being loaded. We use
;; define_peephole2 to change the register used for addis to be the register
;; being loaded, since we can look at whether it is dead after the load insn.
(define_peephole
[(set (match_operand:P 0 "base_reg_operand" "")
(match_operand:P 1 "fusion_gpr_addis" ""))
(set (match_operand:INT1 2 "base_reg_operand" "")
(match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
"TARGET_P8_FUSION
&& fusion_gpr_load_p (operands[0], operands[1], operands[2], operands[3],
insn)"
"TARGET_P8_FUSION && fusion_gpr_load_p (operands, false)"
{
return emit_fusion_gpr_load (operands[0], operands[1], operands[2],
operands[3]);
return emit_fusion_gpr_load (operands);
}
[(set_attr "type" "load")
(set_attr "length" "8")])
(define_peephole
[(set (match_operand:DI 0 "base_reg_operand" "")
(match_operand:DI 1 "fusion_gpr_addis" ""))
(set (match_operand:DI 2 "base_reg_operand" "")
(zero_extend:DI (match_operand:QHSI 3 "fusion_gpr_mem_load" "")))]
"TARGET_P8_FUSION && TARGET_POWERPC64
&& fusion_gpr_load_p (operands[0], operands[1], operands[2], operands[3],
insn)"
{
return emit_fusion_gpr_load (operands[0], operands[1], operands[2],
operands[3]);
}
[(set_attr "type" "load")
(set_attr "length" "8")])
;; Power8 does not fuse a sign extending load, so convert the sign extending
;; load into a zero extending load, and do an explicit sign extension. Don't
;; do this if we are trying to optimize for space. Do this as a peephole2 to
;; allow final rtl optimizations and scheduling to move the sign extend.
(define_peephole2
[(set (match_operand:DI 0 "base_reg_operand" "")
(match_operand:DI 1 "fusion_gpr_addis" ""))
(set (match_operand:DI 2 "base_reg_operand" "")
(sign_extend:DI (match_operand:HSI 3 "fusion_gpr_mem_load" "")))]
"TARGET_P8_FUSION && TARGET_P8_FUSION_SIGN && TARGET_POWERPC64
&& fusion_gpr_load_p (operands[0], operands[1], operands[2], operands[3],
NULL_RTX)"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 4) (match_dup 3))
(set (match_dup 2) (sign_extend:DI (match_dup 4)))]
{
unsigned int offset
= (BYTES_BIG_ENDIAN ? 8 - GET_MODE_SIZE (<MODE>mode) : 0);
operands[4] = simplify_subreg (<MODE>mode, operands[2], DImode,
offset);
})
(define_peephole
[(set (match_operand:P 0 "base_reg_operand" "")
(match_operand:P 1 "fusion_gpr_addis" ""))
(set (match_operand:SI 2 "base_reg_operand" "")
(zero_extend:SI (match_operand:QHI 3 "fusion_gpr_mem_load" "")))]
(set (match_operand:INT1 2 "base_reg_operand" "")
(match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
"TARGET_P8_FUSION
&& fusion_gpr_load_p (operands[0], operands[1], operands[2], operands[3],
insn)"
{
return emit_fusion_gpr_load (operands[0], operands[1], operands[2],
operands[3]);
}
[(set_attr "type" "load")
(set_attr "length" "8")])
(define_peephole2
[(set (match_operand:P 0 "base_reg_operand" "")
(match_operand:P 1 "fusion_gpr_addis" ""))
(set (match_operand:SI 2 "base_reg_operand" "")
(sign_extend:SI (match_operand:HI 3 "fusion_gpr_mem_load" "")))]
"TARGET_P8_FUSION && TARGET_P8_FUSION_SIGN
&& fusion_gpr_load_p (operands[0], operands[1], operands[2], operands[3],
NULL_RTX)"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 4) (match_dup 3))
(set (match_dup 2) (sign_extend:SI (match_dup 4)))]
&& (REGNO (operands[0]) != REGNO (operands[2])
|| GET_CODE (operands[3]) == SIGN_EXTEND)
&& fusion_gpr_load_p (operands, true)"
[(const_int 0)]
{
unsigned int offset = (BYTES_BIG_ENDIAN ? 2 : 0);
operands[4] = simplify_subreg (HImode, operands[2], SImode, offset);
expand_fusion_gpr_load (operands);
DONE;
})
(define_peephole
[(set (match_operand:P 0 "base_reg_operand" "")
(match_operand:P 1 "fusion_gpr_addis" ""))
(set (match_operand:HI 2 "base_reg_operand" "")
(zero_extend:HI (match_operand:QI 3 "fusion_gpr_mem_load" "")))]
"TARGET_P8_FUSION
&& fusion_gpr_load_p (operands[0], operands[1], operands[2], operands[3],
insn)"
{
return emit_fusion_gpr_load (operands[0], operands[1], operands[2],
operands[3]);
}
[(set_attr "type" "load")
(set_attr "length" "8")])
(include "sync.md")
......
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