Skip to content

Add long offset TRIE regnodes#24544

Open
demerphq wants to merge 17 commits into
bleadfrom
yves/LTRIE
Open

Add long offset TRIE regnodes#24544
demerphq wants to merge 17 commits into
bleadfrom
yves/LTRIE

Conversation

@demerphq

@demerphq demerphq commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

This is a second PR to address #23388, see also: 03f74bb

  • This set of changes probably does require a perldelta entry - I will add one after there is some feedback, especially from Karl.

FWIW, this patch ended up being a bit of a rabbit hole, as make depend was silently not working for me, and hiding that the perl I was building was not always the latest or even the same code at the same time. Hence I ended up doing various secondary hacks to rule out issues that in the end came down to the unstable build process.

The general idea here however is to add LTRIE and LTRIEC as complements to TRIE and TRIEC regex engine opcodes. These handle longer jump distances correctly. In fact with this PR tries overall now use 32 bit offsets (jump tables and whatnot), but we keep the "small trie" opcode as it comes in handy when we are optimizing very small patterns.

@demerphq demerphq changed the title Yves/ltrie Add long offset TRIE regnodes Jul 7, 2026
@demerphq demerphq requested a review from khwilliamson July 7, 2026 18:58
@Leont Leont added the defer-next-dev This PR should not be merged yet, but await the next development cycle label Jul 7, 2026
Comment thread regcomp_trie.c
Comment thread regexp.h
demerphq added 14 commits July 8, 2026 20:15
The makedepend infra adds "." and ".." to the path, apparently to assist
"cppstdin" functioning. However if your cc compiler is configured to be
something like "ccache gcc", and you happen to have a "gcc" dev
directory with a built "gcc" executable in it in a sister directory to
your perl repo then the path change results in ccache finding the wrong
gcc and using it for the dependency analysis, which then breaks the
dependencies.

The path munging doesn't make sense when the compiler is a command like
this, and apparently is only there to assist 'ccpstdin' so this patch just
disables the path munging when the compiler is something else.
Sometimes I use a project local cache dir. This hides it when I use it.
Replace numeric trie/Aho-Corasick opcode assumptions with explicit
classification and mapping.

Use IS_TRIE_AC() for debug-time trie data selection and convert TRIE and
TRIEC to their Aho-Corasick forms with an explicit mapping instead of
relying on opcode spacing. This hardens the regex engine against adding
new trie-like regops that shift opcode numbers without being used.
The define RE_PREFER_LONG_TRIE can be used to control whether
we produce LTRIE or TRIE by preference. For testing this was set
to 1 to make sure the LTRIE functionality worked, but in practice
we prefer 0, as it means regexp programs are a little smaller
overall.

@khwilliamson khwilliamson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is far more than I was expecting. From the comments in the earlier code, I inferred that all that mattered was that the length of the current node fit in a U16, and I just wasn't seeing how to avoid looking at the total length between the first and final nodes. I didn't expect a distinct trie type for longer chains

arguably we could just get rid of it entirely, but its helpful to test
@tonycoz

tonycoz commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

I haven't looked at it in detail yet, but this introduces a warning:

cc -c -DPERL_CORE -D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -std=c99 -O2 -Wall -Werror=pointer-arith -Werror=vla -Wextra -Wno-long-long -Wno-declaration-after-statement -Wno-nonnull-compare -Wc++-compat -Wwrite-strings -Wno-use-after-free regcomp_trie.c
In file included from regcomp_trie.c:14:
regcomp_trie.c: In function ‘Perl_construct_ahocorasick_from_trie’:
regcomp.h:578:67: warning: array subscript ‘struct regnode_charclass_trie[0]’ is partly outside array bounds of ‘regnode[10]’ [-Warray-bounds=]
  578 | #define ARG2u_AFTERCC_LOC(p) (((struct regnode_charclass_trie *)p)->arg2.u32)
      |                                                                   ^~
regcomp.h:425:29: note: in definition of macro ‘ARG__SET’
  425 | #define ARG__SET(arg,val) ((arg) = (val))
      |                             ^~~
regcomp.h:469:44: note: in expansion of macro ‘ARG2u_AFTERCC_LOC’
  469 | #define ARG2u_AFTERCC_SET(p, val) ARG__SET(ARG2u_AFTERCC_LOC(p), (val))
      |                                            ^~~~~~~~~~~~~~~~~
regcomp.h:1335:9: note: in expansion of macro ‘ARG2u_AFTERCC_SET’
 1335 |         ARG2u_AFTERCC_SET((p), (val));                                     \
      |         ^~~~~~~~~~~~~~~~~
regcomp_trie.c:1738:5: note: in expansion of macro ‘TRIE_DATA_SLOT_set’
 1738 |     TRIE_DATA_SLOT_set(stclass, data_slot);
      |     ^~~~~~~~~~~~~~~~~~
In file included from perl.h:4514,
                 from regcomp_trie.c:9:
iperlsys.h:884:49: note: object of size 40 allocated by ‘calloc’
  884 | #  define PerlMemShared_calloc(num, size)       calloc((num), (size))
      |                                                 ^~~~~~~~~~~~~~~~~~~~~
regcomp_trie.c:1725:13: note: in expansion of macro ‘PerlMemShared_calloc’
 1725 |             PerlMemShared_calloc(1, sizeof(tregnode_AHOCORASICKC));
      |             ^~~~~~~~~~~~~~~~~~~~
iperlsys.h:884:49: note: object of size 8 allocated by ‘calloc’
  884 | #  define PerlMemShared_calloc(num, size)       calloc((num), (size))
      |                                                 ^~~~~~~~~~~~~~~~~~~~~
regcomp_trie.c:1732:13: note: in expansion of macro ‘PerlMemShared_calloc’
 1732 |             PerlMemShared_calloc(1, sizeof(tregnode_AHOCORASICK));
      |             ^~~~~~~~~~~~~~~~~~~~

see this

@demerphq

demerphq commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

@tonycoz - I can't reproduce that right now, but i am pretty sure i know what I did wrong. Ill push a patch shortly hopefully.

demerphq added 2 commits July 9, 2026 11:35
Tony Cook has reported a case where the TRIE_DATA_SLOT_set(stclass, data_slot) warns
about
The comment says it all, some compilers dont understand this code and think
it will write out of bounds so we unroll the TRIE_DATA_SLOT_set() macro
to allow us to resuse just the part we need here.
@demerphq

demerphq commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

@tonycoz I think the warning is bogus, and that the code wont write out of bounds. Nevertheless I replaced the offending macro with one the compiler should be more comfortable with.

@tonycoz

tonycoz commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@tonycoz I think the warning is bogus, and that the code wont write out of bounds. Nevertheless I replaced the offending macro with one the compiler should be more comfortable with.

That fixed it, though the commit message is a little misleading: the warning was from gcc 13 on linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

defer-next-dev This PR should not be merged yet, but await the next development cycle

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants