Imported from ../lua-4.0.tar.gz.
[lua.git] / src / luac / opt.c
blobe51a0868524fc1de70b8dd438338f34b8fd4c539
1 /*
2 ** $Id: opt.c,v 1.22 2000/10/31 16:57:23 lhf Exp $
3 ** optimize bytecodes
4 ** See Copyright Notice in lua.h
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "luac.h"
13 static int MapConstant(Hash* t, int j, const TObject* key)
15 const TObject* o=luaH_get(L,t,key);
16 if (ttype(o)==LUA_TNUMBER)
17 return (int) nvalue(o);
18 else
20 TObject val;
21 ttype(&val)=LUA_TNUMBER;
22 nvalue(&val)=j;
23 *luaH_set(L,t,key)=val;
24 LUA_ASSERT(j>=0,"MapConstant returns negative!");
25 return j;
29 static int MapConstants(Proto* tf, Hash* map)
31 int i,j,k,n,m=0;
32 TObject o;
33 j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
34 for (i=0; i<n; i++)
36 nvalue(&o)=tf->knum[i];
37 k=MapConstant(map,j,&o);
38 if (k==j) j++;
40 m=j;
41 j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
42 for (i=0; i<n; i++)
44 tsvalue(&o)=tf->kstr[i];
45 k=MapConstant(map,j,&o);
46 if (k==j) j++;
48 return m+j;
51 static void PackConstants(Proto* tf, Hash* map)
53 int i,j,k,n;
54 TObject o;
55 #ifdef DEBUG
56 printf("%p before pack nknum=%d nkstr=%d\n",tf,tf->nknum,tf->nkstr);
57 #endif
58 j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
59 for (i=0; i<n; i++)
61 nvalue(&o)=tf->knum[i];
62 k=MapConstant(map,-1,&o);
63 if (k==j) tf->knum[j++]=tf->knum[i];
65 tf->nknum=j;
66 j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
67 for (i=0; i<n; i++)
69 tsvalue(&o)=tf->kstr[i];
70 k=MapConstant(map,-1,&o);
71 if (k==j) tf->kstr[j++]=tf->kstr[i];
73 tf->nkstr=j;
74 #ifdef DEBUG
75 printf("%p after pack nknum=%d nkstr=%d\n",tf,tf->nknum,tf->nkstr);
76 #endif
79 static void OptConstants(Proto* tf)
81 Instruction* p;
82 int n=tf->nknum+tf->nkstr;
83 Hash* map=luaH_new(L,n);
84 int m=MapConstants(tf,map);
85 #ifdef DEBUG
86 printf("%p n=%d m=%d %s\n",tf,n,m,(m==n)?"nothing to optimize":"yes!");
87 #endif
88 if (m==n) return;
89 for (p=tf->code;; p++)
91 Instruction i=*p;
92 int op=GET_OPCODE(i);
93 switch (op)
95 TObject o;
96 int j,k;
97 case OP_PUSHNUM: case OP_PUSHNEGNUM:
98 j=GETARG_U(i);
99 ttype(&o)=LUA_TNUMBER; nvalue(&o)=tf->knum[j];
100 k=MapConstant(map,-1,&o);
101 if (k!=j) *p=CREATE_U(op,k);
102 break;
103 case OP_PUSHSTRING: case OP_GETGLOBAL: case OP_GETDOTTED:
104 case OP_PUSHSELF: case OP_SETGLOBAL:
105 j=GETARG_U(i);
106 ttype(&o)=LUA_TSTRING; tsvalue(&o)=tf->kstr[j];
107 k=MapConstant(map,-1,&o);
108 if (k!=j) *p=CREATE_U(op,k);
109 break;
110 case OP_END:
111 PackConstants(tf,map);
112 luaH_free(L,map);
113 return;
114 default:
115 break;
120 #define OptFunction luaU_optchunk
122 void OptFunction(Proto* tf)
124 int i,n=tf->nkproto;
125 OptConstants(tf);
126 for (i=0; i<n; i++) OptFunction(tf->kproto[i]);