March 23, 2019
On Thursday, 21 March 2019 at 21:01:51 UTC, kinke wrote:
> I'm sure you'd be of great help. :)

Thanks :)

> Wrt. DIP1014, I tried to point out in the discussion that it probably needs a D ABI change (I know that it definitely will for LDC). We're not talking about a trivial minor adaptation, but a change affecting all non-POD arguments passed by value - don't copy in registers or on the stack anymore and let callEE destruct it, but have callER create a temporary, pass it by ref and then destruct it by callER (also when callEE throws), just like C++. As a nice side-effect, this will also fix C++ interop in this regard.

I missed that it would require an ABI changes, thanks for mentioning
this! Because of this I do not feel confrontable to try and implement
this DIP and it is probably better to focus on the bare metal runtime
topic.

> IMO, it should indeed be something like a druntime-lite without any external dependencies, and druntime build on top of it. Containing the 'absolutely essential runtime bits for the core features' (to be defined ;) - e.g., (most?) runtime functions implicitly invoked by the compiler, e.g., for array copying/initializing). As a goal, it should be fairly simple to add support for any new target, e.g., WebAssembly and a new OS like your PowerNex.

Thanks, I added these requirements to my notes.
March 23, 2019
On Thursday, 21 March 2019 at 19:50:49 UTC, Dan Printzell wrote:
> Hey everyone!
> I have been meaning to send these questions earlier, but then school happened.
>
> [...]

How about this - https://forum.dlang.org/thread/uqydrkgfqiehwugsnfxz@forum.dlang.org
March 24, 2019
On Friday, 22 March 2019 at 02:03:05 UTC, Mike Franklin wrote:
> Hi Dan,

Hey Mike,
Sorry about the late response, I had to finish a school assignment
and I wanted to really go through everything you linked.

> I've been a fan of your work, benefit greatly from your Arch Linux contributions, and admire what you've accomplished so far.  ( ̄^ ̄)ゞ  <-- That's supposed to be a salute.

Thanks :)

> # Suggestion 1 - Replace Runtime Hooks with Templates
This is something I would like to do. As this would help with both
writing a new bare metal runtime and it could help the current
druntime. I can see that this idea would probably be the easiest to
plan for as you could plan for it to be like X amount of runtime
symbols per GSoC milestone, or something simular to this.

This could be better than writing a new bare metal runtime as it would
decrease the amount of code needed to get something to at least
compile. I still have to think about if there is a smart way to allow
"druntime-lite" to be used as a foundation for druntime. Because if
the new runtime would only be a separate runtime it could become a
annoyance if you need to update two runtimes for each runtime change.

> # Suggestion 2 - Create a No-dependency D Library

One question that need to be decided for this type of library would be
where should it live inside the D ecosystem, and would this mean that
the algorithm would live in two places, one copy inside phobos and one
copy inside this library.

It would be nice to try and design a module runtime, but the question
is how this could be limited into something that I could do in about 3
months, with clearly defined milestones.

> # Suggestion 3 - Port the Entire Runtime to [...]

Yes I agree, this would require both suggestions or at least
suggestion 2. The reason why I have not ported druntime to PowerNex
yet is because I do not want to sit and add tons of stub & wrapper
functions to get it to link.

This would be a future goal and not a GSoC goal.

> # Suggestion 4 - Replace Software Building Blocks with

I guess I'm not like most (after all I'm writing my own OS from
scratch :P), because I see the value of having D implementation of all
these functions. Basically all bare metal code require these function
in one way or another. I would say that these are a requirement for a
bare metal runtime.

>

I've started to structure everything in my proposal draft to try and
get a better more clear ideas of all the ideas that have been
discussed so far. From one of your links I found this post[1] chain
which I felt gave a lot of good information when planning this
proposal, thanks for the links :).

> Let me know if you're interested in engaging with me and I'll do my best to help.  You can reach me on Slack under the handle JinShil, and I think you're clever enough to get my e-mail through the same handle at GitHub, should you choose to contact me that way.  Or we can just go nuts in this thread if you'd like.

Sure I would love to talk more about ideas. For me it doesn't really
matter where because I read / lurk basically everywhere. But maybe
better to do it here on the forum in case other people have comments
and ideas.


