summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2017-09-07 05:35:35 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2017-09-07 05:35:35 +0000
commit681fbb64a4cdaba874280bb23e41d2126c7c5766 (patch)
treea184914b63e3b0255bc80a29e8fcb9c0307a297a
parent754e58407667361533f778ea195f3a98bafde3ec (diff)
downloadbcm5719-llvm-681fbb64a4cdaba874280bb23e41d2126c7c5766.tar.gz
bcm5719-llvm-681fbb64a4cdaba874280bb23e41d2126c7c5766.zip
ModuleSummaryAnalysis: Correctly handle all function operand references.
The current code that handles personality functions when creating a module summary does not correctly handle the case where a function's personality function operand refers to the function indirectly (e.g. via a bitcast). This patch handles such cases by treating personality function references like any other reference, i.e. by adding them to the function's reference list. This has the minor side benefit of allowing personality functions to participate in early dead stripping. We do this by calling findRefEdges on the function itself. This way we also end up handling other function operands (specifically prefix data and prologue data) for free. Differential Revision: https://reviews.llvm.org/D37553 llvm-svn: 312698
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp12
-rw-r--r--llvm/test/ThinLTO/X86/Inputs/personality.ll8
-rw-r--r--llvm/test/ThinLTO/X86/personality.ll39
3 files changed, 52 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 4950780ae75..2b355deade3 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -215,9 +215,13 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
SetVector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls,
TypeCheckedLoadConstVCalls;
ICallPromotionAnalysis ICallAnalysis;
+ SmallPtrSet<const User *, 8> Visited;
+
+ // Add personality function, prefix data and prologue data to function's ref
+ // list.
+ findRefEdges(Index, &F, RefEdges, Visited);
bool HasInlineAsmMaybeReferencingInternal = false;
- SmallPtrSet<const User *, 8> Visited;
for (const BasicBlock &BB : F)
for (const Instruction &I : BB) {
if (isa<DbgInfoIntrinsic>(I))
@@ -456,12 +460,6 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
CantBePromoted);
}
- // Set live flag for all personality functions. That allows to
- // preserve them during DCE.
- for (const llvm::Function &F : M)
- if (!F.isDeclaration() && F.hasPersonalityFn())
- setLiveRoot(Index, F.getPersonalityFn()->getName());
-
// Compute summaries for all variables defined in module, and save in the
// index.
for (const GlobalVariable &G : M.globals()) {
diff --git a/llvm/test/ThinLTO/X86/Inputs/personality.ll b/llvm/test/ThinLTO/X86/Inputs/personality.ll
index 88c32cb11a2..37046b5c28d 100644
--- a/llvm/test/ThinLTO/X86/Inputs/personality.ll
+++ b/llvm/test/ThinLTO/X86/Inputs/personality.ll
@@ -8,3 +8,11 @@ define void @bar() personality i32 (i32, i32, i64, i8*, i8*)* @personality_routi
define protected i32 @personality_routine(i32, i32, i64, i8*, i8*) {
ret i32 0
}
+
+define protected i32 @personality_routine2(i32, i32, i64, i8*, i8*) {
+ ret i32 0
+}
+
+define protected i32 @personality_routine3(i32, i32, i64, i8*, i8*) {
+ ret i32 0
+}
diff --git a/llvm/test/ThinLTO/X86/personality.ll b/llvm/test/ThinLTO/X86/personality.ll
index 4b77cb34f72..a6caf3711ef 100644
--- a/llvm/test/ThinLTO/X86/personality.ll
+++ b/llvm/test/ThinLTO/X86/personality.ll
@@ -4,8 +4,14 @@
; RUN: llvm-lto2 run -o %t.o %t1.bc %t2.bc -save-temps \
; RUN: -r %t2.bc,bar,p \
; RUN: -r %t2.bc,personality_routine,p \
+; RUN: -r %t2.bc,personality_routine2,p \
+; RUN: -r %t2.bc,personality_routine3,p \
; RUN: -r %t1.bc,foo,p \
+; RUN: -r %t1.bc,foo2,p \
+; RUN: -r %t1.bc,foo3,p \
; RUN: -r %t1.bc,personality_routine,l \
+; RUN: -r %t1.bc,personality_routine2,l \
+; RUN: -r %t1.bc,personality_routine3,l \
; RUN: -r %t1.bc,main,xp \
; RUN: -r %t1.bc,bar,l
; RUN: llvm-readobj -t %t.o.1 | FileCheck %s --check-prefix=BINDING
@@ -22,18 +28,51 @@
; BINDING-NEXT: Section: .text
; BINDING-NEXT: }
+; BINDING-NEXT: Symbol {
+; BINDING-NEXT: Name: personality_routine2
+; BINDING-NEXT: Value:
+; BINDING-NEXT: Size:
+; BINDING-NEXT: Binding: Global
+; BINDING-NEXT: Type: Function
+; BINDING-NEXT: Other [
+; BINDING-NEXT: STV_PROTECTED
+; BINDING-NEXT: ]
+; BINDING-NEXT: Section: .text
+; BINDING-NEXT: }
+
+; BINDING-NOT: Name: personality_routine3
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
declare protected i32 @personality_routine(i32, i32, i64, i8*, i8*)
+declare protected i32 @personality_routine2(i32, i32, i64, i8*, i8*)
+declare protected i32 @personality_routine3(i32, i32, i64, i8*, i8*)
declare void @bar()
define void @foo() personality i32 (i32, i32, i64, i8*, i8*)* @personality_routine {
ret void
}
+define internal void @foo2b() personality i8* bitcast (i32 (i32, i32, i64, i8*, i8*)* @personality_routine2 to i8*) {
+ ret void
+}
+
+define internal void @foo2a() prologue void ()* @foo2b {
+ ret void
+}
+
+define void @foo2() prefix void ()* @foo2a {
+ ret void
+}
+
+define void @foo3() personality i8* bitcast (i32 (i32, i32, i64, i8*, i8*)* @personality_routine3 to i8*) {
+ ret void
+}
+
define i32 @main() {
call void @foo()
+ call void @foo2()
call void @bar()
ret i32 0
}
OpenPOWER on IntegriCloud