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