2 ** $Id: opt.c,v 1.12 1999/07/02 19:34:26 lhf Exp $
4 ** See Copyright Notice in lua.h
12 static void FixArg(Byte
* p
, int i
, int j
, int isconst
)
16 else if (i
<=MAX_BYTE
) /* j<i, so j fits where i did */
20 if (isconst
&& j
<=MAX_BYTE
) /* may use byte variant instead */
22 p
[0]++; /* byte variant follows word variant */
26 else /* stuck with word variant */
32 else /* previous instruction must've been LONGARG */
34 if (isconst
&& j
<=MAX_WORD
) p
[-2]=p
[-1]=NOP
; else p
[-1]=j
>>16;
40 static void FixConstants(TProtoFunc
* tf
, int* C
)
52 if (op
==PUSHCONSTANT
|| op
==GETGLOBAL
|| op
==GETDOTTED
||
53 op
==PUSHSELF
|| op
==SETGLOBAL
|| op
==CLOSURE
)
55 else if (op
==LONGARG
) longarg
=i
<<16;
56 else if (op
==ENDCODE
) break;
61 #define UNREF 1 /* "type" of unused constants */
62 #define BIAS 128 /* mark for used constants */
64 static void NoUnrefs(TProtoFunc
* tf
)
70 for (;;) /* mark all used constants */
77 if (op
==PUSHCONSTANT
|| op
==GETGLOBAL
|| op
==GETDOTTED
||
78 op
==PUSHSELF
|| op
==SETGLOBAL
|| op
==CLOSURE
)
80 TObject
* o
=tf
->consts
+i
;
81 if (ttype(o
)<=0) ttype(o
)+=BIAS
; /* mark as used */
83 else if (op
==LONGARG
) longarg
=i
<<16;
84 else if (op
==ENDCODE
) break;
87 for (i
=0; i
<n
; i
++) /* mark all unused constants */
89 TObject
* o
=tf
->consts
+i
;
91 ttype(o
)=UNREF
; /* mark as unused */
93 ttype(o
)-=BIAS
; /* unmark used constant */
97 #define CMP(oa,ob,f) memcmp(&f(oa),&f(ob),sizeof(f(oa)))
99 static int compare(TProtoFunc
* tf
, int ia
, int ib
)
101 TObject
* oa
=tf
->consts
+ia
;
102 TObject
* ob
=tf
->consts
+ib
;
103 int t
=ttype(oa
)-ttype(ob
);
107 case LUA_T_NUMBER
: return CMP(oa
,ob
,nvalue
);
108 case LUA_T_STRING
: return CMP(oa
,ob
,tsvalue
);
109 case LUA_T_PROTO
: return CMP(oa
,ob
,tfvalue
);
110 case LUA_T_NIL
: return 0;
111 case UNREF
: return 0;
112 default: return ia
-ib
; /* cannot happen */
116 static TProtoFunc
* TF
; /* for sort */
118 static int compare1(const void* a
, const void* b
)
122 int t
=compare(TF
,ia
,ib
);
123 return (t
) ? t
: ia
-ib
;
126 static void OptConstants(TProtoFunc
* tf
)
133 luaM_reallocvector(C
,n
,int);
134 luaM_reallocvector(D
,n
,int);
136 for (i
=0; i
<n
; i
++) C
[i
]=D
[i
]=i
; /* group duplicates */
137 TF
=tf
; qsort(C
,n
,sizeof(C
[0]),compare1
);
138 k
=C
[0]; /* build duplicate table */
142 if (compare(tf
,k
,j
)==0) D
[j
]=k
; else k
=j
;
144 k
=0; /* build rename map & pack constants */
147 if (D
[i
]==i
) /* new value */
149 TObject
* o
=tf
->consts
+i
;
152 tf
->consts
[k
]=tf
->consts
[i
];
160 printf("\t" SOURCE
" reduced constants from %d to %d\n",
161 tf
->source
->str
,tf
->lineDefined
,n
,k
);
167 static int NoDebug(TProtoFunc
* tf
)
171 int lop
=NOP
; /* last opcode */
173 for (;;) /* change SETLINE to NOP */
176 int n
=INFO(tf
,p
,&OP
);
179 else if (op
==SETLINE
)
182 if (lop
==LONGARG
) m
=2; else if (lop
==LONGARGW
) m
=3; else m
=0;
183 nop
+=n
+m
; memset(p
-m
,NOP
,n
+m
);
185 else if (op
==ENDCODE
) break;
192 static int FixJump(TProtoFunc
* tf
, Byte
* a
, Byte
* b
)
199 int n
=INFO(tf
,p
,&OP
);
202 else if (op
==ENDCODE
) break;
208 static void FixJumps(TProtoFunc
* tf
)
216 int n
=INFO(tf
,p
,&OP
);
218 int i
=OP
.arg
+longarg
;
221 if (op
==ENDCODE
) break;
222 else if (op
==IFTUPJMP
|| op
==IFFUPJMP
)
223 nop
=FixJump(tf
,p
-i
+n
,p
);
224 else if (op
==ONTJMP
|| op
==ONFJMP
|| op
==JMP
|| op
==IFFJMP
)
225 nop
=FixJump(tf
,p
,p
+i
+n
);
226 else if (op
==LONGARG
) longarg
=i
<<16;
227 if (nop
>0) FixArg(p
,i
,i
-nop
,0);
232 static void PackCode(TProtoFunc
* tf
)
240 int n
=INFO(tf
,p
,&OP
);
242 if (op
!=NOP
) { memcpy(q
,p
,n
); q
+=n
; }
244 if (op
==ENDCODE
) break;
246 printf("\t" SOURCE
" reduced code from %d to %d\n",
247 tf
->source
->str
,tf
->lineDefined
,(int)(p
-code
),(int)(q
-code
));
250 static void OptCode(TProtoFunc
* tf
)
252 if (NoDebug(tf
)==0) return; /* cannot improve code */
257 static void OptFunction(TProtoFunc
* tf
);
259 static void OptFunctions(TProtoFunc
* tf
)
264 TObject
* o
=tf
->consts
+i
;
265 if (ttype(o
)==LUA_T_PROTO
) OptFunction(tfvalue(o
));
269 static void OptFunction(TProtoFunc
* tf
)
274 tf
->source
=luaS_new("");
278 void luaU_optchunk(TProtoFunc
* Main
)