-
-
Notifications
You must be signed in to change notification settings - Fork 272
Fix issue #1712 #1718
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
base: master
Are you sure you want to change the base?
Fix issue #1712 #1718
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -143,18 +143,21 @@ bool defineAsExternallyAvailable(FuncDeclaration &fdecl) { | |
| return false; | ||
| } | ||
|
|
||
| if (fdecl.semanticRun >= PASSsemantic3) { | ||
| if ((fdecl.inlining != PINLINEalways) && fdecl.semanticRun >= PASSsemantic3) { | ||
| // If semantic analysis has come this far, the function will be defined | ||
| // elsewhere and should not get the available_externally attribute from | ||
| // here. | ||
| // here. However, pragma(inline, true) functions should remain | ||
| // defineAsExternallyAvailable candidates to fix GH #1712. | ||
| // TODO: This check prevents inlining of nested functions. | ||
| IF_LOG Logger::println("Semantic analysis already completed"); | ||
| return false; | ||
| } | ||
|
|
||
| if (alreadyOrWillBeDefined(fdecl)) { | ||
| if ((fdecl.inlining != PINLINEalways) && alreadyOrWillBeDefined(fdecl)) { | ||
| // This check is needed because of ICEs happening because of unclear issues | ||
| // upon changing the codegen order without this check. | ||
| // pragma(inline, true) functions remain defineAsExternallyAvailable | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So what this is saying then is that
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is non-singleobj compilation, because most (all?) instantiated functions are put into one module, which may be different from the callsite's module. So if alreadyOrWillBeDefined is true the function will be defined, yes, but for inlining it needs to be defined in every calling module. |
||
| // candidates to fix GH #1712. | ||
| IF_LOG Logger::println("Function will be defined later."); | ||
| return false; | ||
| } | ||
|
|
@@ -170,6 +173,7 @@ bool defineAsExternallyAvailable(FuncDeclaration &fdecl) { | |
|
|
||
| IF_LOG Logger::println("Potential inlining candidate"); | ||
|
|
||
| if (fdecl.semanticRun < PASSsemantic3) | ||
| { | ||
| IF_LOG Logger::println("Do semantic analysis"); | ||
| LOG_SCOPE | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // Test inlining related to Github issue 1712 | ||
|
|
||
| // REQUIRES: atleast_llvm307 | ||
|
|
||
| // RUN: %ldc %s -c -output-ll -O3 -of=%t.ll && FileCheck %s < %t.ll | ||
| // RUN: %ldc -O3 -run %s | ||
|
|
||
| module mod; | ||
|
|
||
| void test9785_2() | ||
| { | ||
| int j = 3; | ||
|
|
||
| void loop(scope const void function(int x) dg) | ||
| { | ||
| pragma(inline, true); | ||
| dg(++j); | ||
| } | ||
|
|
||
| static void func(int x) | ||
| { | ||
| pragma(inline, true); | ||
| assert(x == 4); | ||
| } | ||
|
|
||
| loop(&func); | ||
| } | ||
|
|
||
| void main() | ||
| { | ||
| test9785_2(); | ||
| } | ||
|
|
||
| // There was a bug where pragma(inline, true) nested functions were incorrectly emitted with `available_externally` linkage. | ||
|
|
||
| // CHECK: define | ||
| // CHECK-NOT: available_externally | ||
| // CHECK-SAME: @{{.*}}D3mod10test9785_2FZv | ||
|
|
||
| // CHECK: define | ||
| // CHECK-NOT: available_externally | ||
| // CHECK-SAME: @{{.*}}D3mod10test9785_2FZ4loopMFMxPFiZvZv | ||
|
|
||
| // CHECK: define | ||
| // CHECK-NOT: available_externally | ||
| // CHECK-SAME: @{{.*}}D3mod10test9785_2FZ4funcFiZv |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // REQUIRES: atleast_llvm307 | ||
|
|
||
| // RUN: %ldc -output-ll -od=%T -I%S -O0 -release -enable-cross-module-inlining %s %S/inputs/inlining_gh1712_string.d \ | ||
| // RUN: && FileCheck %s < %T/inlining_gh1712_originalbug.ll | ||
|
|
||
| import inputs.inlinables; | ||
|
|
||
| void main() | ||
| { | ||
| call_template_foo(1); | ||
| } | ||
|
|
||
| // Make sure that the pragma(inline, true) function `call_template_foo` is defined, and not just declared. | ||
| // When it is correctly defined, optimization (available_externally+alwaysinline) even at -O0 means that it will dissappear from IR. | ||
| // CHECK-NOT: declare {{.*}} @call_template_foo |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import inputs.inlinables; | ||
|
|
||
| void foo() | ||
| { | ||
| call_template_foo(1); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This predicate looks like a good candidate for a helper function that takes a
Dsymbol *or whatever – feeling compelled to copy-and-paste comments is probably a good indicator for that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely.