diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-06 14:36:52 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-06 14:36:52 -0300 |
commit | d615e78e08201906e2f1dfc054b080fbbf7db428 (patch) | |
tree | bc5e815f32ef1c49cb6f4c5a9fb1786365258d54 /lcode.c | |
parent | c6965ce551ec8097dcaa3ed066fa12011857d42a (diff) | |
download | lua-d615e78e08201906e2f1dfc054b080fbbf7db428.tar.gz lua-d615e78e08201906e2f1dfc054b080fbbf7db428.tar.bz2 lua-d615e78e08201906e2f1dfc054b080fbbf7db428.zip |
new optimization: jumps to jumps
Diffstat (limited to 'lcode.c')
-rw-r--r-- | lcode.c | 22 |
1 files changed, 18 insertions, 4 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.19 2000/04/04 20:48:44 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.20 2000/04/05 17:51:58 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -171,7 +171,12 @@ static void luaK_neq (FuncState *fs) { | |||
171 | 171 | ||
172 | 172 | ||
173 | int luaK_jump (FuncState *fs) { | 173 | int luaK_jump (FuncState *fs) { |
174 | return luaK_S(fs, OP_JMP, NO_JUMP, 0); | 174 | int j = luaK_S(fs, OP_JMP, NO_JUMP, 0); |
175 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ | ||
176 | luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ | ||
177 | fs->jlt = NO_JUMP; | ||
178 | } | ||
179 | return j; | ||
175 | } | 180 | } |
176 | 181 | ||
177 | 182 | ||
@@ -220,11 +225,17 @@ static int luaK_getjump (FuncState *fs, int pc) { | |||
220 | 225 | ||
221 | 226 | ||
222 | /* | 227 | /* |
228 | ** discharge list of jumps to last target. | ||
223 | ** returns current `pc' and marks it as a jump target (to avoid wrong | 229 | ** returns current `pc' and marks it as a jump target (to avoid wrong |
224 | ** optimizations with consecutive instructions not in the same basic block). | 230 | ** optimizations with consecutive instructions not in the same basic block). |
225 | */ | 231 | */ |
226 | int luaK_getlabel (FuncState *fs) { | 232 | int luaK_getlabel (FuncState *fs) { |
227 | fs->lasttarget = fs->pc; | 233 | if (fs->pc != fs->lasttarget) { |
234 | int lasttarget = fs->lasttarget; | ||
235 | fs->lasttarget = fs->pc; | ||
236 | luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ | ||
237 | fs->jlt = NO_JUMP; /* nobody jumps to this new label (till now) */ | ||
238 | } | ||
228 | return fs->pc; | 239 | return fs->pc; |
229 | } | 240 | } |
230 | 241 | ||
@@ -394,7 +405,10 @@ static void luaK_patchlistaux (FuncState *fs, int list, int target, | |||
394 | 405 | ||
395 | 406 | ||
396 | void luaK_patchlist (FuncState *fs, int list, int target) { | 407 | void luaK_patchlist (FuncState *fs, int list, int target) { |
397 | luaK_patchlistaux(fs, list, target, OP_END, 0); | 408 | if (target == fs->lasttarget) /* same target that list `jlt'? */ |
409 | luaK_concat(fs, &fs->jlt, list); /* delay fixing */ | ||
410 | else | ||
411 | luaK_patchlistaux(fs, list, target, OP_END, 0); | ||
398 | } | 412 | } |
399 | 413 | ||
400 | 414 | ||