[1] https://forum.dlang.org/post/mvbxrrpxquvsdjfvfhkc@forum.dlang.org

March 26, 2019
On Sunday, 24 March 2019 at 23:26:05 UTC, Dan Printzell wrote:

>> # Suggestion 1 - Replace Runtime Hooks with Templates
> This is something I would like to do. As this would help with both
> writing a new bare metal runtime and it could help the current
> druntime. I can see that this idea would probably be the easiest to
> plan for as you could plan for it to be like X amount of runtime
> symbols per GSoC milestone, or something simular to this.
>
> This could be better than writing a new bare metal runtime as it would
> decrease the amount of code needed to get something to at least
> compile.

Indeed!

There are some dragons to slay, though...

1) This will require familiarizing oneself with both DMD and druntime, as both will need to be modified simultaneously.  If you intend to make pull requests to these repositories, please be aware that there currently isn't a great way to test two interdependent pull requests that reside in both DMD and druntime.  I recommend the following procedure, but there may be a better way:
  1. Add the template to druntime with unittests to verify the implementation.  This PR should be merged first.
  2. Modify DMD to lower expressions to the new template.  Assuming there is already sufficient test cases added to the test suite, this should require additional tests; the real test is to ensure nothing breaks. This PR assumes 1. is already merged.
  3. Submit a PR to druntime to remove the old runtime hook.

2) I described this in more detail in the last paragraph here (https://forum.dlang.org/post/hequvmostuhwnvcgrcge@forum.dlang.org), that the compiler is currently lying to us about `@safe`, `pure`, and `nothrow` guarantees.  When the runtime hook is converted to a template, the template will go through the semantic phase in the compiler, and the author will be forced to suddenly be honest.  It could be quite difficult to make this work without breaking code or without hackish workarounds to avoid said breakage.

As you alluded to, this can be done incrementally.  It may be too large a project to tackle all of druntime, so maybe a good GSoC project would be, for example, to just get all array features finished.

I recommend not worrying about getting things to work with -betterC at first; it just adds additional complexity and controversy.  If you can first succeed without -betterC, you can then make additional changes to make the templates work in -betterC.  If you submit PRs to druntime and DMD, this will also make the PR review go much smoother.

> I still have to think about if there is a smart way to allow
> "druntime-lite" to be used as a foundation for druntime. Because if
> the new runtime would only be a separate runtime it could become a
> annoyance if you need to update two runtimes for each runtime change.

Annoying indeed!  I don't think it's necessary to have two different runtimes with duplicate implementations in each if druntime is modularized and the dividing lines between modules are well thought out.  Having worked with DMD and druntime a little and having given this some thought over the years and recently, I'm feeling more confident in something like the following:

1) - No-dependency D library (Basically, Suggestion 2 below) -  I have more to say about this below.

2) - Level 0 druntime module(s) - Imports (1), but additionally adds compiler intrinsics and runtime features that don't require dynamic memory heap memory allocation.  I envision these runtime features to be common to both bare-metal and OS platforms.

3) - Level 1 druntime module(s) - Imports (1) and (2), but additionally adds runtime features that require dynamic heap memory allocation and potentially runtime initialization and deinitialization, which seem to currently require dynamic heap memory allocation.  This would still be quite suitable for some, if not most, bare-metal platforms.

4) - Level 2 druntime module(s) - Imports (1), (2), and (3), but finishes off the runtime with classes, GC, and threads.  This could still be used for some bare-metal platforms, but would basically require implementing a mini OS inside the runtime itself.  For OS platforms, one just needs to tie into the OS implementations as it is currently done.

There are probably hundreds of different ways to organize this.  For example, the compiler intrinsics and lowerings could be separate modules/libraries, threads and fibers could also be their own modules/libraries, etc..  The basic idea, though, is that users, and the compiler itself, can import just the language features they need or want, in a pay-as-you-go fashion.

Also, with design by introspection, even imported modules can make decisions at compile-time about what is or isn't needed as is currently done with `ModuleInfo`, `TypeInfo`, and `Throwable`.  It's important to do this tastefully, however, as it could easily turn into a monstrosity if taken too far.

