[all-commits] [llvm/llvm-project] 4553dc: [Support] Rewrite GlobPattern

Fangrui Song via All-commits all-commits at lists.llvm.org
Tue Jul 25 18:47:09 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 4553dc46a05ec6f1e2aebcde1ce185772a26780b
      https://github.com/llvm/llvm-project/commit/4553dc46a05ec6f1e2aebcde1ce185772a26780b
  Author: Fangrui Song <i at maskray.me>
  Date:   2023-07-25 (Tue, 25 Jul 2023)

  Changed paths:
    M llvm/include/llvm/Support/GlobPattern.h
    M llvm/lib/Support/GlobPattern.cpp
    M llvm/unittests/Support/GlobPatternTest.cpp

  Log Message:
  -----------
  [Support] Rewrite GlobPattern

The current implementation has two primary issues:

* Matching `a*a*a*b` against `aaaaaa` has exponential complexity.
* BitVector harms data cache and is inefficient for literal matching.

and a minor issue that `\` at the end may cause an out of bounds access
in `StringRef::operator[]`.

Switch to an O(|S|*|P|) greedy algorithm instead: factor the pattern
into segments split by '*'. The segment is matched sequentianlly by
finding the first occurrence past the end of the previous match. This
algorithm is used by lots of fnmatch implementations, including musl and
NetBSD's.

In addition, `optional<StringRef> Exact, Suffix, Prefix` wastes space.
Instead, match the non-metacharacter prefix against the haystack, then
match the pattern with the rest.

In practice `*suffix` style patterns are less common and our new
algorithm is fast enough, so don't bother storing the non-metacharacter
suffix.

Note: brace expansions (D153587) can leverage the `matchOne` function.

Differential Revision: https://reviews.llvm.org/D156046




More information about the All-commits mailing list