www.digitalmars.com         C & C++   DMDScript  

D.gnu - Cross-module inlining

reply Johannes Pfau <nospam example.com> writes:
Has anybody had a closer look at cross-module inlining?
What exactly is necessary to get it working and how difficult would it
be to implement?

AFAICS
* We'd need to do semantic3 on all imported modules
* We'd have to call (a modified) toObjfile on all functions from
  imported modules

However, we of course can't emit the functions so could we mark them
as EXTERN? I've also tried to do that, but in non-toy examples
GDC always crashes somewhere. Do we also need to call toObjfile for
variables, classes, etc used in these functions (of course somehow
without emitting symbols)?

All in all this seems to be a complicated task, correct?
Nov 26 2014
parent reply "Iain Buclaw via D.gnu" <d.gnu puremagic.com> writes:
On 26 November 2014 at 15:40, Johannes Pfau via D.gnu
<d.gnu puremagic.com> wrote:
 Has anybody had a closer look at cross-module inlining?
 What exactly is necessary to get it working and how difficult would it
 be to implement?

 AFAICS
 * We'd need to do semantic3 on all imported modules
 * We'd have to call (a modified) toObjfile on all functions from
   imported modules

 However, we of course can't emit the functions so could we mark them
 as EXTERN? I've also tried to do that, but in non-toy examples
 GDC always crashes somewhere. Do we also need to call toObjfile for
 variables, classes, etc used in these functions (of course somehow
 without emitting symbols)?

 All in all this seems to be a complicated task, correct?
As best as I can explain it: - Inlining never occurs because there is no body (that has been converted to gcc). - The front-end knows the body, however semantic3 pass must be ran before attempting inline (in the front-end). - toObjFile performs the entire compilation in one swoop; generate body, add to cgraph/global decls and send to backend to compile. I'm not sure of where you are getting the ICE/crash, but there is one or two scenarios: 1) We only need the tree body to be available. For inlining to occur, we only need part of what toObjFile already does for us. Yes, generate the body, no do not add to the global decls/perform any finalisation for us. We should not need to explicitly mark the function as EXTERN as it has been defined (it has a body). But by not emitting the function to the backend, guarantees that the function won't appear in assembly. 2) We need the body to be gimplified. This is trickier. Hopefully the gcc inline pass will do the gimplification for us. But if that is not the case, then we are going to have to go about marking the function as EXTERN INLINE, send it to the backend for compilation - complicating our codegen routines in the process.
Nov 26 2014
next sibling parent Johannes Pfau <nospam example.com> writes:
Am Wed, 26 Nov 2014 17:19:25 +0000
schrieb "Iain Buclaw via D.gnu" <d.gnu puremagic.com>:

 On 26 November 2014 at 15:40, Johannes Pfau via D.gnu
 <d.gnu puremagic.com> wrote:
 Has anybody had a closer look at cross-module inlining?
 What exactly is necessary to get it working and how difficult would
 it be to implement?

 AFAICS
 * We'd need to do semantic3 on all imported modules
 * We'd have to call (a modified) toObjfile on all functions from
   imported modules

 However, we of course can't emit the functions so could we mark them
 as EXTERN? I've also tried to do that, but in non-toy examples
 GDC always crashes somewhere. Do we also need to call toObjfile for
 variables, classes, etc used in these functions (of course somehow
 without emitting symbols)?

 All in all this seems to be a complicated task, correct?
As best as I can explain it: - Inlining never occurs because there is no body (that has been converted to gcc). - The front-end knows the body, however semantic3 pass must be ran before attempting inline (in the front-end).
Calling semantic3 on all modules (like dmd does here: https://github.com/D-Programming-Language/dmd/commit/9cf4601702e24250dff3a61b510bae30a12eb8ae) currently causes infinite memory allocation with some testcases (runnable/test19.d). I guess we can't do this with the 2.065 frontend. The dmd changes were first in 2.066.
Nov 30 2014
prev sibling parent Johannes Pfau <nospam example.com> writes:
Am Wed, 26 Nov 2014 17:19:25 +0000
schrieb "Iain Buclaw via D.gnu" <d.gnu puremagic.com>:

 On 26 November 2014 at 15:40, Johannes Pfau via D.gnu
 <d.gnu puremagic.com> wrote:
 Has anybody had a closer look at cross-module inlining?
 What exactly is necessary to get it working and how difficult would
 it be to implement?

 AFAICS
 * We'd need to do semantic3 on all imported modules
 * We'd have to call (a modified) toObjfile on all functions from
   imported modules

 However, we of course can't emit the functions so could we mark them
 as EXTERN? I've also tried to do that, but in non-toy examples
 GDC always crashes somewhere. Do we also need to call toObjfile for
 variables, classes, etc used in these functions (of course somehow
 without emitting symbols)?

 All in all this seems to be a complicated task, correct?
As best as I can explain it: - Inlining never occurs because there is no body (that has been converted to gcc). - The front-end knows the body, however semantic3 pass must be ran before attempting inline (in the front-end). - toObjFile performs the entire compilation in one swoop; generate body, add to cgraph/global decls and send to backend to compile. I'm not sure of where you are getting the ICE/crash, but there is one or two scenarios: 1) We only need the tree body to be available. For inlining to occur, we only need part of what toObjFile already does for us. Yes, generate the body, no do not add to the global decls/perform any finalisation for us. We should not need to explicitly mark the function as EXTERN as it has been defined (it has a body). But by not emitting the function to the backend, guarantees that the function won't appear in assembly. 2) We need the body to be gimplified. This is trickier. Hopefully the gcc inline pass will do the gimplification for us. But if that is not the case, then we are going to have to go about marking the function as EXTERN INLINE, send it to the backend for compilation - complicating our codegen routines in the process.
OK, we do have to call cgraph_node::finalize_function. And from tree.h: Note that this does not necessarily imply the entity represented by NODE has no program source-level definition in this translation unit. For example, for a FUNCTION_DECL, DECL_SAVED_TREE may be non-NULL and DECL_EXTERNAL may be true simultaneously; that can be the case for a C99 "extern inline" function. */ #define DECL_EXTERNAL(NODE) Here's a first try: https://github.com/jpf91/GDC/commit/919efaa2246e2f56a021f57b0991476f82c8eee5 If you see some obvious problems, please comment ;-) This is good enough for simple test cases, however, even importing std.stdio crashes somewhere in the mangle code. Maybe I'll have to do some of the checks in output_declaration_p for inlining as well.
Dec 01 2014