summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2015-11-11 20:25:08 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2015-11-11 20:25:08 (GMT)
commit5d3e22ea69cc46a48e6a256ed23ad117213e6df8 (patch)
tree40cbc3941c73f2360ee0f4207320479c77502121
parent2175ff15dd858504ad209bcb2b69b9d54ef850fe (diff)
downloadtcl-mig_optimize.zip
tcl-mig_optimize.tar.gz
tcl-mig_optimize.tar.bz2
*** ABANDONED - see branch mig-opt2 *** mig_optimize
simplify, avoid using PATHS before init, (partial) solution to infinite loops
-rw-r--r--generic/tclOptimize.c129
1 files changed, 48 insertions, 81 deletions
diff --git a/generic/tclOptimize.c b/generic/tclOptimize.c
index f7f7752..c53bb8f 100644
--- a/generic/tclOptimize.c
+++ b/generic/tclOptimize.c
@@ -23,8 +23,7 @@ typedef struct optPad {
static void markPath(CompileEnv *envPtr, int pc, optPad *padPtr,
int mark);
-static int effectivePCInternal(CompileEnv *envPtr, int pc,
- optPad *padPtr, int start);
+static int effectivePC(CompileEnv *envPtr, int pc, optPad *padPtr);
static void ThreadJumps(CompileEnv *envPtr, optPad *padPtr);
static int UpdateJump(CompileEnv *envPtr,optPad *padPtr, int pc);
static int optimizePush_0(CompileEnv *envPtr,optPad *padPtr, int pc);
@@ -35,6 +34,8 @@ static void CompactCode(CompileEnv *envPtr, optPad *padPtr,
static void Optimize_0(CompileEnv *envPtr, optPad *padPtr);
static void Optimize_1(CompileEnv *envPtr, optPad *padPtr);
+static void Initialize(CompileEnv *envPtr, optPad *padPtr);
+
#define INIT_SIZE \
int codeSize = padPtr->codeSize
@@ -107,26 +108,6 @@ static void Optimize_1(CompileEnv *envPtr, optPad *padPtr);
#define FOLLOW(pc) \
effectivePC(envPtr, (pc), padPtr)
-static inline int
-effectivePC(
- CompileEnv *envPtr,
- int pc,
- optPad *padPtr)
-{
- unsigned char inst = INST_AT_PC(pc);
-
- if ((inst == INST_NOP)
- || (inst == INST_JUMP1)
- || (inst == INST_JUMP4)) {
- /* do update the whole path forward */
- pc = effectivePCInternal(envPtr, pc, padPtr, pc);
- }
- return pc;
-}
-
-
-static void Initialize(CompileEnv *envPtr, optPad *padPtr);
-
/*
* ----------------------------------------------------------------------
@@ -165,7 +146,7 @@ TclOptimizeBytecode(
/* 1. Path-independent opts: push elimination, jump threading, etc. We
* could advance some jumps (to cond-jump, to done or return) */
- Optimize_0(envPtr, padPtr);
+ Optimize_0(envPtr, padPtr);
/* 2. Initial path marking, move unreachable code to after INST_DONE and
* compress */
@@ -197,7 +178,7 @@ Initialize(
int i;
/*
- * Initialize NEXT to identity, PATHS to 0.
+ * Initialize PATHS to 0.
*/
for (i=0; i < codeSize; i++) {
@@ -261,7 +242,7 @@ Optimize_0(
optPad *padPtr)
{
int codeSize = padPtr->codeSize;
- int pc, nextpc;
+ int pc, nextpc, new;
unsigned char inst;
for (pc = 0; pc < codeSize; pc = nextpc) {
@@ -275,17 +256,15 @@ Optimize_0(
case INST_PUSH4:
optimizePush_0(envPtr, padPtr, pc);
-
- case INST_JUMP1:
- case INST_JUMP_TRUE1:
- case INST_JUMP_FALSE1:
+
case INST_JUMP_TRUE4:
case INST_JUMP_FALSE4:
case INST_JUMP4:
- case INST_JUMP_TABLE:
- UPDATE_JUMP(pc);
+ new = FOLLOW(pc);
+ if (new != pc) {
+ SET_INT4_AT_PC(new-pc, pc+1);
+ }
break;
-
}
}
}
@@ -645,59 +624,49 @@ CompactCode(
/*
* ----------------------------------------------------------------------
*
- * effectivePC, effectivePCinternal --
+ * effectivePC --
*
* Utility functions. Find the effective newpc that will be executed when
- * we get at pc, by following through jumps and nops. The results are
- * cached in the NEXT array.
+ * we get at pc, by following through jumps and nops.
*
- * Side effects: may update the PATHS array.
- *
- * Remark: PATHS needs to be initialized to 0 before the first call (as
- * this may call MARK/UNMARK which requires that).
* ----------------------------------------------------------------------
*/
int
-effectivePCInternal(
+effectivePC(
CompileEnv *envPtr,
int pc,
- optPad *padPtr,
- int start)
+ optPad *padPtr)
{
- int old, new;
unsigned char inst;
+ int start = pc, new;
+
+ /* recurse so that the whole path forward is updated and cached? */
+ while (1) {
+ inst = INST_AT_PC(pc);
+ switch (inst) {
+ case INST_NOP:
+ new = pc + 1;
+ break;
+
+ case INST_JUMP1:
+ new = pc + GET_INT1_AT_PC(pc+1);
+ break;
- /* recurse so that the whole path forward is updated and cached */
-
- inst = INST_AT_PC(pc);
- switch (inst) {
- case INST_NOP:
- old = pc + 1;
- break;
-
- case INST_JUMP1:
- old = pc + GET_INT1_AT_PC(pc+1);
- break;
-
- case INST_JUMP4:
- old = pc + GET_INT4_AT_PC(pc+1);
- break;
+ case INST_JUMP4:
+ new = pc + GET_INT4_AT_PC(pc+1);
+ break;
- default:
+ default:
+ return pc;
+ }
+ if (new == start) {
+ /* infinite loop! how do we kill it in <= 5 bytes? */
+ INST_AT_PC(new) = INST_CONTINUE;
return pc;
+ }
+ pc = new;
}
-
- if (start == old) {
- /*
- * INFINITE LOOP! TODO
- * Eventually insert error generating code, possibly after INST_DONE?
- */
- return pc;
- }
-
- new = FOLLOW(old);
- return new;
}
int
@@ -713,7 +682,6 @@ UpdateJump(
int result = 0;
inst = INST_AT_PC(pc);
-
switch(inst) {
default:
return 0;
@@ -726,7 +694,7 @@ UpdateJump(
old = pc + PTR2INT(Tcl_GetHashValue(hPtr));
new = FOLLOW(old);
if (new != old) {
- //REPLACE(old, new);
+ REPLACE(old, new);
Tcl_SetHashValue(hPtr, INT2PTR(new - pc));
result = 1;
}
@@ -737,16 +705,15 @@ UpdateJump(
case INST_JUMP_FALSE4:
case INST_JUMP4:
old = pc + GET_INT4_AT_PC(pc+1);
+ new = FOLLOW(old);
+ if (new != old) {
+ REPLACE(old, new);
+ SET_INT4_AT_PC(new - pc, pc+1);
+ return 1;
+ }
break;
}
-
- new = FOLLOW(old);
- if (new == old) {
- return 0;
- }
- SET_INT4_AT_PC(new - pc, pc+1);
- //REPLACE(old, new);
- return 1;
+ return 0;
}
void
@@ -873,7 +840,7 @@ markPath(
if (PATHS[pc] > 1) {
PATHS[pc]--;
return;
- } else if (PATHS[pc] <=0) {
+ } else if (PATHS[pc] <= 0) {
PATHS[pc] = 0;
return;
}