[llvm] r266958 - ThinLTO: Resolve linkonce_odr aliases just like functions

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 21 06:28:57 PDT 2016


I just added a comment to D19308 (for some reason, phab didn't email it?).
In any case, this could be cleaned up as a post-commit fix. See
http://reviews.llvm.org/D19308#inline-162966, copied here:

I don't remember the history unfortunately.

Just looked this up to refresh my memory. This was in the first version of
D18346 <http://reviews.llvm.org/D18346>, and here is my comment as to why
it wasn't legal to do the part that was converting weakany/linkonceany to
available_externally in the multiple definition case:
http://reviews.llvm.org/D18346?id=51265#inline-155935

But as I pointed out later, you can still do the linkonceany->weakany
conversion:
http://reviews.llvm.org/D18346?id=51265#inline-156013

I believe that is what is needed here when a linkonceany is exported, for
correctness.

What I am gonna do is moving forward with this patch, leaving the bug
as-is, since it is already
existing I think.

I don't believe there is a bug in the current upstream head, just in the
libLTO case once D19096 <http://reviews.llvm.org/D19096> goes in and
prevents linkonce from being force imported.

I'll implement in a new patch (or a few patches) the proper handling of the
4 points above.

AFAICT the only place we are getting things wrong is with linkonce(any),
due to your first point. And that should be easy to fix here - just do the
conversion to weakany when the linkonceany is exported. (Then the name
should probably be changed from ResolveODR to ResolveWeakLinkOnce or
something more broad like that.)

The last point can't be done via available_externally for
linkonceany/weakany due to the issue I pointed out in the old patch in the
first link above. It could be done via dropping the unselected defs (they
can't be inlined anyway), but that is a compile time optimization, not a
correctness issue.




On Wed, Apr 20, 2016 at 10:47 PM, Mehdi Amini via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: mehdi_amini
> Date: Thu Apr 21 00:47:17 2016
> New Revision: 266958
>
> URL: http://llvm.org/viewvc/llvm-project?rev=266958&view=rev
> Log:
> ThinLTO: Resolve linkonce_odr aliases just like functions
>
> This help to streamline the process of handling importing since
> we don't need to special case alias everywhere: just like
> linkonce_odr function, make sure at least one alias is emitted
> by turning it weak.
>
> Differential Revision: http://reviews.llvm.org/D19308
>
> From: Mehdi Amini <mehdi.amini at apple.com>
>
> Added:
>     llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll
>     llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll
>     llvm/trunk/test/ThinLTO/X86/alias_import.ll
>     llvm/trunk/test/ThinLTO/X86/alias_resolution.ll
> Modified:
>     llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp
>     llvm/trunk/test/ThinLTO/X86/odr_resolution.ll
>
> Modified: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp?rev=266958&r1=266957&r2=266958&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp (original)
> +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp Thu Apr 21 00:47:17 2016
> @@ -122,10 +122,11 @@ bool IsFirstDefinitionForLinker(const Gl
>    return true;
>  }
>
> -static GlobalValue::LinkageTypes ResolveODR(const ModuleSummaryIndex
> &Index,
> -                                            StringRef ModuleIdentifier,
> -                                            GlobalValue::GUID GUID,
> -                                            const GlobalValueSummary &GV)
> {
> +static GlobalValue::LinkageTypes
> +ResolveODR(const ModuleSummaryIndex &Index,
> +           const FunctionImporter::ExportSetTy &ExportList,
> +           StringRef ModuleIdentifier, GlobalValue::GUID GUID,
> +           const GlobalValueSummary &GV) {
>    auto HasMultipleCopies =
>        [&](const GlobalValueInfoList &GVInfo) { return GVInfo.size() > 1;
> };
>
> @@ -146,13 +147,19 @@ static GlobalValue::LinkageTypes Resolve
>      auto &GVInfo = Index.findGlobalValueInfoList(GUID)->second;
>      // We need to emit only one of these, the first module will keep
>      // it, but turned into a weak while the others will drop it.
> -    if (!HasMultipleCopies(GVInfo))
> +    if (!HasMultipleCopies(GVInfo)) {
> +      // Exported LinkonceODR needs to be promoted to not be discarded
> +      if (GlobalValue::isDiscardableIfUnused(OriginalLinkage) &&
> +          ExportList.count(GUID))
> +        return GlobalValue::WeakODRLinkage;
>        break;
> +    }
>      if (IsFirstDefinitionForLinker(GVInfo, Index, ModuleIdentifier))
>        return GlobalValue::WeakODRLinkage;
> -    else
> -      return GlobalValue::AvailableExternallyLinkage;
> -    break;
> +    else if (isa<AliasSummary>(&GV))
> +      // Alias can't be turned into available_externally.
> +      return OriginalLinkage;
> +    return GlobalValue::AvailableExternallyLinkage;
>    }
>    }
>    return OriginalLinkage;
> @@ -166,6 +173,7 @@ static GlobalValue::LinkageTypes Resolve
>  /// one copy.
>  static void ResolveODR(
>      const ModuleSummaryIndex &Index,
> +    const FunctionImporter::ExportSetTy &ExportList,
>      const std::map<GlobalValue::GUID, GlobalValueSummary *>
> &DefinedGlobals,
>      StringRef ModuleIdentifier,
>      DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR) {
> @@ -185,7 +193,8 @@ static void ResolveODR(
>    for (auto &GV : DefinedGlobals) {
>      if (GlobalInvolvedWithAlias.count(GV.second))
>        continue;
> -    auto NewLinkage = ResolveODR(Index, ModuleIdentifier, GV.first,
> *GV.second);
> +    auto NewLinkage =
> +        ResolveODR(Index, ExportList, ModuleIdentifier, GV.first,
> *GV.second);
>      if (NewLinkage != GV.second->linkage()) {
>        ResolvedODR[GV.first] = NewLinkage;
>      }
> @@ -213,6 +222,14 @@ void fixupODR(
>                   << GV.getLinkage() << " to " << NewLinkage->second <<
> "\n");
>      GV.setLinkage(NewLinkage->second);
>    }
> +  for (auto &GV : TheModule.aliases()) {
> +    auto NewLinkage = ResolvedODR.find(GV.getGUID());
> +    if (NewLinkage == ResolvedODR.end())
> +      continue;
> +    DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "`
> from "
> +                 << GV.getLinkage() << " to " << NewLinkage->second <<
> "\n");
> +    GV.setLinkage(NewLinkage->second);
> +  }
>  }
>
>  static StringMap<MemoryBufferRef>
> @@ -453,17 +470,25 @@ std::unique_ptr<ModuleSummaryIndex> Thin
>   */
>  void ThinLTOCodeGenerator::promote(Module &TheModule,
>                                     ModuleSummaryIndex &Index) {
> +  auto ModuleCount = Index.modulePaths().size();
>    auto ModuleIdentifier = TheModule.getModuleIdentifier();
>    // Collect for each module the list of function it defines (GUID ->
> Summary).
>    StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
>        ModuleToDefinedGVSummaries;
>    Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
>
> +  // Generate import/export list
> +  StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
> +  StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
> +  ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
> +                           ExportLists);
> +  auto &ExportList = ExportLists[ModuleIdentifier];
> +
>    // Resolve the LinkOnceODR, trying to turn them into
> "available_externally"
>    // where possible.
>    // This is a compile-time optimization.
>    DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> ResolvedODR;
> -  ResolveODR(Index, ModuleToDefinedGVSummaries[ModuleIdentifier],
> +  ResolveODR(Index, ExportList,
> ModuleToDefinedGVSummaries[ModuleIdentifier],
>               ModuleIdentifier, ResolvedODR);
>    fixupODR(TheModule, ResolvedODR);
>
> @@ -577,9 +602,11 @@ void ThinLTOCodeGenerator::run() {
>          Context.setDiscardValueNames(LTODiscardValueNames);
>          Context.enableDebugTypeODRUniquing();
>          auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier();
> +        auto &ExportList = ExportLists[ModuleIdentifier];
>
>          DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes>
> ResolvedODR;
> -        ResolveODR(*Index, ModuleToDefinedGVSummaries[ModuleIdentifier],
> +        ResolveODR(*Index, ExportList,
> +                   ModuleToDefinedGVSummaries[ModuleIdentifier],
>                     ModuleIdentifier, ResolvedODR);
>
>          // Parse module now
>
> Added: llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll?rev=266958&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll (added)
> +++ llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll Thu Apr 21 00:47:17
> 2016
> @@ -0,0 +1,64 @@
> +
> +
> +
> +
> + at globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to
> void (...)*)
> + at globalfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @globalfunc to void (...)*)
> + at globalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @globalfunc to void (...)*)
> + at globalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @globalfunc to void (...)*)
> + at globalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @globalfunc to void (...)*)
> +define void @globalfunc() {
> +entry:
> +  ret void
> +}
> +
> + at internalfuncAlias = alias void (...), bitcast (void ()* @internalfunc to
> void (...)*)
> + at internalfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @internalfunc to void (...)*)
> + at internalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @internalfunc to void (...)*)
> + at internalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @internalfunc to void (...)*)
> + at internalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @internalfunc to void (...)*)
> +define internal void @internalfunc() {
> +entry:
> +  ret void
> +}
> +
> + at linkonceODRfuncAlias = alias void (...), bitcast (void ()*
> @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void
> ()* @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void
> ()* @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @linkonceODRfunc to void (...)*)
> +define linkonce_odr void @linkonceODRfunc() {
> +entry:
> +  ret void
> +}
> +
> + at weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc to
> void (...)*)
> + at weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @weakODRfunc to void (...)*)
> + at weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @weakODRfunc to void (...)*)
> + at weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @weakODRfunc to void (...)*)
> + at weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @weakODRfunc to void (...)*)
> +define weak_odr void @weakODRfunc() {
> +entry:
> +  ret void
> +}
> +
> + at linkoncefuncAlias = alias void (...), bitcast (void ()* @linkoncefunc to
> void (...)*)
> + at linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()*
> @linkoncefunc to void (...)*)
> + at linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @linkoncefunc to void (...)*)
> + at linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @linkoncefunc to void (...)*)
> + at linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @linkoncefunc to void (...)*)
> +define linkonce void @linkoncefunc() {
> +entry:
> +  ret void
> +}
> +
> + at weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc to void
> (...)*)
> + at weakfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakfunc
> to void (...)*)
> + at weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @weakfunc to void (...)*)
> + at weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @weakfunc to void (...)*)
> + at weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void
> ()* @weakfunc to void (...)*)
> +define weak void @weakfunc() {
> +entry:
> +  ret void
> +}
> +
>
> Added: llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll?rev=266958&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll (added)
> +++ llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll Thu Apr 21
> 00:47:17 2016
> @@ -0,0 +1,64 @@
> +
> +
> +
> +
> + at globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to
> void (...)*)
> + at globalfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @globalfunc to void (...)*)
> + at globalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @globalfunc to void (...)*)
> + at globalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @globalfunc to void (...)*)
> + at globalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @globalfunc to void (...)*)
> +define void @globalfunc() {
> +entry:
> +  ret void
> +}
> +
> + at internalfuncAlias = alias void (...), bitcast (void ()* @internalfunc to
> void (...)*)
> + at internalfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @internalfunc to void (...)*)
> + at internalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @internalfunc to void (...)*)
> + at internalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @internalfunc to void (...)*)
> + at internalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @internalfunc to void (...)*)
> +define internal void @internalfunc() {
> +entry:
> +  ret void
> +}
> +
> + at linkonceODRfuncAlias = alias void (...), bitcast (void ()*
> @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void
> ()* @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void
> ()* @linkonceODRfunc to void (...)*)
> + at linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @linkonceODRfunc to void (...)*)
> +define linkonce_odr void @linkonceODRfunc() {
> +entry:
> +  ret void
> +}
> +
> + at weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc to
> void (...)*)
> + at weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @weakODRfunc to void (...)*)
> + at weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @weakODRfunc to void (...)*)
> + at weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @weakODRfunc to void (...)*)
> + at weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @weakODRfunc to void (...)*)
> +define weak_odr void @weakODRfunc() {
> +entry:
> +  ret void
> +}
> +
> + at linkoncefuncAlias = alias void (...), bitcast (void ()* @linkoncefunc to
> void (...)*)
> + at linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()*
> @linkoncefunc to void (...)*)
> + at linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @linkoncefunc to void (...)*)
> + at linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @linkoncefunc to void (...)*)
> + at linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @linkoncefunc to void (...)*)
> +define linkonce void @linkoncefunc() {
> +entry:
> +  ret void
> +}
> +
> + at weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc to void
> (...)*)
> + at weakfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakfunc
> to void (...)*)
> + at weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @weakfunc to void (...)*)
> + at weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @weakfunc to void (...)*)
> + at weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void
> ()* @weakfunc to void (...)*)
> +define weak void @weakfunc() {
> +entry:
> +  ret void
> +}
> +
>
> Added: llvm/trunk/test/ThinLTO/X86/alias_import.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/alias_import.ll?rev=266958&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ThinLTO/X86/alias_import.ll (added)
> +++ llvm/trunk/test/ThinLTO/X86/alias_import.ll Thu Apr 21 00:47:17 2016
> @@ -0,0 +1,168 @@
> +; RUN: opt -module-summary %s -o %t1.bc
> +; RUN: opt -module-summary %p/Inputs/alias_import.ll -o %t2.bc
> +; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
> +; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t2.bc
> -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE
> +; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index.bc %t1.bc
> -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT
> +
> +;
> +; Alias can't point to "available_externally", so we can only import an
> alias
> +; when we can import the aliasee with a linkage that won't be
> +; available_externally, i.e linkOnceODR. (FIXME this limitation could be
> lifted)
> +; PROMOTE-DAG: @globalfuncAlias = alias void (...), bitcast (void ()*
> @globalfunc to void (...)*)
> +; PROMOTE-DAG: @globalfuncWeakAlias = weak alias void (...), bitcast
> (void ()* @globalfunc to void (...)*)
> +; PROMOTE-DAG: @globalfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @globalfunc to void (...)*)
> +; PROMOTE-DAG: @globalfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @globalfunc to void (...)*)
> +; PROMOTE-DAG: @globalfuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @globalfunc to void (...)*)
> +; PROMOTE-DAG: @internalfuncAlias = alias void (...), bitcast (void ()*
> @internalfunc.llvm.0 to void (...)*)
> +; PROMOTE-DAG: @internalfuncWeakAlias = weak alias void (...), bitcast
> (void ()* @internalfunc.llvm.0 to void (...)*)
> +; PROMOTE-DAG: @internalfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
> +; PROMOTE-DAG: @internalfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
> +; PROMOTE-DAG: @internalfuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
> +; PROMOTE-DAG: @linkoncefuncAlias = alias void (...), bitcast (void ()*
> @linkoncefunc to void (...)*)
> +; PROMOTE-DAG: @linkoncefuncWeakAlias = weak alias void (...), bitcast
> (void ()* @linkoncefunc to void (...)*)
> +; PROMOTE-DAG: @linkoncefuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @linkoncefunc to void (...)*)
> +; PROMOTE-DAG: @linkoncefuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @linkoncefunc to void (...)*)
> +; PROMOTE-DAG: @linkoncefuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @linkoncefunc to void (...)*)
> +; PROMOTE-DAG: @weakfuncAlias = alias void (...), bitcast (void ()*
> @weakfunc to void (...)*)
> +; PROMOTE-DAG: @weakfuncWeakAlias = weak alias void (...), bitcast (void
> ()* @weakfunc to void (...)*)
> +; PROMOTE-DAG: @weakfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @weakfunc to void (...)*)
> +; PROMOTE-DAG: @weakfuncWeakODRAlias = weak_odr alias void (...), bitcast
> (void ()* @weakfunc to void (...)*)
> +; PROMOTE-DAG: @weakfuncLinkonceODRAlias = linkonce_odr alias void (...),
> bitcast (void ()* @weakfunc to void (...)*)
> +; PROMOTE-DAG: @weakODRfuncAlias = alias void (...), bitcast (void ()*
> @weakODRfunc to void (...)*)
> +; PROMOTE-DAG: @weakODRfuncWeakAlias = weak alias void (...), bitcast
> (void ()* @weakODRfunc to void (...)*)
> +; PROMOTE-DAG: @weakODRfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @weakODRfunc to void (...)*)
> +; PROMOTE-DAG: @weakODRfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @weakODRfunc to void (...)*)
> +; PROMOTE-DAG: @weakODRfuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @weakODRfunc to void (...)*)
> +
> +; Only alias to LinkonceODR aliasee can be imported
> +; PROMOTE-DAG: @linkonceODRfuncAlias = alias void (...), bitcast (void
> ()* @linkonceODRfunc to void (...)*)
> +; PROMOTE-DAG: @linkonceODRfuncWeakAlias = weak alias void (...), bitcast
> (void ()* @linkonceODRfunc to void (...)*)
> +; PROMOTE-DAG: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @linkonceODRfunc to void (...)*)
> +; Amongst these that are imported, check that we promote only
> linkonce->weak
> +; PROMOTE-DAG: @linkonceODRfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @linkonceODRfunc to void (...)*)
> +; PROMOTE-DAG: @linkonceODRfuncLinkonceODRAlias = weak_odr alias void
> (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
> +
> +; These will be imported, check the linkage/renaming after promotion
> +; PROMOTE-DAG: define void @globalfunc()
> +; PROMOTE-DAG: define hidden void @internalfunc.llvm.0()
> +; PROMOTE-DAG: define linkonce_odr void @linkonceODRfunc()
> +; PROMOTE-DAG: define weak_odr void @weakODRfunc()
> +; PROMOTE-DAG: define linkonce void @linkoncefunc()
> +; PROMOTE-DAG: define weak void @weakfunc()
> +
> +; On the import side now, verify that aliases to a linkonce_odr are
> imported, but the weak (never import weak)
> +; IMPORT-DAG:  declare void @linkonceODRfuncWeakAlias
> +; IMPORT-DAG:  @linkonceODRfuncAlias = alias void (...), bitcast (void
> ()* @linkonceODRfunc to void (...)*)
> +; IMPORT-DAG:  @linkonceODRfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @linkonceODRfunc to void (...)*)
> +; IMPORT-DAG:  @linkonceODRfuncWeakODRAlias = alias void (...), bitcast
> (void ()* @linkonceODRfunc to void (...)*)
> +; IMPORT-DAG:  @linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
> +; IMPORT-DAG:  define linkonce_odr void @linkonceODRfunc()
> +
> +
> +; On the import side, these aliases are not imported (they don't point to
> a linkonce_odr)
> +; IMPORT-DAG: declare void @globalfuncAlias()
> +; IMPORT-DAG: declare void @globalfuncWeakAlias()
> +; IMPORT-DAG: declare void @globalfuncLinkonceAlias()
> +; IMPORT-DAG: declare void @globalfuncWeakODRAlias()
> +; IMPORT-DAG: declare void @globalfuncLinkonceODRAlias()
> +; IMPORT-DAG: declare void @internalfuncAlias()
> +; IMPORT-DAG: declare void @internalfuncWeakAlias()
> +; IMPORT-DAG: declare void @internalfuncLinkonceAlias()
> +; IMPORT-DAG: declare void @internalfuncWeakODRAlias()
> +; IMPORT-DAG: declare void @internalfuncLinkonceODRAlias()
> +; IMPORT-DAG: declare void @weakODRfuncAlias()
> +; IMPORT-DAG: declare void @weakODRfuncWeakAlias()
> +; IMPORT-DAG: declare void @weakODRfuncLinkonceAlias()
> +; IMPORT-DAG: declare void @weakODRfuncWeakODRAlias()
> +; IMPORT-DAG: declare void @weakODRfuncLinkonceODRAlias()
> +; IMPORT-DAG: declare void @linkoncefuncAlias()
> +; IMPORT-DAG: declare void @linkoncefuncWeakAlias()
> +; IMPORT-DAG: declare void @linkoncefuncLinkonceAlias()
> +; IMPORT-DAG: declare void @linkoncefuncWeakODRAlias()
> +; IMPORT-DAG: declare void @linkoncefuncLinkonceODRAlias()
> +; IMPORT-DAG: declare void @weakfuncAlias()
> +; IMPORT-DAG: declare void @weakfuncWeakAlias()
> +; IMPORT-DAG: declare void @weakfuncLinkonceAlias()
> +; IMPORT-DAG: declare void @weakfuncWeakODRAlias()
> +; IMPORT-DAG: declare void @weakfuncLinkonceODRAlias()
> +
> +
> +
> +define i32 @main() #0 {
> +entry:
> +  call void @globalfuncAlias()
> +  call void @globalfuncWeakAlias()
> +  call void @globalfuncLinkonceAlias()
> +  call void @globalfuncWeakODRAlias()
> +  call void @globalfuncLinkonceODRAlias()
> +
> +  call void @internalfuncAlias()
> +  call void @internalfuncWeakAlias()
> +  call void @internalfuncLinkonceAlias()
> +  call void @internalfuncWeakODRAlias()
> +  call void @internalfuncLinkonceODRAlias()
> +  call void @linkonceODRfuncAlias()
> +  call void @linkonceODRfuncWeakAlias()
> +  call void @linkonceODRfuncLinkonceAlias()
> +  call void @linkonceODRfuncWeakODRAlias()
> +  call void @linkonceODRfuncLinkonceODRAlias()
> +
> +  call void @weakODRfuncAlias()
> +  call void @weakODRfuncWeakAlias()
> +  call void @weakODRfuncLinkonceAlias()
> +  call void @weakODRfuncWeakODRAlias()
> +  call void @weakODRfuncLinkonceODRAlias()
> +
> +  call void @linkoncefuncAlias()
> +  call void @linkoncefuncWeakAlias()
> +  call void @linkoncefuncLinkonceAlias()
> +  call void @linkoncefuncWeakODRAlias()
> +  call void @linkoncefuncLinkonceODRAlias()
> +
> +  call void @weakfuncAlias()
> +  call void @weakfuncWeakAlias()
> +  call void @weakfuncLinkonceAlias()
> +  call void @weakfuncWeakODRAlias()
> +  call void @weakfuncLinkonceODRAlias()
> +
> +  ret i32 0
> +}
> +
> +
> +declare void @globalfuncAlias()
> +declare void @globalfuncWeakAlias()
> +declare void @globalfuncLinkonceAlias()
> +declare void @globalfuncWeakODRAlias()
> +declare void @globalfuncLinkonceODRAlias()
> +
> +declare void @internalfuncAlias()
> +declare void @internalfuncWeakAlias()
> +declare void @internalfuncLinkonceAlias()
> +declare void @internalfuncWeakODRAlias()
> +declare void @internalfuncLinkonceODRAlias()
> +
> +declare void @linkonceODRfuncAlias()
> +declare void @linkonceODRfuncWeakAlias()
> +declare void @linkonceODRfuncLinkonceAlias()
> +declare void @linkonceODRfuncWeakODRAlias()
> +declare void @linkonceODRfuncLinkonceODRAlias()
> +
> +declare void @weakODRfuncAlias()
> +declare void @weakODRfuncWeakAlias()
> +declare void @weakODRfuncLinkonceAlias()
> +declare void @weakODRfuncWeakODRAlias()
> +declare void @weakODRfuncLinkonceODRAlias()
> +
> +declare void @linkoncefuncAlias()
> +declare void @linkoncefuncWeakAlias()
> +declare void @linkoncefuncLinkonceAlias()
> +declare void @linkoncefuncWeakODRAlias()
> +declare void @linkoncefuncLinkonceODRAlias()
> +
> +declare void @weakfuncAlias()
> +declare void @weakfuncWeakAlias()
> +declare void @weakfuncLinkonceAlias()
> +declare void @weakfuncWeakODRAlias()
> +declare void @weakfuncLinkonceODRAlias()
> +
> +
>
> Added: llvm/trunk/test/ThinLTO/X86/alias_resolution.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/alias_resolution.ll?rev=266958&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ThinLTO/X86/alias_resolution.ll (added)
> +++ llvm/trunk/test/ThinLTO/X86/alias_resolution.ll Thu Apr 21 00:47:17
> 2016
> @@ -0,0 +1,82 @@
> +; RUN: opt -module-summary %s -o %t1.bc
> +; RUN: opt -module-summary %p/Inputs/alias_resolution.ll -o %t2.bc
> +; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
> +; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t2.bc
> -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE_MOD2
> --check-prefix=NOTPROMOTED
> +; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t1.bc
> -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE
> --check-prefix=NOTPROMOTED
> +
> +; There is no importing going on with this IR, but let's check the ODR
> resolution for compile time
> +
> +; NOTPROMOTED: @linkonceODRfuncAlias = alias void (...), bitcast (void
> ()* @linkonceODRfunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @linkonceODRfuncWeakAlias = weak alias void (...), bitcast
> (void ()* @linkonceODRfunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @linkonceODRfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @linkonceODRfunc{{.*}} to void (...)*)
> +; PROMOTE_MOD1: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @linkonceODRfunc to void (...)*)
> +; PROMOTE_MOD1: @linkonceODRfuncLinkonceODRAlias = weak_odr alias void
> (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @linkonceODRfuncLinkonceODRAlias = linkonce_odr alias
> void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
> +
> +; NOTPROMOTED: @weakODRfuncAlias = alias void (...), bitcast (void ()*
> @weakODRfunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @weakODRfuncWeakAlias = weak alias void (...), bitcast
> (void ()* @weakODRfunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @weakODRfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @weakODRfunc{{.*}} to void (...)*)
> +; PROMOTE_MOD1: @weakODRfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @weakODRfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @weakODRfunc to void (...)*)
> +; PROMOTE_MOD1: @weakODRfuncLinkonceODRAlias = weak_odr alias void (...),
> bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @weakODRfuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @weakODRfunc to void (...)*)
> +
> +; NOTPROMOTED: @linkoncefuncAlias = alias void (...), bitcast (void ()*
> @linkoncefunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @linkoncefuncWeakAlias = weak alias void (...), bitcast
> (void ()* @linkoncefunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @linkoncefuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @linkoncefunc{{.*}} to void (...)*)
> +; PROMOTE_MOD1: @linkoncefuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @linkoncefuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @linkoncefunc to void (...)*)
> +; PROMOTE_MOD1: @linkoncefuncLinkonceODRAlias = weak_odr alias void
> (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @linkoncefuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @linkoncefunc to void (...)*)
> +
> +; NOTPROMOTED: @weakfuncAlias = alias void (...), bitcast (void ()*
> @weakfunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @weakfuncWeakAlias = weak alias void (...), bitcast (void
> ()* @weakfunc{{.*}} to void (...)*)
> +; NOTPROMOTED: @weakfuncLinkonceAlias = linkonce alias void (...),
> bitcast (void ()* @weakfunc{{.*}} to void (...)*)
> +; FIXME: The "resolution" should turn one of these to linkonce_odr
> +; PROMOTE_MOD1: @weakfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @weakfunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @weakfuncWeakODRAlias = weak_odr alias void (...),
> bitcast (void ()* @weakfunc to void (...)*)
> +; PROMOTE_MOD1: @weakfuncLinkonceODRAlias = weak_odr alias void (...),
> bitcast (void ()* @weakfunc.mod1 to void (...)*)
> +; PROMOTE_MOD2: @weakfuncLinkonceODRAlias = linkonce_odr alias void
> (...), bitcast (void ()* @weakfunc to void (...)*)
> +
> +
> + at linkonceODRfuncAlias = alias void (...), bitcast (void ()*
> @linkonceODRfunc.mod1 to void (...)*)
> + at linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @linkonceODRfunc.mod1 to void (...)*)
> + at linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void
> ()* @linkonceODRfunc.mod1 to void (...)*)
> + at linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void
> ()* @linkonceODRfunc.mod1 to void (...)*)
> + at linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @linkonceODRfunc.mod1 to void (...)*)
> +define linkonce_odr void @linkonceODRfunc.mod1() {
> +entry:
> +  ret void
> +}
> +
> + at weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc.mod1
> to void (...)*)
> + at weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @weakODRfunc.mod1 to void (...)*)
> + at weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @weakODRfunc.mod1 to void (...)*)
> + at weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @weakODRfunc.mod1 to void (...)*)
> + at weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @weakODRfunc.mod1 to void (...)*)
> +define weak_odr void @weakODRfunc.mod1() {
> +entry:
> +  ret void
> +}
> +
> + at linkoncefuncAlias = alias void (...), bitcast (void ()*
> @linkoncefunc.mod1 to void (...)*)
> + at linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()*
> @linkoncefunc.mod1 to void (...)*)
> + at linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @linkoncefunc.mod1 to void (...)*)
> + at linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @linkoncefunc.mod1 to void (...)*)
> + at linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast
> (void ()* @linkoncefunc.mod1 to void (...)*)
> +define linkonce void @linkoncefunc.mod1() {
> +entry:
> +  ret void
> +}
> +
> + at weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc.mod1 to
> void (...)*)
> + at weakfuncWeakAlias = weak alias void (...), bitcast (void ()*
> @weakfunc.mod1 to void (...)*)
> + at weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()*
> @weakfunc.mod1 to void (...)*)
> + at weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()*
> @weakfunc.mod1 to void (...)*)
> + at weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void
> ()* @weakfunc.mod1 to void (...)*)
> +define weak void @weakfunc.mod1() {
> +entry:
> +  ret void
> +}
> +
>
> Modified: llvm/trunk/test/ThinLTO/X86/odr_resolution.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/odr_resolution.ll?rev=266958&r1=266957&r2=266958&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/ThinLTO/X86/odr_resolution.ll (original)
> +++ llvm/trunk/test/ThinLTO/X86/odr_resolution.ll Thu Apr 21 00:47:17 2016
> @@ -10,8 +10,8 @@
>  target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>  target triple = "x86_64-apple-macosx10.11.0"
>
> -; Alias are not optimized
> -; MOD1: @linkoncealias = linkonce_odr alias void (), void ()*
> @linkonceodrfuncwithalias
> +; Alias are resolved, but can't be turned into "available_externally"
> +; MOD1: @linkoncealias = weak_odr alias void (), void ()*
> @linkonceodrfuncwithalias
>  ; MOD2: @linkoncealias = linkonce_odr alias void (), void ()*
> @linkonceodrfuncwithalias
>  @linkoncealias = linkonce_odr alias void (), void ()*
> @linkonceodrfuncwithalias
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>



-- 
Teresa Johnson |  Software Engineer |  tejohnson at google.com |  408-460-2413
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160421/c2e65afc/attachment.html>


More information about the llvm-commits mailing list