]> granicus.if.org Git - clang/commitdiff
Speed up NumericLiteralParser::GetIntegerValue.
authorDaniel Dunbar <daniel@zuster.org>
Thu, 16 Oct 2008 07:32:01 +0000 (07:32 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 16 Oct 2008 07:32:01 +0000 (07:32 +0000)
 - Implement fast path when value easily fits in a uint64.
 - ~6x faster, translates to 1-2% on Cocoa.h

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57632 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/LiteralSupport.cpp

index 1b86ba5def85f8741b3700661eb434f8071dd46e..34b59255ac7e0bdc06c10a0644bd7daa40ac100b 100644 (file)
@@ -457,6 +457,26 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
 /// matches Val's input width.  If there is an overflow, set Val to the low bits
 /// of the result and return true.  Otherwise, return false.
 bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) {
+  // Fast path: Compute a conservative bound on the maximum number of
+  // bits per digit in this radix. If we can't possibly overflow a
+  // uint64 based on that bound then do the simple conversion to
+  // integer. This avoids the expensive overflow checking below, and
+  // handles the common cases that matter (small decimal integers and
+  // hex/octal values which don't overflow).
+  unsigned MaxBitsPerDigit = 1;
+  while ((1U << MaxBitsPerDigit) < radix) 
+    MaxBitsPerDigit += 1;
+  if ((SuffixBegin - DigitsBegin) * MaxBitsPerDigit <= 64) {
+    uint64_t N = 0;
+    for (s = DigitsBegin; s != SuffixBegin; ++s)
+      N = N*radix + HexDigitValue(*s);
+
+    // This will truncate the value to Val's input width. Simply check
+    // for overflow by comparing.
+    Val = N;
+    return Val.getZExtValue() != N;
+  }
+
   Val = 0;
   s = DigitsBegin;