summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2017-11-02 21:55:40 +0000
committerDavid Blaikie <dblaikie@gmail.com>2017-11-02 21:55:40 +0000
commit08267297931ca6138f0545c5ea8c8178c5d485be (patch)
treebd9320174e93e1b01f216c7baf95e797ee18953d
parent4b3289e84f4f816ee084b4849c7f7ba4c1656352 (diff)
downloadbcm5719-llvm-08267297931ca6138f0545c5ea8c8178c5d485be.tar.gz
bcm5719-llvm-08267297931ca6138f0545c5ea8c8178c5d485be.zip
Modular Codegen: Don't home/modularize static functions in headers
Consistent with various workarounds in the backwards compatible modules that allow static functions in headers to exist, be deduplicated to some degree, and not generally fail right out of the gate... do the same with modular codegen as there are enough cases (including in libstdc++ and in LLVM itself - though I cleaned up the easy ones) that it's worth supporting as a migration/backcompat step. Simply create a separate, internal linkage function in each object that needs it. If an available_externally/modularized function references a static function, but the modularized function is eventually dropped and not inlined, the static function will be dropped as unreferenced. llvm-svn: 317274
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp25
-rw-r--r--clang/test/Modules/codegen-opt.test12
2 files changed, 25 insertions, 12 deletions
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 803795887c9..bf34d01751c 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -2258,15 +2258,22 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
assert(FD->doesThisDeclarationHaveABody());
bool ModulesCodegen = false;
if (Writer->WritingModule && !FD->isDependentContext()) {
- // Under -fmodules-codegen, codegen is performed for all defined functions.
- // When building a C++ Modules TS module interface unit, a strong definition
- // in the module interface is provided by the compilation of that module
- // interface unit, not by its users. (Inline functions are still emitted
- // in module users.)
- ModulesCodegen =
- Writer->Context->getLangOpts().ModulesCodegen ||
- (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit &&
- Writer->Context->GetGVALinkageForFunction(FD) == GVA_StrongExternal);
+ Optional<GVALinkage> Linkage;
+ if (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) {
+ // When building a C++ Modules TS module interface unit, a strong
+ // definition in the module interface is provided by the compilation of
+ // that module interface unit, not by its users. (Inline functions are
+ // still emitted in module users.)
+ Linkage = Writer->Context->GetGVALinkageForFunction(FD);
+ ModulesCodegen = *Linkage == GVA_StrongExternal;
+ }
+ if (Writer->Context->getLangOpts().ModulesCodegen) {
+ // Under -fmodules-codegen, codegen is performed for all non-internal,
+ // non-always_inline functions.
+ if (!Linkage)
+ Linkage = Writer->Context->GetGVALinkageForFunction(FD);
+ ModulesCodegen = *Linkage != GVA_Internal;
+ }
}
Record->push_back(ModulesCodegen);
if (ModulesCodegen)
diff --git a/clang/test/Modules/codegen-opt.test b/clang/test/Modules/codegen-opt.test
index 2f4997a7c73..f62cf38a535 100644
--- a/clang/test/Modules/codegen-opt.test
+++ b/clang/test/Modules/codegen-opt.test
@@ -25,7 +25,13 @@ FOO-NOT: {{define|declare}}
FOO: declare void @_Z2f1Ri(i32*
FOO-NOT: {{define|declare}}
-FIXME: this internal function should be weak_odr, comdat, and with a new mangling
+Internal functions are not modularly code generated - they are
+internal wherever they're used. This might not be ideal, but
+continues to workaround/support some oddities that backwards
+compatible modules have seen and supported in the wild. To remove
+the duplication here, the internal functions would need to be
+promoted to weak_odr, placed in comdat and given a new mangling -
+this would be needed for the C++ Modules TS anyway.
FOO: define internal void @_ZL2f2v() #{{[0-9]+}}
FOO-NOT: {{define|declare}}
@@ -45,7 +51,7 @@ BAR-OPT: define available_externally void @_Z3foov()
BAR-CMN-NOT: {{define|declare}}
BAR-OPT: declare void @_Z2f1Ri(i32*
BAR-OPT-NOT: {{define|declare}}
-BAR-OPT: define available_externally void @_ZL2f2v()
+BAR-OPT: define internal void @_ZL2f2v()
BAR-OPT-NOT: {{define|declare}}
@@ -61,5 +67,5 @@ USE-OPT: define available_externally void @_Z3foov()
USE-OPT-NOT: {{define|declare}}
USE-OPT: declare void @_Z2f1Ri(i32*
USE-OPT-NOT: {{define|declare}}
-USE-OPT: define available_externally void @_ZL2f2v()
+USE-OPT: define internal void @_ZL2f2v()
USE-OPT-NOT: {{define|declare}}
OpenPOWER on IntegriCloud