diff --git a/llvm/lib/Support/StringRef.cpp b/llvm/lib/Support/StringRef.cpp --- a/llvm/lib/Support/StringRef.cpp +++ b/llvm/lib/Support/StringRef.cpp @@ -148,6 +148,23 @@ const char *Stop = Start + (Size - N + 1); + if (N == 2) { + // Provide a fast path for newline finding (CRLF case) in InclusionRewriter. + // This is basically a naive search with a little bit twiddling. + + // In theory we could use uint16_t, but some architectures don't support + // 16-bit arithmetic and will require a (& 65535) after the bit operations. + // Using 32-bit arithmetic with a shift of 16 would be more efficient for + // those cases. + uint32_t NeedleWord = + (uint32_t)(uint8_t)Needle[0] << 16 | (uint8_t)Needle[1]; + uint32_t HaystackWord = + (uint32_t)(uint8_t)Start[0] << 16 | (uint8_t)Start[1]; + for (Start++; Start < Stop && NeedleWord != HaystackWord;) + HaystackWord = HaystackWord << 16 | (uint8_t) * ++Start; + return NeedleWord == HaystackWord ? Start - Data - 1 : npos; + } + // For short haystacks or unsupported needles fall back to the naive algorithm if (Size < 16 || N > 255) { do { @@ -370,16 +387,11 @@ /// the string. size_t StringRef::count(StringRef Str) const { size_t Count = 0; + size_t Pos = 0; size_t N = Str.size(); - if (!N || N > Length) - return 0; - for (size_t i = 0, e = Length - N + 1; i < e;) { - if (substr(i, N).equals(Str)) { - ++Count; - i += N; - } - else - ++i; + while ((Pos = find(Str, Pos)) != npos) { + ++Count; + Pos += N; } return Count; }