Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 10985 - Compiler doesn't attempt to inline non-templated functions from libraries (even having the full source) #2561

Merged
merged 2 commits into from May 17, 2014

Conversation

9rnsr
Copy link
Contributor

@9rnsr 9rnsr commented Sep 16, 2013

http://d.puremagic.com/issues/show_bug.cgi?id=10985

This PR requires druntime fix: https://github.com/dlang/druntime/pull/608

Today, implicitly generated code for assertions/array-bounds-check uses ModuleInfo object.
However ModuleInfo object won't be generated if the module is not in root - even though the code in module could be directly used by template instantiation and/or inlining.

To fix the issues:

  1. Stop using ModuleInfo for assertion and array bounds check.
  2. Relax the condition for inlining, due to fix bug 10985.

During the work, I found a wrong-code [bug 11049](http://d.puremagic.com/issues/show_bug.cgi?id=11049), and this PR also fixes it.

@ibuclaw
Copy link
Member

ibuclaw commented Sep 16, 2013

+1 on removing _d_array_boundsm, _d_assertm, _d_unittestm (should these be removed from druntime too?)

-1 on slowing down compilation speed. :-)

@9rnsr
Copy link
Contributor Author

9rnsr commented Sep 16, 2013

should these be removed from druntime too?

I'm worrying that immediately removing them might break backward compatibility.

@ibuclaw
Copy link
Member

ibuclaw commented Sep 16, 2013

Ok, no problem. We don't yet ship phobos/druntime as a shared library, so I can't imagine how though.

@MartinNowak
Copy link
Member

Great to finally address this issue, thanks a lot Kenji.

I'm worrying that immediately removing them might break backward compatibility.

Let's remove them after the next release.
I usually try to keep old stuff around for a while because it's annoying to match druntime and dmd versions.
Immediately removing runtime symbols requires to rebase local dmd branches which don't have related changes and makes bisecting much harder.

@ibuclaw
Copy link
Member

ibuclaw commented Sep 16, 2013

Also +1 on code convergence (gdc has never implemented the toModuleArray methods... should get round to either supporting or removing _d_switch_errorm in the next release merge)

@ibuclaw
Copy link
Member

ibuclaw commented Sep 16, 2013

Did Walter break the testsuite again?

@ghost
Copy link

ghost commented Sep 16, 2013

@9rnsr: If the compiler can now do this analysis, could it also try and error on this code:

class C
{
    void foo() { }
    void foo() { }
}

void main() { }

This currently creates a linker error, but this should really be caught in the compiler.

@9rnsr
Copy link
Contributor Author

9rnsr commented Sep 17, 2013

Currently some issues there.

  • Out of memory error of runnable/test19.d in Win32
    Fixed by removing import of std.string.
  • Link-failures by undefined symbols
    It was the appearance of bug 9571.
    Fixed by Issue 9571 - link error due to using unique ids in anonymous funcliteral #2566, and now this PR relies on that.
  • Unittest failure of std/numeric.d(1416) in Linux 64bit codegen
    I'm still not sure the reason.
  • "corrupt or invalid COFF symbol table" error on creating druntime.lib in Win64
    Still not sure the reason, too.

@9rnsr
Copy link
Contributor Author

9rnsr commented Sep 17, 2013

this should really be caught in the compiler

@AndrejMitrovic I agree. It should be fixed in the future.

@ibuclaw
Copy link
Member

ibuclaw commented Sep 18, 2013

Currently some issues there.

