[Pcre-svn] [1435] code/trunk: JIT: Optimize might be empty c…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [1435] code/trunk: JIT: Optimize might be empty checks.
Revision: 1435
          http://vcs.pcre.org/viewvc?view=rev&revision=1435
Author:   zherczeg
Date:     2014-01-07 07:47:12 +0000 (Tue, 07 Jan 2014)


Log Message:
-----------
JIT: Optimize might be empty checks.

Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/pcre_jit_compile.c


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2014-01-06 20:04:50 UTC (rev 1434)
+++ code/trunk/ChangeLog    2014-01-07 07:47:12 UTC (rev 1435)
@@ -51,7 +51,10 @@
     backtracking path, when more than four alternatives are present inside a
     bracket.


+11. Empty match is not possible, when the minimum length is greater than zero,
+    and there is no \K in the pattern. Remove these unnecessary checks form JIT.


+
Version 8.34 15-December-2013
-----------------------------


Modified: code/trunk/pcre_jit_compile.c
===================================================================
--- code/trunk/pcre_jit_compile.c    2014-01-06 20:04:50 UTC (rev 1434)
+++ code/trunk/pcre_jit_compile.c    2014-01-07 07:47:12 UTC (rev 1435)
@@ -362,6 +362,8 @@
   sljit_sw lcc;
   /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
   int mode;
+  /* TRUE, when minlength is greater than 0. */
+  BOOL might_be_empty;
   /* \K is found in the pattern. */
   BOOL has_set_som;
   /* (*SKIP:arg) is found in the pattern. */
@@ -789,6 +791,7 @@
     {
     case OP_SET_SOM:
     common->has_set_som = TRUE;
+    common->might_be_empty = TRUE;
     cc += 1;
     break;


@@ -7853,7 +7856,7 @@
return cc + 1;
}

-if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
+if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
{
/* No need to check notempty conditions. */
if (common->accept_label == NULL)
@@ -9496,14 +9499,14 @@
label_addr_list *label_addr;
struct sljit_label *mainloop_label = NULL;
struct sljit_label *continue_match_label;
-struct sljit_label *empty_match_found_label;
-struct sljit_label *empty_match_backtrack_label;
+struct sljit_label *empty_match_found_label = NULL;
+struct sljit_label *empty_match_backtrack_label = NULL;
struct sljit_label *reset_match_label;
struct sljit_label *quit_label;
struct sljit_jump *jump;
struct sljit_jump *minlength_check_failed = NULL;
struct sljit_jump *reqbyte_notfound = NULL;
-struct sljit_jump *empty_match;
+struct sljit_jump *empty_match = NULL;

SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
study = extra->study_data;
@@ -9522,6 +9525,7 @@
common->fcc = tables + fcc_offset;
common->lcc = (sljit_sw)(tables + lcc_offset);
common->mode = mode;
+common->might_be_empty = study->minlength == 0;
common->nltype = NLTYPE_FIXED;
switch(re->options & PCRE_NEWLINE_BITS)
{
@@ -9815,8 +9819,11 @@
return;
}

-empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
-empty_match_found_label = LABEL();
+if (common->might_be_empty)
+ {
+ empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ empty_match_found_label = LABEL();
+ }

common->accept_label = LABEL();
if (common->accept != NULL)
@@ -9840,7 +9847,8 @@
return_with_partial_match(common, common->quit_label);
}

-empty_match_backtrack_label = LABEL();
+if (common->might_be_empty)
+ empty_match_backtrack_label = LABEL();
compile_backtrackingpath(common, rootbacktrack.top);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
{
@@ -9894,15 +9902,18 @@

flush_stubs(common);

-JUMPHERE(empty_match);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
-CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
-OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
-CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
-JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
+if (common->might_be_empty)
+ {
+ JUMPHERE(empty_match);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+ CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
+ JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
+ }

common->currententry = common->entries;
common->local_exit = TRUE;