From 5b85d8d67b28f082db53863a922895211a01baa2 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Tue, 3 May 2016 00:27:28 +0000 Subject: [PATCH] ThinLTO: do not import function whose linkage prevents inlining. There is not point in importing a "weak" or a "linkonce" function since we won't be able to inline it anyway. We already had a targeted check for WeakAny, this is using the same check on GlobalValue as the inline, i.e. isMayBeOverriddenLinkage() From: Mehdi Amini llvm-svn: 268341 --- llvm/include/llvm/IR/GlobalValue.h | 46 ++++++++++++---------- llvm/lib/Transforms/IPO/FunctionImport.cpp | 4 +- llvm/test/ThinLTO/X86/alias_import.ll | 4 +- .../Transforms/FunctionImport/Inputs/funcimport.ll | 5 +++ llvm/test/Transforms/FunctionImport/funcimport.ll | 5 +++ 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h index 0d12fe8..5030238 100644 --- a/llvm/include/llvm/IR/GlobalValue.h +++ b/llvm/include/llvm/IR/GlobalValue.h @@ -124,26 +124,7 @@ private: /// non-equivalent at link time. For example, if a function has weak linkage /// then the code defining it may be replaced by different code. bool mayBeOverridden() const { - switch (getLinkage()) { - case WeakAnyLinkage: - case LinkOnceAnyLinkage: - case CommonLinkage: - case ExternalWeakLinkage: - return true; - - case AvailableExternallyLinkage: - case LinkOnceODRLinkage: - case WeakODRLinkage: - // The above three cannot be overridden but can be de-refined. - - case ExternalLinkage: - case AppendingLinkage: - case InternalLinkage: - case PrivateLinkage: - return false; - } - - llvm_unreachable("Fully covered switch above!"); + return isMayBeOverriddenLinkage(getLinkage()); } protected: @@ -285,6 +266,31 @@ public: return Linkage == CommonLinkage; } + /// Whether the definition of this global may be replaced by something + /// non-equivalent at link time. For example, if a function has weak linkage + /// then the code defining it may be replaced by different code. + static bool isMayBeOverriddenLinkage(LinkageTypes Linkage) { + switch (Linkage) { + case WeakAnyLinkage: + case LinkOnceAnyLinkage: + case CommonLinkage: + case ExternalWeakLinkage: + return true; + + case AvailableExternallyLinkage: + case LinkOnceODRLinkage: + case WeakODRLinkage: + // The above three cannot be overridden but can be de-refined. + + case ExternalLinkage: + case AppendingLinkage: + case InternalLinkage: + case PrivateLinkage: + return false; + } + llvm_unreachable("Fully covered switch above!"); + } + /// Whether the definition of this global may be discarded if it is not used /// in its compilation unit. static bool isDiscardableIfUnused(LinkageTypes Linkage) { diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index ec82248..d9860a9 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -156,8 +156,8 @@ selectCallee(const ModuleSummaryIndex &Index, CalleeSummaryList, [&](const std::unique_ptr &SummaryPtr) { auto *GVSummary = SummaryPtr.get(); - if (GlobalValue::isWeakAnyLinkage(GVSummary->linkage())) - // There is no point in importing weak symbols, we can't inline them + if (GlobalValue::isMayBeOverriddenLinkage(GVSummary->linkage())) + // There is no point in importing these, we can't inline them return false; if (auto *AS = dyn_cast(GVSummary)) { GVSummary = &AS->getAliasee(); diff --git a/llvm/test/ThinLTO/X86/alias_import.ll b/llvm/test/ThinLTO/X86/alias_import.ll index 6ba0da0..d4ba9bb 100644 --- a/llvm/test/ThinLTO/X86/alias_import.ll +++ b/llvm/test/ThinLTO/X86/alias_import.ll @@ -50,10 +50,10 @@ ; 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) +; On the import side now, verify that aliases to a linkonce_odr are imported, but the weak/linkonce (we can't inline them) ; IMPORT-DAG: declare void @linkonceODRfuncWeakAlias +; IMPORT-DAG: declare void @linkonceODRfuncLinkonceAlias ; 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() diff --git a/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll b/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll index 03ea364..fa96b8e 100644 --- a/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll +++ b/llvm/test/Transforms/FunctionImport/Inputs/funcimport.ll @@ -75,6 +75,11 @@ entry: ret void } +define linkonce void @linkoncefunc2() #0 { +entry: + ret void +} + define internal i32 @staticfunc() #0 { entry: ret i32 1 diff --git a/llvm/test/Transforms/FunctionImport/funcimport.ll b/llvm/test/Transforms/FunctionImport/funcimport.ll index f0df320..478613a 100644 --- a/llvm/test/Transforms/FunctionImport/funcimport.ll +++ b/llvm/test/Transforms/FunctionImport/funcimport.ll @@ -28,6 +28,7 @@ entry: call void (...) @setfuncptr() call void (...) @callfuncptr() call void (...) @weakfunc() + call void (...) @linkoncefunc2() call void (...) @referencelargelinkonce() ret i32 0 } @@ -94,6 +95,10 @@ declare void @referencelargelinkonce(...) ; CHECK-DAG: declare void @weakfunc(...) declare void @weakfunc(...) #1 +; Won't import linkonce func +; CHECK-DAG: declare void @linkoncefunc2(...) +declare void @linkoncefunc2(...) #1 + ; INSTLIMDEF-DAG: Import funcwithpersonality ; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { ; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.{{.*}}() -- 2.7.4