Find branches which can be eliminated by using cmov and do so.
We do this by looking for control flow splits where both branches
are only doing assignments. If these can reasonably
be translated into one block using cmovs then do so.
For this we introduce a new Cmm Node CmmCondAssign.
- The condition expression
- A list of registers and the expressions they should be assigned for each branch.
- We maintain the invarant that when doing the assignments in sequence that there can be no true dependency.
This is not finished yet. Among other things:
- This was only test on x64, and probably also only works there. So I still have to add checks for other platforms and implement codeGen for llvm.
- There is still tracing code in here.
- This was written with compiler performance at most being an afterthought. So I expect compiler performance to suffer somewhat.
- We might limit cmov transformation to fewer cases than neccesary.
- In particular we only allow non floating point comparisons as the condition. (To avoid the unordered number nastiness)
- We don't limit the length of the branchs which we probably should. At some point calculating more expression will be more expensive than the occasional pipeline stall.
- We don't take advantage of the fact that cmov can take a memory operand.