diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -19,6 +19,7 @@ #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" +#include "lld/Common/Arrays.h" #include "lld/Common/Filesystem.h" #include "lld/Common/Memory.h" #include "lld/Common/Strings.h" @@ -2972,19 +2973,6 @@ sec->writeTo(Out::bufferStart + sec->offset); } -// Split one uint8 array into small pieces of uint8 arrays. -static std::vector> split(ArrayRef arr, - size_t chunkSize) { - std::vector> ret; - while (arr.size() > chunkSize) { - ret.push_back(arr.take_front(chunkSize)); - arr = arr.drop_front(chunkSize); - } - if (!arr.empty()) - ret.push_back(arr); - return ret; -} - // Computes a hash value of Data using a given hash function. // In order to utilize multiple cores, we first split data into 1MB // chunks, compute a hash for each chunk, and then compute a hash value diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -20,12 +20,14 @@ #include "Target.h" #include "UnwindInfoSection.h" +#include "lld/Common/Arrays.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/Parallel.h" #include "llvm/Support/Path.h" #include "llvm/Support/xxhash.h" @@ -910,9 +912,17 @@ osec->writeTo(buf + osec->fileOff); } +// In order to utilize multiple cores, we first split the buffer into 1MB +// chunks, compute a hash for each chunk, and then compute a hash value +// of the hash values. void Writer::writeUuid() { - uint64_t digest = - xxHash64({buffer->getBufferStart(), buffer->getBufferEnd()}); + ArrayRef data{buffer->getBufferStart(), buffer->getBufferEnd()}; + std::vector> chunks = split(data, 1024 * 1024); + std::vector hashes(chunks.size()); + parallelForEachN(0, chunks.size(), + [&](size_t i) { hashes[i] = xxHash64(chunks[i]); }); + uint64_t digest = xxHash64({reinterpret_cast(hashes.data()), + hashes.size() * sizeof(uint64_t)}); uuidCommand->writeUuid(digest); } diff --git a/lld/include/lld/Common/Arrays.h b/lld/include/lld/Common/Arrays.h new file mode 100644 --- /dev/null +++ b/lld/include/lld/Common/Arrays.h @@ -0,0 +1,32 @@ +//===- Arrays.h ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_ARRAYS_H +#define LLD_ARRAYS_H + +#include "llvm/ADT/ArrayRef.h" + +#include + +namespace lld { +// Split one uint8 array into small pieces of uint8 arrays. +inline std::vector> split(ArrayRef arr, + size_t chunkSize) { + std::vector> ret; + while (arr.size() > chunkSize) { + ret.push_back(arr.take_front(chunkSize)); + arr = arr.drop_front(chunkSize); + } + if (!arr.empty()) + ret.push_back(arr); + return ret; +} + +} // namespace lld + +#endif