aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/LTO/LTO.cpp
diff options
context:
space:
mode:
authorYuanfang Chen <yuanfang.chen@sony.com>2021-03-18 15:32:29 -0700
committerYuanfang Chen <yuanfang.chen@sony.com>2021-03-18 15:33:42 -0700
commitb4a8c0ebb6d49f757c687833d85f843aaeb19133 (patch)
tree49e5bdab5f57216fca93eabcae74e63d2e12e817 /llvm/lib/LTO/LTO.cpp
parent2df65f87c1ea81008768e14522e5d9277234ba70 (diff)
downloadllvm-b4a8c0ebb6d49f757c687833d85f843aaeb19133.zip
llvm-b4a8c0ebb6d49f757c687833d85f843aaeb19133.tar.gz
llvm-b4a8c0ebb6d49f757c687833d85f843aaeb19133.tar.bz2
[LTO][MC] Discard non-prevailing defined symbols in module-level assembly
This is the alternative approach to D96931. In LTO, for each module with inlineasm block, prepend directive ".lto_discard <sym>, <sym>*" to the beginning of the inline asm. ".lto_discard" is both a module inlineasm block marker and (optionally) provides a list of symbols to be discarded. In MC while emitting for inlineasm, discard symbol binding & symbol definitions according to ".lto_disard". Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D98762
Diffstat (limited to 'llvm/lib/LTO/LTO.cpp')
-rw-r--r--llvm/lib/LTO/LTO.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 8bcb160..3cd8c78 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -11,7 +11,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/LTO/LTO.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
@@ -752,6 +754,7 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
Skip();
std::set<const Comdat *> NonPrevailingComdats;
+ SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
for (const InputFile::Symbol &Sym : Syms) {
assert(ResI != ResE);
SymbolResolution Res = *ResI++;
@@ -798,7 +801,14 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
GV->setDLLStorageClass(GlobalValue::DLLStorageClassTypes::
DefaultStorageClass);
}
+ } else if (auto *AS = Msym.dyn_cast<ModuleSymbolTable::AsmSymbol *>()) {
+ // Collect non-prevailing symbols.
+ if (!Res.Prevailing)
+ NonPrevailingAsmSymbols.insert(AS->first);
+ } else {
+ llvm_unreachable("unknown symbol type");
}
+
// Common resolution: collect the maximum size/alignment over all commons.
// We also record if we see an instance of a common as prevailing, so that
// if none is prevailing we can ignore it later.
@@ -812,11 +822,29 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
CommonRes.Align = max(*SymAlign, CommonRes.Align);
CommonRes.Prevailing |= Res.Prevailing;
}
-
}
+
if (!M.getComdatSymbolTable().empty())
for (GlobalValue &GV : M.global_values())
handleNonPrevailingComdat(GV, NonPrevailingComdats);
+
+ // Prepend ".lto_discard <sym>, <sym>*" directive to each module inline asm
+ // block.
+ if (!M.getModuleInlineAsm().empty()) {
+ std::string NewIA = ".lto_discard";
+ if (!NonPrevailingAsmSymbols.empty()) {
+ // Don't dicard a symbol if there is a live .symver for it.
+ ModuleSymbolTable::CollectAsmSymvers(
+ M, [&](StringRef Name, StringRef Alias) {
+ if (!NonPrevailingAsmSymbols.count(Alias))
+ NonPrevailingAsmSymbols.erase(Name);
+ });
+ NewIA += " " + llvm::join(NonPrevailingAsmSymbols, ", ");
+ }
+ NewIA += "\n";
+ M.setModuleInlineAsm(NewIA + M.getModuleInlineAsm());
+ }
+
assert(MsymI == MsymE);
return std::move(Mod);
}