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 {