Commit 053ec9ea1f for perl
commit 053ec9ea1f5cccb6b5676c2e861347db1b6d9e1c
Author: Richard Leach <rich+perl@hyphen-dash-hyphen.info>
Date: Thu Oct 22 22:02:58 2026 +0000
regexec_flags: don't call fbm_instr if re_intuit found the start
In cases where `Perl_re_intuit_start` successfully found a valid start
position for a match, `Perl_regexec_flags` might still redundantly call
`Perl_fbm_instr` and perform an unnecessary search for the start.
This commit adds a flag to keep track of a successful `re_intuit_start`
so that the unnecessary search is avoided.
_gcov_ counts from running the test harness shows that many
unnecessary calls to `Perl_fbm_instr` are avoided this way.
```
6712392: 4325: while (s <= last) {
6660202: 4326: if (skip_first_search) { <------ new flag
4360129: 4327: skip_first_search = FALSE; <------ fbn_instr avoided
4360129: 4328: s = HOP4c(s, back_min, strbeg, strend);
-: 4329: assert(memEQ(s, SvPVX_const(must),
-: 4330: SvCUR(must) - cBOOL(SvTAIL(must))));
-: 4331: }
-: 4332: else {
2300073: 4333: s = fbm_instr((unsigned char*)HOP4c(s, back_min, strbeg, strend),
-: 4334: (unsigned char*)strend, must,
-: 4335: multiline ? FBMrf_MULTILINE : 0);
2300073: 4336: if (!s)
216182: 4337: break;
-: 4338: }
```
diff --git a/regexec.c b/regexec.c
index 981776ad3b..89d3b19b1e 100644
--- a/regexec.c
+++ b/regexec.c
@@ -4126,6 +4126,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
regmatch_info *const reginfo = ®info_buf;
regexp_paren_pair *swap = NULL;
bool offs_spare_used = FALSE;
+ bool intuit_success = FALSE;
I32 oldsave;
DECLARE_AND_GET_RE_DEBUG_FLAGS;
@@ -4219,6 +4220,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
flags, NULL);
if (!s)
return 0;
+ intuit_success = TRUE;
if (prog->extflags & RXf_CHECK_ALL) {
/* we can match based purely on the result of INTUIT.
@@ -4614,13 +4616,23 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
else
last1 = s - 1; /* bogus */
- /* XXXX check_substr already used to find "s", can optimize if
- check_substr == must. */
+ bool skip_first_search = intuit_success
+ && (prog->anchored_substr || prog->anchored_utf8);
dontbother = 0;
- while ( (s <= last) &&
- (s = fbm_instr((unsigned char*)HOP4c(s, back_min, strbeg, strend),
- (unsigned char*)strend, must,
- multiline ? FBMrf_MULTILINE : 0)) ) {
+ while (s <= last) {
+ if (skip_first_search) {
+ skip_first_search = FALSE;
+ s = HOP4c(s, back_min, strbeg, strend);
+ assert(memEQ(s, SvPVX_const(must),
+ SvCUR(must) - cBOOL(SvTAIL(must))));
+ }
+ else {
+ s = fbm_instr((unsigned char*)HOP4c(s, back_min, strbeg, strend),
+ (unsigned char*)strend, must,
+ multiline ? FBMrf_MULTILINE : 0);
+ if (!s)
+ break;
+ }
DEBUG_EXECUTE_r( did_match = 1 );
if (HOPc(s, -back_max) > last1) {
last1 = HOPc(s, -back_min);