This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: microblaze unroll loops optimization
Hi Richard,
On 16 January 2013 06:58, Richard Henderson <rth@redhat.com> wrote:
>
> You could, however, use two CCmodes for the result of the compares:
>
> (set (reg:CC r) (compare:CC (reg:SI x) (reg:SI y)))
> => cmp r, x, y
>
> (set (reg:CCU r) (compare:CCU (reg:SI x) (reg:SI y)))
> => cmpu r, x, y
>
> and then the branch insns consume CC and CCU mode inputs:
>
> (set (pc)
> (if_then_else
> (match_operator 1 "mb_signed_cmp_op" // eq, lt, le
> [(match_operand:CC 2 "register_operand" "r")
> (const_int 0)]0
> (label_ref (match_operand 0))
> (pc)))
>
> and similar for "mb_unsigned_cmp_op" (eq, ltu, leu) with CCUmode.
>
> I believe you'll find that MODE_CC modes default to word size
> already, so if you arrange for mov{cc,ccu} patterns, reload will
> spill/reload these values as required and everything will Just Work.
>
Thanks for the reply and suggestion - I had implemented a combined
branch_compare
insns as I had indicated worked for us in the past with our out of
tree gcc 4.1.2,
and can confirm that unrolling of loops was successful.
I've also tried using CCmode / CCUmodes method, and while it works and
produces correct code, passing the testsuite with no regressions, it
unfortunately
doesnt unroll loops - it appears to be due to the get_condition check in
loop-iv.c:check_simple_exit, which has allow_cc_mode=false, which means we
return 0 from canonicalize_condition;
/* If OP0 is the result of a comparison, we weren't able to find what
was really being compared, so fail. */
if (!allow_cc_mode
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
return 0;
and mark the loop as 'not simple'.
I'm still looking, but these are the instructions as I implemented them;
(define_insn "signed_compare"
[(set (match_operand:CC 0 "register_operand" "=d")
(compare:CC
(match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))]
""
"cmp\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "4")])
(define_insn "unsigned_compare"
[(set (match_operand:CCU 0 "register_operand" "=d")
(compare:CCU
(match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))]
""
"cmpu\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "4")])
and branches;
(define_insn "signed_condbranch"
[(set (pc)
(if_then_else (match_operator: 0 "signed_cmp_op"
[(match_operand:CC 1 "register_operand" "d")
(const_int 0)])
(label_ref (match_operand 2))
(pc)))]
""
"b%C0i%?\t%z1,%2"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "4")]
)
(define_insn "unsigned_condbranch"
[(set (pc)
(if_then_else (match_operator: 0 "unsigned_cmp_op"
[(match_operand:CCU 1 "register_operand" "d")
(const_int 0)])
(label_ref (match_operand 2))
(pc)))]
""
"b%C0i%?\t%z1,%2"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "4")]
)
thanks,
David