D.gnu - -ffreestanding option
- Mike (45/45) May 05 2015 Iain recently asked me to let him know what might be needed for a
- Johannes Pfau (25/52) May 05 2015 Isn't this simply two ways of looking at the same thing? You want to
- Jens Bauer (9/13) May 06 2015 This is definitely a good move. :)
- Zheng (Vic) Luo (20/74) Jul 25 2018 Current implementation of compilers assumes the existence of some
- Mike Franklin (15/29) Jul 25 2018 GDC doesn't seem to be affected. See
- Zheng (Vic) Luo (9/39) Jul 25 2018 The real problem is that current D toolchain makes no promise
- Mike Franklin (5/9) Jul 25 2018 I doesn't need to be avoided. As long as you provide a proper
- Iain Buclaw (8/50) Jul 26 2018 And even if you avoid having such calls generated by the front-end,
- Iain Buclaw (6/24) Jul 26 2018 It only goes as far as not recognizing user declared functions as
Iain recently asked me to let him know what might be needed for a -ffreestanding implementation in GDC. I couldn't really give a good answer, so I tried to spend some more time thinking "What does freestanding mean in D?" It is my understanding that the -ffreestanding switch in C prevents the compiler from generating any calls to built-ins and requires only a small subset of the C standard library (https://gcc.gnu.org/onlinedocs/gcc/Standards.html). In my C/C++ embedded work, I actually don't compile with the -ffreestanding switch even though I'm building right on the metal. Rather, I create a startup file that initializes the hardware and calls main. If the compiler generates any calls to built-ins, I implement them. Typically, I need built-ins like memcpy and memset for my startup file anyway. Compiling with -ffunction-sections, -fdata-sections, and linking with --gc-sections seems to get rid of any built-ins that my code is not using. It makes me wonder, though, "What would the compiler generate for copying or comparing structs if it couldn't generate those built-ins?" In my D work, I don't have much need for the C standard library. I typically only need a few functions from it, and they are easy enough to implement in D. So, perhaps in my ignorance, I have to say that I don't need a -ffreestanding option, but I don't consider myself much of an expert in this field. If you know of a need for the -ffreestanding option, please let it be known. What I really need is more granular control of the language features, either by adding compiler switches, or delegating implementation to the runtime. My dream would be to have runtime .di files inform the compiler what the language features look like, and have the compiler use that information to generate optimized code or compiler errors if the runtime doesn't provide what everything compiler needs. At the moment, the most pressing issue for me is the phony support I have to add for TypeInfo and the removal of dead code (or lack there of) due to GCC bug 192. Some binaries I've created are so full of TypeInfo stuff that I can't even get them to fit in my MCU's flash memory for testing and debugging. Not to mention the added upload time it takes, diminishing the efficiency of my development cycle. I remember from previous discussions that there was work to be done in binutils to get better LTO and dead-code removal. I'd be interested in hearing more details about that too. Thanks for the continued support, Mike
May 05 2015
Am Tue, 05 May 2015 11:37:17 +0000 schrieb "Mike" <none none.com>:So, perhaps in my ignorance, I have to say that I don't need a -ffreestanding option, but I don't consider myself much of an expert in this field. If you know of a need for the -ffreestanding option, please let it be known. =20 What I really need is more granular control of the language features, either by adding compiler switches, or delegating implementation to the runtime. My dream would be to have runtime .di files inform the compiler what the language features look like, and have the compiler use that information to generate optimized code or compiler errors if the runtime doesn't provide what everything compiler needs.Isn't this simply two ways of looking at the same thing? You want to disable language features (I guess mostly those requiring runtime hooks), -ffreestanding disables all these features. I realize you want fine-grained control. But then: -ffreestanding: -fno-exceptions -fno-rtti -fno-gc -fno-invariants -fno-moduleinfo -fno-string-switch -fno-utf-support (foreach over utf strings) -fno-boundscheck -fno-switch-error =46rom an implementation point of view these are the same and fine-grained switches are easy to support. Access using .di is then simple to add as well. If the compiler is clever it can look if the required features/hooks are implemented. This requires some compiler work. Simpler alternative: Enum values in special d module (e.g. rt.config) enum RUNTIME_SUPPORTS_GC =3D false;=20 At the moment, the most pressing issue for me is the phony support I have to add for TypeInfo and the removal of dead code (or lack there of) due to GCC bug 192. Some binaries I've created are so full of TypeInfo stuff that I can't even get them to fit in my MCU's flash memory for testing and debugging. Not to mention the added upload time it takes, diminishing the efficiency of my development cycle.I'll implement fno-rtti next weekend. We can think about more fine-grained solutions in the future but fno-rtti should be a good start.I remember from previous discussions that there was work to be done in binutils to get better LTO and dead-code removal. I'd be interested in hearing more details about that too. =20 Thanks for the continued support, =20 Mike
May 05 2015
On Tuesday, 5 May 2015 at 17:51:51 UTC, Johannes Pfau wrote:I'll implement fno-rtti next weekend. We can think about more fine-grained solutions in the future but fno-rtti should be a good start.This is definitely a good move. :) I'm not yet ready to look at RTTI; I've not gotten through level 2 of this game yet. The next D-related thing I will look at, is trying to write an example hardware support file (or module). Nothing final, it's just to get an idea on how it can be done. But before that, I'll need to have a look at creating a new Makefile and possibly the linker-scripts.
May 06 2015
On Tuesday, 5 May 2015 at 17:51:51 UTC, Johannes Pfau wrote:Am Tue, 05 May 2015 11:37:17 +0000 schrieb "Mike" <none none.com>:Current implementation of compilers assumes the existence of some symbols from libc, which leads to an infinite loop if we want to implement primitives like "memset" with our own code because the compiler will optimize consecutive set with "memset". This suggests that we cannot write a freestanding program without supports from compiler. With "-betterC" flag, dmd/gdc/ldc also come into this issue[5], which also applies to C/C++[1] and rust [2][3][4]. It would be better to provide a standard flag like "-ffreestanding" (or -fno-builtin?) to disable such optimizations to facilitate freestanding programming instead of forcing the developers to hack around different compiler implementations, so I was wondering is there any progress on this problem? [1] https://godbolt.org/g/5gVWeN [2] https://play.rust-lang.org/?gist=64f2acafa8cec112893633a5f2e12a9a&version=stable&mode=release&edition=2015 [3] https://github.com/rust-lang/rust/issues/10116 [4] https://github.com/thestinger/rust-core#freestanding [5] https://run.dlang.io/is/nnKWnZSo, perhaps in my ignorance, I have to say that I don't need a -ffreestanding option, but I don't consider myself much of an expert in this field. If you know of a need for the -ffreestanding option, please let it be known. What I really need is more granular control of the language features, either by adding compiler switches, or delegating implementation to the runtime. My dream would be to have runtime .di files inform the compiler what the language features look like, and have the compiler use that information to generate optimized code or compiler errors if the runtime doesn't provide what everything compiler needs.Isn't this simply two ways of looking at the same thing? You want to disable language features (I guess mostly those requiring runtime hooks), -ffreestanding disables all these features. I realize you want fine-grained control. But then: -ffreestanding: -fno-exceptions -fno-rtti -fno-gc -fno-invariants -fno-moduleinfo -fno-string-switch -fno-utf-support (foreach over utf strings) -fno-boundscheck -fno-switch-error From an implementation point of view these are the same and fine-grained switches are easy to support. Access using .di is then simple to add as well. If the compiler is clever it can look if the required features/hooks are implemented. This requires some compiler work. Simpler alternative: Enum values in special d module (e.g. rt.config) enum RUNTIME_SUPPORTS_GC = false;At the moment, the most pressing issue for me is the phony support I have to add for TypeInfo and the removal of dead code (or lack there of) due to GCC bug 192. Some binaries I've created are so full of TypeInfo stuff that I can't even get them to fit in my MCU's flash memory for testing and debugging. Not to mention the added upload time it takes, diminishing the efficiency of my development cycle.I'll implement fno-rtti next weekend. We can think about more fine-grained solutions in the future but fno-rtti should be a good start.I remember from previous discussions that there was work to be done in binutils to get better LTO and dead-code removal. I'd be interested in hearing more details about that too. Thanks for the continued support, Mike
Jul 25 2018
On Wednesday, 25 July 2018 at 08:37:28 UTC, Zheng (Vic) Luo wrote:Current implementation of compilers assumes the existence of some symbols from libc, which leads to an infinite loop if we want to implement primitives like "memset" with our own code because the compiler will optimize consecutive set with "memset". This suggests that we cannot write a freestanding program without supports from compiler. With "-betterC" flag, dmd/gdc/ldc also come into this issue[5], which also applies to C/C++[1] and rust [2][3][4].GDC doesn't seem to be affected. See https://explore.dgnu.org/g/ZJVjAu i.e. no recursive calls to `memset`, but I don't know if I just got lucky with my implementation.It would be better to provide a standard flag like "-ffreestanding" (or -fno-builtin?) to disable such optimizations to facilitate freestanding programming instead of forcing the developers to hack around different compiler implementations, so I was wondering is there any progress on this problem?According to https://wiki.dlang.org/Using_GDC, `-fno-builtin` is already there. From my experience I haven't yet found a need for `-ffreestanding`, as GDC always seems to do the right thing for me. It does generate calls for `memset`, `memcmp`, etc..., but as long as I provide my own implementation with the correct symbol name as it expects (i.e. `memset` with no name mangling, a.k.a `extern(C) void* memset(void*, int, size_t)`) it seems to work fine. Mike
Jul 25 2018
On Wednesday, 25 July 2018 at 10:05:50 UTC, Mike Franklin wrote:On Wednesday, 25 July 2018 at 08:37:28 UTC, Zheng (Vic) Luo wrote:The real problem is that current D toolchain makes no promise about the generation of calls to libc: When are they called/Which subset is called/How to disable the calls? What if users embed this memset snippet in their own function? Instead of forcing developers to avoid memset-like access pattern in a freestanding environment and increasing their mental burden, a universal flags to disable these the generation of these calls will probably be a better choice.Current implementation of compilers assumes the existence of some symbols from libc, which leads to an infinite loop if we want to implement primitives like "memset" with our own code because the compiler will optimize consecutive set with "memset". This suggests that we cannot write a freestanding program without supports from compiler. With "-betterC" flag, dmd/gdc/ldc also come into this issue[5], which also applies to C/C++[1] and rust [2][3][4].GDC doesn't seem to be affected. See https://explore.dgnu.org/g/ZJVjAu i.e. no recursive calls to `memset`, but I don't know if I just got lucky with my implementation.It would be better to provide a standard flag like "-ffreestanding" (or -fno-builtin?) to disable such optimizations to facilitate freestanding programming instead of forcing the developers to hack around different compiler implementations, so I was wondering is there any progress on this problem?According to https://wiki.dlang.org/Using_GDC, `-fno-builtin` is already there. From my experience I haven't yet found a need for `-ffreestanding`, as GDC always seems to do the right thing for me. It does generate calls for `memset`, `memcmp`, etc..., but as long as I provide my own implementation with the correct symbol name as it expects (i.e. `memset` with no name mangling, a.k.a `extern(C) void* memset(void*, int, size_t)`) it seems to work fine. Mike
Jul 25 2018
On Wednesday, 25 July 2018 at 10:32:40 UTC, Zheng (Vic) Luo wrote:Instead of forcing developers to avoid memset-like access pattern in a freestanding environment and increasing their mental burden, a universal flags to disable these the generation of these calls will probably be a better choice.I doesn't need to be avoided. As long as you provide a proper implementation of `memset` you can use memset-like patterns as you wish. Mike
Jul 25 2018
On 25 July 2018 at 12:32, Zheng Luo (Vic) via D.gnu <d.gnu puremagic.com> wrote:On Wednesday, 25 July 2018 at 10:05:50 UTC, Mike Franklin wrote:And even if you avoid having such calls generated by the front-end, the gcc optimizer may decide to add calls to memset if the right pass is enabled - i.e: -ftree-loop-distribute-patterns. I think in this case, the work of providing your own implementation is so trivial in comparison to the hoops and red lines needed to go without, that it's just not worth it. Iain.On Wednesday, 25 July 2018 at 08:37:28 UTC, Zheng (Vic) Luo wrote:The real problem is that current D toolchain makes no promise about the generation of calls to libc: When are they called/Which subset is called/How to disable the calls? What if users embed this memset snippet in their own function? Instead of forcing developers to avoid memset-like access pattern in a freestanding environment and increasing their mental burden, a universal flags to disable these the generation of these calls will probably be a better choice.Current implementation of compilers assumes the existence of some symbols from libc, which leads to an infinite loop if we want to implement primitives like "memset" with our own code because the compiler will optimize consecutive set with "memset". This suggests that we cannot write a freestanding program without supports from compiler. With "-betterC" flag, dmd/gdc/ldc also come into this issue[5], which also applies to C/C++[1] and rust [2][3][4].GDC doesn't seem to be affected. See https://explore.dgnu.org/g/ZJVjAu i.e. no recursive calls to `memset`, but I don't know if I just got lucky with my implementation.It would be better to provide a standard flag like "-ffreestanding" (or -fno-builtin?) to disable such optimizations to facilitate freestanding programming instead of forcing the developers to hack around different compiler implementations, so I was wondering is there any progress on this problem?According to https://wiki.dlang.org/Using_GDC, `-fno-builtin` is already there. From my experience I haven't yet found a need for `-ffreestanding`, as GDC always seems to do the right thing for me. It does generate calls for `memset`, `memcmp`, etc..., but as long as I provide my own implementation with the correct symbol name as it expects (i.e. `memset` with no name mangling, a.k.a `extern(C) void* memset(void*, int, size_t)`) it seems to work fine. Mike
Jul 26 2018
On 25 July 2018 at 12:05, Mike Franklin via D.gnu <d.gnu puremagic.com> wrote:On Wednesday, 25 July 2018 at 08:37:28 UTC, Zheng (Vic) Luo wrote:It only goes as far as not recognizing user declared functions as being built-in. The compiler may still generate builtin calls internally, and you may explicitly call any function in the gcc.builtins module. Iain.Current implementation of compilers assumes the existence of some symbols from libc, which leads to an infinite loop if we want to implement primitives like "memset" with our own code because the compiler will optimize consecutive set with "memset". This suggests that we cannot write a freestanding program without supports from compiler. With "-betterC" flag, dmd/gdc/ldc also come into this issue[5], which also applies to C/C++[1] and rust [2][3][4].GDC doesn't seem to be affected. See https://explore.dgnu.org/g/ZJVjAu i.e. no recursive calls to `memset`, but I don't know if I just got lucky with my implementation.It would be better to provide a standard flag like "-ffreestanding" (or -fno-builtin?) to disable such optimizations to facilitate freestanding programming instead of forcing the developers to hack around different compiler implementations, so I was wondering is there any progress on this problem?According to https://wiki.dlang.org/Using_GDC, `-fno-builtin` is already there.
Jul 26 2018