This is the mail archive of the gcc-patches@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: RFA: Make compare_and_jump_seq check that it has a jump insn


On 06/24/2010 11:50 AM, Nick Clifton wrote:
Hi Jeff,

OK.

Thanks.


Presumably it was a port error that was causing do_compare_rtx_and_jump
to return a CODE_LABEL --

Right.


it certainly seems quite odd to get that as
the final insn from a compare & jump sequence.

It can be a jump over another compare-and-jump. do_compare_rtx_and_jump can return that even if the backend does not do it, Most of the time in the case of loop-unswitching the condition is taken straight from another compare-and-jump, but canon_condition may for example change LE to LT, then you can get into this code which creates a jump-over-jump:


  if ((! if_true_label
       || ! can_compare_p (code, mode, ccp_jump))
      && (! FLOAT_MODE_P (mode) || ...))
    {
      enum rtx_code rcode;
      if (FLOAT_MODE_P (mode))
        rcode = reverse_condition_maybe_unordered (code);
      else
        rcode = reverse_condition (code);

      /* Canonicalize to UNORDERED for the libcall.  */
      if (can_compare_p (rcode, mode, ccp_jump)
          || ... )
        {
          tem = if_true_label;
          if_true_label = if_false_label;
          if_false_label = tem;
          code = rcode;
          prob = inv (prob);
        }
    }

...

  if (! if_true_label)
    dummy_label = if_true_label = gen_label_rtx ();

...

  if (if_false_label)
    emit_jump (if_false_label);
  if (dummy_label)
    emit_label (dummy_label);

Since compare_and_jump_seq passes NULL if_false_label, if the jump is reversed the last emitted instruction will be a label. I think it is rarely seen only because a) not many loops are unswitched at RTL level, b) loop unswitching is only run at -O3.

The backend was converting:

(set (cc) (compare) (foo) (bar))
(set (pc) (if_then_else) (compare (cc) (const_int 0))
(label)
(pc))

into:

(set (cc) (reversed compare) (foo) (bar))
(set (pc) (if_then_else (compare (cc) (const_int 0))
(over-label)
(pc))
(set (pc) (label))
(over-label)

That's exactly what do_compare_rtx_and_jump could do (and will often do for x86_64 floating-point jumps, but those are unswitched on the tree level).


Paolo


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