cris: Move trivially from cc0 to reg:CC model, removing most optimizations.
authorHans-Peter Nilsson <hp@axis.com>
Wed, 22 Jan 2020 04:54:15 +0000 (05:54 +0100)
committerHans-Peter Nilsson <hp@axis.com>
Sat, 9 May 2020 01:34:18 +0000 (03:34 +0200)
commitfb062a8b7bca66243d52213a897c7a241f2b14e1
treeb0244f19be34c052025f71d62aa727335759201f
parentd0780379c1b621813fbea60449bc51b65f6f8c6e
cris: Move trivially from cc0 to reg:CC model, removing most optimizations.

In the parlance of <https://gcc.gnu.org/wiki/CC0Transition>,
this is a basic "type 2" conversion, without
condition-code-related optimizations (just plain CCmode), but
with "cstore{M}4" defined.  CRIS is somewhat similar to the
m68k; most instructions affect condition-codes.  To wit, it
lacks sufficient instructions to compose an arbitrary valid
address in a register, specifically from a valid address where
involved registers have to be spilled or adjusted, without
affecting condition-codes in CRIS_CC0_REGNUM aka. dccr.

On the other hand, moving dccr to and from a stackpointer-plus-
constant-offset-address *can* be done without additional register
use, and moving to or from a general register does not affect
it.  There's no instruction to add a constant to a register or
to put a constant in a register, without affecting dccr, but
there *is* an instruction to add a register (optionally scaled)
to another without affecting dccr (i.e. "addi").  Also, moves
*to* memory from any register do not affect dccr, and likewise
between another special registers and a general register.  Maybe
some of that opens up the solution-space to a better solution
than clobbering dccr until reload_completed; to be investigated.
FAOD: I know what to do in the direction of defining and using
additional CCmodes, but prefer to do the full transition in
smaller steps.

Regarding the similarity to m68k, I didn't follow the steps of
the m68k cc0 transition, making use of the final_postscan_insn
hook as with the a NOTICE_UPDATE_CC machinery.  For one, because
it seems to be lacking in that it keeps compare-elimination
restricted to output-time, but also because it seems a bad match
considering that CRIS has delay-slots; better try to eliminate
compares earlier.  Another approach which I originally intended
to implement, that of the visium port of defining three variants
for most insns (not counting the define_subst expansions;
unaffecting-before-reload, clobbering and setting), seems
overworked and bloating the machine description.  I may be
proven wrong, but I prefer we fix gcc if some something bails on
seeing a parallel with a clobber of that specific hard-register.

Also, I chose to remove most anonymous combination-matching
patterns; matchers, splitters and peepholes instead of
converting them to add clobbers of CRIS_CC0_REGNUM.  There are
exclusions: those covered in the test-suite, if trivial enough.

Many of these patterns are used to handle the side-effect-
assignment addressing-modes as put together by combine: a
"prefix instruction" before the main instruction, where the main
instruction uses the post-incremented-register addressing-mode
and the "left-over" instruction-field in the prefixed insn to
assign a register.  An example: the hopefully descriptive
"move.d $r9,[$r0=$r1+1234]" compared to "move.d $r9,[$r1+1234]";
both formed by the prefix insn "biap.w 1234,$r1" before
respectively "move.d $r9,[$r0+]" and "move.d $r9,[$r0]".  Other
prefix variants exist.  Useful, but optional, except where
side-effect assignment was used in a special case in the
function prologue; adjusted to a less optimal combination.
Support like the function cris_side_effect_mode_ok is kept.

I intend to put back as many as I find use for, of those
anonymous patterns in a controlled manner, with self-contained
test-cases proving their usability, rather than symmetry with
other instructions and similar addressing modes, which guided
the original introduction.  I've entered pr93372 to track code
performance regressions related to this transition, with focus
on target-side causes and fixes; besides the function prologue
special-case, there were some checking presence of the bit-test
(btstq) instruction.

The now-gone "tst<mode>" patterns deserve a comment too: they
were an artefact from pre-"cbranch" era, now fully folded into
the "cmp<mode>" patterns.

I've left the now-unused "cc" insn attribute in, for the time
being; to be removed, used or transformed to be useful with
further work to fix pr93372.  It can't be used as is, because
"normal" doesn't mean "like a compare instruction" but "handled
by NOTICE_UPDATE_CC" and may in fact be reflecting e.g. reverse
operands, something that bit me during the conversion.

gcc:
Move trivially from cc0 to reg:CC model, removing most optimizations.
* config/cris/cris.md: Remove all side-effect patterns and their
splitters.  Remove most peepholes.  Add clobbers of CRIS_CC0_REGNUM
to all but post-reload control-flow and movem insns.  Remove
constraints on all modified expanders.  Remove obsoleted cc0-related
references.
(attr "cc"): Remove alternative "rev".
(mode_iterator BWDD, DI_, SI_): New.
(mode_attr sCC_destc, cmp_op1c, cmp_op2c): New.
("tst<mode>"): Remove; fold as "M" alternative into compare insn.
("mstep_shift", "mstep_mul"): Remove patterns.
("s<rcond>", "s<ocond>", "s<ncond>"): Anonymize.
* config/cris/cris.c: Change all non-condition-code,
non-control-flow emitted insns to add a parallel with clobber of
CRIS_CC0_REGNUM, mostly by changing from gen_rtx_SET with
emit_insn to use of emit_move_insn, gen_add2_insn or
cris_emit_insn, as convenient.
(cris_reg_overlap_mentioned_p)
(cris_normal_notice_update_cc, cris_notice_update_cc): Remove.
(cris_movem_load_rest_p): Don't assume all elements in a
PARALLEL are SETs.
(cris_store_multiple_op_p): Ditto.
(cris_emit_insn): New function.
* cris/cris-protos.h (cris_emit_insn): Declare.
gcc/ChangeLog
gcc/config/cris/cris-protos.h
gcc/config/cris/cris.c
gcc/config/cris/cris.h
gcc/config/cris/cris.md
gcc/config/cris/predicates.md
gcc/config/cris/sync.md