Comments (4)
Peephole rules are always kind of a second choice.
Their advantage that they are easy to write by anyone looking at the generated asm, and thinking about what could be done better locally.
However they also have disadvantages:
- They tend to become obsolete with code generation improvements - as happened to yours
- They are somewhat of a maintenance burden
- They only improve the code locally. Example: When the peephole optimizer optimizes out the use of register A, that only helps locally. But when code generation can do without A, the register allocator knows about it and can use A for some other purpose.
Therefore, peephole rules only tend to get used when an optimization
- Would be not that easy to do in a different stage of the compiler
- Is important enough (e.g. requested by SDCC users)
SDCC is sometimes a bit inefficient when handling pointers (and aggregates and unions, which are implemented via pointers), and it shows here:
The portable code without __at is formally a pointer access. And even at code generation, three iCodes are there, one to load from address 0x500f (and store into a temporary), one to xor a temporary with #0x10, and one to store the temporary to address 0x500f.
When using __at, there is only one iCode: xor the global variable named PD_ODR with #0x10. Then code generation can use bcpl (and the linker is responsible for placing PD_ODR at 0x500f).
Philipp
from stm8-bare-min.
Hey Philipp, thanks a lot for letting me know - I've updated the rules. Out of curiosity: is there a particular reason why something like this wasn't done in the default peephole rules?
Oh, and thank you for the tip: initially I wanted to declare registers this way but thought that it won't make a difference since __sfr
keyword was not implemented in STM8 port. I wasn't aware that it could affect code optimization.
from stm8-bare-min.
Any interest in a patch to use the __at() declarations instead of the SFR defines?
Also, in the code:
#define _MEM_(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_(mem_addr) (*(volatile uint8_t *)((mem_addr)))
why do we need both, the only difference being the extra parens around mem_addr?
from stm8-bare-min.
Initially, the idea was to have SFR defined for each compiler, since __at is an SDCC-specific attribute and I wanted to keep the header portable. MEM is just a general-purpose macro for byte-access to memory - in this case the only difference is code readability.
from stm8-bare-min.
Related Issues (6)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from stm8-bare-min.