summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2007-08-16 20:39:34 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2007-08-16 20:39:34 (GMT)
commit58d90767821271f9546b8f34b7db85d896784941 (patch)
tree21a230c65d3d1523d38ad7705c93e30312d51cb9
parentb41667264c8c24d55fc76ed14dd42747e88d044f (diff)
downloadtcl-58d90767821271f9546b8f34b7db85d896784941.zip
tcl-58d90767821271f9546b8f34b7db85d896784941.tar.gz
tcl-58d90767821271f9546b8f34b7db85d896784941.tar.bz2
* generic/tclExecute.c: check the two most frequent instructions
before the switch. Reduces both runtime and obj size a tiny bit.
-rw-r--r--ChangeLog5
-rw-r--r--generic/tclExecute.c18
2 files changed, 22 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 47b9063..9aae28e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-08-16 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: check the two most frequent instructions
+ before the switch. Reduces both runtime and obj size a tiny bit.
+
2007-08-16 Don Porter <dgp@users.sourceforge.net>
* generic/tclCompExpr.c: Added a "constant" field to the OpNode
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 43bd58a..5b3185b 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclExecute.c,v 1.314 2007/08/14 21:04:28 msofer Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.315 2007/08/16 20:39:34 msofer Exp $
*/
#include "tclInt.h"
@@ -1640,6 +1640,21 @@ TclExecuteByteCode(
}
}
+ /*
+ * These two instructions account for 26% of all instructions (according
+ * to measurements on tclbench by Ben Vitale
+ * [http://www.cs.toronto.edu/syslab/pubs/tcl2005-vitale-zaleski.pdf]
+ * Resolving them before the switch reduces the cost of branch
+ * mispredictions, seems to improve runtime by 5% to 15%, and (amazingly!)
+ * reduces total obj size.
+ */
+
+ if (*pc == INST_LOAD_SCALAR1) {
+ goto instLoadScalar1;
+ } else if (*pc == INST_PUSH1) {
+ goto instPush1Peephole;
+ }
+
switch (*pc) {
case INST_RETURN_IMM: {
int code = TclGetInt4AtPtr(pc+1);
@@ -2257,6 +2272,7 @@ TclExecuteByteCode(
Tcl_Obj *objPtr;
case INST_LOAD_SCALAR1:
+ instLoadScalar1:
opnd = TclGetUInt1AtPtr(pc+1);
varPtr = &(compiledLocals[opnd]);
while (TclIsVarLink(varPtr)) {