This still needs a lot more thought and work, but that's where I'm currently at.  I'm just brainstorming, anyway. I'm not sure how something like this would integrate into the existing ecosystem.  A good strategy that leverages incremental change will probably find more success.  I think Suggestion 2 is a good start.  It would help set a precedent and test the palatability for more modularity in the future.

>> # Suggestion 2 - Create a No-dependency D Library
>
> One question that need to be decided for this type of library would be
> where should it live inside the D ecosystem, and would this mean that
> the algorithm would live in two places, one copy inside phobos and one
> copy inside this library.

Yes, there are definitely architectural challenges here.  And then, worst of all, you'd have to figure out what to name it.  Deimos is taken, so if my astronomy is correct, we're out of moons.

I suggest it be its own library independent from Phobos, druntime, and DMD; I think that would be the most scalable.  Phobos, druntime, and DMD could all privately import and forward to it, and users wouldn't even know anything happened.  It could also be published as a separate library on DUB for -betterC and bare-metal programmers to utilize without having to import Phobos and druntime.

DUB could actually be utilized to great effect for all of D development if it could just be made into something that the entire community could get behind.  In the end, DMD is just another D program, and Phobos and druntime are just D libraries.

> It would be nice to try and design a module runtime, but the question
> is how this could be limited into something that I could do in about 3
> months, with clearly defined milestones.

Understood.  There's an awful lot to sort out here. I suggest just focussing on few modules from Phobos and/or druntime (e.g. std.meta, std.traits, core.attribute, etc...).  Create a DUB library and GitHub repository for the GSoC project.  After GSoC keep working on it.  It will still be quite useful to -betterC and bare-metal programmers.

In the longer-term, it could eventually be integrated into the larger D ecosystem and hopefully transferred to the D Language Foundation for inclusion in Phobos, druntime, and DMD and continued maintenance.  I'm still not sure what that looks like, but regardless I think it is a worthwhile project in and of itself.

>> # Suggestion 3 - Port the Entire Runtime to [...]
>
> Yes I agree, this would require both suggestions or at least
> suggestion 2. The reason why I have not ported druntime to PowerNex
> yet is because I do not want to sit and add tons of stub & wrapper
> functions to get it to link.
>
> This would be a future goal and not a GSoC goal.

Yeah, Suggestion 1 should significantly reduce, if not eliminate, the need for all of those hacking workarounds that are currently required just to get a build.  Take a look at the changelog for 2.079, though, to see what improvements you might be able to make today to your bare-metal runtime - https://dlang.org/changelog/2.079.0.html#minimal_runtime

>> # Suggestion 4 - Replace Software Building Blocks with
>
> I guess I'm not like most (after all I'm writing my own OS from
> scratch :P), because I see the value of having D implementation of all
> these functions. Basically all bare metal code require these function
> in one way or another. I would say that these are a requirement for a
> bare metal runtime.

Good! We can continue to utilize libc's implementations, but then we don't get all of the advantages (design-by introspection, CTFE, memory safety, etc...) that could potentially improve performance and reliability of the software as a whole.  After the runtime hooks are implemented as templates, I would hope that we could one day use something like `memcpy(T)(scope T* dest, scope const T* source) @safe pure nothrow` instead of `mempcy(void* dest, const void* source, size_t n)` in druntime's implementations.

If it's not something you're interested in, I hope there are others that can see the value in such a thing and will find it to be a rewarding project for themselves.  I think it would be a great project for a newcomer to D as it doesn't require mastery of the language, and the semantics of those building-blocks are well-understood.  We won't see the benefit of using these D implementations, though, until the runtime hooks are converted to templates.


Looking forward to hearing more about whatever it is you decide.

Mike


March 28, 2019
On Tuesday, 26 March 2019 at 04:15:54 UTC, Mike Franklin wrote:
> Looking forward to hearing more about whatever it is you decide.

I decided on doing the 'replacing runtime hooks with template'
idea. After re-read everything you posted and took some time to think
about it I concluded that this is the most sane idea for the time
frame of a GSoC. I feel that this will be able to give the most
improvement to the whole language, without the possibility of creating
a library that may not be used or by trying to design a new
druntime. You can also classify this idea as a continuation of
previous work, that for example you have done, with replacing hooks
with templates.

