mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
LowerTypeTests: Propagate symver directives
Summary: This change fixes https://crbug.com/834474, a build failure caused by LowerTypeTests not preserving .symver symbol versioning directives for exported functions. Emit symver information to ThinLTO summary data and then propagate symver directives for exported functions to the merged module. Emitting symver information to the summaries increases the size of intermediate build artifacts for a Chromium build by less than 0.2%. Reviewers: pcc Reviewed By: pcc Subscribers: tejohnson, mehdi_amini, eraman, llvm-commits, eugenis, kcc Differential Revision: https://reviews.llvm.org/D45798 llvm-svn: 330387
This commit is contained in:
parent
3b74e527e4
commit
e5f98a3c30
@ -57,6 +57,15 @@ public:
|
||||
static void CollectAsmSymbols(
|
||||
const Module &M,
|
||||
function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol);
|
||||
|
||||
/// Parse inline ASM and collect the symvers directives that are defined in
|
||||
/// the current module.
|
||||
///
|
||||
/// For each found symbol, call \p AsmSymver with the name of the symbol and
|
||||
/// its alias.
|
||||
static void
|
||||
CollectAsmSymvers(const Module &M,
|
||||
function_ref<void(StringRef, StringRef)> AsmSymver);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -68,9 +68,9 @@ void ModuleSymbolTable::addModule(Module *M) {
|
||||
});
|
||||
}
|
||||
|
||||
void ModuleSymbolTable::CollectAsmSymbols(
|
||||
const Module &M,
|
||||
function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
|
||||
static void
|
||||
initializeRecordStreamer(const Module &M,
|
||||
function_ref<void(RecordStreamer &)> Init) {
|
||||
StringRef InlineAsm = M.getModuleInlineAsm();
|
||||
if (InlineAsm.empty())
|
||||
return;
|
||||
@ -119,6 +119,13 @@ void ModuleSymbolTable::CollectAsmSymbols(
|
||||
if (Parser->Run(false))
|
||||
return;
|
||||
|
||||
Init(Streamer);
|
||||
}
|
||||
|
||||
void ModuleSymbolTable::CollectAsmSymbols(
|
||||
const Module &M,
|
||||
function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
|
||||
initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
|
||||
Streamer.flushSymverDirectives();
|
||||
|
||||
for (auto &KV : Streamer) {
|
||||
@ -149,6 +156,16 @@ void ModuleSymbolTable::CollectAsmSymbols(
|
||||
}
|
||||
AsmSymbol(Key, BasicSymbolRef::Flags(Res));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ModuleSymbolTable::CollectAsmSymvers(
|
||||
const Module &M, function_ref<void(StringRef, StringRef)> AsmSymver) {
|
||||
initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
|
||||
for (auto &KV : Streamer.symverAliases())
|
||||
for (auto &Alias : KV.second)
|
||||
AsmSymver(KV.first->getName(), Alias);
|
||||
});
|
||||
}
|
||||
|
||||
void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
|
||||
|
@ -128,6 +128,11 @@ void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
|
||||
SymverAliasMap[Aliasee].push_back(AliasName);
|
||||
}
|
||||
|
||||
iterator_range<RecordStreamer::const_symver_iterator>
|
||||
RecordStreamer::symverAliases() {
|
||||
return {SymverAliasMap.begin(), SymverAliasMap.end()};
|
||||
}
|
||||
|
||||
void RecordStreamer::flushSymverDirectives() {
|
||||
// Mapping from mangled name to GV.
|
||||
StringMap<const GlobalValue *> MangledNameMap;
|
||||
|
@ -47,10 +47,6 @@ private:
|
||||
public:
|
||||
RecordStreamer(MCContext &Context, const Module &M);
|
||||
|
||||
using const_iterator = StringMap<State>::const_iterator;
|
||||
|
||||
const_iterator begin();
|
||||
const_iterator end();
|
||||
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
|
||||
bool) override;
|
||||
void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
|
||||
@ -63,9 +59,19 @@ public:
|
||||
/// Record .symver aliases for later processing.
|
||||
void emitELFSymverDirective(StringRef AliasName,
|
||||
const MCSymbol *Aliasee) override;
|
||||
|
||||
// Emit ELF .symver aliases and ensure they have the same binding as the
|
||||
// defined symbol they alias with.
|
||||
void flushSymverDirectives();
|
||||
|
||||
// Symbols iterators
|
||||
using const_iterator = StringMap<State>::const_iterator;
|
||||
const_iterator begin();
|
||||
const_iterator end();
|
||||
|
||||
// SymverAliasMap iterators
|
||||
using const_symver_iterator = decltype(SymverAliasMap)::const_iterator;
|
||||
iterator_range<const_symver_iterator> symverAliases();
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -1947,6 +1947,24 @@ bool LowerTypeTestsModule::lower() {
|
||||
}
|
||||
}
|
||||
|
||||
// Emit .symver directives for exported functions, if they exist.
|
||||
if (ExportSummary) {
|
||||
if (NamedMDNode *SymversMD = M.getNamedMetadata("symvers")) {
|
||||
for (auto Symver : SymversMD->operands()) {
|
||||
assert(Symver->getNumOperands() >= 2);
|
||||
StringRef SymbolName =
|
||||
cast<MDString>(Symver->getOperand(0))->getString();
|
||||
StringRef Alias = cast<MDString>(Symver->getOperand(1))->getString();
|
||||
|
||||
if (!ExportedFunctions.count(SymbolName))
|
||||
continue;
|
||||
|
||||
M.appendModuleInlineAsm(
|
||||
(llvm::Twine(".symver ") + SymbolName + ", " + Alias).str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Object/ModuleSymbolTable.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/ScopedPrinter.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -301,13 +302,13 @@ void splitAndWriteThinLTOBitcode(
|
||||
promoteInternals(*MergedM, M, ModuleId, CfiFunctions);
|
||||
promoteInternals(M, *MergedM, ModuleId, CfiFunctions);
|
||||
|
||||
auto &Ctx = MergedM->getContext();
|
||||
SmallVector<MDNode *, 8> CfiFunctionMDs;
|
||||
for (auto V : CfiFunctions) {
|
||||
Function &F = *cast<Function>(V);
|
||||
SmallVector<MDNode *, 2> Types;
|
||||
F.getMetadata(LLVMContext::MD_type, Types);
|
||||
|
||||
auto &Ctx = MergedM->getContext();
|
||||
SmallVector<Metadata *, 4> Elts;
|
||||
Elts.push_back(MDString::get(Ctx, F.getName()));
|
||||
CfiFunctionLinkage Linkage;
|
||||
@ -336,7 +337,6 @@ void splitAndWriteThinLTOBitcode(
|
||||
continue;
|
||||
|
||||
auto *F = cast<Function>(A.getAliasee());
|
||||
auto &Ctx = MergedM->getContext();
|
||||
SmallVector<Metadata *, 4> Elts;
|
||||
|
||||
Elts.push_back(MDString::get(Ctx, A.getName()));
|
||||
@ -355,6 +355,25 @@ void splitAndWriteThinLTOBitcode(
|
||||
NMD->addOperand(MD);
|
||||
}
|
||||
|
||||
SmallVector<MDNode *, 8> Symvers;
|
||||
ModuleSymbolTable::CollectAsmSymvers(M, [&](StringRef Name, StringRef Alias) {
|
||||
Function *F = M.getFunction(Name);
|
||||
if (!F || F->use_empty())
|
||||
return;
|
||||
|
||||
SmallVector<Metadata *, 2> Elts;
|
||||
Elts.push_back(MDString::get(Ctx, Name));
|
||||
Elts.push_back(MDString::get(Ctx, Alias));
|
||||
|
||||
Symvers.push_back(MDTuple::get(Ctx, Elts));
|
||||
});
|
||||
|
||||
if (!Symvers.empty()) {
|
||||
NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("symvers");
|
||||
for (auto MD : Symvers)
|
||||
NMD->addOperand(MD);
|
||||
}
|
||||
|
||||
simplifyExternals(*MergedM);
|
||||
|
||||
// FIXME: Try to re-use BSI and PFI from the original module here.
|
||||
|
16
test/Transforms/LowerTypeTests/export-symver.ll
Normal file
16
test/Transforms/LowerTypeTests/export-symver.ll
Normal file
@ -0,0 +1,16 @@
|
||||
; RUN: opt -S %s -lowertypetests -lowertypetests-summary-action=export -lowertypetests-read-summary=%S/Inputs/use-typeid1-typeid2.yaml | FileCheck %s
|
||||
;
|
||||
; CHECK: module asm ".symver exported_and_symver, alias1"
|
||||
; CHECK-NOT: .symver exported
|
||||
; CHECK-NOT: .symver symver
|
||||
|
||||
target triple = "x86_64-unknown-linux"
|
||||
|
||||
!cfi.functions = !{!0, !1}
|
||||
!symvers = !{!3, !4}
|
||||
|
||||
!0 = !{!"exported_and_symver", i8 2, !2}
|
||||
!1 = !{!"exported", i8 2, !2}
|
||||
!2 = !{i64 0, !"typeid1"}
|
||||
!3 = !{!"exported_and_symver", !"alias1"}
|
||||
!4 = !{!"symver", !"alias2"}
|
22
test/Transforms/ThinLTOBitcodeWriter/symver.ll
Normal file
22
test/Transforms/ThinLTOBitcodeWriter/symver.ll
Normal file
@ -0,0 +1,22 @@
|
||||
; RUN: opt -thinlto-bc -o %t %s
|
||||
; RUN: llvm-modextract -n 1 -o - %t | llvm-dis | FileCheck %s
|
||||
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
module asm ".symver used, used@VER"
|
||||
module asm ".symver unused, unused@VER"
|
||||
module asm ".symver variable, variable@VER"
|
||||
|
||||
declare !type !0 void @used()
|
||||
declare !type !0 void @unused()
|
||||
@variable = global i32 0
|
||||
|
||||
define i32* @use() {
|
||||
call void @used()
|
||||
ret i32* @variable
|
||||
}
|
||||
|
||||
; CHECK: !symvers = !{![[SYMVER:[0-9]+]]}
|
||||
; CHECK: ![[SYMVER]] = !{!"used", !"used@VER"}
|
||||
|
||||
!0 = !{i64 0, !"_ZTSFvvE"}
|
Loading…
x
Reference in New Issue
Block a user