I think that maintaining all those lists is a work itself... I would only support size and speed
I don't see the maintenance cost... it is just a matter of splitting the current file into several ones and provides a default set if the user doesn't specify one...
Undocumented instructions are now a day documented, there is no reason to exclude them
Some people may prefer not to use undocumented instructions (e.g.: mzoran in the previous comment). With multiple pattern files, you get the ability to enable/disable this with no cost.
Moreover having multiple files it does not solve the fact that you have one code sequence that can match multiple patterns. Consider this (...)
Every pattern+constraints should appear only once per file.
There are three scenarios in your example: BC is in use, DE is in use, both BC and DE are in use. The first ones can be solved by choosing the shortest/fastest optimization (the one without PUSH/PO). For the latter, I don't mind if the optimizer chooses PUSH/BC/POP or PUSH/DE/POP; utimately, I would consider one of the patterns is redundant *
* unless if choosing BC or DE affects the constraints of a previous pattern and then it should be choosen to allow better optimizations in the other pattern, but that's a different beast!!!
Where can i find a list of undocumented instructions (I actually know and use only ld a,ixl ld a,ixh ld a, iyl ld a, iyh). I'm intersted on this topic and wanna know more (so I need something to read/try). And Santi can your optimization patterns be seen on Github? Is there a proper link to them?
Wow, thanks for all the discussion! Very interesting! At work right now, so, I might need to think a bit more about these. But here's some quick reactions
- About prioritizing optimizations: Good point @ARTRAG, I am going to make a not about this (prioritizing optimizations that achieve highest savings) in my to-do list to experiment with some possibilities for this and see what works/doesn't work!
- About missing colon warnings: I think you are right @mzoran, I added the "colon" warning because labels without colons lead to a lot of ambiguous parsing situations, so they are dangerous. But I understand that each one has a different coding style. I will make that off by default.
- About the unofficial op syntax: MDL only warns when you use an unofficial way of writing an instruction, e.g. "add 1" instead of "add a,1". But that is different from "undocumented instructions". All undocumented instructions are supported, optimizations can indeed contain them, and there is no warning for these.
- @mzoran, if you want to stop an optimization from happening / being suggested. You can add a commend with this directive in any line: mdl:no-opt. For example:
nop ; mdl:no-opt
- @mzoran, I totally agree about those "LD L, lower byte of (label)" optimizations. I myself feel very uncomfortable actually making those changes. These optimizations are useful once a project is completely finished and will not change in the future. But it's dangerous to change them in early stages, as labels might change.
- I think I like @theNestruo idea of multiple pattern files (There are currently already 3 pattern files, the default one, and then one for size-only oriented optimizations and another for speed-only oriented optimizations). Maintaining different ones might indeed be complicated. So, what I did to make this easier is to allow "include" statements in the pattern files. So, for example the current "size" and "speed" files start with an "include" of the base patterns, and then just define speed and size specific patterns. So, we might want to have a few base files, and then compose others by including the previous ones. Also, right now there is a "-popatterns " flag. But that might be a bit obscure. So, I like the idea of having a few predefined ones that you can activate just by doing "-po speed" for example!
- @thegeps, indeed! the patterns are in GitHub. The file "pbo-patterns.txt" is the default set of patterns (you'll see there's two others, once for speed, one for size), and can be found here: https://github.com/santiontanon/mdlz80optimizer/tree/master/...
- @thegeps As for undocumented opcodes, check this one out: http://www.z80.info/zip/z80-documented.pdf
thank you so much as always, Santi! Just added both links to my favourites!
I'm not completely sure that for the case above priorities are the best solution
For the specific situation above you could improve the sintax of the parser to admit different options of replacement for a given pattern according to the use of auxiliary registers
- @mzoran, I totally agree about those "LD L, lower byte of (label)" optimizations. I myself feel very uncomfortable actually making those changes. These optimizations are useful once a project is completely finished and will not change in the future. But it's dangerous to change them in early stages, as labels might change.
This is indeed the reason why I said earlier that the optimizer should be used to produce a binary, either directly (acting as an assembler) or indirectly (acting as a preprocessor). If used as a linter, in many, perhaps most cases you don't want to apply the suggested optimizations because of code clarity. This argument applies to many of the optimizations, like jp -> jr (what if the code in between gets big enough?), cp 1 -> dec a (especially if the 1 is actually a label that can change later), etc.
As for size vs speed, I think the programmer should be able to specify how to optimize certain sections of the code; e.g. code that will execute only rarely, could be optimized for size, while code in a critical path could be optimized for speed.
@ARTRAG: Yes, I need to think about a good solution for this type of situation. Right now, what I have been doing is to place the "preferred" patterns (in your example, the ones without push/pop) earlier in the file, so they will match first. But that can become cumbersome to maintain very quickly. Right now there are over 100 patterns, and it is already becoming difficult for me to even remember which patterns are already there and which are not...
So, probably generalizing the pattern-definition language to merge those that have the same "pattern" but different "replacements" based on the constraints as you suggest would be a good idea to make it more manageable. I will have to start classifying them into categories at some point as well, so it's easy to find if one is there or not
@pgimeno: my take on this is that I would like to support different ways to use MDL. I like using it as a linter when I code (I have been using it over the past few weeks already, and it's pretty nice to hit "command+B" in Sublime every once in a while and get a few optimization recommendations (which some times I follow, some times I ignore, haha). This is the main mode I have been using it. But I have also been trying to support the "use it to generate a binary" use case. Right now, MDL cannot generate binaries itself (although it would not be too hard at this point actually). But can generate code already optimized (with the "-asm" flag), that can then be assembled into a binary with a separate assembler. Not sure if this is easy to use for others. So, I might consider generating binaries in the future. But I don't think MDL is robust enough at this point as for me trusting it in generating a binary haha. Maybe in a few more versions
Where can i find a list of undocumented instructions (I actually know and use only ld a,ixl ld a,ixh ld a, iyl ld a, iyh).
I find this condensed table-version very handy: http://clrhome.org/table/
(the timing is original Zilog Z80 timing, like used in ZX Spectrum or TI calculators, for MSX you need to add extra cycles for memory fetches, quick google found page done by this forum member and "glass" assembler author, describing the difference: http://map.grauw.nl/resources/z80instr.php )
SDCC support requested on github
Yes! I will prioritize it! In the past few days I have just been working in improving my internal testing pipeline for MDL, to make sure it becomes more and more robust. I have a few more ideas for improving the pattern definition based on the discussion above, and after that I'll start adding support for SDCC!