summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/IPO/LowerTypeTests.cpp58
-rw-r--r--llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp25
-rw-r--r--llvm/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml11
-rw-r--r--llvm/test/Transforms/LowerTypeTests/export-alias.ll21
-rw-r--r--llvm/test/Transforms/LowerTypeTests/import-alias.ll30
-rw-r--r--llvm/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll25
6 files changed, 170 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 8db7e1e142d..20f54ef53f7 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -956,6 +956,21 @@ void LowerTypeTestsModule::importFunction(Function *F, bool isDefinition) {
FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
Name, &M);
FDecl->setVisibility(Visibility);
+
+ // Delete aliases pointing to this function, they'll be re-created in the
+ // merged output
+ SmallVector<GlobalAlias*, 4> ToErase;
+ for (auto &U : F->uses()) {
+ if (auto *A = dyn_cast<GlobalAlias>(U.getUser())) {
+ Function *AliasDecl = Function::Create(
+ F->getFunctionType(), GlobalValue::ExternalLinkage, "", &M);
+ AliasDecl->takeName(A);
+ A->replaceAllUsesWith(AliasDecl);
+ ToErase.push_back(A);
+ }
+ }
+ for (auto *A : ToErase)
+ A->eraseFromParent();
} else {
// Function definition without type metadata, where some other translation
// unit contained a declaration with type metadata. This normally happens
@@ -1804,6 +1819,49 @@ bool LowerTypeTestsModule::lower() {
allocateByteArrays();
+ // Parse alias data to replace stand-in function declarations for aliases
+ // with an alias to the intended target.
+ if (ExportSummary) {
+ if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
+ for (auto AliasMD : AliasesMD->operands()) {
+ assert(AliasMD->getNumOperands() >= 4);
+ StringRef AliasName =
+ cast<MDString>(AliasMD->getOperand(0))->getString();
+ StringRef Aliasee = cast<MDString>(AliasMD->getOperand(1))->getString();
+
+ if (!ExportedFunctions.count(Aliasee) ||
+ ExportedFunctions[Aliasee].Linkage != CFL_Definition ||
+ !M.getNamedAlias(Aliasee))
+ continue;
+
+ GlobalValue::VisibilityTypes Visibility =
+ static_cast<GlobalValue::VisibilityTypes>(
+ cast<ConstantAsMetadata>(AliasMD->getOperand(2))
+ ->getValue()
+ ->getUniqueInteger()
+ .getZExtValue());
+ bool Weak =
+ static_cast<bool>(cast<ConstantAsMetadata>(AliasMD->getOperand(3))
+ ->getValue()
+ ->getUniqueInteger()
+ .getZExtValue());
+
+ auto *Alias = GlobalAlias::create("", M.getNamedAlias(Aliasee));
+ Alias->setVisibility(Visibility);
+ if (Weak)
+ Alias->setLinkage(GlobalValue::WeakAnyLinkage);
+
+ if (auto *F = M.getFunction(AliasName)) {
+ Alias->takeName(F);
+ F->replaceAllUsesWith(Alias);
+ F->eraseFromParent();
+ } else {
+ Alias->setName(AliasName);
+ }
+ }
+ }
+ }
+
return true;
}
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index caffc03339c..f5a3d4452c7 100644
--- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -357,6 +357,31 @@ void splitAndWriteThinLTOBitcode(
NMD->addOperand(MD);
}
+ SmallVector<MDNode *, 8> FunctionAliases;
+ for (auto &A : M.aliases()) {
+ if (!isa<Function>(A.getAliasee()))
+ continue;
+
+ auto *F = cast<Function>(A.getAliasee());
+ auto &Ctx = MergedM->getContext();
+ SmallVector<Metadata *, 4> Elts;
+
+ Elts.push_back(MDString::get(Ctx, A.getName()));
+ Elts.push_back(MDString::get(Ctx, F->getName()));
+ Elts.push_back(ConstantAsMetadata::get(
+ llvm::ConstantInt::get(Type::getInt8Ty(Ctx), A.getVisibility())));
+ Elts.push_back(ConstantAsMetadata::get(
+ llvm::ConstantInt::get(Type::getInt8Ty(Ctx), A.isWeakForLinker())));
+
+ FunctionAliases.push_back(MDTuple::get(Ctx, Elts));
+ }
+
+ if (!FunctionAliases.empty()) {
+ NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("aliases");
+ for (auto MD : FunctionAliases)
+ NMD->addOperand(MD);
+ }
+
simplifyExternals(*MergedM);
// FIXME: Try to re-use BSI and PFI from the original module here.
diff --git a/llvm/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml b/llvm/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml
new file mode 100644
index 00000000000..a5943cb9fd6
--- /dev/null
+++ b/llvm/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml
@@ -0,0 +1,11 @@
+---
+TypeIdMap:
+ typeid1:
+ TTRes:
+ Kind: AllOnes
+ SizeM1BitWidth: 7
+WithGlobalValueDeadStripping: false
+CfiFunctionDefs:
+ - f
+CfiFunctionDecls:
+...
diff --git a/llvm/test/Transforms/LowerTypeTests/export-alias.ll b/llvm/test/Transforms/LowerTypeTests/export-alias.ll
new file mode 100644
index 00000000000..6e9c074068d
--- /dev/null
+++ b/llvm/test/Transforms/LowerTypeTests/export-alias.ll
@@ -0,0 +1,21 @@
+; RUN: opt -S %s -lowertypetests -lowertypetests-summary-action=export -lowertypetests-read-summary=%S/Inputs/use-typeid1-typeid2.yaml | FileCheck %s
+;
+; CHECK: @alias1 = weak alias void (), void ()* @f
+; CHECK: @alias2 = hidden alias void (), void ()* @f
+; CHECK: declare !type !1 void @alias3()
+; CHECK-NOT: @alias3 = alias
+
+target triple = "x86_64-unknown-linux"
+
+!cfi.functions = !{!0, !2, !3}
+!aliases = !{!4, !5, !6}
+
+!0 = !{!"f", i8 0, !1}
+!1 = !{i64 0, !"typeid1"}
+!2 = !{!"alias1", i8 1, !1}
+; alias2 not included here, this could happen if the only reference to alias2
+; is in a module compiled without cfi-icall
+!3 = !{!"alias3", i8 1, !1}
+!4 = !{!"alias1", !"f", i8 0, i8 1}
+!5 = !{!"alias2", !"f", i8 1, i8 0}
+!6 = !{!"alias3", !"not_present", i8 0, i8 0}
diff --git a/llvm/test/Transforms/LowerTypeTests/import-alias.ll b/llvm/test/Transforms/LowerTypeTests/import-alias.ll
new file mode 100644
index 00000000000..e673da7484c
--- /dev/null
+++ b/llvm/test/Transforms/LowerTypeTests/import-alias.ll
@@ -0,0 +1,30 @@
+; RUN: opt -S %s -lowertypetests -lowertypetests-summary-action=import -lowertypetests-read-summary=%S/Inputs/import-alias.yaml | FileCheck %s
+;
+; Check that the definitions for @f and @f_alias are removed from this module
+; but @g_alias remains.
+;
+; CHECK: @g_alias = alias void (), void ()* @g
+; CHECK: define hidden void @f.cfi
+; CHECK: declare void @f()
+; CHECK: declare void @f_alias()
+
+target triple = "x86_64-unknown-linux"
+
+@f_alias = alias void (), void ()* @f
+@g_alias = alias void (), void ()* @g
+
+; Definition moved to the merged module
+define void @f() {
+ ret void
+}
+
+; Definition not moved to the merged module
+define void @g() {
+ ret void
+}
+
+define void @uses_aliases() {
+ call void @f_alias()
+ call void @g_alias()
+ ret void
+}
diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll
new file mode 100644
index 00000000000..119b8219bab
--- /dev/null
+++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll
@@ -0,0 +1,25 @@
+; RUN: opt -thinlto-bc -o %t %s
+; RUN: llvm-modextract -n 1 -o - %t | llvm-dis | FileCheck --check-prefix=CHECK1 %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define hidden void @Func() !type !0 {
+ ret void
+}
+
+; CHECK1: !aliases = !{![[A1:[0-9]+]], ![[A2:[0-9]+]], ![[A3:[0-9]+]]}
+
+; CHECK1: ![[A1]] = !{!"Alias", !"Func", i8 1, i8 0}
+; CHECK1: ![[A2]] = !{!"Hidden_Alias", !"Func", i8 1, i8 0}
+; CHECK1: ![[A3]] = !{!"Weak_Alias", !"Func", i8 0, i8 1}
+@Alias = hidden alias void (), void ()* @Func
+@Hidden_Alias = hidden alias void (), void ()* @Func
+@Weak_Alias = weak alias void (), void ()* @Func
+
+@Variable = global i32 0
+
+; Only generate summary alias information for aliases to functions
+; CHECK1-NOT: Variable_Alias
+@Variable_Alias = alias i32, i32* @Variable
+
+!0 = !{i64 0, !"_ZTSFvvE"}
OpenPOWER on IntegriCloud