> Combiner is an older approach of code selection. Combine can be considered both as code selection or optimization. Likewise, CSE. In many cases, especially now that we have the tree optimizers, CSE does more code selection (best choice of operand) than CSE. So you could say that CSE and Combine are, in some sense, doing the same thing but with different data structures.
Well before GCC 4.x there was an attempt that a few of us worked on to try to move the algebraic simplifications from combine to simplify-rtx.c, just like we put tree folding in fold-const.c. At that point, combine just becomes "bookkeeping". The problem with that approach was what to do with such things as nonzero_bits and num sign bit copies. But if those (and more!) become part of a global DF infrastructure, then they are available in *all* RTL passes. Next, one can finish the task of moving the simplifications to simplify-rtx.c (since the global information will always be around) and much of the rest of combine is replaced by the incremental update part of DF. That means we could merge CSE and combine and do a *lot* more than we ever were able to do before while having the code for both passes be much simpler.