This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]