[llvm][StringExtras] Use a lookup table for `hexDigitValue`
authorRiver Riddle <riddleriver@gmail.com>
Wed, 28 Oct 2020 23:46:31 +0000 (16:46 -0700)
committerRiver Riddle <riddleriver@gmail.com>
Wed, 28 Oct 2020 23:58:06 +0000 (16:58 -0700)
This method is at the core of the conversion from hex to binary, and using a lookup table great improves the compile time of hex conversions.

Context: In MLIR we use hex strings to represent very large constants in the textual format of the IR. These changes lead to a large decrease in compile time when parsing these constants (>1 second -> 350 miliseconds).

Differential Revision: https://reviews.llvm.org/D90320

llvm/include/llvm/ADT/StringExtras.h

index 6084a56..77288f8 100644 (file)
@@ -66,10 +66,22 @@ inline ArrayRef<uint8_t> arrayRefFromStringRef(StringRef Input) {
 ///
 /// If \p C is not a valid hex digit, -1U is returned.
 inline unsigned hexDigitValue(char C) {
-  if (C >= '0' && C <= '9') return C-'0';
-  if (C >= 'a' && C <= 'f') return C-'a'+10U;
-  if (C >= 'A' && C <= 'F') return C-'A'+10U;
-  return -1U;
+  struct HexTable {
+    unsigned LUT[255] = {};
+    constexpr HexTable() {
+      // Default initialize everything to invalid.
+      for (int i = 0; i < 255; ++i)
+        LUT[i] = -1U;
+      // Initialize `0`-`9`.
+      for (int i = 0; i < 10; ++i)
+        LUT['0' + i] = i;
+      // Initialize `A`-`F` and `a`-`f`.
+      for (int i = 0; i < 6; ++i)
+        LUT['A' + i] = LUT['a' + i] = 10 + i;
+    }
+  };
+  constexpr HexTable Table;
+  return Table.LUT[static_cast<unsigned char>(C)];
 }
 
 /// Checks if character \p C is one of the 10 decimal digits.