[llvm] 427e202 - [APInt] improve initialization performance (#106945)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 3 23:54:40 PDT 2024


Author: Princeton Ferro
Date: 2024-09-04T08:54:36+02:00
New Revision: 427e202a401514cb28bf2ca621baae8e1b2f552f

URL: https://github.com/llvm/llvm-project/commit/427e202a401514cb28bf2ca621baae8e1b2f552f
DIFF: https://github.com/llvm/llvm-project/commit/427e202a401514cb28bf2ca621baae8e1b2f552f.diff

LOG: [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%.

Added: 
    

Modified: 
    llvm/lib/Support/APInt.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 78d573966c6c99..2348a4c9b795e1 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) {


        


More information about the llvm-commits mailing list