digitalmars.D.ldc - Cortex-M3 low level assert issue.
- Jack Applegame (33/33) May 01 2019 file test.d:
- kinke (5/8) May 02 2019 That's what -betterC is for (omit ModuleInfos, TypeInfos etc.).
- David Nadlinger (5/13) May 02 2019 True, but shouldn't gc-sections (with
- Jack Applegame (18/21) May 04 2019 ```
- kinke (3/6) May 04 2019 Thanks for noting, that's a bug, tackled in
- Jack Applegame (3/5) May 04 2019 Thanks for fixing.
- kinke (5/6) May 04 2019 This seems to be the perfectly corresponding C++ question (string
- Jack Applegame (2/9) May 05 2019 Thanks. Now I see.
- David Nadlinger (5/12) May 05 2019 Next question: How do we fix this?
- Mike Franklin (5/9) May 05 2019 Iain fixed a similar issue a few years ago. I'm not sure if it's
- David Nadlinger (7/10) May 05 2019 I haven't looked at that report in detail, but sure, making the string
- Jack Applegame (2/9) May 08 2019 How difficult to fix it? I could donate money for the work.
- kinke (4/5) May 08 2019 Should be straight-forward, but I fully agree with David and
- Jack Applegame (7/12) May 09 2019 I tried to use `lld` instead of `arm-none-eabi-ld` and got some
- kinke (4/14) May 09 2019 Ah, nice. [A non-ancient version of] gold may strip them too then
- Mike Franklin (50/65) May 02 2019 If you'd like to see a more complete cortex-m project, please see
- Mike Franklin (4/10) May 02 2019 This looks relevant:
- kinke (9/13) May 03 2019 Yep, and this for the linker cmdline:
- Mike Franklin (4/18) May 03 2019 What about `arm-none-eabi`? There's no "linux" in that triple.
- kinke (3/6) May 03 2019 Yep, just strip the `f` prefix - `ldc2 -help-hidden | grep
- Jack Applegame (10/15) May 04 2019 I'm already using `--gc-sections` flag.
file test.d: ``` module test; struct Foo { struct Bar { struct Baz { } } } void foo() { assert(0); } ``` compile and dump: ``` $ ldc2 -c -mtriple=thumb-none-linux-eabi -mcpu=cortex-m3 test.d $ arm-none-eabi-objdump -dhsS test.o > test.o.dump ``` LDC compiles `assert(0)` to `_d_assert(file, line)` call and puts file name (test.d) to section `.rodata.str1.1`: ``` Contents of section .rodata.str1.1: 0000 74657374 2e466f6f 2e426172 00746573 test.Foo.Bar.tes 0010 742e466f 6f007465 73742e64 00 t.Foo.test.d. ``` The problem is that this section also contains symbols `test.Foo.Bar` and `test.Foo`. I don't know why these symbols are needed, but they are definitely not used in the program. And because they are in the same section as `test.d`, this whole section goes into firmware. In my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.
May 01 2019
On Wednesday, 1 May 2019 at 21:55:09 UTC, Jack Applegame wrote:In my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.That's what -betterC is for (omit ModuleInfos, TypeInfos etc.). If that's not an option, you can also hack your object.d and try to remove TypeInfo, ModuleInfo etc. We also have LDC-specific pragmas wrt. this.
May 02 2019
On Thursday, 2 May 2019 at 09:24:00 UTC, kinke wrote:On Wednesday, 1 May 2019 at 21:55:09 UTC, Jack Applegame wrote:True, but shouldn't gc-sections (with llvm::TargetOptions::DataSections == true) take care of eliminating the unused strings? — DavidIn my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.That's what -betterC is for (omit ModuleInfos, TypeInfos etc.). If that's not an option, you can also hack your object.d and try to remove TypeInfo, ModuleInfo etc. We also have LDC-specific pragmas wrt. this.
May 02 2019
On Thursday, 2 May 2019 at 09:24:00 UTC, kinke wrote:If that's not an option, you can also hack your object.d and try to remove TypeInfo, ModuleInfo etc. We also have LDC-specific pragmas wrt. this.``` module test; pragma(LDC_no_moduleinfo); pragma(LDC_no_typeinfo) struct Foo { pragma(LDC_no_typeinfo) struct Bar { pragma(LDC_no_typeinfo) struct Baz { } } } void foo() { assert(0); } ``` Nothing changes.
May 04 2019
On Saturday, 4 May 2019 at 14:05:00 UTC, Jack Applegame wrote:pragma(LDC_no_typeinfo) [...] Nothing changes.Thanks for noting, that's a bug, tackled in https://github.com/ldc-developers/ldc/pull/3068.
May 04 2019
On Saturday, 4 May 2019 at 16:49:48 UTC, kinke wrote:Thanks for noting, that's a bug, tackled in https://github.com/ldc-developers/ldc/pull/3068.Thanks for fixing. And why `-data-sections` flag also doesn't change anything?
May 04 2019
On Saturday, 4 May 2019 at 18:37:40 UTC, Jack Applegame wrote:And why `-data-sections` flag also doesn't change anything?This seems to be the perfectly corresponding C++ question (string literals placed shared readonly section) with a nice answer: https://stackoverflow.com/questions/54996229/is-ffunction-sections-fdata-sections-and-gc-sections-not-working LDC emits these strings as private constants in LLVM IR.
May 04 2019
On Saturday, 4 May 2019 at 19:06:26 UTC, kinke wrote:On Saturday, 4 May 2019 at 18:37:40 UTC, Jack Applegame wrote:Thanks. Now I see.And why `-data-sections` flag also doesn't change anything?This seems to be the perfectly corresponding C++ question (string literals placed shared readonly section) with a nice answer: https://stackoverflow.com/questions/54996229/is-ffunction-sections-fdata-sections-and-gc-sections-not-working LDC emits these strings as private constants in LLVM IR.
May 05 2019
On 5 May 2019, at 8:29, Jack Applegame via digitalmars-d-ldc wrote:On Saturday, 4 May 2019 at 19:06:26 UTC, kinke wrote:Next question: How do we fix this? It seems like GCC might handle this by default: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=192 —DavidThis seems to be the perfectly corresponding C++ question (string literals placed shared readonly section) with a nice answer: https://stackoverflow.com/questions/54996229/is-ffunction-sections-fdata-sections-and-gc-sections-not-working LDC emits these strings as private constants in LLVM IR.Thanks. Now I see.
May 05 2019
On Sunday, 5 May 2019 at 15:40:58 UTC, David Nadlinger wrote:Next question: How do we fix this? It seems like GCC might handle this by default: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=192 —DavidIain fixed a similar issue a few years ago. I'm not sure if it's related or not: See the last comment here: https://issues.dlang.org/show_bug.cgi?id=14758 Mike
May 05 2019
On 5 May 2019, at 21:57, Mike Franklin via digitalmars-d-ldc wrote:Iain fixed a similar issue a few years ago. I'm not sure if it's related or not: See the last comment here: https://issues.dlang.org/show_bug.cgi?id=14758I haven't looked at that report in detail, but sure, making the string literals named symbols is a possible workaround. It would just be nice to avoid having to do that manually and instead have LLVM emit them in whatever way appropriate to get both constant merging (where applicable) and linker garbage collection. — David
May 05 2019
On Saturday, 4 May 2019 at 19:06:26 UTC, kinke wrote:On Saturday, 4 May 2019 at 18:37:40 UTC, Jack Applegame wrote:How difficult to fix it? I could donate money for the work.And why `-data-sections` flag also doesn't change anything?This seems to be the perfectly corresponding C++ question (string literals placed shared readonly section) with a nice answer: https://stackoverflow.com/questions/54996229/is-ffunction-sections-fdata-sections-and-gc-sections-not-working LDC emits these strings as private constants in LLVM IR.
May 08 2019
On Wednesday, 8 May 2019 at 09:18:23 UTC, Jack Applegame wrote:How difficult to fix it? I could donate money for the work.Should be straight-forward, but I fully agree with David and would rather have LLVM provide that functionality - maybe it already does and we just don't know about it yet. ;)
May 08 2019
On Wednesday, 8 May 2019 at 15:16:26 UTC, kinke wrote:On Wednesday, 8 May 2019 at 09:18:23 UTC, Jack Applegame wrote:I tried to use `lld` instead of `arm-none-eabi-ld` and got some interesting results. `lld` successfully removed unused string constants. I found that there is special SFH_MERGE flag. The linker should remove unused constants and merge duplicates in sections marked with this flag. But it seems that the GNU linker ignores it.How difficult to fix it? I could donate money for the work.Should be straight-forward, but I fully agree with David and would rather have LLVM provide that functionality - maybe it already does and we just don't know about it yet. ;)
May 09 2019
On Thursday, 9 May 2019 at 11:23:27 UTC, Jack Applegame wrote:I tried to use `lld` instead of `arm-none-eabi-ld` and got some interesting results. `lld` successfully removed unused string constants. I found that there is special SFH_MERGE flag. The linker should remove unused constants and merge duplicates in sections marked with this flag. But it seems that the GNU linker ignores it.Ah, nice. [A non-ancient version of] gold may strip them too then (maybe even recent version of bfd), according to this snippet from the gcc bugzilla linked above (from 2015):[...] perhaps ld's --gc-sections or new special option should just remove unused string literals from mergeable sections.I believe (I've read, but I haven't verified) that Gold already does this.
May 09 2019
On Wednesday, 1 May 2019 at 21:55:09 UTC, Jack Applegame wrote:LDC compiles `assert(0)` to `_d_assert(file, line)` call and puts file name (test.d) to section `.rodata.str1.1`: ``` Contents of section .rodata.str1.1: 0000 74657374 2e466f6f 2e426172 00746573 test.Foo.Bar.tes 0010 742e466f 6f007465 73742e64 00 t.Foo.test.d. ``` The problem is that this section also contains symbols `test.Foo.Bar` and `test.Foo`. I don't know why these symbols are needed, but they are definitely not used in the program. And because they are in the same section as `test.d`, this whole section goes into firmware. In my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.If you'd like to see a more complete cortex-m project, please see https://github.com/JinShil/stm32f42_discovery_demo You can see how I compile with ldc2 at https://github.com/JinShil/stm32f42_discovery_demo/blob/2f6419de1c30179a85c07e0bf1e3ddd026ace93c/build.d#L78-L88 The technique I use in that project is to create my own minimal runtime: https://github.com/JinShil/stm32f42_discovery_demo/tree/master/source/runtime It just contains the runtime implementations that I need; nothing more. If you want to have support for asserts, you'll have to implement the runtime hooks as shown here: https://github.com/JinShil/stm32f42_discovery_demo/blob/master/source/runtime/exception.d Note that it's ok for your .o files be full of junk. They can be stripped out at link time with the `--gc-sections` flag. Just be sure you're compiling with `-ffunction-sections` and `-fdata-sections` for `--gc-sections` to work well. Question for LDC developers: Are the above compiler flags enabled by default? How can one confirm? You can start your minimal runtime project with just an empty `object.d`: object.d ``` module object; ``` test.d ``` module test; struct Foo { struct Bar { struct Baz { } } } void foo() { assert(0); } ``` ``` ldc2 -conf= -c -mtriple=thumb-none--eabi -mcpu=cortex-m3 test.d arm-none-eabi-size test.o text data bss dec hex filename 48 0 0 48 30 test.o ``` Compare that without the object.d. When the compiler detects a local object.d file, it will use it instead of the runtime. The `-conf=` tells the compiler not to use the default configuration that imports the runtime that comes bundled with the compiler. Compile with `-v` and compare with and without the `-conf=` flag to see the difference. If this just prompts more questions, let them fly. Mike
May 02 2019
On Friday, 3 May 2019 at 03:00:43 UTC, Mike Franklin wrote:Note that it's ok for your .o files be full of junk. They can be stripped out at link time with the `--gc-sections` flag. Just be sure you're compiling with `-ffunction-sections` and `-fdata-sections` for `--gc-sections` to work well. Question for LDC developers: Are the above compiler flags enabled by default? How can one confirm?This looks relevant: https://github.com/ldc-developers/ldc/blob/c81a0c94e535c3d670a4fab7aca9b1de22c3778c/driver/targetmachine.cpp#L472-L481 Mike
May 02 2019
On Friday, 3 May 2019 at 03:18:00 UTC, Mike Franklin wrote:Yep, and this for the linker cmdline: https://github.com/ldc-developers/ldc/blob/13cc3c4ed2f4e77096313916e55ce460f9dd1ddc/driver/linker-gcc.cpp#L535-L543 So yes, these are the default settings for Linux targets (the linker-strip-dead option is enabled by default), even for debug builds. For non-Linux targets, we rely on the LLVM defaults wrt. func/data sections; --gc-section is definitely only used for Linux targets though (use `-v` in the LDC cmdline to print the linker cmdline).Question for LDC developers: Are the above compiler flags enabled by default? How can one confirm?This looks relevant: https://github.com/ldc-developers/ldc/blob/c81a0c94e535c3d670a4fab7aca9b1de22c3778c/driver/targetmachine.cpp#L472-L481
May 03 2019
On Friday, 3 May 2019 at 16:31:34 UTC, kinke wrote:On Friday, 3 May 2019 at 03:18:00 UTC, Mike Franklin wrote:What about `arm-none-eabi`? There's no "linux" in that triple. Is there any way to pass the equivalent of `-ffunction-sections` and `-fdata-sections` on the ldc2 command line?Yep, and this for the linker cmdline: https://github.com/ldc-developers/ldc/blob/13cc3c4ed2f4e77096313916e55ce460f9dd1ddc/driver/linker-gcc.cpp#L535-L543 So yes, these are the default settings for Linux targets (the linker-strip-dead option is enabled by default), even for debug builds. For non-Linux targets, we rely on the LLVM defaults wrt. func/data sections; --gc-section is definitely only used for Linux targets though (use `-v` in the LDC cmdline to print the linker cmdline).Question for LDC developers: Are the above compiler flags enabled by default? How can one confirm?This looks relevant: https://github.com/ldc-developers/ldc/blob/c81a0c94e535c3d670a4fab7aca9b1de22c3778c/driver/targetmachine.cpp#L472-L481
May 03 2019
On Saturday, 4 May 2019 at 00:51:16 UTC, Mike Franklin wrote:Is there any way to pass the equivalent of `-ffunction-sections` and `-fdata-sections` on the ldc2 command line?Yep, just strip the `f` prefix - `ldc2 -help-hidden | grep sections`
May 03 2019
On Friday, 3 May 2019 at 03:00:43 UTC, Mike Franklin wrote:Note that it's ok for your .o files be full of junk. They can be stripped out at link time with the `--gc-sections` flag. Just be sure you're compiling with `-ffunction-sections` and `-fdata-sections` for `--gc-sections` to work well.I'm already using `--gc-sections` flag. The junk gets into the same section as useful data. In this case `--gc-sections` flag doesn't help. Also `-data-sections` and `-function-sections` doesn't help too.ldc2 -conf= -c -mtriple=thumb-none--eabi -mcpu=cortex-m3 test.dWow! Result looks nice. Thanks. But unfortunately `-conf=` flag also makes impossible to use the standard library at compile time. I was also inspired by your `MMIO` library. Great idea! By the way, I personally prefer to use `interface` instead of `final abstract class`.
May 04 2019