+2017-01-14 Alan Modra <amodra@gmail.com>
+
+ PR target/72749
+ * combine.c (recog_for_combine_1): Set INSN_CODE before calling
+ target legitimate_combined_insn.
+ * config/rs6000/rs6000.c (TARGET_LEGITIMATE_COMBINED_INSN): Define.
+ (rs6000_legitimate_combined_insn): New function.
+ * config/rs6000/rs6000.md (UNSPEC_DOLOOP): Delete, and remove
+ all uses.
+ (ctr<mode>_internal3): Rename from *ctr<mode>_internal5.
+ (ctr<mode>_internal4): Rename from *ctr<mode>_internal6.
+ (ctr<mode>_internal1, ctr<mode>_internal2): Remove '*' from name.
+
2017-01-14 Gerald Pfeifer <gerald@pfeifer.com>
* doc/frontends.texi (G++ and GCC): Remove references to Java.
-
+
2017-01-13 Jeff Law <law@redhat.com>
PR tree-optimization/33562
* config.gcc (*-*-fuchsia*): Set native_system_header_dir.
(aarch64*-*-fuchsia*, arm*-*-fuchsia*, x86_64-*-fuchsia*): Add to
targets.
- * config.host: (aarch64*-*-fuchsia*, arm*-*-fuchsia*): Add to hosts.
+ * config.host: (aarch64*-*-fuchsia*, arm*-*-fuchsia*): Add to hosts.
2016-01-10 Richard Biener <rguenther@suse.de>
#undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
#define TARGET_CONST_NOT_OK_FOR_DEBUG_P rs6000_const_not_ok_for_debug_p
+#undef TARGET_LEGITIMATE_COMBINED_INSN
+#define TARGET_LEGITIMATE_COMBINED_INSN rs6000_legitimate_combined_insn
+
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
return false;
}
+
+/* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook. */
+
+static bool
+rs6000_legitimate_combined_insn (rtx_insn *insn)
+{
+ switch (INSN_CODE (insn))
+ {
+ /* Reject creating doloop insns. Combine should not be allowed
+ to create these for a number of reasons:
+ 1) In a nested loop, if combine creates one of these in an
+ outer loop and the register allocator happens to allocate ctr
+ to the outer loop insn, then the inner loop can't use ctr.
+ Inner loops ought to be more highly optimized.
+ 2) Combine often wants to create one of these from what was
+ originally a three insn sequence, first combining the three
+ insns to two, then to ctrsi/ctrdi. When ctrsi/ctrdi is not
+ allocated ctr, the splitter takes use back to the three insn
+ sequence. It's better to stop combine at the two insn
+ sequence.
+ 3) Faced with not being able to allocate ctr for ctrsi/crtdi
+ insns, the register allocator sometimes uses floating point
+ or vector registers for the pseudo. Since ctrsi/ctrdi is a
+ jump insn and output reloads are not implemented for jumps,
+ the ctrsi/ctrdi splitters need to handle all possible cases.
+ That's a pain, and it gets to be seriously difficult when a
+ splitter that runs after reload needs memory to transfer from
+ a gpr to fpr. See PR70098 and PR71763 which are not fixed
+ for the difficult case. It's better to not create problems
+ in the first place. */
+ case CODE_FOR_ctrsi_internal1:
+ case CODE_FOR_ctrdi_internal1:
+ case CODE_FOR_ctrsi_internal2:
+ case CODE_FOR_ctrdi_internal2:
+ case CODE_FOR_ctrsi_internal3:
+ case CODE_FOR_ctrdi_internal3:
+ case CODE_FOR_ctrsi_internal4:
+ case CODE_FOR_ctrdi_internal4:
+ return false;
+ }
+ return true;
+}
+
/* Construct the SYMBOL_REF for the tls_get_addr function. */
static GTY(()) rtx rs6000_tls_symbol;
UNSPEC_IEEE128_MOVE
UNSPEC_IEEE128_CONVERT
UNSPEC_SIGNBIT
- UNSPEC_DOLOOP
UNSPEC_SF_FROM_SI
UNSPEC_SI_FROM_SF
])
(set (match_dup 0)
(plus:P (match_dup 0)
(const_int -1)))
- (unspec [(const_int 0)] UNSPEC_DOLOOP)
(clobber (match_scratch:CC 2 ""))
(clobber (match_scratch:P 3 ""))])]
""
;; JUMP_INSNs.
;; For the length attribute to be calculated correctly, the
;; label MUST be operand 0.
-;; The UNSPEC is present to prevent combine creating this pattern.
+;; rs6000_legitimate_combined_insn prevents combine creating any of
+;; the ctr<mode> insns.
-(define_insn "*ctr<mode>_internal1"
+(define_insn "ctr<mode>_internal1"
[(set (pc)
(if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
(const_int 1))
(set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
(plus:P (match_dup 1)
(const_int -1)))
- (unspec [(const_int 0)] UNSPEC_DOLOOP)
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:P 4 "=X,X,&r,r"))]
""
[(set_attr "type" "branch")
(set_attr "length" "*,16,20,20")])
-(define_insn "*ctr<mode>_internal2"
+(define_insn "ctr<mode>_internal2"
[(set (pc)
(if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
(const_int 1))
(set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
(plus:P (match_dup 1)
(const_int -1)))
- (unspec [(const_int 0)] UNSPEC_DOLOOP)
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:P 4 "=X,X,&r,r"))]
""
;; Similar but use EQ
-(define_insn "*ctr<mode>_internal5"
+(define_insn "ctr<mode>_internal3"
[(set (pc)
(if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
(const_int 1))
(set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
(plus:P (match_dup 1)
(const_int -1)))
- (unspec [(const_int 0)] UNSPEC_DOLOOP)
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:P 4 "=X,X,&r,r"))]
""
[(set_attr "type" "branch")
(set_attr "length" "*,16,20,20")])
-(define_insn "*ctr<mode>_internal6"
+(define_insn "ctr<mode>_internal4"
[(set (pc)
(if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
(const_int 1))
(set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
(plus:P (match_dup 1)
(const_int -1)))
- (unspec [(const_int 0)] UNSPEC_DOLOOP)
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:P 4 "=X,X,&r,r"))]
""
(match_operand 6 "" "")))
(set (match_operand:P 0 "int_reg_operand" "")
(plus:P (match_dup 1) (const_int -1)))
- (unspec [(const_int 0)] UNSPEC_DOLOOP)
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:P 4 ""))]
"reload_completed"
(match_operand 6 "" "")))
(set (match_operand:P 0 "nonimmediate_operand" "")
(plus:P (match_dup 1) (const_int -1)))
- (unspec [(const_int 0)] UNSPEC_DOLOOP)
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:P 4 ""))]
"reload_completed && ! gpc_reg_operand (operands[0], SImode)"