dovecot-2.0-pigeonhole: lib-sieve: optimized compilation of test...
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Sun Jun 26 22:25:50 EEST 2011
details: http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/cf3b58e583ec
changeset: 1505:cf3b58e583ec
user: Stephan Bosch <stephan at rename-it.nl>
date: Sun Jun 26 17:07:53 2011 +0200
description:
lib-sieve: optimized compilation of tests that yield constant results (i.e. known at compile tme), such as true and false.
If the result of a test is known at compile time, it is optimized away. If an if-command depends on an entirely constant test, it is optimized away as well,
causing only the 'true' sub-block to be compiled.
diffstat:
TODO | 2 -
src/lib-sieve/cmd-discard.c | 2 +-
src/lib-sieve/cmd-if.c | 121 ++++--
src/lib-sieve/cmd-keep.c | 2 +-
src/lib-sieve/cmd-redirect.c | 3 +-
src/lib-sieve/cmd-require.c | 2 +-
src/lib-sieve/cmd-stop.c | 3 +-
src/lib-sieve/ext-envelope.c | 3 +-
src/lib-sieve/ext-fileinto.c | 3 +-
src/lib-sieve/ext-reject.c | 6 +-
src/lib-sieve/plugins/body/tst-body.c | 3 +-
src/lib-sieve/plugins/date/tst-date.c | 6 +-
src/lib-sieve/plugins/enotify/cmd-notify.c | 3 +-
src/lib-sieve/plugins/enotify/tst-notify-method-capability.c | 3 +-
src/lib-sieve/plugins/enotify/tst-valid-notify-method.c | 3 +-
src/lib-sieve/plugins/environment/tst-environment.c | 3 +-
src/lib-sieve/plugins/imap4flags/cmd-flag.c | 9 +-
src/lib-sieve/plugins/imap4flags/ext-imapflags.c | 4 +-
src/lib-sieve/plugins/imap4flags/tst-hasflag.c | 3 +-
src/lib-sieve/plugins/include/cmd-global.c | 21 +-
src/lib-sieve/plugins/include/cmd-include.c | 3 +-
src/lib-sieve/plugins/include/cmd-return.c | 2 +-
src/lib-sieve/plugins/mailbox/tst-mailboxexists.c | 3 +-
src/lib-sieve/plugins/notify/cmd-denotify.c | 3 +-
src/lib-sieve/plugins/notify/cmd-notify.c | 1 +
src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c | 8 +-
src/lib-sieve/plugins/vacation/cmd-vacation.c | 3 +-
src/lib-sieve/plugins/variables/cmd-set.c | 3 +-
src/lib-sieve/plugins/variables/tst-string.c | 3 +-
src/lib-sieve/plugins/vnd.dovecot/debug/cmd-debug-log.c | 1 +
src/lib-sieve/sieve-commands.h | 5 +-
src/lib-sieve/sieve-validator.c | 73 +++-
src/lib-sieve/tst-address.c | 3 +-
src/lib-sieve/tst-allof.c | 25 +-
src/lib-sieve/tst-anyof.c | 31 +-
src/lib-sieve/tst-exists.c | 3 +-
src/lib-sieve/tst-header.c | 3 +-
src/lib-sieve/tst-not.c | 25 +-
src/lib-sieve/tst-size.c | 1 +
src/lib-sieve/tst-truefalse.c | 47 ++-
src/testsuite/cmd-test-binary.c | 6 +-
src/testsuite/cmd-test-config.c | 8 +-
src/testsuite/cmd-test-fail.c | 3 +-
src/testsuite/cmd-test-mailbox.c | 6 +-
src/testsuite/cmd-test-message.c | 3 +-
src/testsuite/cmd-test-result.c | 4 +-
src/testsuite/cmd-test-set.c | 3 +-
src/testsuite/cmd-test.c | 3 +-
src/testsuite/tst-test-error.c | 3 +-
src/testsuite/tst-test-multiscript.c | 3 +-
src/testsuite/tst-test-result-action.c | 3 +-
src/testsuite/tst-test-result-execute.c | 2 +-
src/testsuite/tst-test-script-compile.c | 3 +-
src/testsuite/tst-test-script-run.c | 2 +-
tests/control-if.svtest | 146 ++++++++-
tests/test-allof.svtest | 288 ++++++++++++++++
tests/test-anyof.svtest | 289 +++++++++++++++++
57 files changed, 1085 insertions(+), 141 deletions(-)
diffs (truncated from 2130 to 300 lines):
diff -r b9050c63a238 -r cf3b58e583ec TODO
--- a/TODO Wed Jun 22 22:17:28 2011 +0200
+++ b/TODO Sun Jun 26 17:07:53 2011 +0200
@@ -27,8 +27,6 @@
- Implement configurable sender exclusion list.
- Implement mechanism for implicitly including an account's aliases in the
vacation command's :addresses list.
-* Optimize code containing true/false tests to omit explicit JMP opcodes
- (i.e. optimize the test away and any code that negatively depends on it)
* Implement ihave extension.
* Fix remaining RFC deviations:
- Fix issues listed in doc/rfc/RFC-questions.txt based on answers
diff -r b9050c63a238 -r cf3b58e583ec src/lib-sieve/cmd-discard.c
--- a/src/lib-sieve/cmd-discard.c Wed Jun 22 22:17:28 2011 +0200
+++ b/src/lib-sieve/cmd-discard.c Sun Jun 26 17:07:53 2011 +0200
@@ -29,7 +29,7 @@
"discard",
SCT_COMMAND,
0, 0, FALSE, FALSE,
- NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
cmd_discard_generate,
NULL
};
diff -r b9050c63a238 -r cf3b58e583ec src/lib-sieve/cmd-if.c
--- a/src/lib-sieve/cmd-if.c Wed Jun 22 22:17:28 2011 +0200
+++ b/src/lib-sieve/cmd-if.c Sun Jun 26 17:07:53 2011 +0200
@@ -12,23 +12,31 @@
* Commands
*/
+static bool cmd_if_validate
+ (struct sieve_validator *valdtr, struct sieve_command *cmd);
+static bool cmd_elsif_validate
+ (struct sieve_validator *valdtr, struct sieve_command *cmd);
+static bool cmd_if_validate_const
+ (struct sieve_validator *valdtr, struct sieve_command *cmd,
+ int *const_current, int const_next);
+static bool cmd_if_generate
+ (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd);
+static bool cmd_else_generate
+ (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd);
+
/* If command
*
* Syntax:
* if <test1: test> <block1: block>
*/
-static bool cmd_if_validate
- (struct sieve_validator *valdtr, struct sieve_command *cmd);
-static bool cmd_if_generate
- (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd);
-
const struct sieve_command_def cmd_if = {
"if",
SCT_COMMAND,
0, 1, TRUE, TRUE,
NULL, NULL,
- cmd_if_validate,
+ cmd_if_validate,
+ cmd_if_validate_const,
cmd_if_generate,
NULL
};
@@ -39,15 +47,13 @@
* elsif <test2: test> <block2: block>
*/
-static bool cmd_elsif_validate
- (struct sieve_validator *valdtr, struct sieve_command *cmd);
-
const struct sieve_command_def cmd_elsif = {
"elsif",
SCT_COMMAND,
0, 1, TRUE, TRUE,
NULL, NULL,
- cmd_elsif_validate,
+ cmd_elsif_validate,
+ cmd_if_validate_const,
cmd_if_generate,
NULL
};
@@ -58,15 +64,14 @@
* else <block>
*/
-static bool cmd_else_generate
- (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd);
const struct sieve_command_def cmd_else = {
"else",
SCT_COMMAND,
0, 0, TRUE, TRUE,
NULL, NULL,
- cmd_elsif_validate,
+ cmd_elsif_validate,
+ cmd_if_validate_const,
cmd_else_generate,
NULL
};
@@ -79,6 +84,8 @@
struct cmd_if_context_data *previous;
struct cmd_if_context_data *next;
+ int const_condition;
+
bool jump_generated;
sieve_size_t exit_jump;
};
@@ -91,13 +98,23 @@
/* Assign context */
cmd_data = p_new(sieve_command_pool(cmd), struct cmd_if_context_data, 1);
cmd_data->exit_jump = 0;
- cmd_data->jump_generated = FALSE;
+ cmd_data->jump_generated = FALSE;
/* Update linked list of contexts */
cmd_data->previous = previous;
cmd_data->next = NULL;
if ( previous != NULL )
previous->next = cmd_data;
+
+ /* Check const status */
+ cmd_data->const_condition = -1;
+ while ( previous != NULL ) {
+ if ( previous->const_condition > 0 ) {
+ cmd_data->const_condition = 0;
+ break;
+ }
+ previous = previous->previous;
+ }
/* Assign to command context */
cmd->data = cmd_data;
@@ -139,6 +156,27 @@
return TRUE;
}
+static bool cmd_if_validate_const
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command *cmd,
+ int *const_current, int const_next)
+{
+ struct cmd_if_context_data *cmd_data =
+ (struct cmd_if_context_data *) cmd->data;
+
+ if ( cmd_data != NULL ) {
+ if ( cmd_data->const_condition == 0 ) {
+ *const_current = cmd_data->const_condition;
+ return FALSE;
+ }
+
+ cmd_data->const_condition = const_next;
+ }
+
+ *const_current = const_next;
+
+ return ( const_next < 0 );
+}
+
/*
* Code generation
*/
@@ -171,21 +209,29 @@
(struct cmd_if_context_data *) cmd->data;
struct sieve_ast_node *test;
struct sieve_jumplist jmplist;
-
- /* Prepare jumplist */
- sieve_jumplist_init_temp(&jmplist, sblock);
-
+
/* Generate test condition */
- test = sieve_ast_test_first(cmd->ast_node);
- if ( !sieve_generate_test(cgenv, test, &jmplist, FALSE) )
- return FALSE;
+ if ( cmd_data->const_condition < 0 ) {
+ /* Prepare jumplist */
+ sieve_jumplist_init_temp(&jmplist, sblock);
+
+ test = sieve_ast_test_first(cmd->ast_node);
+ if ( !sieve_generate_test(cgenv, test, &jmplist, FALSE) )
+ return FALSE;
+ }
/* Case true { */
- if ( !sieve_generate_block(cgenv, cmd->ast_node) )
- return FALSE;
-
+ if ( cmd_data->const_condition != 0 ) {
+ if ( !sieve_generate_block(cgenv, cmd->ast_node) )
+ return FALSE;
+ }
+
/* Are we the final command in this if-elsif-else structure? */
- if ( cmd_data->next != NULL ) {
+ if ( cmd_data->next == NULL || cmd_data->const_condition == 1 ) {
+ /* Yes, Resolve previous exit jumps to this point */
+ cmd_if_resolve_exit_jumps(sblock, cmd_data);
+
+ } else if ( cmd_data->const_condition < 0 ) {
/* No, generate jump to end of if-elsif-else structure (resolved later)
* This of course is not necessary if the {} block contains a command
* like stop at top level that unconditionally exits the block already
@@ -196,13 +242,12 @@
cmd_data->exit_jump = sieve_binary_emit_offset(sblock, 0);
cmd_data->jump_generated = TRUE;
}
- } else {
- /* Yes, Resolve previous exit jumps to this point */
- cmd_if_resolve_exit_jumps(sblock, cmd_data);
}
-
- /* Case false ... (subsequent elsif/else commands might generate more) */
- sieve_jumplist_resolve(&jmplist);
+
+ if ( cmd_data->const_condition < 0 ) {
+ /* Case false ... (subsequent elsif/else commands might generate more) */
+ sieve_jumplist_resolve(&jmplist);
+ }
return TRUE;
}
@@ -214,12 +259,14 @@
(struct cmd_if_context_data *) cmd->data;
/* Else { */
- if ( !sieve_generate_block(cgenv, cmd->ast_node) )
- return FALSE;
-
- /* } End: resolve all exit blocks */
- cmd_if_resolve_exit_jumps(cgenv->sblock, cmd_data);
-
+ if ( cmd_data->const_condition != 0 ) {
+ if ( !sieve_generate_block(cgenv, cmd->ast_node) )
+ return FALSE;
+
+ /* } End: resolve all exit blocks */
+ cmd_if_resolve_exit_jumps(cgenv->sblock, cmd_data);
+ }
+
return TRUE;
}
diff -r b9050c63a238 -r cf3b58e583ec src/lib-sieve/cmd-keep.c
--- a/src/lib-sieve/cmd-keep.c Wed Jun 22 22:17:28 2011 +0200
+++ b/src/lib-sieve/cmd-keep.c Sun Jun 26 17:07:53 2011 +0200
@@ -27,7 +27,7 @@
"keep",
SCT_COMMAND,
0, 0, FALSE, FALSE,
- NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
cmd_keep_generate,
NULL
};
diff -r b9050c63a238 -r cf3b58e583ec src/lib-sieve/cmd-redirect.c
--- a/src/lib-sieve/cmd-redirect.c Wed Jun 22 22:17:28 2011 +0200
+++ b/src/lib-sieve/cmd-redirect.c Sun Jun 26 17:07:53 2011 +0200
@@ -49,7 +49,8 @@
SCT_COMMAND,
1, 0, FALSE, FALSE,
NULL, NULL,
- cmd_redirect_validate,
+ cmd_redirect_validate,
+ NULL,
cmd_redirect_generate,
NULL
};
diff -r b9050c63a238 -r cf3b58e583ec src/lib-sieve/cmd-require.c
--- a/src/lib-sieve/cmd-require.c Wed Jun 22 22:17:28 2011 +0200
+++ b/src/lib-sieve/cmd-require.c Sun Jun 26 17:07:53 2011 +0200
@@ -25,7 +25,7 @@
1, 0, FALSE, FALSE,
NULL, NULL,
cmd_require_validate,
- NULL, NULL
+ NULL, NULL, NULL
};
/*
diff -r b9050c63a238 -r cf3b58e583ec src/lib-sieve/cmd-stop.c
--- a/src/lib-sieve/cmd-stop.c Wed Jun 22 22:17:28 2011 +0200
+++ b/src/lib-sieve/cmd-stop.c Sun Jun 26 17:07:53 2011 +0200
@@ -25,7 +25,8 @@
SCT_COMMAND,
0, 0, FALSE, FALSE,
NULL, NULL,
- cmd_stop_validate,
+ cmd_stop_validate,
+ NULL,
cmd_stop_generate,
NULL
};
diff -r b9050c63a238 -r cf3b58e583ec src/lib-sieve/ext-envelope.c
--- a/src/lib-sieve/ext-envelope.c Wed Jun 22 22:17:28 2011 +0200
+++ b/src/lib-sieve/ext-envelope.c Sun Jun 26 17:07:53 2011 +0200
@@ -87,7 +87,8 @@
2, 0, FALSE, FALSE,
tst_envelope_registered,
More information about the dovecot-cvs
mailing list