summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@redhat.com>2018-10-26 16:52:32 +0000
committerTom Stellard <tstellar@redhat.com>2018-10-26 16:52:32 +0000
commit4c946b7981db07c0108f8ea6c539a5611f754923 (patch)
tree5d8d72c0d0c6f4a2cca8ed079000cbdf7037a34a
parenteb0722e28e734de2b7ce39c52d4ce7e53f222550 (diff)
Merging r344325:
------------------------------------------------------------------------ r344325 | evgeny777 | 2018-10-12 00:24:02 -0700 (Fri, 12 Oct 2018) | 4 lines [ThinLTO] Don't import GV which contains blockaddress Differential revision: https://reviews.llvm.org/D53139 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_70@345401 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/ModuleSummaryAnalysis.cpp19
-rw-r--r--lib/Transforms/IPO/FunctionImport.cpp3
-rw-r--r--test/ThinLTO/X86/Inputs/globals-import-blockaddr.ll12
-rw-r--r--test/ThinLTO/X86/globals-import-blockaddr.ll18
4 files changed, 47 insertions, 5 deletions
diff --git a/lib/Analysis/ModuleSummaryAnalysis.cpp b/lib/Analysis/ModuleSummaryAnalysis.cpp
index 17dae20ce3a..ce099ed2f39 100644
--- a/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -74,9 +74,17 @@ cl::opt<FunctionSummary::ForceSummaryHotnessType, true> FSEC(
// Walk through the operands of a given User via worklist iteration and populate
// the set of GlobalValue references encountered. Invoked either on an
// Instruction or a GlobalVariable (which walks its initializer).
-static void findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
+// Return true if any of the operands contains blockaddress. This is important
+// to know when computing summary for global var, because if global variable
+// references basic block address we can't import it separately from function
+// containing that basic block. For simplicity we currently don't import such
+// global vars at all. When importing function we aren't interested if any
+// instruction in it takes an address of any basic block, because instruction
+// can only take an address of basic block located in the same function.
+static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
SetVector<ValueInfo> &RefEdges,
SmallPtrSet<const User *, 8> &Visited) {
+ bool HasBlockAddress = false;
SmallVector<const User *, 32> Worklist;
Worklist.push_back(CurUser);
@@ -92,8 +100,10 @@ static void findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
const User *Operand = dyn_cast<User>(OI);
if (!Operand)
continue;
- if (isa<BlockAddress>(Operand))
+ if (isa<BlockAddress>(Operand)) {
+ HasBlockAddress = true;
continue;
+ }
if (auto *GV = dyn_cast<GlobalValue>(Operand)) {
// We have a reference to a global value. This should be added to
// the reference set unless it is a callee. Callees are handled
@@ -105,6 +115,7 @@ static void findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
Worklist.push_back(Operand);
}
}
+ return HasBlockAddress;
}
static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount,
@@ -369,7 +380,7 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
DenseSet<GlobalValue::GUID> &CantBePromoted) {
SetVector<ValueInfo> RefEdges;
SmallPtrSet<const User *, 8> Visited;
- findRefEdges(Index, &V, RefEdges, Visited);
+ bool HasBlockAddress = findRefEdges(Index, &V, RefEdges, Visited);
bool NonRenamableLocal = isNonRenamableLocal(V);
GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
/* Live = */ false, V.isDSOLocal());
@@ -377,6 +388,8 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
if (NonRenamableLocal)
CantBePromoted.insert(V.getGUID());
+ if (HasBlockAddress)
+ GVarSummary->setNotEligibleToImport();
Index.addGlobalValueSummary(V, std::move(GVarSummary));
}
diff --git a/lib/Transforms/IPO/FunctionImport.cpp b/lib/Transforms/IPO/FunctionImport.cpp
index 15808a07389..ed97d342f34 100644
--- a/lib/Transforms/IPO/FunctionImport.cpp
+++ b/lib/Transforms/IPO/FunctionImport.cpp
@@ -258,8 +258,7 @@ static void computeImportForReferencedGlobals(
for (auto &RefSummary : VI.getSummaryList())
if (RefSummary->getSummaryKind() == GlobalValueSummary::GlobalVarKind &&
- // Don't try to import regular LTO summaries added to dummy module.
- !RefSummary->modulePath().empty() &&
+ !RefSummary->notEligibleToImport() &&
!GlobalValue::isInterposableLinkage(RefSummary->linkage()) &&
RefSummary->refs().empty()) {
ImportList[RefSummary->modulePath()].insert(VI.getGUID());
diff --git a/test/ThinLTO/X86/Inputs/globals-import-blockaddr.ll b/test/ThinLTO/X86/Inputs/globals-import-blockaddr.ll
new file mode 100644
index 00000000000..fe1fa70ee83
--- /dev/null
+++ b/test/ThinLTO/X86/Inputs/globals-import-blockaddr.ll
@@ -0,0 +1,12 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@label_addr = internal constant [1 x i8*] [i8* blockaddress(@foo, %lb)], align 8
+
+; Function Attrs: noinline norecurse nounwind optnone uwtable
+define dso_local [1 x i8*]* @foo() {
+ br label %lb
+
+lb:
+ ret [1 x i8*]* @label_addr
+}
diff --git a/test/ThinLTO/X86/globals-import-blockaddr.ll b/test/ThinLTO/X86/globals-import-blockaddr.ll
new file mode 100644
index 00000000000..d4ed674030a
--- /dev/null
+++ b/test/ThinLTO/X86/globals-import-blockaddr.ll
@@ -0,0 +1,18 @@
+; RUN: opt -module-summary %s -o %t1.bc
+; RUN: opt -module-summary %p/Inputs/globals-import-blockaddr.ll -o %t2.bc
+; RUN: llvm-lto2 run -save-temps %t1.bc -r=%t1.bc,foo,l -r=%t1.bc,main,pl %t2.bc -r=%t2.bc,foo,pl -o %t3
+; RUN: llvm-dis %t3.1.3.import.bc -o - | FileCheck %s
+
+; Verify that we haven't imported GV containing blockaddress
+; CHECK: @label_addr.llvm.0 = external hidden constant
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare dso_local [1 x i8*]* @foo();
+
+define dso_local i32 @main() {
+ %p = call [1 x i8*]* @foo()
+ %v = ptrtoint [1 x i8*]* %p to i32
+ ret i32 %v
+}