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