Following our discussion, we were thinking that we may want two pointer types in the IR: - pointers to objects with built-in offsets (to facilitate GC) - raw pointers to anywhere in memory (ignored by GC)
However, I have been wondering how efficient this would be in terms of performance, because pointers with offsets are bigger (up to twice as big) and the offset must be considered by many instruction operating on those pointers, adding extra overhead to these instructions. There is also the issue of extra GC concerns being mixed in with the IR.
I have been thinking that instead, a better solution might be to have only two pointer types in the IR: - Pointers to the start address of an object (directly usable by GC) - Raw pointers
Instead of passing an offset along, I am thinking of simply modifying the load and store instructions to take an offset along with an object pointer. This way, the backend can generate optimized code for those cases where we want to load and store at an offset, but the IR never sees anything but pointers to the start of an object.
Code that needs to iterate over addresses in an object would simply maintain the offset on its own, in a separate temporary. In addition, this may have the benefit of allowing a simple load with a immediate offset when the offset passed is a constant value.
- Maxime