diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO')
| -rw-r--r-- | llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 58 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp | 25 |
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. |

