diff options
author | Teresa Johnson <tejohnson@google.com> | 2019-05-10 20:08:24 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2019-05-10 20:08:24 +0000 |
commit | 37b80122bd1225eb8889d42b4fd5d7d383a329e7 (patch) | |
tree | 6ccf622e3818974d1cb31b009f828f959bd333a9 /llvm/lib/AsmParser | |
parent | bcb9bbc01122a3386ac2e321f8b505b1fb246298 (diff) | |
download | bcm5719-llvm-37b80122bd1225eb8889d42b4fd5d7d383a329e7.tar.gz bcm5719-llvm-37b80122bd1225eb8889d42b4fd5d7d383a329e7.zip |
[ThinLTO] Auto-hide prevailing linkonce_odr only when all copies eligible
Summary:
We hit undefined references building with ThinLTO when one source file
contained explicit instantiations of a template method (weak_odr) but
there were also implicit instantiations in another file (linkonce_odr),
and the latter was the prevailing copy. In this case the symbol was
marked hidden when the prevailing linkonce_odr copy was promoted to
weak_odr. It led to unsats when the resulting shared library was linked
with other code that contained a reference (expecting to be resolved due
to the explicit instantiation).
Add a CanAutoHide flag to the GV summary to allow the thin link to
identify when all copies are eligible for auto-hiding (because they were
all originally linkonce_odr global unnamed addr), and only do the
auto-hide in that case.
Most of the changes here are due to plumbing the new flag through the
bitcode and llvm assembly, and resulting test changes. I augmented the
existing auto-hide test to check for this situation.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, arphaman, dang, llvm-commits, steven_wu, wmi
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59709
llvm-svn: 360466
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 76 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 |
3 files changed, 47 insertions, 31 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index bc3776da966..c0b9cd12d0c 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -733,6 +733,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(notEligibleToImport); KEYWORD(live); KEYWORD(dsoLocal); + KEYWORD(canAutoHide); KEYWORD(function); KEYWORD(insts); KEYWORD(funcFlags); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 907bbdd7ef7..9558bd0b783 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -7859,7 +7859,7 @@ bool LLParser::ParseFunctionSummary(std::string Name, GlobalValue::GUID GUID, StringRef ModulePath; GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false, - /*Live=*/false, /*IsLocal=*/false); + /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false); unsigned InstCount; std::vector<FunctionSummary::EdgeTy> Calls; FunctionSummary::TypeIdInfo TypeIdInfo; @@ -7929,7 +7929,7 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID, StringRef ModulePath; GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false, - /*Live=*/false, /*IsLocal=*/false); + /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false); GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false); std::vector<ValueInfo> Refs; if (ParseToken(lltok::colon, "expected ':' here") || @@ -7972,7 +7972,7 @@ bool LLParser::ParseAliasSummary(std::string Name, GlobalValue::GUID GUID, StringRef ModulePath; GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false, - /*Live=*/false, /*IsLocal=*/false); + /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false); if (ParseToken(lltok::colon, "expected ':' here") || ParseToken(lltok::lparen, "expected '(' here") || ParseModuleReference(ModulePath) || @@ -8462,41 +8462,55 @@ bool LLParser::ParseVFuncId(FunctionSummary::VFuncId &VFuncId, /// GVFlags /// ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ',' /// 'notEligibleToImport' ':' Flag ',' 'live' ':' Flag ',' -/// 'dsoLocal' ':' Flag ')' +/// 'dsoLocal' ':' Flag ',' 'canAutoHide' ':' Flag ')' bool LLParser::ParseGVFlags(GlobalValueSummary::GVFlags &GVFlags) { assert(Lex.getKind() == lltok::kw_flags); Lex.Lex(); - bool HasLinkage; if (ParseToken(lltok::colon, "expected ':' here") || - ParseToken(lltok::lparen, "expected '(' here") || - ParseToken(lltok::kw_linkage, "expected 'linkage' here") || - ParseToken(lltok::colon, "expected ':' here")) - return true; - - GVFlags.Linkage = parseOptionalLinkageAux(Lex.getKind(), HasLinkage); - assert(HasLinkage && "Linkage not optional in summary entry"); - Lex.Lex(); - - unsigned Flag; - if (ParseToken(lltok::comma, "expected ',' here") || - ParseToken(lltok::kw_notEligibleToImport, - "expected 'notEligibleToImport' here") || - ParseToken(lltok::colon, "expected ':' here") || ParseFlag(Flag)) - return true; - GVFlags.NotEligibleToImport = Flag; - - if (ParseToken(lltok::comma, "expected ',' here") || - ParseToken(lltok::kw_live, "expected 'live' here") || - ParseToken(lltok::colon, "expected ':' here") || ParseFlag(Flag)) + ParseToken(lltok::lparen, "expected '(' here")) return true; - GVFlags.Live = Flag; - if (ParseToken(lltok::comma, "expected ',' here") || - ParseToken(lltok::kw_dsoLocal, "expected 'dsoLocal' here") || - ParseToken(lltok::colon, "expected ':' here") || ParseFlag(Flag)) - return true; - GVFlags.DSOLocal = Flag; + do { + unsigned Flag; + switch (Lex.getKind()) { + case lltok::kw_linkage: + Lex.Lex(); + if (ParseToken(lltok::colon, "expected ':'")) + return true; + bool HasLinkage; + GVFlags.Linkage = parseOptionalLinkageAux(Lex.getKind(), HasLinkage); + assert(HasLinkage && "Linkage not optional in summary entry"); + Lex.Lex(); + break; + case lltok::kw_notEligibleToImport: + Lex.Lex(); + if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag)) + return true; + GVFlags.NotEligibleToImport = Flag; + break; + case lltok::kw_live: + Lex.Lex(); + if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag)) + return true; + GVFlags.Live = Flag; + break; + case lltok::kw_dsoLocal: + Lex.Lex(); + if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag)) + return true; + GVFlags.DSOLocal = Flag; + break; + case lltok::kw_canAutoHide: + Lex.Lex(); + if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Flag)) + return true; + GVFlags.CanAutoHide = Flag; + break; + default: + return Error(Lex.getLoc(), "expected gv flag type"); + } + } while (EatIfPresent(lltok::comma)); if (ParseToken(lltok::rparen, "expected ')' here")) return true; diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 80a1eb99e35..33ea28bb10e 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -364,6 +364,7 @@ enum Kind { kw_notEligibleToImport, kw_live, kw_dsoLocal, + kw_canAutoHide, kw_function, kw_insts, kw_funcFlags, |