diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2012-09-25 19:09:15 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2012-09-25 19:09:15 +0000 |
commit | 191046d0504cec221655e9821f264f492a70f0b1 (patch) | |
tree | 8ebac5401a0b06fbbeb677c7dac9d1f55d598241 /lib/Lex/LiteralSupport.cpp | |
parent | bf7f77ac1cd1f31fc6bf2072327eeee7baed5c6a (diff) | |
download | clang-191046d0504cec221655e9821f264f492a70f0b1.tar.gz clang-191046d0504cec221655e9821f264f492a70f0b1.tar.bz2 clang-191046d0504cec221655e9821f264f492a70f0b1.tar.xz |
Optimize NumericLiteralParser::GetIntegerValue().
It does a conservative estimate on the size of numbers that can fit into
uint64_t. This bound is improved.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164624 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/LiteralSupport.cpp')
-rw-r--r-- | lib/Lex/LiteralSupport.cpp | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index e65d2edbd3..d669c19a0c 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -752,6 +752,20 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { } } +static bool CanFitInto64Bits(unsigned Radix, unsigned NumDigits) { + switch (Radix) { + case 2: + return NumDigits <= 64; + case 8: + return NumDigits <= 64 / 3; // Digits are groups of 3 bits. + case 10: + return NumDigits <= 19; // floor(log10(2^64)) + case 16: + return NumDigits <= 64 / 4; // Digits are groups of 4 bits. + default: + llvm_unreachable("impossible Radix"); + } +} /// GetIntegerValue - Convert this numeric literal value to an APInt that /// matches Val's input width. If there is an overflow, set Val to the low bits @@ -763,13 +777,11 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { // 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) { + const unsigned NumDigits = SuffixBegin - DigitsBegin; + if (CanFitInto64Bits(radix, NumDigits)) { uint64_t N = 0; - for (s = DigitsBegin; s != SuffixBegin; ++s) - N = N*radix + HexDigitValue(*s); + for (const char *Ptr = DigitsBegin; Ptr != SuffixBegin; ++Ptr) + N = N * radix + HexDigitValue(*Ptr); // This will truncate the value to Val's input width. Simply check // for overflow by comparing. @@ -778,15 +790,15 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } Val = 0; - s = DigitsBegin; + const char *Ptr = DigitsBegin; llvm::APInt RadixVal(Val.getBitWidth(), radix); llvm::APInt CharVal(Val.getBitWidth(), 0); llvm::APInt OldVal = Val; bool OverflowOccurred = false; - while (s < SuffixBegin) { - unsigned C = HexDigitValue(*s++); + while (Ptr < SuffixBegin) { + unsigned C = HexDigitValue(*Ptr++); // If this letter is out of bound for this radix, reject it. assert(C < radix && "NumericLiteralParser ctor should have rejected this"); |