[lld] f6bd0a8 - [ELF] Add makeThreadLocal/makeThreadLocalN and remove InputFile::localSymStorage
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 4 11:09:45 PDT 2022
Author: Fangrui Song
Date: 2022-08-04T11:09:40-07:00
New Revision: f6bd0a8f2bc4b62f7f7800a7dd1de6ba764b56c6
URL: https://github.com/llvm/llvm-project/commit/f6bd0a8f2bc4b62f7f7800a7dd1de6ba764b56c6
DIFF: https://github.com/llvm/llvm-project/commit/f6bd0a8f2bc4b62f7f7800a7dd1de6ba764b56c6.diff
LOG: [ELF] Add makeThreadLocal/makeThreadLocalN and remove InputFile::localSymStorage
makeThreadLocal/makeThreadLocalN are moved from D130810 ([ELF] Parallelize input
section initialization) here to make D130810 more focused on the refactor:
* COFF has some needs for multiple linker contexts. D108850 partially removed
global states from lldCommon but left the global variable `lctx`.
* To the best of my knowledge, all multiple-linker-context feature requests to
ELF are more from user convenience, with no very strong argument.
* In practice, ELF port is very difficult to remove global states without
introducing significant performance regression/hurting code readability.
* Per-thread allocators from D122922/D123879 are too expensive and will not
really benefit ELF.
This patch adds a simple thread_local based makeThreadLocal to
lld/Common/Memory.h. It will enable further optimization in ELF.
Added:
Modified:
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/include/lld/Common/Memory.h
Removed:
################################################################################
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 378023abc1928..560e24f5e9233 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1066,8 +1066,7 @@ void ObjFile<ELFT>::initializeSymbols(const object::ELFFile<ELFT> &obj) {
template <class ELFT> void ObjFile<ELFT>::initializeLocalSymbols() {
if (!firstGlobal)
return;
- localSymStorage = std::make_unique<SymbolUnion[]>(firstGlobal);
- SymbolUnion *locals = localSymStorage.get();
+ SymbolUnion *locals = makeThreadLocalN<SymbolUnion>(firstGlobal);
ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();
for (size_t i = 0, end = firstGlobal; i != end; ++i) {
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index a24e664a7e168..dd9f7328a103c 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -304,9 +304,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
// If the section does not exist (which is common), the array is empty.
ArrayRef<Elf_Word> shndxTable;
- // Storage for local symbols.
- std::unique_ptr<SymbolUnion[]> localSymStorage;
-
// Debugging information to retrieve source file and line for error
// reporting. Linker may find reasonable number of errors in a
// single object file, so we cache debugging information in order to
diff --git a/lld/include/lld/Common/Memory.h b/lld/include/lld/Common/Memory.h
index 0b2f474c30135..c7612a08c6b00 100644
--- a/lld/include/lld/Common/Memory.h
+++ b/lld/include/lld/Common/Memory.h
@@ -62,6 +62,32 @@ template <typename T, typename... U> T *make(U &&... args) {
T(std::forward<U>(args)...);
}
+template <typename T>
+inline llvm::SpecificBumpPtrAllocator<T> &
+getSpecificAllocSingletonThreadLocal() {
+ thread_local SpecificAlloc<T> instance;
+ return instance.alloc;
+}
+
+// Create a new instance of T off a thread-local SpecificAlloc, used by code
+// like parallel input section initialization. The use cases assume that the
+// return value outlives the containing parallelForEach (if exists), which is
+// currently guaranteed: when parallelForEach returns, the threads allocating
+// the TLS are not destroyed.
+//
+// Note: Some ports (e.g. ELF) have lots of global states which are currently
+// infeasible to remove, and context() just adds overhead with no benefit. The
+// allocation performance is of higher importance, so we simply use thread_local
+// allocators instead of doing context indirection and pthread_getspecific.
+template <typename T, typename... U> T *makeThreadLocal(U &&...args) {
+ return new (getSpecificAllocSingletonThreadLocal<T>().Allocate())
+ T(std::forward<U>(args)...);
+}
+
+template <typename T> T *makeThreadLocalN(size_t n) {
+ return new (getSpecificAllocSingletonThreadLocal<T>().Allocate(n)) T[n];
+}
+
} // namespace lld
#endif
More information about the llvm-commits
mailing list