1 /********************************** comp/pcmd.c ********************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 contains the parser functions which generate pseude commands and
8 eliminating unnecessary copy instructions
10 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
11 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
13 Last Change: 1997/09/22
15 *******************************************************************************/
18 list *pcmdlist; /* list of pseudo commands */
21 /***************************** support functions ******************************/
23 static void pcmd_init (list *pl)
29 static void pcmd_realmove (u2 type, varid source, varid dest)
33 c -> opcode = CMD_MOVE;
34 c -> source1 = source;
38 c -> u.move.type = type;
39 list_addlast (pcmdlist, c);
46 static void pcmd_invalidatevar (varid v)
50 if (!var_isoriginal(v) ) {
54 while ( (c = var_nextcopy (v)) != NULL) {
55 pcmd_realmove (var_type(v), v,c);
63 static void pcmd_untievar (varid v)
67 if (!var_isoriginal(v)) {
68 pcmd_realmove (var_type(v), var_findoriginal(v), v);
72 while ( (c = var_nextcopy(v)) != NULL) {
73 pcmd_realmove (var_type(v), v, c);
80 static void pcmd_untieall ()
84 while ( (v = var_nextcopiedvar()) != NULL) {
85 pcmd_realmove (var_type(v), var_findoriginal(v), v);
91 /********************** generation of pseudo commands *************************/
93 static void pcmd_drop (varid var)
97 if (var_isoriginal(var)) {
98 pcmd_invalidatevar (var);
101 c -> opcode = CMD_DROP;
103 c -> source1 = c -> source2 = c -> source3 = NOVAR;
104 list_addlast (pcmdlist, c);
110 pcmd_invalidatevar (var);
115 static void pcmd_activate (varid var)
117 pcmd *c = DNEW(pcmd);
121 c -> tag = TAG_ACTIVATE;
122 c -> opcode = CMD_ACTIVATE;
124 c -> source1 = c -> source2 = c -> source3 = NOVAR;
125 list_addlast (pcmdlist, c);
133 static void pcmd_loadconst_i (s4 val, varid var)
135 pcmd *c = DNEW (pcmd);
136 c -> tag = TAG_LOADCONST_I;
137 c -> opcode = CMD_LOADCONST_I;
139 c -> source1 = c -> source2 = c -> source3 = NOVAR;
140 c -> u.i.value = val;
142 pcmd_invalidatevar (var);
143 list_addlast (pcmdlist, c);
153 static void pcmd_loadconst_l (s8 val, varid var)
155 pcmd *c = DNEW (pcmd);
156 c -> tag = TAG_LOADCONST_L;
157 c -> opcode = CMD_LOADCONST_L;
159 c -> source1 = c -> source2 = c -> source3 = NOVAR;
160 c -> u.l.value = val;
162 pcmd_invalidatevar (var);
163 list_addlast (pcmdlist, c);
173 static void pcmd_loadconst_f (float val, varid var)
175 pcmd *c = DNEW (pcmd);
176 c -> tag = TAG_LOADCONST_F;
177 c -> opcode = CMD_LOADCONST_F;
179 c -> source1 = c -> source2 = c -> source3 = NOVAR;
180 c -> u.f.value = val;
182 pcmd_invalidatevar (var);
183 list_addlast (pcmdlist, c);
191 static void pcmd_loadconst_d (double val, varid var)
193 pcmd *c = DNEW (pcmd);
194 c -> tag = TAG_LOADCONST_D;
195 c -> opcode = CMD_LOADCONST_D;
197 c -> source1 = c -> source2 = c -> source3 = NOVAR;
198 c -> u.d.value = val;
200 pcmd_invalidatevar (var);
201 list_addlast (pcmdlist, c);
209 static void pcmd_loadconst_a (void *val, varid var)
211 pcmd *c = DNEW (pcmd);
212 c -> tag = TAG_LOADCONST_A;
213 c -> opcode = CMD_LOADCONST_A;
215 c -> source1 = c -> source2 = c -> source3 = NOVAR;
216 c -> u.a.value = val;
218 pcmd_invalidatevar (var);
219 list_addlast (pcmdlist, c);
229 static void pcmd_move (u2 type, varid source, varid dest)
231 pcmd_invalidatevar (dest);
232 var_makecopy ( var_findoriginal(source), dest);
236 static void pcmd_move_n_drop (u2 type, varid source, varid dest)
240 pcmd_untievar (source);
241 pcmd_untievar (dest);
246 c = list_last (pcmdlist);
249 case TAG_LOADCONST_I:
250 if (c->dest == source) { c->dest = dest; return; }
252 count_pcmd_const_store++;
255 case TAG_LOADCONST_L:
256 if (c->dest == source) { c->dest = dest; return; }
258 case TAG_LOADCONST_F:
259 if (c->dest == source) { c->dest = dest; return; }
261 case TAG_LOADCONST_D:
262 if (c->dest == source) { c->dest = dest; return; }
264 case TAG_LOADCONST_A:
265 if (c->dest == source) { c->dest = dest; return; }
268 if (c->dest == source) { c->dest = dest; return; }
271 if (c->dest == source) { c->dest = dest; return; }
280 c = list_prev (pcmdlist, c);
284 var_makecopy ( source, dest);
287 count_pcmd_store_comb++;
292 static void pcmd_iinc (s4 val, varid sourcedest)
294 pcmd *c = DNEW (pcmd);
296 pcmd_invalidatevar (sourcedest);
299 c -> opcode = CMD_IINC;
300 c -> source1 = var_findoriginal(sourcedest);
301 c -> source2 = NOVAR;
302 c -> source3 = NOVAR;
303 c -> dest = sourcedest;
304 c -> u.i.value = val;
306 list_addlast (pcmdlist, c);
314 static void pcmd_op (u1 opcode,
315 varid source1, varid source2, varid source3, varid dest)
320 c = list_last (pcmdlist);
321 if (c && (c->tag == TAG_LOADCONST_I))
327 count_pcmd_const_store++;
338 count_pcmd_const_alu++;
342 if (dest) pcmd_invalidatevar (dest);
345 c -> opcode = opcode;
346 c -> source1 = source1 ? var_findoriginal(source1) : NOVAR;
347 c -> source2 = source2 ? var_findoriginal(source2) : NOVAR;
348 c -> source3 = source3 ? var_findoriginal(source3) : NOVAR;
350 list_addlast (pcmdlist, c);
357 static void pcmd_mem (u1 opcode, u2 type, varid base, varid source,
358 varid dest, u2 offset)
363 c = list_last (pcmdlist);
364 if (c && (c->tag == TAG_LOADCONST_I) && (opcode == CMD_PUTFIELD))
365 count_pcmd_const_store++;
368 if (dest) pcmd_invalidatevar (dest);
371 c -> opcode = opcode;
372 c -> source1 = base ? var_findoriginal(base) : NOVAR;
373 c -> source2 = source ? var_findoriginal(source) : NOVAR;
374 c -> source3 = NOVAR;
376 c -> u.mem.type = type;
377 c -> u.mem.offset = offset;
378 list_addlast (pcmdlist, c);
386 static void pcmd_bra (u1 opcode, varid s1, varid s2, varid dest, basicblock *target)
392 c = list_last (pcmdlist);
393 if (c && (c->tag == TAG_LOADCONST_I))
401 count_pcmd_const_bra++;
405 or1 = s1 ? var_findoriginal (s1) : NOVAR;
406 or2 = s2 ? var_findoriginal (s2) : NOVAR;
411 c -> opcode = opcode;
414 c -> source3 = NOVAR;
416 c -> u.bra.target = target;
417 list_addlast (pcmdlist, c);
425 static void pcmd_trace (void *method)
429 isleafmethod = false;
433 c -> opcode = CMD_TRACEBUILT;
434 c -> source1 = NOVAR;
435 c -> source2 = NOVAR;
436 c -> source3 = NOVAR;
438 c -> u.a.value = method;
439 list_addlast (pcmdlist, c);
443 static void pcmd_bra_n_drop (u1 opcode, varid s1, varid s2, varid dest, basicblock *target)
446 varid or1=NOVAR,or2=NOVAR;
447 bool isor1=false,isor2=false;
450 c = list_last (pcmdlist);
451 if (c && (c->tag == TAG_LOADCONST_I))
459 count_pcmd_const_bra++;
464 or1 = var_findoriginal (s1);
465 if (! (isor1 = var_isoriginal(s1)) ) var_unlinkcopy (s1);
468 or2 = var_findoriginal (s2);
469 if (! (isor2 = var_isoriginal (s2)) ) var_unlinkcopy (s2);
475 c -> opcode = opcode;
478 c -> source3 = NOVAR;
480 c -> u.bra.target = target;
481 list_addlast (pcmdlist, c);
483 if (isor1) pcmd_drop (s1);
484 if (isor2) pcmd_drop (s2);
492 static void pcmd_tablejump (varid s, u4 targetcount, basicblock **targets)
494 pcmd *c = DNEW(pcmd);
498 c -> tag = TAG_TABLEJUMP;
499 c -> opcode = CMD_TABLEJUMP;
500 c -> source1 = var_findoriginal(s);
501 c -> source2 = NOVAR;
502 c -> source3 = NOVAR;
504 c -> u.tablejump.targetcount = targetcount;
505 c -> u.tablejump.targets = targets;
506 list_addlast (pcmdlist, c);
514 /******* ATTENTION: Method does DROP automatically !!!!! ****/
516 static void pcmd_method (int opcode, methodinfo *mi, functionptr builtin,
517 int paramnum, varid *params, varid result, varid exceptionvar)
522 pcmd *c = DNEW(pcmd);
526 isleafmethod = false;
529 for (i = 0; i < paramnum; i++) {
531 var_proposereg(v, reg_parlistpar(var_type(v)));
535 var_proposereg(result, reg_parlistresult(var_type(result)));
538 exceptionvar -> reg = reg_parlistexception();
541 c -> tag = TAG_METHOD;
542 c -> opcode = opcode;
543 c -> source1 = c -> source2 = c -> source3 = NULL;
545 c -> u.method.method = mi;
546 c -> u.method.builtin = builtin;
547 c -> u.method.paramnum = paramnum;
548 c -> u.method.params = params;
549 c -> u.method.exceptionvar = exceptionvar;
550 list_addlast (pcmdlist, c);
552 for (i = 0; i < paramnum; i++) pcmd_drop(params[i]);
561 static void pcmd_builtin1 (functionptr builtin, varid v1, varid result)
563 varid *args = DMNEW (varid, 1);
565 pcmd_method (CMD_BUILTIN, NULL, builtin, 1, args, result,NOVAR);
568 static void pcmd_builtin2 (functionptr builtin, varid v1, varid v2, varid result)
570 varid *args = DMNEW (varid, 2);
573 pcmd_method (CMD_BUILTIN, NULL, builtin, 2, args, result, NOVAR);
576 static void pcmd_builtin3 (functionptr builtin, varid v1, varid v2, varid v3, varid result)
578 varid *args = DMNEW (varid, 3);
582 pcmd_method (CMD_BUILTIN, NULL, builtin, 3, args, result, NOVAR);
586 static void pcmd_display (pcmd *c)
591 case TAG_LOADCONST_I:
592 printf (" LOADCONST_I #%ld -> ",
593 (long int) c -> u.i.value);
594 var_display (c -> dest);
597 case TAG_LOADCONST_L:
599 printf (" LOADCONST_L #%ld -> ", (long int) c -> u.l.value);
601 printf (" LOADCONST_L #HI: %ld LO: %ld -> ",
602 (long int) c->u.l.value.high, (long int) c->u.l.value.low );
604 var_display (c -> dest);
607 case TAG_LOADCONST_F:
608 printf (" LOADCONST_F #%f -> ", (double) c -> u.f.value);
609 var_display (c -> dest);
612 case TAG_LOADCONST_D:
613 printf (" LOADCONST_D #%f -> ", c -> u.d.value);
614 var_display (c -> dest);
617 case TAG_LOADCONST_A:
618 printf (" LOADCONST_A #%p -> ", c -> u.a.value);
619 var_display (c -> dest);
624 printf (" MOVE_%1d ", c -> u.move.type);
625 var_display (c-> source1);
627 var_display (c -> dest);
632 printf (" OP%3d ", c -> opcode);
633 var_display (c -> source1);
635 var_display (c -> source2);
637 var_display (c -> source3);
639 var_display (c -> dest );
644 printf (" BRA%3d (", c -> opcode);
645 var_display (c -> source1);
647 var_display (c -> source2);
649 var_display (c -> dest);
650 if (c->u.bra.target) {
651 printf (") to pos %ld\n",
652 (long int) c -> u.bra.target -> jpc );
658 printf (" TABLEJUMP ");
659 var_display (c -> source1);
661 for (i=0; i < (int) c->u.tablejump.targetcount; i++) {
662 printf (" %d: to pos %ld\n", (int) i,
663 (long int) c ->u.tablejump.targets[i] -> jpc );
668 printf (" MEM%3d_%d ", c -> opcode, c -> u.mem.type);
669 var_display (c -> source2);
671 var_display (c -> dest);
673 printf ("%d [", (int) (c -> u.mem.offset) );
674 var_display (c -> source1 );
679 printf (" METHOD%3d ", c -> opcode);
680 for (i=0; i < c -> u.method.paramnum; i++) {
681 var_display (c -> u.method.params[i]);
684 var_display (c -> dest);
686 var_display (c->u.method.exceptionvar);
692 var_display (c-> dest);
696 printf (" [ ACTIVATE ");
697 var_display (c-> dest);