diff options
author | Princeton Ferro <princetonferro@gmail.com> | 2024-09-03 23:54:36 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-04 08:54:36 +0200 |
commit | 427e202a401514cb28bf2ca621baae8e1b2f552f (patch) | |
tree | bdc67c6a6f1a4c0c33e390685c03887b16f6616e /llvm/lib/Support/APInt.cpp | |
parent | 06286832db0c4ee1899f9cee1b8f6234e45f16c7 (diff) | |
download | llvm-427e202a401514cb28bf2ca621baae8e1b2f552f.zip llvm-427e202a401514cb28bf2ca621baae8e1b2f552f.tar.gz llvm-427e202a401514cb28bf2ca621baae8e1b2f552f.tar.bz2 |
[APInt] improve initialization performance (#106945)
The purpose is to save an extra memset in both cases:
1. When `int64_t(val) < 0`, zeroing out is redundant as the subsequent
for-loop will initialize to `val .. 0xFFFFF ....`. Instead we should
only create an uninitialized buffer, and transform the slow for-loop
into a memset to initialize the higher words to `0xFF`.
2. In the other case, first we create an uninitialized array (`new
int64_t[]`) and _then_ we zero it out with `memset`. But this can be
combined in one operation with `new int64_t[]()`, which
default-initializes the array.
On one example where use of APInt was heavy, this improved compile time
by 1%.
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 78d5739..2348a4c 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -34,9 +34,7 @@ using namespace llvm; /// A utility function for allocating memory, checking for allocation failures, /// and ensuring the contents are zeroed. inline static uint64_t* getClearedMemory(unsigned numWords) { - uint64_t *result = new uint64_t[numWords]; - memset(result, 0, numWords * sizeof(uint64_t)); - return result; + return new uint64_t[numWords](); } /// A utility function for allocating memory and checking for allocation @@ -74,12 +72,15 @@ inline static unsigned getDigit(char cdigit, uint8_t radix) { void APInt::initSlowCase(uint64_t val, bool isSigned) { - U.pVal = getClearedMemory(getNumWords()); - U.pVal[0] = val; - if (isSigned && int64_t(val) < 0) - for (unsigned i = 1; i < getNumWords(); ++i) - U.pVal[i] = WORDTYPE_MAX; - clearUnusedBits(); + if (isSigned && int64_t(val) < 0) { + U.pVal = getMemory(getNumWords()); + U.pVal[0] = val; + memset(&U.pVal[1], 0xFF, APINT_WORD_SIZE * (getNumWords() - 1)); + clearUnusedBits(); + } else { + U.pVal = getClearedMemory(getNumWords()); + U.pVal[0] = val; + } } void APInt::initSlowCase(const APInt& that) { |