And as you said wrapping/reimplementing the mem{cpy,set,move}
functions will make more sense to do later on when more of these
runtime hooks have been replaced with templates.

I'm currently in the process of writing the first draft of this
proposal and will post it here and on the GSoC application page, as
soon as I get it into a more finished state, which should hopefully be
later today.

- Dan
March 28, 2019
On Thursday, 28 March 2019 at 04:43:31 UTC, Dan Printzell wrote:
> On Tuesday, 26 March 2019 at 04:15:54 UTC, Mike Franklin wrote:
>> Looking forward to hearing more about whatever it is you decide.
>
> I decided on doing the 'replacing runtime hooks with template'
> idea. After re-read everything you posted and took some time to think
> about it I concluded that this is the most sane idea for the time
> frame of a GSoC.

Thumbs up!  This will be great for D in many ways.  I wish you success.  If there's anything I can do to help in any way, let me know.  My skills and resources are quite limited, but I'll do my best.

Mike


March 29, 2019
On Thursday, 28 March 2019 at 13:00:51 UTC, Mike Franklin wrote:
> Thumbs up!  This will be great for D in many ways.  I wish you success.  If there's anything I can do to help in any way, let me know.  My skills and resources are quite limited, but I'll do my best.

If you want to you (others are also welcomed) can look through
my draft to make sure I have not written anything stupid and
possibly suggest improvements.

https://docs.google.com/document/d/15ba1vC1T7n2vX8kvQVikOj1Ip1-mt-zyiEwd0OYBoQA/edit?usp=sharing

March 29, 2019
On Friday, 29 March 2019 at 15:35:10 UTC, Dan Printzell wrote:

> If you want to you (others are also welcomed) can look through
> my draft to make sure I have not written anything stupid and
> possibly suggest improvements.
>
> https://docs.google.com/document/d/15ba1vC1T7n2vX8kvQVikOj1Ip1-mt-zyiEwd0OYBoQA/edit?usp=sharing

I'm a bit rushed at the moment but this is what I have right now:

I wouldn't put too much emphasis on betterC for the following reasons.

1.  To make these templated runtime hooks work in betterC you will need to make it templates-all-the-way-down.  That can easily turn into a huge PR that turns way too much of druntime into templates, and that will significantly reduce the chance of the PR being accepted.

2.  Many of the current runtime hooks throw `Exception`s.  `Exception`s are classes, so they can't be used in betterC.  You *might* be able to work around that by replacing them with `assert`ions, but then again you need to decide if they should be `assert`ions for all builds or just betterC.  If just betterC, then you'll have to `version(SupportsExceptions)` and provide two different implementations.  I tried that and it turned into a headache especially when trying to dynamically create meaningful error messages.  I recommend saving yourself the trouble for the first round; don't worry about betterC until you get the runtime hook working with non-betterC builds.  You can revisit it with a followup PR to address betterC, after the non-betterC changes get accepted.

3.  This work has the potential to make betterC obsolete.  In general, the way betterC works, is it imports druntime, but doesn't link to it.  Users can already achieve a similar result by building and linking separately especially with the work done in 2.079.  Once all runtime hooks are replaced with templates, druntime becomes more of an "header-only" library for lack of better term.  You may be able to achieve a similar result as betterC by simply not using certain features of D.  If that day arrives, there will no longer be much of a reason for betterC.

There are other benefits beyond betterC.

