summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2019-01-11 17:56:35 +0000
committerVedant Kumar <vsk@apple.com>2019-01-11 17:56:35 +0000
commitee10ef737e58409d1c34c68ad17b568e8a50120f (patch)
tree8e643539dfe36331c633f151b3f3b0af039cdd6f
parent08fe7e02fba6206c196d5e8527f8b40bb17941ad (diff)
downloadbcm5719-llvm-ee10ef737e58409d1c34c68ad17b568e8a50120f.tar.gz
bcm5719-llvm-ee10ef737e58409d1c34c68ad17b568e8a50120f.zip
[MergeFunc] Erase unused duplicate functions if they are discardable
MergeFunc only deletes unused duplicate functions if they have local linkage, but it should be safe to relax this to any "discardable if unused" linkage type. Differential Revision: https://reviews.llvm.org/D56574 llvm-svn: 350939
-rw-r--r--llvm/lib/Transforms/IPO/MergeFunctions.cpp2
-rw-r--r--llvm/test/Transforms/MergeFunc/linkonce_odr.ll14
2 files changed, 14 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index 30fe9bbbe61..11efe95b10d 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -845,7 +845,7 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
// If G was internal then we may have replaced all uses of G with F. If so,
// stop here and delete G. There's no need for a thunk. (See note on
// MergeFunctionsPDI above).
- if (G->hasLocalLinkage() && G->use_empty() && !MergeFunctionsPDI) {
+ if (G->isDiscardableIfUnused() && G->use_empty() && !MergeFunctionsPDI) {
G->eraseFromParent();
++NumFunctionsMerged;
return;
diff --git a/llvm/test/Transforms/MergeFunc/linkonce_odr.ll b/llvm/test/Transforms/MergeFunc/linkonce_odr.ll
index 1ad0d727f83..825f9054d7b 100644
--- a/llvm/test/Transforms/MergeFunc/linkonce_odr.ll
+++ b/llvm/test/Transforms/MergeFunc/linkonce_odr.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -mergefunc < %s | FileCheck %s
+; RUN: opt -S -mergefunc < %s | FileCheck %s -implicit-check-not=funC
; Replacments should be totally ordered on the function name.
; If we don't do this we can end up with one module defining a thunk for @funA
@@ -15,6 +15,13 @@
; CHECK-NEXT: tail call i32 @funA(i32 %0, i32 %1)
; CHECK-NEXT: ret
+define linkonce_odr i32 @funC(i32 %x, i32 %y) {
+ %sum = add i32 %x, %y
+ %sum2 = add i32 %x, %sum
+ %sum3 = add i32 %x, %sum2
+ ret i32 %sum3
+}
+
define linkonce_odr i32 @funB(i32 %x, i32 %y) {
%sum = add i32 %x, %y
%sum2 = add i32 %x, %sum
@@ -28,3 +35,8 @@ define linkonce_odr i32 @funA(i32 %x, i32 %y) {
%sum3 = add i32 %x, %sum2
ret i32 %sum3
}
+
+; This creates a use of @funB, preventing -mergefunc from deleting it.
+; @funC, however, can safely be deleted as it has no uses, and is discardable
+; if unused.
+@take_addr_of_funB = global i8* bitcast (i32 (i32, i32)* @funB to i8*)
OpenPOWER on IntegriCloud