I wish the best for fixing them in dmd and I'm looking forward to this. :-)

}
else
{
efilename = m->toEfilename();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generating module filename string and using the symbol causes LNK1235: corrupt or invalid COFF symbol table error on Win64 platform, but I cannot find the reason. (Maybe a bug around coff object file generation?)
@WalterBright Can you help me?

@MartinNowak
Copy link
Member

Here is a reduced test case for the std.numeric failure.

bool normalize(double[] range, double sum = 1)
{
    double s = 0;
    // Step 1: Compute sum and length of the range
    const length = range.length;
    foreach (e; range)
    {
        s += e;
    }
    // Step 2: perform normalization
    if (s == 0)
    {
        return false;
    }
    // The path most traveled
    return true;
}

This generate wrong code for s == 0. It reuses rdx where it previously loaded the content of the xmm register from the stack. You can compare the old (at line 35) and the new (at line 32) dissassembly.

If I remove the SFLexit flag from rtlsym.h it works, this seems to have some side-effect on the backend register usage.

@rainers
Copy link
Member

rainers commented Sep 21, 2013

Generating module filename string and using the symbol causes LNK1235: corrupt or invalid COFF symbol table error on Win64 platform, but I cannot find the reason. (Maybe a bug around coff object file generation?)

Maybe related to http://d.puremagic.com/issues/show_bug.cgi?id=11081. I noticed that function literals sometimes don't have a name, I guess this happens if they are created during speculative template instantiations.

@MartinNowak
Copy link
Member

Oh, I thought this was already merged. What issues still need a fix?

@9rnsr
Copy link
Contributor Author

9rnsr commented Oct 15, 2013

@dawgfoto Wrong-code bugs in some platforms is not yet fixed. Unfortunately I don't have enough time to debug it now.

@MartinNowak
Copy link
Member

@dawgfoto Wrong-code bugs in some platforms is not yet fixed. Unfortunately I don't have enough time to debug it now.

No problem, I put it on my list, but I might not find much time for it either.

@DmitryOlshansky
Copy link
Member

Pardon for nagging. Just a couple of questions:

  • What are the chances to get this in 2.065? I guess it may be disruptive.
  • Will this fix inlining of Phobos (and other libraries) for all compilers? Or is this specific fix for DMD inliner?

@MartinNowak
Copy link
Member

What are the chances to get this in 2.065? I guess it may be disruptive.

It might trigger a lot of currently hidden inline/codegen bugs.

@Safety0ff
Copy link
Contributor

The 64bit code gen errors seem to be the same ones triggered by PR #1426

@ghost
Copy link

ghost commented Mar 18, 2014

The 64bit code gen errors seem to be the same ones triggered by PR #1426

I'm glad to hear this, I thought I must have been doing something really wrong but maybe we're both running into some code that accidentally triggers this bug..

@9rnsr
Copy link
Contributor Author

9rnsr commented May 16, 2014

Fix generation of __assert, __arrayZ, and __unittest_fail. Now they are correctly generated for instantiated templates, and anymore ModuleInfo is not necessary for them.

Ready to merge.

@@ -520,7 +531,7 @@ void Module::genobjfile(bool multiobj)
elinnum = el_var(sp);
}

elem *efilename = el_ptr(toSymbol(this));
elem *efilename = toEfilename(this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep using the modulename instead of the filename?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that the issue 846 fix is unnecessary for this PR, so it is remove now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why aren't the missing assert functions a problem?
When I compile a library in release mode but do the inlining for a debug build, who is emitting the assert functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you compile the release library with -lib switch, compiler will generate and store the assert functions in the library file. In other cases, you should link debug builded library for a debug build of your application.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a note, now I'm separating issue 846 fix to #3552.

@MartinNowak
Copy link
Member

LGTM.
Do you know what resolved the wrong-code issue?

9rnsr added 2 commits May 17, 2014 15:35
This is important due to avoid out-of-memory error with `-unittest -inline`. Currently front-end inlining requires running semantic3 for all imported modules to analyze expanded function body code. By this change, we can remove the Phobos unittest analyzing cost in user application compilation.
…nctions from libraries (even having the full source)
@9rnsr
Copy link
Contributor Author

9rnsr commented May 17, 2014

Updated commits. Now this PR only fixes issue 10985.

@MartinNowak
Copy link
Member

Auto-merge toggled on

MartinNowak added a commit that referenced this pull request May 17, 2014
Issue 10985 - Compiler doesn't attempt to inline non-templated functions from libraries (even having the full source)
@MartinNowak MartinNowak merged commit c2794ce into dlang:master May 17, 2014
@9rnsr 9rnsr deleted the fix10985 branch May 18, 2014 05:03
@WalterBright
Copy link
Member

@MartinNowak I reported your bug report as https://issues.dlang.org/show_bug.cgi?id=12852

@WalterBright
Copy link
Member

Unittest failure of std/numeric.d(1416) in Linux 64bit codegen
I'm still not sure the reason.

#3624

@WalterBright
Copy link
Member

This appears to have caused regression https://issues.dlang.org/show_bug.cgi?id=13193

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants