summaryrefslogtreecommitdiff
path: root/lib/Lex/LiteralSupport.cpp
diff options
context:
space:
mode:
authorDmitri Gribenko <gribozavr@gmail.com>2012-09-25 19:09:15 +0000
committerDmitri Gribenko <gribozavr@gmail.com>2012-09-25 19:09:15 +0000
commit191046d0504cec221655e9821f264f492a70f0b1 (patch)
tree8ebac5401a0b06fbbeb677c7dac9d1f55d598241 /lib/Lex/LiteralSupport.cpp
parentbf7f77ac1cd1f31fc6bf2072327eeee7baed5c6a (diff)
downloadclang-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.cpp30
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");