Thanks for your perspectives guys! Very useful!
What I am currently thinking is this:
- The most "dangerous" optimizations are those that rely on the value of the code labels.
- So, I am thinking of preventing these ones in the default list of patterns (basically, just checking if the optimization depends on a certain code label having a certain value)
- However, those optimizations might still be useful! And can be used in both ways you just suggested (either when (1) the optimizer is used to generate the output binary or an intermediate assembler file or (2) when we use it as a linter (which is the way I am using it now)).
- So, I will include a separate list of patterns that can be activated simply with the current -popatterns command line flag (alternatively, it could be the other way around, that all optimizations are generated by default, but have an separate list of patterns that prevent them, not sure what would be best ).
As for turning the optimizer into an assembler. It currently can almost already work like that. If you add "-asm " as a command line argument, it will dump the optimized assembler code there, which can then be assembled. Given all the machinery already in place in MDL, generating a binary would be trivial at this point though (I was just scared of doing it, as I never intended this to be a full assembler, but just an optimizer, hehe).
Also, btw, I just pushed a new release (alpha v0.6) with all the latest improvements, and also significantly better support for sjasm and asMSX. For example, ARTRAG's Uridium can now be parsed! (so, only Pasmo and the SDCC output do not yet have support, I might start that for the next version).
alpha v0.6: https://github.com/santiontanon/mdlz80optimizer/releases/tag...
For you to have an idea of the improvements from v0.5 to v0.6, I did a small table comparing the optimizations done with each version in a few projects: (bytes / cycles saved)
MDL version | vgmplay | metal gear | xspelunker | uridium alpha v0.5 | 43 / 188 | 53 / 260 | 21 / 116 | - / - alpha v0.6 | 38 / 198 | 89 / 383 | 38 / 178 | 80 / 631 alpha v0.6 (size) | 127 / - | 196 / - | 530 / - | 208 / -
Notice that less optimizations are done on vgmplay in 0.6 and in 0.5, but that's because there were some optimizations that were not correct before! Also, for the size-oriented optimizations I only report bytes saved. There are really just a couple of extra patterns to turn jp into jr when possible (unconditional, or conditional with c/ns/z/nz with offset in -128/127). So, the large amount of savings is just because some projects have LOTS of jp that could be jr :) So, MDL is moving in the right direction, and every week can find more and more optimizations!
I need to think more about the issue we were discussing yesterday of the "tricky" optimizations. But I now need to revise the list of patterns and see which ones can be generalized now that the language of patterns has been significantly improved!
Awesome! I confirm I tend to use JP even when JR could work
I am curious about the optimization proposed on uridium, was the result still fully working?
I will test the results from v0.6 asap
Seems amazing how a well-done peep-hole optimizer can squeeze more speed or RAM from mature developments. This tool could end up being a reference for every MSX (or Z80) programmer!
Can't see CPI listed in your optimizations listing. Have you considered the following?:
label: ... inc hl dec bc ld a,b or c jr nz,label SIZE TIMING ---- ------ JR: 6 37/32 JP: 7 35 label: ... cpi jp pe,label SIZE TIMING ---- ------ JP: 5 29
I've been using it since long time ago...
This is perfect if de is unused or if you have inc de on the same path
Nice pattern! Adding a note to my to-do list to add it! (with the notes Artrag mentions!).
As for if Uridium works afterwards, I actually had not tried! I did look to a subsample of the optimizations and all made sense to me, since I mostly use MDL as a linter.
But I just tried compiling the output that MDL generates if you ask it to just generate optimized assembler directly and for making it work, I had to "undo" 4 of the optimizations (resulting in 4 bytes less saved). This means there is a condition I missed for one particular optimization (that appeared 4 times) to be safe! After that it did work! But this is a nice test, and could be an interesting goal for version 0.7: make sure the automatically optimized code generated for those projects compiles and is still working!
Nice pattern! Adding a note to my to-do list to add it! (with the notes Artrag mentions!).
Better not! I was wrong about DE, CPI is not affecting DE at all, my memory :-)
Sorry!
http://www.z80.info/zip/z80-documented.pdf
To make you forgive my error I can only suggest this variation of the previous pattern
label:
...
dec hl
dec bc
ld a,b
or c
jr nz,label
replaced by
label:
...
cpd
jp pe,label
Also in this case DE is unaffected
Haha, it's alright, and nice! Adding this new pattern to my to-do list too to try it out!
Btw, if any of you try MDL, you will notice that it also gives some "code style warnings". Right now, those are given based on my own style (for example I warn of defining labels without colons, using unofficial z80 syntax, etc.). But they might be annoying or even offensive to other people that have a different coding style than mine haha. So, once MDL's optimizer stabilizes, I might ask for your impression on some of those code style conventions to see which warnings make sense to give.
Sure! It will be a pleasure to contribute