summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/IPO/LowerTypeTests.cpp58
-rw-r--r--llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp25
2 files changed, 83 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.
OpenPOWER on IntegriCloud