On 13/11/20 1:34 AM, Richard Sandiford wrote:
> Chung-Lin Tang <clt...@codesourcery.com> writes:
>>>> +;;  Integer logical Operations
>>>> +
>>>> +(define_code_iterator LOGICAL [and ior xor])
>>>> +(define_code_attr logical_asm [(and "and") (ior "or") (xor "xor")])
>>>> +
>>>> +(define_insn "<code>si3"
>>>> +  [(set (match_operand:SI 0 "register_operand"             "=r,r,r")
>>>> +        (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r,r")
>>>> +                    (match_operand:SI 2 "logical_operand"  "rM,J,K")))]
>>>> +  ""
>>>> +  "@
>>>> +    <logical_asm>\\t%0, %1, %z2
>>>> +    <logical_asm>%i2\\t%0, %1, %2
>>>> +    <logical_asm>h%i2\\t%0, %1, %U2"
>>>> +  [(set_attr "type" "alu")])
>>>> +
>>>> +(define_insn "*norsi3"
>>>> +  [(set (match_operand:SI 0 "register_operand"                  "=r")
>>>> +        (and:SI (not:SI (match_operand:SI 1 "register_operand"  "%r"))
>>>> +                (not:SI (match_operand:SI 2 "reg_or_0_operand"  "rM"))))]
>>>> +  ""
>>>> +  "nor\\t%0, %1, %z2"
>>>> +  [(set_attr "type" "alu")])
>>>
>>> M constraints (for const0_rtx) and reg_or_0 seem unnecessary, no such
>>> RTL should make it to this point.
>>
>> Such RTL does appear under -O0. Removing the 'M' will also
>> require a bit of re-working the operand printing mechanics; not a lot of
>> work, but I'd rather keep it as is. The behavior of using the zero
>> register for a 0-value is also more expected in nios2, I think.

Will any RTL-level passes, say for example, propagate a zero-constant
into the pattern, without also simplifying it to a NOT pattern? (that's
a question, I don't really know)

Personally, I haven't really seen many cases optimizable to NOR, but I
think keeping the 'M' there is pretty harmless.

> Hmm, but if we get (not (const_int 0)) then that sounds like a bug,
> since (and (not X) (not (const_int 0))) should reduce to (not X).
> IMO target-independent code shouldn't try to create the nor-with-0
> form and backends shouldn't match it.
> 
> Why would removing 'M' affect the printing mechanism?  Naively I'd
> have expected:

The *norsi3 here is of course straightforward. I was referring to other
cases, like the AND/IOR/XOR pattern above, where I wanted to combine
them into a single alternative. That needs a bit more work to reorganize
the nios2_print_operand() cases.

> (define_insn "*norsi3"
>   [(set (match_operand:SI 0 "register_operand"                  "=r")
>         (and:SI (not:SI (match_operand:SI 1 "register_operand"  "r"))
>                 (not:SI (match_operand:SI 2 "register_operand"  "r"))))]
>   ""
>   "nor\\t%0, %1, %2"
>   [(set_attr "type" "alu")])
> 
> to just work.

That will definitely work, though I don't think the zero case does any harm.

>>>> +;; Integer comparisons
>>>> +
>>>> +(define_code_iterator EQNE [eq ne])
>>>> +(define_insn "nios2_cmp<code>"
>>>> +  [(set (match_operand:SI 0 "register_operand"           "=r")
>>>> +        (EQNE:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
>>>> +                 (match_operand:SI 2 "arith_operand"     "rI")))]
>>>> +  ""
>>>> +  "cmp<code>%i2\\t%0, %z1, %z2"
>>>> +  [(set_attr "type" "alu")])
>>>
>>> Once again, using reg_or_0 and "M" seems pointless.
>>
>> The compares don't support all operations, with only the second operand
>> capable of an immediate. Using 'rM' should theoretically allow more
>> commutative swapping.
> 
> But rtl-wise, we should never generate an EQ or NE with two constants.
> And if one operand is constant then it's supposed to be the second.
> 
> The "%" should give commutativity on its own, without the "M".

For EQ/NE I guess that's the case, for the other comparisons I'm not so
sure; I'm not familiar enough with the details of the expander machinery
to claim anything.

If this doesn't carry to other comparisons, I intend to keep it in line
with the other cmp patterns. I experimented a bit with the generated
code, nothing is affected.

>>>> +      emit_insn
>>>> +  (gen_rtx_SET (Pmode, tmp,
>>>> +                gen_int_mode (cfun->machine->save_regs_offset,
>>>> +                              Pmode)));
>>>
>>> Shouldn't have a mode on the SET, but really should just call
>>> emit_move_insn. Similar cases elsewhere, search for "gen_rtx_SET (Pmode".
>>
>> I've removed the modes on SET, though I prefer the more bare generation
>> of the insns in some contexts; emit_move_insn() seems to have a lot
>> under the hood.
> 
> There shouldn't be anything to be afraid of though.  Target-independent
> code would use emit_move_insn for this though, so it needs to just work.

It will work, and I did use it in some places, though I did not
exhaustively search-and-replace.

For (subtle) performance reasons, emit_move_insn() really does too much
as a backend utility. Usually backend code is already very precise on
what we want to generate.

>>>> +  HOST_WIDE_INT var_size;       /* # of var. bytes allocated.  */
>>>
>>> Not the first time they occur in this file, but I suppose I should
>>> mention that these in-line comments are probably just outside our coding
>>> guidelines.
>>
>> Deleted the comments outside the struct defs.
> 
> FWIW, I think it was more that comments should be above the field rather
> than tagged on the right.  (One of the big problems with right-column comments
> is that people tend to make them too short.)

I will change to use the over-the-top style in the final patch.

Thanks,
Chung-Lin

Reply via email to