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: A plan for eliminating cc0


OK, here is a different approach toward eliminating cc0, based on a
combination of my earlier proposal and what Alex described.  I'm
looking for comments from anybody.

1) Modify the programs which read the .md file to look for an
   attribute named clobbercc.  If such an attribute exists, then for
   any instruction pattern which defines clobbercc as "yes" (or
   "true", or whatever), automatically add "(clobber (reg:CC CC_REG))"
   to the instruction.

2) Modify the programs which read the .md file to look for
   instructions which set cc0 and instructions which use cc0.  If
   CC_REG is defined for the backend, then for each such instruction:

   2a) Rewrite the instruction to change (cc0) to (reg:CC CC_REG).

   2b) Rewrite the condition such that the instruction is only
       recognized before the cc0 collapse pass and after reload.

   For each pair of cc0 setting instruction and cc0 using instruction:

   2c) Define a new instruction which combines the cc0 set and cc0 use
       into a single combined instruction which does not refer to cc0
       or CC_REG at all.  This is done by mechanically replacing (cc0)
       in the cc0 using instruction with the source of the set of
       (cc0) in the cc0 setting instruction.  (Cases in which cc0 is
       used more than once, or is not simply set, will most likely
       require manual intervention; I don't know how many such cases
       exist).  This instruction will only be recognized after (and
       during) the cc0 collapse pass and before (and during) reload.

   2d) Define a splitter for this new instruction, to be run after
       reload, which splits the combined instruction into the two
       original instructions.

3) Write a new CC0 collapse pass.  This pass is run immediately after
   RTL expansion.  It walks the instruction stream looking for
   instructions which set and use CC_REG.  At this point these
   instructions will always be adjacent.  The pass combines them into
   the combined instruction defined in step 2c above.

4) For each target which uses cc0:

   4a) Define the clobbercc attribute to be "yes" for each insn which
       changes the condition codes unpredictably.  Typically the
       default would be "yes", and then either clobbercc would be
       defined to use cond to select instruction for which it should
       be "no", or those instructions would be marked specifically.

   4b) For insn patterns for which some alternatives clobber CC and
       some do not, split the instruction after reload into one
       variant which clobbers the CC and one variant which does not.
       Or just write different patterns which are only recognized
       after reload.

   4c) Define CC_REG as a new register which accept CCmode values, and
       update the appropriate macros and hooks.

At this point we have eliminated cc0 for the target.  The .md file
still refers to it, but all such references are translated to refer to
CC_REG in the code which the compiler sees.  After reload, the
instructions which use CC_REG are split into instructions which set
CC_REG and instruction which use CC_REG.  These instructions will be
kept as close as they need to be, because most other instructions will
clobber CC_REG.  The generated code should be correct.  However, the
generated code will not be as good, because there will be unnecessary
comparison instructions.

(A note for the uninitiated.  We need to combine the instructions
which set and use CC_REG into a single instruction which is split
after reload because reload has to be able to move values in and out
of memory, and compute addresses, between arbitrary pairs of
instructions.  On cc0 machines, those moves and computations will
themselves change the condition codes, and we will wind up testing the
wrong conditions in the branch instruction.  So reload has to see
set-and-use-cc0 as a single instruction.)

5) Write a new optimization pass enabled on targets which define
   NOTICE_UPDATE_CC.  I think this pass would be run just before
   machine dependent reorg, although perhaps there is a better place
   for it.  Walk through the instructions, calling NOTICE_UPDATE_CC on
   each one.  When we find an instruction which sets CC_REG, check the
   source of the set with the current CC status, just as
   final_scan_insn does now.  If the current CC status is the same,
   delete the instruction which sets CC_REG.

At this point, the generated code quality should be approximately the
same as when the target used cc0.

6) When all targets have been converted, remove all the code in the
   compiler protected by #ifdef HAVE_cc0.  Remove the CC_SETTER and
   CC_USER register notes.  Remove the associated documentation.

7) Profit!


I want to stress that that this approach is intended to permit
reasonably simple elimination of cc0 for all targets.  It does not
preclude any particular target from using a different approach.

In particular, the main oddity here is clobbercc.  Any particular
target can do a more accurate representation of the way any particular
instruction affects the condition codes.  The only important
characteristic that must be retained is that every instruction which
changes the condition codes must indicate that after reload.  There is
nothing which precludes a target from using clobbercc at first, and
then using a more sophisticated representation later.

I don't think that a more accurate representation will help very much
without a lot more work, because the optimizers won't really be able
to use the better representation until after reload, and we don't do
very much optimization after reload.  Specifically, I don't think a
better representation will improve very much on the proposed
NOTICE_UPDATE_CC optimization pass.  But nothing in what I am
suggesting precludes following this path.

Ian


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