1.  Lucia Cojocaru was the first to do some of this work; she did `__equals` and `__cmp`, I think.  In her presentation about it at DConf2017 (https://www.youtube.com/watch?v=endKC3fDxqs), she demonstrated a 30% increase in runtime performance.  It seems, at least to me, that we should be able to expect similar results by refactoring other runtime hooks.

2.  Once converted to templates, we then have the ability to do compile-time microoptimizations base on type, size, alignment, and potentially other information available through design-by-introspection for additional exploitation.

3.  As mentioned before, the compiler is currently bypassing all of D's compiler guarantees for `nothrow`, `@safe`, and `pure`.  This, IMO, is a bug in the compiler.  After converting runtime hooks to templates, the compiler will enforce these constraints, having the compiler automatically audit the implementation.  That may prove to find and fix bugs we aren't currently aware of, just as Walter recently found and fixed a stack corruption bug when enabling -dip1000 in Phobos.  The result is a verifiably more reliable implementation, one in which future bugs can't even be introduced because they won't build.

4.  All the information the implementations need is available at compile-time.  There is no reason to utilize runtime type information `TypeInfo`.  `TypeInfo` is a class, so the current implementation has an intrinsic dependency on classes.  Classes have an intrinsic dependency on the GC and other features.  Replacing the runtime hooks with templates that parameterize on type, remove that dependency making the runtime more pay-as-you-go for implementations, like, but not limited to, bare-metal, that don't want or don't have the resources for the runtime overhead of classes and the GC.  There still may be other classes that the implementation depends on (e.g. `Exception`s) but those dependencies could be refactored in followup PRs to completely eliminate the dependency on classes. That will bring more of D's features to the aforementioned implementations so users.  Users will have a betterD rather than a betterC.

Challenges to overcome.

1.  Because `@safe`, `nothrow`, and `pure` will suddenly be enforced, the implementation will have to be refactored to abide by the compiler's enforcement of those constraints.  Here are a few things I've learned.
  a.  You may be able to use `pureMalloc` and friends (https://github.com/dlang/druntime/blob/29f495b5b3571484bcf4d0af2fe211d6b7d86830/src/core/memory.d#L862-L891) to overcome the purity constraint.
  b.  You should be able to use `trusted` to workaround the `@safe` constraint.
  c.  You may be able to use `assert`ions instead of throwing `Exception`s to workaround the `nothrow` constraint.

I have private e-mails from Walter approving, at least superficially, these techniques should you need them to gain leverage in the review process.  It's not a guarantee, but it sounds promising.

2.  One of the things Lucia and myself have not yet done is to measure the impact of converting these runtime hooks to templates on compile-time and template bloat.  A more thorough and professional approach would be to provide data with each PR with such measurements.

That's all I have time for at the moment.  I'll make another pass later.

Mike
March 30, 2019
On Friday, 29 March 2019 at 15:35:10 UTC, Dan Printzell wrote:
> On Thursday, 28 March 2019 at 13:00:51 UTC, Mike Franklin wrote:
>> Thumbs up!  This will be great for D in many ways.  I wish you success.  If there's anything I can do to help in any way, let me know.  My skills and resources are quite limited, but I'll do my best.
>
> If you want to you (others are also welcomed) can look through
> my draft to make sure I have not written anything stupid and
> possibly suggest improvements.
>
> https://docs.google.com/document/d/15ba1vC1T7n2vX8kvQVikOj1Ip1-mt-zyiEwd0OYBoQA/edit?usp=sharing

I spent the day today trying to revive my work on `_d_arraycast` (https://github.com/dlang/dmd/pull/9516).  I have not worked on D in a while, and I didn't realize that the druntime PR (https://github.com/dlang/druntime/pull/2264) was pulled, and I closed the original DMD PR (https://github.com/dlang/dmd/pull/8531).  Since the druntime PR was merged, I think I'm on the hook to follow through and finish the job.

I encountered an interesting issue that you may encounter in the GSoC project, so beware the following.  Since the template will be processed through the semantic phase of the compiler, it will also be subject to CTFE.  That's a good thing, but with `_d_arraycast` I discovered some casts are not supported in CTFE.  The error being emitted is "reinterpreting cast from `void[]` to `Array*` is not supported in CTFE".

I'm not sure what to do about it and I asked for some ideas.  Perhaps I may be able to modify the runtime template with some `static if (__ctfe)` as a workaround.  Anyway, it will be good to be aware of this issue.  I had not previously anticipated it.

Mike
March 31, 2019
On Friday, 29 March 2019 at 15:35:10 UTC, Dan Printzell wrote:
> If you want to you (others are also welcomed) can look through
> my draft to make sure I have not written anything stupid and
> possibly suggest improvements.
>
> https://docs.google.com/document/d/15ba1vC1T7n2vX8kvQVikOj1Ip1-mt-zyiEwd0OYBoQA/edit?usp=sharing

I've been spending some time trying to think about how to articulate the benefits of this work to D, and its community.  For some reason, I'm finding it difficult to articulate, but I'll try.  Hopefully, it will help you write a stronger proposal.

Andei recently "hit the nail on the head" with this post - https://forum.dlang.org/post/q7j4sl$17pe$1@digitalmars.com

> Oh, and druntime must go.
>
> The whole distinction between the runtime library and the standard library is clowny and has more to do with poorly ported tradition from other languages, than with anything else.
>
> We need one standard library that is entirely pay-as-you-go (e.g. empty main() means no library file is ever needed for linking) and that offers an opt-in continuum.

IMO, that is *exactly* what we need.

Some of D's features are extremely powerful assets in some problem domains (e.g. PC application software, Web services, etc.), but an unfortunate liability in other problem domains (e.g. bare-metal, resource-constrained applications, etc.)  To make D scalable to all of these domains, it needs to be more pay-as-you-go and provide an opt-in continuum, as Andrei so eloquently stated.

Converting the runtime hooks to templates provides an excellent first step towards reaching that goal.  There are immediate benefits (I've already mentioned these, so sorry for the repetition.)

*  Some language features will no longer depend on `TypeInfo` (and therefore, classes, and the GC) so D will immediately become more scalable to bare-metal and other resource-constrained platforms that want features like arrays, but don't want the overhead classes and the GC (at least initially while they are bringing up a board, OS, or porting the D language to a new platform).

*  There is evidence in Lucia Cojocaru's work that this work has the potential to provide significant performance increases.

*  The new templates will finally run through the full semantic phase of the compiler enforce compiler guarantees such as memory safety, purity, etc.

*  This work makes druntime more of a "header-only" library.  This is helpful in cross-compiling scenarios (e.g. microcontroller programming) because one will not need to cross-compile the runtime ahead of time to use those D features implemented by the templates.

But the benefits will not stop there.  Once this initial work is completed it will open up new opportunities for more performance optimizations and the aforementioned pay-as-you-go, opt-in continuum for expanding D to more platforms and problem domains.

*  The new templates will allow developers to make better decisions at design-time (design by introspection) and compile-time to make additional performance optimizations to the template implementations.  I suspect significant exploitations will be discovered and implemented over time.

*  The templates can be further refactored with versioning and design by introspection to remove additional dependencies (i.e. `Exception`s).  This will further bring the aforementioned pay-as-you-go, opt-in continuum to reality.  Indirect benefits include more D features available to betterC, and consequently, more Phobos features available to betterC.  In the longer term, however, if the pay-as-you-go, opt-in continuum becomes a reality, there will no longer be any reason for betterC; one just chooses not to use the D features they're not willing to pay for.

*  With the runtime hooks converted to templates, software building blocks like `memcpy`, `memcmp`, `malloc`, etc. can be re-written in D, extending the aforementioned design by introspection, compile-time optimizations, memory safety and other compiler enforced guarantees all the way down the call stack for fine-tuned, high-performance, reliable software.  An exploration of `memcpy` in D can be found at https://github.com/JinShil/memcpyD

*  As the pay-as-you-go, opt-in continuum becomes more and more a reality, users will find D an attractive alternative for all kind of bare-metal, embedded, IoT, microcontroller, etc. problem domains competing with the likes of C and Rust that currently dominate those domains.  One of the reasons Rust is taking off in the embedded space is due to it's "minimal runtime" philosophy.  D can have that too, and converting the runtime hooks to templates is an important step in that direction.

To keep the project within scope and on schedule, I recommend a direct translation first (to whatever extent possible).  Avoid the temptation to do too much refactoring.  Remember, you can always followup with more PRs to clean things up, optimize, whatever if time and energy remain.

I hope I'm being helpful.  Keep in mind I've never participated in GSoC or anything like it.  I don't know much about writing proposals like this.  Don't feel compelled to include any of it in your proposal.

I'm also no expert with this stuff.  I'm just someone who spent some time on it in 2018.  I didn't submit many pull requests because I had to learn so much first about what needed to be done, and how.  I'm trying to pass that on to you and others.  I hope even after GSoC this kind of work will continue.

I'll take another look at your proposal in a few days, assuming you do some polishing between now and then.

Mike