Commit c8012fbc by Wilco Dijkstra Committed by Jiong Wang

[Patch 1/4] Simplify the representation of CCMP patterns by using

    2015-01-19  Wilco Dijkstra  <wdijkstr@arm.com>

    gcc/
        * target.def (gen_ccmp_first): Update documentation.
        (gen_ccmp_next): Likewise.
        * doc/tm.texi (gen_ccmp_first): Update documentation.
        (gen_ccmp_next): Likewise.
        * ccmp.c (expand_ccmp_expr): Extract cmp_code from return value of
        expand_ccmp_expr_1.  Improve comments.
        * config/aarch64/aarch64.md (ccmp_and): Use if_then_else for ccmp.
        (ccmp_ior<mode>): Remove pattern.
        (cmp<mode>): Remove expand.
        (cmp): Globalize pattern.
        (cstorecc4): Use cc_register.
        (mov<mode>cc): Remove ccmp_cc_register check.
        * config/aarch64/aarch64.c (aarch64_get_condition_code_1):
        Simplify after removal of CC_DNE/* modes.
        (aarch64_ccmp_mode_to_code): Remove.
        (aarch64_print_operand): Remove 'K' case.  Merge 'm' and 'M' cases.
        In 'k' case use integer as condition.
        (aarch64_nzcv_codes): Remove inverted cases.
        (aarch64_code_to_ccmode): Remove.
        (aarch64_gen_ccmp_first): Use cmp pattern directly.  Return the correct
        comparison with CC register to be used in folowing CCMP/branch/CSEL.
        (aarch64_gen_ccmp_next): Use previous comparison and mode in CCMP
        pattern.  Return the comparison with CC register.  Invert conditions
        when bitcode is OR.
        * config/aarch64/aarch64-modes.def: Remove CC_DNE/* modes.
        * config/aarch64/predicates.md (ccmp_cc_register): Remove.

From-SVN: r232561
parent 756f4e90
2016-01-19 Wilco Dijkstra <wdijkstr@arm.com>
* target.def (gen_ccmp_first): Update documentation.
(gen_ccmp_next): Likewise.
* doc/tm.texi (gen_ccmp_first): Update documentation.
(gen_ccmp_next): Likewise.
* ccmp.c (expand_ccmp_expr): Extract cmp_code from return value of
expand_ccmp_expr_1. Improve comments.
* config/aarch64/aarch64.md (ccmp_and): Use if_then_else for ccmp.
(ccmp_ior<mode>): Remove pattern.
(cmp<mode>): Remove expand.
(cmp): Globalize pattern.
(cstorecc4): Use cc_register.
(mov<mode>cc): Remove ccmp_cc_register check.
* config/aarch64/aarch64.c (aarch64_get_condition_code_1):
Simplify after removal of CC_DNE/* modes.
(aarch64_ccmp_mode_to_code): Remove.
(aarch64_print_operand): Remove 'K' case. Merge 'm' and 'M' cases.
In 'k' case use integer as condition.
(aarch64_nzcv_codes): Remove inverted cases.
(aarch64_code_to_ccmode): Remove.
(aarch64_gen_ccmp_first): Use cmp pattern directly. Return the correct
comparison with CC register to be used in folowing CCMP/branch/CSEL.
(aarch64_gen_ccmp_next): Use previous comparison and mode in CCMP
pattern. Return the comparison with CC register. Invert conditions
when bitcode is OR.
* config/aarch64/aarch64-modes.def: Remove CC_DNE/* modes.
* config/aarch64/predicates.md (ccmp_cc_register): Remove.
2016-01-19 Jan Hubicka <hubicka@ucw.cz> 2016-01-19 Jan Hubicka <hubicka@ucw.cz>
* cgraphunit.c (cgraph_node::reset): Clear thunk info and * cgraphunit.c (cgraph_node::reset): Clear thunk info and
......
...@@ -49,6 +49,10 @@ along with GCC; see the file COPYING3. If not see ...@@ -49,6 +49,10 @@ along with GCC; see the file COPYING3. If not see
- gen_ccmp_first expands the first compare in CCMP. - gen_ccmp_first expands the first compare in CCMP.
- gen_ccmp_next expands the following compares. - gen_ccmp_next expands the following compares.
Both hooks return a comparison with the CC register that is equivalent
to the value of the gimple comparison. This is used by the next CCMP
and in the final conditional store.
* We use cstorecc4 pattern to convert the CCmode intermediate to * We use cstorecc4 pattern to convert the CCmode intermediate to
the integer mode result that expand_normal is expecting. the integer mode result that expand_normal is expecting.
...@@ -114,10 +118,12 @@ ccmp_candidate_p (gimple *g) ...@@ -114,10 +118,12 @@ ccmp_candidate_p (gimple *g)
return false; return false;
} }
/* PREV is the CC flag from precvious compares. The function expands the /* PREV is a comparison with the CC register which represents the
next compare based on G which ops previous compare with CODE. result of the previous CMP or CCMP. The function expands the
next compare based on G which is ANDed/ORed with the previous
compare depending on CODE.
PREP_SEQ returns all insns to prepare opearands for compare. PREP_SEQ returns all insns to prepare opearands for compare.
GEN_SEQ returnss all compare insns. */ GEN_SEQ returns all compare insns. */
static rtx static rtx
expand_ccmp_next (gimple *g, enum tree_code code, rtx prev, expand_ccmp_next (gimple *g, enum tree_code code, rtx prev,
rtx *prep_seq, rtx *gen_seq) rtx *prep_seq, rtx *gen_seq)
...@@ -233,9 +239,10 @@ expand_ccmp_expr (gimple *g) ...@@ -233,9 +239,10 @@ expand_ccmp_expr (gimple *g)
enum insn_code icode; enum insn_code icode;
enum machine_mode cc_mode = CCmode; enum machine_mode cc_mode = CCmode;
tree lhs = gimple_assign_lhs (g); tree lhs = gimple_assign_lhs (g);
rtx_code cmp_code = GET_CODE (tmp);
#ifdef SELECT_CC_MODE #ifdef SELECT_CC_MODE
cc_mode = SELECT_CC_MODE (NE, tmp, const0_rtx); cc_mode = SELECT_CC_MODE (cmp_code, XEXP (tmp, 0), const0_rtx);
#endif #endif
icode = optab_handler (cstore_optab, cc_mode); icode = optab_handler (cstore_optab, cc_mode);
if (icode != CODE_FOR_nothing) if (icode != CODE_FOR_nothing)
...@@ -246,8 +253,8 @@ expand_ccmp_expr (gimple *g) ...@@ -246,8 +253,8 @@ expand_ccmp_expr (gimple *g)
emit_insn (prep_seq); emit_insn (prep_seq);
emit_insn (gen_seq); emit_insn (gen_seq);
tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode, tmp = emit_cstore (target, icode, cmp_code, cc_mode, cc_mode,
0, tmp, const0_rtx, 1, mode); 0, XEXP (tmp, 0), const0_rtx, 1, mode);
if (tmp) if (tmp)
return tmp; return tmp;
} }
......
...@@ -25,16 +25,6 @@ CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make it RHS). */ ...@@ -25,16 +25,6 @@ CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make it RHS). */
CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS). */ CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS). */
CC_MODE (CC_NZ); /* Only N and Z bits of condition flags are valid. */ CC_MODE (CC_NZ); /* Only N and Z bits of condition flags are valid. */
CC_MODE (CC_Z); /* Only Z bit of condition flags is valid. */ CC_MODE (CC_Z); /* Only Z bit of condition flags is valid. */
CC_MODE (CC_DNE);
CC_MODE (CC_DEQ);
CC_MODE (CC_DLE);
CC_MODE (CC_DLT);
CC_MODE (CC_DGE);
CC_MODE (CC_DGT);
CC_MODE (CC_DLEU);
CC_MODE (CC_DLTU);
CC_MODE (CC_DGEU);
CC_MODE (CC_DGTU);
/* Half-precision floating point for __fp16. */ /* Half-precision floating point for __fp16. */
FLOAT_MODE (HF, 2, 0); FLOAT_MODE (HF, 2, 0);
......
...@@ -271,18 +271,17 @@ ...@@ -271,18 +271,17 @@
"" ""
"") "")
(define_insn "ccmp_and<mode>" (define_insn "ccmp<mode>"
[(set (match_operand 1 "ccmp_cc_register" "") [(set (match_operand:CC 1 "cc_register" "")
(compare (if_then_else:CC
(and:SI
(match_operator 4 "aarch64_comparison_operator" (match_operator 4 "aarch64_comparison_operator"
[(match_operand 0 "ccmp_cc_register" "") [(match_operand 0 "cc_register" "")
(const_int 0)]) (const_int 0)])
(match_operator 5 "aarch64_comparison_operator" (compare:CC
[(match_operand:GPI 2 "register_operand" "r,r,r") (match_operand:GPI 2 "register_operand" "r,r,r")
(match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")])) (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn"))
(const_int 0)))] (match_operand 5 "immediate_operand")))]
"aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])" ""
"@ "@
ccmp\\t%<w>2, %<w>3, %k5, %m4 ccmp\\t%<w>2, %<w>3, %k5, %m4
ccmp\\t%<w>2, %<w>3, %k5, %m4 ccmp\\t%<w>2, %<w>3, %k5, %m4
...@@ -290,39 +289,6 @@ ...@@ -290,39 +289,6 @@
[(set_attr "type" "alus_sreg,alus_imm,alus_imm")] [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
) )
(define_insn "ccmp_ior<mode>"
[(set (match_operand 1 "ccmp_cc_register" "")
(compare
(ior:SI
(match_operator 4 "aarch64_comparison_operator"
[(match_operand 0 "ccmp_cc_register" "")
(const_int 0)])
(match_operator 5 "aarch64_comparison_operator"
[(match_operand:GPI 2 "register_operand" "r,r,r")
(match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
(const_int 0)))]
"aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
"@
ccmp\\t%<w>2, %<w>3, %K5, %M4
ccmp\\t%<w>2, %<w>3, %K5, %M4
ccmn\\t%<w>2, #%n3, %K5, %M4"
[(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
)
(define_expand "cmp<mode>"
[(set (match_operand 0 "cc_register" "")
(match_operator:CC 1 "aarch64_comparison_operator"
[(match_operand:GPI 2 "register_operand" "")
(match_operand:GPI 3 "aarch64_plus_operand" "")]))]
""
{
operands[1] = gen_rtx_fmt_ee (COMPARE,
SELECT_CC_MODE (GET_CODE (operands[1]),
operands[2], operands[3]),
operands[2], operands[3]);
}
)
;; Expansion of signed mod by a power of 2 using CSNEG. ;; Expansion of signed mod by a power of 2 using CSNEG.
;; For x0 % n where n is a power of 2 produce: ;; For x0 % n where n is a power of 2 produce:
;; negs x1, x0 ;; negs x1, x0
...@@ -2874,7 +2840,7 @@ ...@@ -2874,7 +2840,7 @@
;; Comparison insns ;; Comparison insns
;; ------------------------------------------------------------------- ;; -------------------------------------------------------------------
(define_insn "*cmp<mode>" (define_insn "cmp<mode>"
[(set (reg:CC CC_REGNUM) [(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:GPI 0 "register_operand" "r,r,r") (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
(match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))] (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
...@@ -2961,7 +2927,7 @@ ...@@ -2961,7 +2927,7 @@
(define_expand "cstorecc4" (define_expand "cstorecc4"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
(match_operator 1 "aarch64_comparison_operator" (match_operator 1 "aarch64_comparison_operator"
[(match_operand 2 "ccmp_cc_register") [(match_operand 2 "cc_register")
(match_operand 3 "const0_operand")]))] (match_operand 3 "const0_operand")]))]
"" ""
"{ "{
...@@ -3164,20 +3130,16 @@ ...@@ -3164,20 +3130,16 @@
(match_operand:ALLI 3 "register_operand" "")))] (match_operand:ALLI 3 "register_operand" "")))]
"" ""
{ {
rtx ccreg;
enum rtx_code code = GET_CODE (operands[1]); enum rtx_code code = GET_CODE (operands[1]);
if (code == UNEQ || code == LTGT) if (code == UNEQ || code == LTGT)
FAIL; FAIL;
if (!ccmp_cc_register (XEXP (operands[1], 0),
GET_MODE (XEXP (operands[1], 0))))
{
rtx ccreg;
ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0), ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
XEXP (operands[1], 1)); XEXP (operands[1], 1));
operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
} }
}
) )
(define_expand "mov<GPF:mode><GPI:mode>cc" (define_expand "mov<GPF:mode><GPI:mode>cc"
......
...@@ -43,23 +43,6 @@ ...@@ -43,23 +43,6 @@
(ior (match_operand 0 "register_operand") (ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_ccmp_immediate"))) (match_operand 0 "aarch64_ccmp_immediate")))
(define_special_predicate "ccmp_cc_register"
(and (match_code "reg")
(and (match_test "REGNO (op) == CC_REGNUM")
(ior (match_test "mode == GET_MODE (op)")
(match_test "mode == VOIDmode
&& (GET_MODE (op) == CC_DNEmode
|| GET_MODE (op) == CC_DEQmode
|| GET_MODE (op) == CC_DLEmode
|| GET_MODE (op) == CC_DLTmode
|| GET_MODE (op) == CC_DGEmode
|| GET_MODE (op) == CC_DGTmode
|| GET_MODE (op) == CC_DLEUmode
|| GET_MODE (op) == CC_DLTUmode
|| GET_MODE (op) == CC_DGEUmode
|| GET_MODE (op) == CC_DGTUmode)"))))
)
(define_predicate "aarch64_simd_register" (define_predicate "aarch64_simd_register"
(and (match_code "reg") (and (match_code "reg")
(ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS") (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
......
...@@ -11370,27 +11370,27 @@ modes and they have different conditional execution capability, such as ARM. ...@@ -11370,27 +11370,27 @@ modes and they have different conditional execution capability, such as ARM.
@deftypefn {Target Hook} rtx TARGET_GEN_CCMP_FIRST (rtx *@var{prep_seq}, rtx *@var{gen_seq}, int @var{code}, tree @var{op0}, tree @var{op1}) @deftypefn {Target Hook} rtx TARGET_GEN_CCMP_FIRST (rtx *@var{prep_seq}, rtx *@var{gen_seq}, int @var{code}, tree @var{op0}, tree @var{op1})
This function prepares to emit a comparison insn for the first compare in a This function prepares to emit a comparison insn for the first compare in a
sequence of conditional comparisions. It returns a appropriate @code{CC} sequence of conditional comparisions. It returns an appropriate comparison
for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to with @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.
prepare the compare are saved in @var{prep_seq} and the compare insns are The insns to prepare the compare are saved in @var{prep_seq} and the compare
saved in @var{gen_seq}. They will be emitted when all the compares in the insns are saved in @var{gen_seq}. They will be emitted when all the
the conditional comparision are generated without error. @var{code} is compares in the the conditional comparision are generated without error.
the @code{rtx_code} of the compare for @var{op0} and @var{op1}. @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.
@end deftypefn @end deftypefn
@deftypefn {Target Hook} rtx TARGET_GEN_CCMP_NEXT (rtx *@var{prep_seq}, rtx *@var{gen_seq}, rtx @var{prev}, int @var{cmp_code}, tree @var{op0}, tree @var{op1}, int @var{bit_code}) @deftypefn {Target Hook} rtx TARGET_GEN_CCMP_NEXT (rtx *@var{prep_seq}, rtx *@var{gen_seq}, rtx @var{prev}, int @var{cmp_code}, tree @var{op0}, tree @var{op1}, int @var{bit_code})
This function prepare to emit a conditional comparison within a sequence of This function prepares to emit a conditional comparison within a sequence
conditional comparisons. It returns a appropriate @code{CC} for passing to of conditional comparisons. It returns an appropriate comparison with
@code{gen_ccmp_next} or @code{cbranch_optab}. The insns to prepare the @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.
compare are saved in @var{prep_seq} and the compare insns are saved in The insns to prepare the compare are saved in @var{prep_seq} and the compare
@var{gen_seq}. They will be emitted when all the compares in the conditional insns are saved in @var{gen_seq}. They will be emitted when all the
comparision are generated without error. The @var{prev} expression is the compares in the conditional comparision are generated without error. The
result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It @var{prev} expression is the result of a prior call to @code{gen_ccmp_first}
may return @code{NULL} if the combination of @var{prev} and this comparison is or @code{gen_ccmp_next}. It may return @code{NULL} if the combination of
not supported, otherwise the result must be appropriate for passing to @var{prev} and this comparison is not supported, otherwise the result must
@code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is the be appropriate for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.
@code{rtx_code} of the compare for @var{op0} and @var{op1}. @var{bit_code} @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.
is @code{AND} or @code{IOR}, which is the op on the two compares. @var{bit_code} is @code{AND} or @code{IOR}, which is the op on the compares.
@end deftypefn @end deftypefn
@deftypefn {Target Hook} unsigned TARGET_LOOP_UNROLL_ADJUST (unsigned @var{nunroll}, struct loop *@var{loop}) @deftypefn {Target Hook} unsigned TARGET_LOOP_UNROLL_ADJUST (unsigned @var{nunroll}, struct loop *@var{loop})
......
...@@ -2611,29 +2611,29 @@ modes and they have different conditional execution capability, such as ARM.", ...@@ -2611,29 +2611,29 @@ modes and they have different conditional execution capability, such as ARM.",
DEFHOOK DEFHOOK
(gen_ccmp_first, (gen_ccmp_first,
"This function prepares to emit a comparison insn for the first compare in a\n\ "This function prepares to emit a comparison insn for the first compare in a\n\
sequence of conditional comparisions. It returns a appropriate @code{CC}\n\ sequence of conditional comparisions. It returns an appropriate comparison\n\
for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to\n\ with @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\
prepare the compare are saved in @var{prep_seq} and the compare insns are\n\ The insns to prepare the compare are saved in @var{prep_seq} and the compare\n\
saved in @var{gen_seq}. They will be emitted when all the compares in the\n\ insns are saved in @var{gen_seq}. They will be emitted when all the\n\
the conditional comparision are generated without error. @var{code} is\n\ compares in the the conditional comparision are generated without error.\n\
the @code{rtx_code} of the compare for @var{op0} and @var{op1}.", @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.",
rtx, (rtx *prep_seq, rtx *gen_seq, int code, tree op0, tree op1), rtx, (rtx *prep_seq, rtx *gen_seq, int code, tree op0, tree op1),
NULL) NULL)
DEFHOOK DEFHOOK
(gen_ccmp_next, (gen_ccmp_next,
"This function prepare to emit a conditional comparison within a sequence of\n\ "This function prepares to emit a conditional comparison within a sequence\n\
conditional comparisons. It returns a appropriate @code{CC} for passing to\n\ of conditional comparisons. It returns an appropriate comparison with\n\
@code{gen_ccmp_next} or @code{cbranch_optab}. The insns to prepare the\n\ @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\
compare are saved in @var{prep_seq} and the compare insns are saved in\n\ The insns to prepare the compare are saved in @var{prep_seq} and the compare\n\
@var{gen_seq}. They will be emitted when all the compares in the conditional\n\ insns are saved in @var{gen_seq}. They will be emitted when all the\n\
comparision are generated without error. The @var{prev} expression is the\n\ compares in the conditional comparision are generated without error. The\n\
result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It\n\ @var{prev} expression is the result of a prior call to @code{gen_ccmp_first}\n\
may return @code{NULL} if the combination of @var{prev} and this comparison is\n\ or @code{gen_ccmp_next}. It may return @code{NULL} if the combination of\n\
not supported, otherwise the result must be appropriate for passing to\n\ @var{prev} and this comparison is not supported, otherwise the result must\n\
@code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is the\n\ be appropriate for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\
@code{rtx_code} of the compare for @var{op0} and @var{op1}. @var{bit_code}\n\ @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.\n\
is @code{AND} or @code{IOR}, which is the op on the two compares.", @var{bit_code} is @code{AND} or @code{IOR}, which is the op on the compares.",
rtx, (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, tree op0, tree op1, int bit_code), rtx, (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, tree op0, tree op1, int bit_code),
NULL) NULL)
......
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