CACAO
SSAConstructionPass.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/SSAConstructionPass.cpp - SSAConstructionPass
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
32 
33 #include "vm/descriptor.hpp"
34 
35 #include "vm/jit/jit.hpp"
36 #include "vm/jit/show.hpp"
37 #include "vm/jit/ir/icmd.hpp"
39 
40 #include "vm/statistics.hpp"
41 
42 #include "toolbox/logging.hpp"
43 
44 #define DEBUG_NAME "compiler2/SSAConstruction"
45 
46 STAT_DECLARE_GROUP(compiler2_stat)
47 STAT_REGISTER_GROUP_VAR(std::size_t,num_trivial_phis,0,"# trivial phis","number of trivial phis",compiler2_stat)
48 STAT_REGISTER_GROUP_VAR(std::size_t,num_icmd_inst,0,"icmd instructions",
49  "ICMD instructions processed (by the compiler2)",compiler2_stat)
50 
51 
52 namespace cacao {
53 
54 namespace {
55 #if 0
56 OStream& show_variable_intern_OS(OStream &OS, const jitdata *jd, s4 index, int stage)
57 {
58  char type;
59  char kind;
60  varinfo *v;
61 
62  if (index < 0 || index >= jd->vartop) {
63  OS << "<INVALID INDEX:" << index << ">";
64  return OS;
65  }
66 
67  v = VAR(index);
68 
69  switch (v->type) {
70  case TYPE_INT: type = 'i'; break;
71  case TYPE_LNG: type = 'l'; break;
72  case TYPE_FLT: type = 'f'; break;
73  case TYPE_DBL: type = 'd'; break;
74  case TYPE_ADR: type = 'a'; break;
75  case TYPE_RET: type = 'r'; break;
76  default: type = '?';
77  }
78 
79  if (index < jd->localcount) {
80  kind = 'L';
81  if (v->flags & (PREALLOC | INOUT))
82  OS << "<INVALID FLAGS!>";
83  }
84  else {
85  if (v->flags & PREALLOC) {
86  kind = 'A';
87  if (v->flags & INOUT) {
88  /* PREALLOC is used to avoid allocation of TYPE_RET */
89  if (v->type == TYPE_RET)
90  kind = 'i';
91  else
92  OS << "<INVALID FLAGS!>";
93  }
94  }
95  else if (v->flags & INOUT)
96  kind = 'I';
97  else
98  kind = 'T';
99  }
100 
101  printf("%c%c%d", kind, type, index);
102  OS << kind << type << index;
103 
104  if (v->flags & SAVEDVAR)
105  OS << '!';
106 
107  if (stage >= SHOW_REGS || (v->flags & PREALLOC)) {
108  OS << '(';
109  OS << "TODO: show_allocation(v->type, v->flags, v->vv.regoff);";
110  OS << ')';
111  }
112 
113  if (v->type == TYPE_RET && (v->flags & PREALLOC)) {
114  printf("(L%03d)", v->vv.retaddr->nr);
115  OS << "(L" << setw(3) << v->vv.retaddr->nr;
116  }
117 
118  return OS;
119 }
120 #endif
121 
122 #define SHOW_TARGET(OS, target) \
123  if (stage >= SHOW_PARSE) { \
124  OS << "--> L" << setw(3) << (target).block->nr; \
125  } \
126  else { \
127  OS << "--> insindex " << (target).insindex; \
128  }
129 
130 #define SHOW_INT_CONST(OS, val) \
131  if (stage >= SHOW_PARSE) { \
132  OS << (int32_t) (val) << "0x" << hex << setw(8) << (int32_t) (val) << dec; \
133  } \
134  else { \
135  OS << "iconst "; \
136  }
137 
138 #define SHOW_LNG_CONST(OS, val) \
139  if (stage >= SHOW_PARSE) \
140  OS << (val) << "0x" << hex << setw(16) << (val) << dec;\
141  else \
142  OS << "lconst ";
143 
144 #define SHOW_ADR_CONST(OS, val) \
145  if (stage >= SHOW_PARSE) \
146  OS << "0x" << hex << setw(8) << (ptrint) (val) << dec; \
147  else \
148  OS << "aconst ";
149 
150 #define SHOW_FLT_CONST(OS, val) \
151  if (stage >= SHOW_PARSE) { \
152  imm_union v; \
153  v.f = (val); \
154  OS << (val) << hex << setw(8) << v.i << dec; \
155  } \
156  else { \
157  OS << "fconst "; \
158  }
159 
160 #define SHOW_DBL_CONST(OS, val) \
161  if (stage >= SHOW_PARSE) { \
162  imm_union v; \
163  v.d = (val); \
164  OS << (val) << hex << setw(16) << v.l << dec; \
165  } \
166  else \
167  OS << "dconst ";
168 
169 #define SHOW_INDEX(OS, index) \
170  if (stage >= SHOW_PARSE) { \
171  OS << index << ""; \
172  } \
173  else { \
174  OS << "index"; \
175  }
176 
177 #define SHOW_STRING(OS, val) \
178  if (stage >= SHOW_PARSE) { \
179  OS << "\""; \
180  OS << (Utf8String)JavaString((java_handle_t*) (val)).to_utf8();\
181  OS << "\" "; \
182  } \
183  else { \
184  OS << "string "; \
185  }
186 #if 0
187 #define SHOW_CLASSREF_OR_CLASSINFO(OS, c) \
188  if (stage >= SHOW_PARSE) { \
189  if (IS_CLASSREF(c)) \
190  class_classref_print(c.ref); \
191  else \
192  class_print(c.cls); \
193  putchar(' '); \
194  } \
195  else { \
196  printf("class "); \
197  }
198 #else
199 #define SHOW_CLASSREF_OR_CLASSINFO(OS, c) \
200  if (stage >= SHOW_PARSE) { \
201  OS << "class (TODO)"; \
202  } \
203  else { \
204  OS << "class "; \
205  }
206 #endif
207 #if 0
208 #define SHOW_FIELD(OS, fmiref) \
209  if (stage >= SHOW_PARSE) { \
210  field_fieldref_print(fmiref); \
211  putchar(' '); \
212  } \
213  else { \
214  printf("field "); \
215  }
216 #else
217 #define SHOW_FIELD(OS, fmiref) \
218  if (stage >= SHOW_PARSE) { \
219  OS << "field (TODO)"; \
220  } \
221  else { \
222  OS << "field "; \
223  }
224 #endif
225 
226 #define SHOW_VARIABLE(OS, v) \
227  show_variable_intern_OS(OS, jd, (v), stage)
228 
229 #define SHOW_S1(OS, iptr) \
230  if (stage >= SHOW_STACK) { \
231  SHOW_VARIABLE(OS, iptr->s1.varindex); \
232  }
233 
234 #define SHOW_S2(OS, iptr) \
235  if (stage >= SHOW_STACK) { \
236  SHOW_VARIABLE(OS, iptr->sx.s23.s2.varindex); \
237  }
238 
239 #define SHOW_S3(OS, iptr) \
240  if (stage >= SHOW_STACK) { \
241  SHOW_VARIABLE(OS, iptr->sx.s23.s3.varindex); \
242  }
243 
244 #define SHOW_DST(OS, iptr) \
245  if (stage >= SHOW_STACK) { \
246  OS << "=> "; \
247  SHOW_VARIABLE(OS, iptr->dst.varindex); \
248  }
249 
250 #define SHOW_S1_LOCAL(OS, iptr) \
251  if (stage >= SHOW_STACK) { \
252  OS << "L" << iptr->s1.varindex; \
253  } \
254  else { \
255  OS << "JavaL" << iptr->s1.varindex << " "; \
256  }
257 
258 #define SHOW_DST_LOCAL(OS, iptr) \
259  if (stage >= SHOW_STACK) { \
260  OS << "=> L" << iptr->dst.varindex << " "; \
261  } \
262  else { \
263  OS << "=> JavaL" << iptr->dst.varindex << " "; \
264  }
265 #if 0
266 //cacao::OStream& operator<<(cacao::OStream &OS, const struct instruction &inst) {
267 cacao::OStream& print_instruction_OS(cacao::OStream &OS, const jitdata *jd, const struct instruction &inst) {
268  const instruction *iptr = &inst;
269  int stage = SHOW_CFG;
270  u2 opcode;
271  branch_target_t *table;
272  lookup_target_t *lookup;
273  constant_FMIref *fmiref;
274  s4 *argp;
275  s4 i;
276 
277  /* get the opcode and the condition */
278 
279  opcode = iptr->opc;
280 
281  if (stage < SHOW_PARSE)
282  return OS;
283 
284  /* Print the condition for conditional instructions. */
285 
286  /* XXX print condition from flags */
287 
288  if (iptr->flags.bits & INS_FLAG_UNRESOLVED)
289  OS << "(UNRESOLVED) ";
290 
291  switch (inst.opc) {
292  case ICMD_POP:
293  case ICMD_CHECKNULL:
294  SHOW_S1(OS, iptr);
295  break;
296 
297  /* unary */
298  case ICMD_ARRAYLENGTH:
299  case ICMD_INEG:
300  case ICMD_LNEG:
301  case ICMD_FNEG:
302  case ICMD_DNEG:
303  case ICMD_I2L:
304  case ICMD_I2F:
305  case ICMD_I2D:
306  case ICMD_L2I:
307  case ICMD_L2F:
308  case ICMD_L2D:
309  case ICMD_F2I:
310  case ICMD_F2L:
311  case ICMD_F2D:
312  case ICMD_D2I:
313  case ICMD_D2L:
314  case ICMD_D2F:
315  case ICMD_INT2BYTE:
316  case ICMD_INT2CHAR:
317  case ICMD_INT2SHORT:
318  SHOW_S1(OS, iptr);
319  SHOW_DST(OS, iptr);
320  break;
321 
322  /* binary */
323  case ICMD_IADD:
324  case ICMD_LADD:
325  case ICMD_FADD:
326  case ICMD_DADD:
327  case ICMD_ISUB:
328  case ICMD_LSUB:
329  case ICMD_FSUB:
330  case ICMD_DSUB:
331  case ICMD_IMUL:
332  case ICMD_LMUL:
333  case ICMD_FMUL:
334  case ICMD_DMUL:
335  case ICMD_IDIV:
336  case ICMD_LDIV:
337  case ICMD_FDIV:
338  case ICMD_DDIV:
339  case ICMD_IREM:
340  case ICMD_LREM:
341  case ICMD_FREM:
342  case ICMD_DREM:
343  case ICMD_ISHL:
344  case ICMD_LSHL:
345  case ICMD_ISHR:
346  case ICMD_LSHR:
347  case ICMD_IUSHR:
348  case ICMD_LUSHR:
349  case ICMD_IAND:
350  case ICMD_LAND:
351  case ICMD_IOR:
352  case ICMD_LOR:
353  case ICMD_IXOR:
354  case ICMD_LXOR:
355  case ICMD_LCMP:
356  case ICMD_FCMPL:
357  case ICMD_FCMPG:
358  case ICMD_DCMPL:
359  case ICMD_DCMPG:
360  SHOW_S1(OS, iptr);
361  SHOW_S2(OS, iptr);
362  SHOW_DST(OS, iptr);
363  break;
364 
365  /* binary/const INT */
366  case ICMD_IADDCONST:
367  case ICMD_ISUBCONST:
368  case ICMD_IMULCONST:
369  case ICMD_IMULPOW2:
370  case ICMD_IDIVPOW2:
371  case ICMD_IREMPOW2:
372  case ICMD_IANDCONST:
373  case ICMD_IORCONST:
374  case ICMD_IXORCONST:
375  case ICMD_ISHLCONST:
376  case ICMD_ISHRCONST:
377  case ICMD_IUSHRCONST:
378  case ICMD_LSHLCONST:
379  case ICMD_LSHRCONST:
380  case ICMD_LUSHRCONST:
381  SHOW_S1(OS, iptr);
382  SHOW_INT_CONST(OS, iptr->sx.val.i);
383  SHOW_DST(OS, iptr);
384  break;
385 
386  /* ?ASTORECONST (trinary/const INT) */
387  case ICMD_IASTORECONST:
388  case ICMD_BASTORECONST:
389  case ICMD_CASTORECONST:
390  case ICMD_SASTORECONST:
391  SHOW_S1(OS, iptr);
392  SHOW_S2(OS, iptr);
393  SHOW_INT_CONST(OS, iptr->sx.s23.s3.constval);
394  break;
395 
396  /* const INT */
397  case ICMD_ICONST:
398  SHOW_INT_CONST(OS, iptr->sx.val.i);
399  SHOW_DST(OS, iptr);
400  break;
401 
402  /* binary/const LNG */
403  case ICMD_LADDCONST:
404  case ICMD_LSUBCONST:
405  case ICMD_LMULCONST:
406  case ICMD_LMULPOW2:
407  case ICMD_LDIVPOW2:
408  case ICMD_LREMPOW2:
409  case ICMD_LANDCONST:
410  case ICMD_LORCONST:
411  case ICMD_LXORCONST:
412  SHOW_S1(OS, iptr);
413  SHOW_LNG_CONST(OS, iptr->sx.val.l);
414  SHOW_DST(OS, iptr);
415  break;
416 
417  /* trinary/const LNG (<= pointer size) */
418  case ICMD_LASTORECONST:
419  SHOW_S1(OS, iptr);
420  SHOW_S2(OS, iptr);
421  SHOW_ADR_CONST(OS, iptr->sx.s23.s3.constval);
422  break;
423 
424  /* const LNG */
425  case ICMD_LCONST:
426  SHOW_LNG_CONST(OS, iptr->sx.val.l);
427  SHOW_DST(OS, iptr);
428  break;
429 
430  /* const FLT */
431  case ICMD_FCONST:
432  SHOW_FLT_CONST(OS, iptr->sx.val.f);
433  SHOW_DST(OS, iptr);
434  break;
435 
436  /* const DBL */
437  case ICMD_DCONST:
438  SHOW_DBL_CONST(OS, iptr->sx.val.d);
439  SHOW_DST(OS, iptr);
440  break;
441 
442  /* const ADR */
443  case ICMD_ACONST:
444  if (iptr->flags.bits & INS_FLAG_CLASS) {
445  SHOW_ADR_CONST(OS, iptr->sx.val.anyptr);
446  SHOW_CLASSREF_OR_CLASSINFO(OS, iptr->sx.val.c);
447  }
448  else if (iptr->sx.val.anyptr == NULL) {
449  OS << "NULL ";
450  }
451  else {
452  SHOW_ADR_CONST(OS, iptr->sx.val.anyptr);
453  SHOW_STRING(OS, iptr->sx.val.stringconst);
454  }
455  SHOW_DST(OS, iptr);
456  break;
457 
458  case ICMD_AASTORECONST:
459  SHOW_S1(OS, iptr);
460  SHOW_S2(OS, iptr);
461  printf("%p ", (void*) iptr->sx.s23.s3.constval);
462  break;
463 
464  case ICMD_GETFIELD: /* 1 -> 1 */
465  case ICMD_PUTFIELD: /* 2 -> 0 */
466  case ICMD_PUTSTATIC: /* 1 -> 0 */
467  case ICMD_GETSTATIC: /* 0 -> 1 */
468  case ICMD_PUTSTATICCONST: /* 0 -> 0 */
469  case ICMD_PUTFIELDCONST: /* 1 -> 0 */
470  if (opcode != ICMD_GETSTATIC && opcode != ICMD_PUTSTATICCONST) {
471  SHOW_S1(OS, iptr);
472  if (opcode == ICMD_PUTFIELD) {
473  SHOW_S2(OS, iptr);
474  }
475  }
476  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
477  SHOW_FIELD(OS, fmiref);
478 
479  if (opcode == ICMD_GETSTATIC || opcode == ICMD_GETFIELD) {
480  SHOW_DST(OS, iptr);
481  }
482  break;
483 
484  case ICMD_IINC:
485  SHOW_S1_LOCAL(OS, iptr);
486  SHOW_INT_CONST(OS, iptr->sx.val.i);
487  SHOW_DST_LOCAL(OS, iptr);
488  break;
489 
490  case ICMD_IASTORE:
491  case ICMD_SASTORE:
492  case ICMD_BASTORE:
493  case ICMD_CASTORE:
494  case ICMD_LASTORE:
495  case ICMD_DASTORE:
496  case ICMD_FASTORE:
497  case ICMD_AASTORE:
498  SHOW_S1(OS, iptr);
499  SHOW_S2(OS, iptr);
500  SHOW_S3(OS, iptr);
501  break;
502 
503  case ICMD_IALOAD:
504  case ICMD_SALOAD:
505  case ICMD_BALOAD:
506  case ICMD_CALOAD:
507  case ICMD_LALOAD:
508  case ICMD_DALOAD:
509  case ICMD_FALOAD:
510  case ICMD_AALOAD:
511  SHOW_S1(OS, iptr);
512  SHOW_S2(OS, iptr);
513  SHOW_DST(OS, iptr);
514  break;
515 
516  case ICMD_RET:
517  SHOW_S1_LOCAL(OS, iptr);
518  if (stage >= SHOW_STACK) {
519  printf(" ---> L%03d", iptr->dst.block->nr);
520  }
521  break;
522 
523  case ICMD_ILOAD:
524  case ICMD_LLOAD:
525  case ICMD_FLOAD:
526  case ICMD_DLOAD:
527  case ICMD_ALOAD:
528  SHOW_S1_LOCAL(OS, iptr);
529  SHOW_DST(OS, iptr);
530  break;
531 
532  case ICMD_ISTORE:
533  case ICMD_LSTORE:
534  case ICMD_FSTORE:
535  case ICMD_DSTORE:
536  case ICMD_ASTORE:
537  SHOW_S1(OS, iptr);
538  SHOW_DST_LOCAL(OS, iptr);
539  if (stage >= SHOW_STACK && iptr->sx.s23.s3.javaindex != jitdata::UNUSED)
540  printf(" (javaindex %d)", iptr->sx.s23.s3.javaindex);
541  if (iptr->flags.bits & INS_FLAG_RETADDR) {
542  printf(" (retaddr L%03d)", RETADDR_FROM_JAVALOCAL(iptr->sx.s23.s2.retaddrnr));
543  }
544  break;
545 
546  case ICMD_NEW:
547  SHOW_DST(OS, iptr);
548  break;
549 
550  case ICMD_NEWARRAY:
551  SHOW_DST(OS, iptr);
552  break;
553 
554  case ICMD_ANEWARRAY:
555  SHOW_DST(OS, iptr);
556  break;
557 
558  case ICMD_MULTIANEWARRAY:
559  if (stage >= SHOW_STACK) {
560  argp = iptr->sx.s23.s2.args;
561  i = iptr->s1.argcount;
562  while (i--) {
563  SHOW_VARIABLE(OS, *(argp++));
564  }
565  }
566  else {
567  printf("argcount=%d ", iptr->s1.argcount);
568  }
570  putchar(' ');
571  SHOW_DST(OS, iptr);
572  break;
573 
574  case ICMD_CHECKCAST:
575  SHOW_S1(OS, iptr);
577  putchar(' ');
578  SHOW_DST(OS, iptr);
579  break;
580 
581  case ICMD_INSTANCEOF:
582  SHOW_S1(OS, iptr);
583  SHOW_DST(OS, iptr);
584  break;
585 
586  case ICMD_INLINE_START:
587  case ICMD_INLINE_END:
588  case ICMD_INLINE_BODY:
589 #if 0
590 #if defined(ENABLE_INLINING)
591  {
592  insinfo_inline *ii = iptr->sx.s23.s3.inlineinfo;
593  show_inline_info(jd, ii, opcode, stage);
594  }
595 #endif
596 #endif
597  break;
598 
599  case ICMD_BUILTIN:
600  if (stage >= SHOW_STACK) {
601  argp = iptr->sx.s23.s2.args;
602  i = iptr->s1.argcount;
603  while (i--) {
604  if ((iptr->s1.argcount - 1 - i) == iptr->sx.s23.s3.bte->md->paramcount)
605  printf(" pass-through: ");
606  SHOW_VARIABLE(OS, *(argp++));
607  }
608  }
609  printf("%s ", iptr->sx.s23.s3.bte->cname);
610  if (iptr->sx.s23.s3.bte->md->returntype.type != TYPE_VOID) {
611  SHOW_DST(OS, iptr);
612  }
613  break;
614 
615  case ICMD_INVOKEVIRTUAL:
616  case ICMD_INVOKESPECIAL:
617  case ICMD_INVOKESTATIC:
619  if (stage >= SHOW_STACK) {
620  methoddesc *md;
621  INSTRUCTION_GET_METHODDESC(iptr, md);
622  argp = iptr->sx.s23.s2.args;
623  i = iptr->s1.argcount;
624  while (i--) {
625  if ((iptr->s1.argcount - 1 - i) == md->paramcount)
626  printf(" pass-through: ");
627  SHOW_VARIABLE(OS, *(argp++));
628  }
629  }
630  INSTRUCTION_GET_METHODREF(iptr, fmiref);
631  method_methodref_print(fmiref);
632  if (fmiref->parseddesc.md->returntype.type != TYPE_VOID) {
633  putchar(' ');
634  SHOW_DST(OS, iptr);
635  }
636  break;
637 
638  case ICMD_IFEQ:
639  case ICMD_IFNE:
640  case ICMD_IFLT:
641  case ICMD_IFGE:
642  case ICMD_IFGT:
643  case ICMD_IFLE:
644  SHOW_S1(OS, iptr);
645  SHOW_INT_CONST(OS, iptr->sx.val.i);
646  SHOW_TARGET(OS, iptr->dst);
647  break;
648 
649  case ICMD_IF_LEQ:
650  case ICMD_IF_LNE:
651  case ICMD_IF_LLT:
652  case ICMD_IF_LGE:
653  case ICMD_IF_LGT:
654  case ICMD_IF_LLE:
655  SHOW_S1(OS, iptr);
656  SHOW_LNG_CONST(OS, iptr->sx.val.l);
657  SHOW_TARGET(OS, iptr->dst);
658  break;
659 
660  case ICMD_GOTO:
661  SHOW_TARGET(OS, iptr->dst);
662  break;
663 
664  case ICMD_JSR:
665  SHOW_TARGET(OS, iptr->sx.s23.s3.jsrtarget);
666  SHOW_DST(OS, iptr);
667  break;
668 
669  case ICMD_IFNULL:
670  case ICMD_IFNONNULL:
671  SHOW_S1(OS, iptr);
672  SHOW_TARGET(OS, iptr->dst);
673  break;
674 
675  case ICMD_IF_ICMPEQ:
676  case ICMD_IF_ICMPNE:
677  case ICMD_IF_ICMPLT:
678  case ICMD_IF_ICMPGE:
679  case ICMD_IF_ICMPGT:
680  case ICMD_IF_ICMPLE:
681 
682  case ICMD_IF_LCMPEQ:
683  case ICMD_IF_LCMPNE:
684  case ICMD_IF_LCMPLT:
685  case ICMD_IF_LCMPGE:
686  case ICMD_IF_LCMPGT:
687  case ICMD_IF_LCMPLE:
688 
689  case ICMD_IF_ACMPEQ:
690  case ICMD_IF_ACMPNE:
691  SHOW_S1(OS, iptr);
692  SHOW_S2(OS, iptr);
693  SHOW_TARGET(OS, iptr->dst);
694  break;
695 
696  case ICMD_TABLESWITCH:
697  SHOW_S1(OS, iptr);
698  table = iptr->dst.table;
699 
700  i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
701 
702  printf("high=%d low=%d count=%d\n", iptr->sx.s23.s3.tablehigh, iptr->sx.s23.s2.tablelow, i);
703  while (--i >= 0) {
704  printf("\t\t%d --> ", (int) (table - iptr->dst.table));
705  printf("L%03d\n", table->block->nr);
706  table++;
707  }
708 
709  break;
710 
711  case ICMD_LOOKUPSWITCH:
712  SHOW_S1(OS, iptr);
713 
714  printf("count=%d, default=L%03d\n",
715  iptr->sx.s23.s2.lookupcount,
716  iptr->sx.s23.s3.lookupdefault.block->nr);
717 
718  lookup = iptr->dst.lookup;
719  i = iptr->sx.s23.s2.lookupcount;
720 
721  while (--i >= 0) {
722  printf("\t\t%d --> L%03d\n",
723  lookup->value,
724  lookup->target.block->nr);
725  lookup++;
726  }
727  break;
728 
729  case ICMD_FRETURN:
730  case ICMD_IRETURN:
731  case ICMD_DRETURN:
732  case ICMD_LRETURN:
733  SHOW_S1(OS, iptr);
734  break;
735 
736  case ICMD_ARETURN:
737  case ICMD_ATHROW:
738  SHOW_S1(OS, iptr);
739  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
740  /* XXX this needs more work */
741 #if 0
742  unresolved_class_debug_dump(iptr->sx.s23.s2.uc, stdout);
743 #endif
744  }
745  break;
746 
747  case ICMD_COPY:
748  case ICMD_MOVE:
749  SHOW_S1(OS, iptr);
750  SHOW_DST(OS, iptr);
751  break;
752  case ICMD_GETEXCEPTION:
753  SHOW_DST(OS, iptr);
754  break;
755 #if defined(ENABLE_SSA)
756  case ICMD_PHI:
757  printf("[ ");
758  for (i = 0; i < iptr->s1.argcount; ++i) {
759  SHOW_VARIABLE(OS, iptr->sx.s23.s2.iargs[i]->dst.varindex);
760  }
761  printf("] ");
762  SHOW_DST(OS, iptr);
763  if (iptr->flags.bits & (1 << 0)) OS << "used ";
764  if (iptr->flags.bits & (1 << 1)) OS << "redundantAll ";
765  if (iptr->flags.bits & (1 << 2)) OS << "redundantOne ";
766  break;
767 #endif
768  }
769  return OS << icmd_table[inst.opc].name;
770 }
771 #endif
772 
773 } // end anonymous namespace
774 
775 namespace jit {
776 namespace compiler2 {
777 
778 class InVarPhis {
779 private:
780  PHIInst *phi;
781  jitdata *jd;
782  std::size_t bb_num;
783  std::size_t in_var_index;
784  SSAConstructionPass *parent;
785 public:
786  // constructs
787  InVarPhis(PHIInst *phi, jitdata *jd, std::size_t bb_num, std::size_t in_var_index,
788  SSAConstructionPass *parent)
789  : phi(phi), jd(jd), bb_num(bb_num), in_var_index(in_var_index), parent(parent) {}
790 
791  // fill phi operands
792  void fill_operands() {
793  basicblock *bb = &jd->basicblocks[bb_num];
794  for(s4 i = 0; i < bb->predecessorcount; ++i) {
795  basicblock *pred = bb->predecessors[i];
796  assert(pred->outdepth == bb->indepth);
797  s4 pred_nr = pred->nr;
798  s4 var = pred->outvars[in_var_index];
799  // append operand
800  phi->append_op(parent->read_variable(var,pred_nr));
801  }
802  }
803 };
804 
805 void SSAConstructionPass::write_variable(size_t varindex, size_t bb, Value* v) {
806  LOG2("write variable(" << varindex << "," << bb << ") = " << v << nl);
807  current_def[varindex][bb] = v;
808 }
809 
810 Value* SSAConstructionPass::read_variable(size_t varindex, size_t bb) {
811  LOG2("read variable(" << varindex << "," << bb << ")" << nl);
812  Value* v = current_def[varindex][bb];
813  #if 0
814  if (v) {
815  // local value numbering
816  return v;
817  }
818  // global value numbering
819  return read_variable_recursive(varindex, bb);
820  #endif
821  if (v) {
822  // local value numbering
823  //v = v;
824  } else {
825  // global value numbering
826  v = read_variable_recursive(varindex, bb);
827  }
828  LOG2("Value: " << v << nl);
829  return v;
830 }
831 
832 Value* SSAConstructionPass::read_variable_recursive(size_t varindex, size_t bb) {
833  Value *val; // current definition
834  if(BB[bb]->pred_size() == 0) {
835  // variable not defined oO
836  // create constant for now but seriously, this should not happen!
837  #if 0
838  varinfo *v = VAR(varindex);
839  Type::TypeID type = convert_var_type(v->type);
840  Instruction *konst;
841  switch (type) {
842  case Type::IntTypeID:
843  konst = new CONSTInst(0,Type::IntType());
844  break;
845  case Type::LongTypeID:
846  konst = new CONSTInst(0,Type::LongType());
847  break;
848  case Type::FloatTypeID:
849  konst = new CONSTInst(0,Type::FloatType());
850  break;
851  case Type::DoubleTypeID:
852  konst = new CONSTInst(0,Type::DoubleType());
853  break;
854  default: assert(0);
855  konst = NULL;
856  }
857  ERROR_MSG("no predecessor ","basic block " << bb << " var index " << varindex
858  << " constant: " << konst );
859  M->add_Instruction(konst);
860  return konst;
861  #endif
862  ABORT_MSG("no predecessor ","basic block " << bb << " var index " << varindex);
863  return NULL;
864  }
865  if (!sealed_blocks[bb]) {
866  PHIInst *phi = new PHIInst(var_type_tbl[varindex], BB[bb]);
867  incomplete_phi[bb][varindex] = phi;
868  M->add_Instruction(phi);
869  val = phi;
870  } else if (BB[bb]->pred_size() == 1) { // one predecessor
871  // get first (and only predecessor
872  BeginInst *pred = *(BB[bb]->pred_begin());
873  val = read_variable(varindex, beginToIndex[pred]);
874  } else {
875  PHIInst *phi = new PHIInst(var_type_tbl[varindex], BB[bb]);
876  write_variable(varindex, bb, phi);
877  M->add_Instruction(phi);
878  val = add_phi_operands(varindex, phi);
879  // might get deleted by try_remove_trivial_phi()
880  assert(val->to_Instruction());
881  }
882  write_variable(varindex, bb, val);
883  return val;
884 }
885 
886 Value* SSAConstructionPass::add_phi_operands(size_t varindex, PHIInst *phi) {
887  // determine operands from predecessors
888  BeginInst *BI = phi->get_BeginInst();
889  for (BeginInst::PredecessorListTy::const_iterator i = BI->pred_begin(),
890  e = BI->pred_end(); i != e; ++i) {
891  //
892  phi->append_op(read_variable(varindex,beginToIndex[*i]));
893  }
894  return try_remove_trivial_phi(phi);
895 }
896 
897 Value* SSAConstructionPass::try_remove_trivial_phi(PHIInst *phi) {
898  Value *same = NULL;
899  for(Instruction::OperandListTy::const_iterator i = phi->op_begin(),
900  e = phi->op_end(); i != e; ++i) {
901  Value *op = *i;
902  if ( (op == same) || (op == (Value*)phi) ) {
903  continue; // unique value or self-reference
904  }
905  if (same != NULL) {
906  return phi; // not trivial (merges at least two values)
907  }
908  same = op;
909  }
910  if (same == NULL) {
911  same = NULL; // Phi instruction not reachable
912  }
913  LOG(BoldGreen << "going to remove PHI: " << reset_color << phi << nl);
914  if (DEBUG_COND_N(2)) {
915  for (std::size_t i = 0, e = current_def.size(); i < e; ++i) {
916  for (std::size_t j = 0, e = current_def[i].size(); j < e; ++j) {
917  if (current_def[i][j] == phi) {
918  LOG2("current_def["<<i<<"]["<<j<<"] will be invalid" << nl);
919  }
920  }
921  }
922  }
923  STATISTICS(num_trivial_phis++);
924  alloc::list<Instruction*>::type users(phi->user_begin(),phi->user_end());
925  users.remove(phi);
926  phi->replace_value(same);
927  // update table
928  // XXX this should be done in a smarter way (e.g. by using value references)
929  for (std::size_t i = 0, e = current_def.size(); i < e; ++i) {
930  for (std::size_t j = 0, e = current_def[i].size(); j < e; ++j) {
931  if (current_def[i][j] == phi) {
932  current_def[i][j] = same;
933  }
934  }
935  }
936  // TODO delete phi
937  M->remove_Instruction(phi);
938 
939  for(alloc::list<Instruction*>::type::iterator i = users.begin(), e = users.end();
940  i != e; ++i) {
941  assert(*i);
942  PHIInst *p = (*i)->to_PHIInst();
943  if (p) {
944  try_remove_trivial_phi(p);
945  }
946  }
947 
948  return same;
949 }
950 
951 void SSAConstructionPass::seal_block(size_t bb) {
952  LOG("sealing basic block: " << bb << nl);
953  alloc::vector<PHIInst*>::type &inc_phi_bb = incomplete_phi[bb];
954  for (int i = 0, e = inc_phi_bb.size(); i != e ; ++i) {
955  PHIInst *phi = inc_phi_bb[i];
956  if (phi) {
957  add_phi_operands(i,phi);
958  }
959  }
960  alloc::list<InVarPhis*>::type &in_var_bb = incomplete_in_phi[bb];
961  std::for_each(in_var_bb.begin(),in_var_bb.end(),
962  std::mem_fun(&InVarPhis::fill_operands));
963  sealed_blocks[bb] = true;
964 }
965 
966 
967 bool SSAConstructionPass::try_seal_block(basicblock *bb) {
968  if (sealed_blocks[bb->nr])
969  return true;
970 
971  LOG("try sealing basic block: " << bb->nr << nl);
972  for(int i = 0; i < bb->predecessorcount; ++i)
973  if (!filled_blocks[bb->predecessors[i]->nr])
974  return false;
975 
976  // seal it!
977  seal_block(bb->nr);
978  #if 0
979  // try seal successors
980  for(int i = 0; i < bb->successorcount; ++i) {
981  try_seal_block(bb->successors[i]);
982  }
983  #endif
984 
985  return true;
986 }
987 
988 void SSAConstructionPass::print_current_def() const {
989  for(alloc::vector<alloc::vector<Value*>::type >::type::const_iterator i = current_def.begin(),
990  e = current_def.end(); i != e ; ++i) {
991  for(alloc::vector<Value*>::type::const_iterator ii = (*i).begin(),
992  ee = (*i).end(); ii != ee ; ++ii) {
993  Value *v = *ii;
994  Instruction *I;
995  int max = 20;
996  if (!v) {
997  out() << setw(max) << "NULL";
998  } else if ( (I = v->to_Instruction()) ) {
999  out() << setw(max) << I->get_name();
1000  } else {
1001  out() << setw(max) << "VALUE";
1002  }
1003  }
1004  out() << nl;
1005  }
1006 }
1007 
1008 bool SSAConstructionPass::run(JITData &JD) {
1009  M = JD.get_Method();
1010  LOG("SSAConstructionPass: " << *M << nl);
1011 
1012  basicblock *bb;
1013  jd = JD.get_jitdata();
1014 
1015  // **** BEGIN initializations
1016 
1017  /**
1018  * There are two kinds of variables in the baseline ir. The javalocals as defined
1019  * in the JVM specification (2.6.1.). These are used for arguments and other values
1020  * not stored on the JVM stack. These variables are addressed using an index. Every
1021  * 'slot' can contain values of each basic type. The type is defined by the access
1022  * instruction (e.g. ILOAD, ISTORE for integer). These instructions are introduced
1023  * by the java compiler (usually javac).
1024  * The other group of variables are intended to replace the jvm stack and are created
1025  * by the baseline parse/stackanalysis pass. In contrast to the javalocals these
1026  * variables have a fixed typed. They are used as arguments and results for
1027  * baseline IR instructions.
1028  * For simplicity of the compiler2 IR both variables groups are treated the same way.
1029  * Their current definitions are stored in a value numbering table.
1030  * The number of variables is already known at this point for both types.
1031  */
1032  //unsigned int num_variables = jd->vartop;
1033  // last block used for argument loading
1034  unsigned int num_basicblocks = jd->basicblockcount;
1035  unsigned int init_basicblock = 0;
1036  bool extra_init_bb = jd->basicblocks[0].predecessorcount;
1037 
1038  assert(jd->basicblockcount);
1039  if (extra_init_bb) {
1040  // The first basicblock is the target of a jump (e.g. loophead).
1041  // We have to create a new one to load the arguments
1042  ++num_basicblocks;
1043  init_basicblock = jd->basicblockcount;
1044  LOG("Extra basic block added (index = " << init_basicblock << ")" << nl);
1045  }
1046 
1047  // store basicblock BeginInst
1048  beginToIndex.clear();
1049  BB.clear();
1050  BB.resize(num_basicblocks, NULL);
1051  for(std::size_t i = 0; i < num_basicblocks; ++i) {
1052  BeginInst *bi = new BeginInst();
1053  BB[i] = bi;
1054  beginToIndex.insert(std::make_pair(bi,i));
1055  }
1056  //
1057  // pseudo variable index for global state
1058  std::size_t global_state = jd->vartop;
1059 
1060  // init incomplete_phi
1061  incomplete_phi.clear();
1062  incomplete_phi.resize(num_basicblocks,alloc::vector<PHIInst*>::type(global_state + 1,NULL));
1063  incomplete_in_phi.clear();
1064  incomplete_in_phi.resize(num_basicblocks);
1065 
1066  // (Local,Global) Value Numbering Map, size #bb times #var, initialized to NULL
1067  current_def.clear();
1068  current_def.resize(global_state+1,alloc::vector<Value*>::type(num_basicblocks,NULL));
1069  // sealed blocks
1070  sealed_blocks.clear();
1071  sealed_blocks.resize(num_basicblocks,false);
1072  // filled blocks
1073  filled_blocks.clear();
1074  filled_blocks.resize(num_basicblocks,false);
1075  // initialize
1076  var_type_tbl.clear();
1077  var_type_tbl.resize(global_state+1,Type::VoidTypeID);
1078 
1079  // create variable type map
1080  for(size_t i = 0, e = jd->vartop; i != e ; ++i) {
1081  varinfo &v = jd->var[i];
1082  var_type_tbl[i] = convert_var_type(v.type);
1083  }
1084  // set global state
1085  var_type_tbl[global_state] = Type::GlobalStateTypeID;
1086 
1087  // initialize arguments
1088  methoddesc *md = jd->m->parseddesc;
1089  assert(md);
1090  assert(md->paramtypes);
1091 
1092  if (extra_init_bb) {
1093  M->add_bb(BB[init_basicblock]);
1094  }
1095  LOG("parameter count: i = " << md->paramcount << " slot count = " << md->paramslots << nl);
1096  for (int i = 0, slot = 0; i < md->paramcount; ++i) {
1097  int type = md->paramtypes[i].type;
1098  int varindex = jd->local_map[slot * 5 + type];
1099  LOG("parameter: i = " << i << " slot = " << slot << " type " << get_var_type(type) << nl);
1100 
1101  if (varindex != jitdata::UNUSED) {
1102  // only load if variable is used
1103  Instruction *I = new LOADInst(convert_var_type(type), i, BB[init_basicblock]);
1104  write_variable(varindex,init_basicblock,I);
1105  M->add_Instruction(I);
1106  }
1107 
1108  switch (type) {
1109  case TYPE_LNG:
1110  case TYPE_DBL:
1111  slot +=2;
1112  break;
1113  default:
1114  ++slot;
1115  }
1116  }
1117  if (extra_init_bb) {
1118  BeginInst *targetBlock = BB[0];
1119  Instruction *result = new GOTOInst(BB[init_basicblock], targetBlock);
1120  M->add_Instruction(result);
1121  // now we mark it filled and sealed
1122  filled_blocks[init_basicblock] = true;
1123  sealed_blocks[init_basicblock] = true;
1124  }
1125 
1126  // set start begin inst
1127  M->set_init_bb(BB[init_basicblock]);
1128 
1129  current_def[global_state][init_basicblock] = BB[init_basicblock];
1130 
1131  // **** END initializations
1132 
1133  #if defined(ENABLE_LOGGING)
1134  // print BeginInsts
1135  for(alloc::vector<BeginInst*>::type::iterator i = BB.begin(), e = BB.end();
1136  i != e; ++i) {
1137  Instruction *v = *i;
1138  LOG("BB: " << (void*)v << nl);
1139  }
1140  // print variables
1141  for(size_t i = 0, e = jd->vartop; i != e ; ++i) {
1142  varinfo &v = jd->var[i];
1143  LOG("var#" << i << " type: " << get_var_type(v.type) << nl);
1144  }
1145  #endif
1146  LOG("# variables: " << jd->vartop << nl);
1147  LOG("# javalocals: " << jd->localcount << nl);
1148  // print arguments
1149  LOG("# parameters: " << md->paramcount << nl);
1150  LOG("# parameter slots: " << md->paramslots << nl);
1151  for (int i = 0; i < md->paramslots; ++i) {
1152  int type = md->paramtypes[i].type;
1153  LOG("argument type: " << get_var_type(type)
1154  << " (index " << i << ")"
1155  << " (var_local " << jd->local_map[i * 5 + type] << ")" << nl);
1156  switch (type) {
1157  case TYPE_LNG:
1158  case TYPE_DBL:
1159  ++i;
1160  break;
1161  }
1162  }
1163  for (int i = 0; i < jd->maxlocals; ++i) {
1164  LOG("localindex: " << i << nl);
1165  for (int j = 0; j < 5; ++j) {
1166  s4 entry = jd->local_map[i*5+j];
1167  if (entry == jitdata::UNUSED)
1168  LOG(" type " <<get_var_type(j) << " UNUSED" << nl);
1169  else
1170  LOG(" type " <<get_var_type(j) << " " << entry << nl);
1171  }
1172  }
1173 
1174  FOR_EACH_BASICBLOCK(jd,bb) {
1175  if (bb->icount == 0 ) {
1176  // this is the last (empty) basicblock
1177  assert(bb->nr == jd->basicblockcount);
1178  assert(bb->predecessorcount == 0);
1179  assert(bb->successorcount == 0);
1180  // we dont need it
1181  continue;
1182  }
1183  std::size_t bbindex = (std::size_t)bb->nr;
1184  instruction *iptr;
1185  LOG("basicblock: " << bbindex << nl);
1186 
1187  // handle invars
1188  for(s4 i = 0; i < bb->indepth; ++i) {
1189  std::size_t varindex = bb->invars[i];
1190  PHIInst *phi = new PHIInst(var_type_tbl[varindex], BB[bbindex]);
1191  write_variable(varindex, bbindex, phi);
1192  if (!sealed_blocks[bbindex]) {
1193  incomplete_in_phi[bbindex].push_back(new InVarPhis(phi, jd, bbindex, i, this));
1194  }
1195  else {
1196  InVarPhis invar(phi, jd, bbindex, i, this);
1197  invar.fill_operands();
1198  }
1199  M->add_Instruction(phi);
1200  }
1201 
1202  // add begin block
1203  assert(BB[bbindex]);
1204  M->add_bb(BB[bbindex]);
1205  // every merge node is a possible statechange
1206  // XXX maybe we can handle this via phi nodes but we must ensure that
1207  // they do not get deleted!
1208  current_def[global_state][bbindex] = BB[bbindex];
1209 
1210  FOR_EACH_INSTRUCTION(bb,iptr) {
1211  STATISTICS(++num_icmd_inst);
1212  #if !defined(NDEBUG)
1213  LOG("iptr: " << icmd_table[iptr->opc].name << nl);
1214  #endif
1215  switch (iptr->opc) {
1216  case ICMD_NOP:
1217  //M->add_Instruction(new NOPInst());
1218  break;
1219  case ICMD_POP:
1220  case ICMD_CHECKNULL:
1221  // SHOW_S1(OS, iptr);
1222  // break;
1223 
1224  goto _default;
1225  // /* unary */
1226  case ICMD_INEG:
1227  case ICMD_LNEG:
1228  case ICMD_FNEG:
1229  case ICMD_DNEG:
1230  {
1231  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1232  Type::TypeID type;
1233  switch (iptr->opc) {
1234  case ICMD_INEG:
1235  type = Type::IntTypeID;
1236  break;
1237  case ICMD_LNEG:
1238  type = Type::LongTypeID;
1239  break;
1240  case ICMD_FNEG:
1241  type = Type::FloatTypeID;
1242  break;
1243  case ICMD_DNEG:
1244  type = Type::DoubleTypeID;
1245  break;
1246  default: assert(0);
1247  type = Type::VoidTypeID;
1248  }
1249  Instruction *result = new NEGInst(type,s1);
1250  write_variable(iptr->dst.varindex,bbindex,result);
1251  M->add_Instruction(result);
1252  break;
1253  }
1254  case ICMD_ARRAYLENGTH:
1255  {
1256  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1257  Instruction *result = new ARRAYLENGTHInst(s1);
1258  write_variable(iptr->dst.varindex,bbindex,result);
1259  M->add_Instruction(result);
1260  break;
1261  }
1262  case ICMD_I2L:
1263  case ICMD_I2F:
1264  case ICMD_I2D:
1265  case ICMD_L2I:
1266  case ICMD_L2F:
1267  case ICMD_L2D:
1268  case ICMD_F2I:
1269  case ICMD_F2L:
1270  case ICMD_F2D:
1271  case ICMD_D2I:
1272  case ICMD_D2L:
1273  case ICMD_D2F:
1274  case ICMD_INT2BYTE:
1275  case ICMD_INT2CHAR:
1276  case ICMD_INT2SHORT:
1277  {
1278  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1279  //Type::TypeID type_from;
1280  Type::TypeID type_to;
1281  switch (iptr->opc) {
1282  case ICMD_INT2SHORT:
1283  type_to = Type::ShortTypeID;
1284  break;
1285  case ICMD_INT2CHAR:
1286  type_to = Type::CharTypeID;
1287  break;
1288  case ICMD_INT2BYTE:
1289  type_to = Type::ByteTypeID;
1290  break;
1291  case ICMD_I2L:
1292  //type_from = Type::IntTypeID;
1293  type_to = Type::LongTypeID;
1294  break;
1295  case ICMD_I2F:
1296  //type_from = Type::IntTypeID;
1297  type_to = Type::FloatTypeID;
1298  break;
1299  case ICMD_I2D:
1300  //type_from = Type::IntTypeID;
1301  type_to = Type::DoubleTypeID;
1302  break;
1303  case ICMD_L2I:
1304  //type_from = Type::LongTypeID;
1305  type_to = Type::IntTypeID;
1306  break;
1307  case ICMD_L2F:
1308  //type_from = Type::LongTypeID;
1309  type_to = Type::FloatTypeID;
1310  break;
1311  case ICMD_L2D:
1312  //type_from = Type::LongTypeID;
1313  type_to = Type::DoubleTypeID;
1314  break;
1315  case ICMD_F2I:
1316  //type_from = Type::FloatTypeID;
1317  type_to = Type::IntTypeID;
1318  break;
1319  case ICMD_F2L:
1320  //type_from = Type::FloatTypeID;
1321  type_to = Type::LongTypeID;
1322  break;
1323  case ICMD_F2D:
1324  //type_from = Type::FloatTypeID;
1325  type_to = Type::DoubleTypeID;
1326  break;
1327  case ICMD_D2I:
1328  //type_from = Type::DoubleTypeID;
1329  type_to = Type::IntTypeID;
1330  break;
1331  case ICMD_D2L:
1332  //type_from = Type::DoubleTypeID;
1333  type_to = Type::LongTypeID;
1334  break;
1335  case ICMD_D2F:
1336  //type_from = Type::DoubleTypeID;
1337  type_to = Type::FloatTypeID;
1338  break;
1339  default:
1340  assert(0);
1341  type_to = Type::VoidTypeID;
1342  }
1343  Instruction *result = new CASTInst(type_to, s1);
1344  write_variable(iptr->dst.varindex,bbindex,result);
1345  M->add_Instruction(result);
1346  break;
1347  }
1348 
1349  case ICMD_IADD:
1350  case ICMD_LADD:
1351  case ICMD_FADD:
1352  case ICMD_DADD:
1353  {
1354  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1355  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1356  Type::TypeID type;
1357  switch (iptr->opc) {
1358  case ICMD_IADD:
1359  type = Type::IntTypeID;
1360  break;
1361  case ICMD_LADD:
1362  type = Type::LongTypeID;
1363  break;
1364  case ICMD_FADD:
1365  type = Type::FloatTypeID;
1366  break;
1367  case ICMD_DADD:
1368  type = Type::DoubleTypeID;
1369  break;
1370  default: assert(0);
1371  type = Type::VoidTypeID;
1372  }
1373  Instruction *result = new ADDInst(type, s1, s2);
1374  write_variable(iptr->dst.varindex,bbindex,result);
1375  M->add_Instruction(result);
1376  }
1377  break;
1378  case ICMD_ISUB:
1379  case ICMD_LSUB:
1380  case ICMD_FSUB:
1381  case ICMD_DSUB:
1382  {
1383  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1384  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1385  Type::TypeID type;
1386  switch (iptr->opc) {
1387  case ICMD_ISUB:
1388  type = Type::IntTypeID;
1389  break;
1390  case ICMD_LSUB:
1391  type = Type::LongTypeID;
1392  break;
1393  case ICMD_FSUB:
1394  type = Type::FloatTypeID;
1395  break;
1396  case ICMD_DSUB:
1397  type = Type::DoubleTypeID;
1398  break;
1399  default: assert(0);
1400  type = Type::VoidTypeID;
1401  }
1402  Instruction *result = new SUBInst(type, s1, s2);
1403  write_variable(iptr->dst.varindex,bbindex,result);
1404  M->add_Instruction(result);
1405  }
1406  break;
1407  case ICMD_IMUL:
1408  case ICMD_LMUL:
1409  case ICMD_FMUL:
1410  case ICMD_DMUL:
1411  {
1412  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1413  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1414  Type::TypeID type;
1415  switch (iptr->opc) {
1416  case ICMD_IMUL:
1417  type = Type::IntTypeID;
1418  break;
1419  case ICMD_LMUL:
1420  type = Type::LongTypeID;
1421  break;
1422  case ICMD_FMUL:
1423  type = Type::FloatTypeID;
1424  break;
1425  case ICMD_DMUL:
1426  type = Type::DoubleTypeID;
1427  break;
1428  default: assert(0);
1429  type = Type::VoidTypeID;
1430  }
1431  Instruction *result = new MULInst(type, s1, s2);
1432  write_variable(iptr->dst.varindex,bbindex,result);
1433  M->add_Instruction(result);
1434  }
1435  break;
1436  case ICMD_IDIV:
1437  case ICMD_LDIV:
1438  case ICMD_FDIV:
1439  case ICMD_DDIV:
1440  {
1441  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1442  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1443  Type::TypeID type;
1444  switch (iptr->opc) {
1445  case ICMD_IDIV:
1446  type = Type::IntTypeID;
1447  break;
1448  case ICMD_LDIV:
1449  type = Type::LongTypeID;
1450  break;
1451  case ICMD_FDIV:
1452  type = Type::FloatTypeID;
1453  break;
1454  case ICMD_DDIV:
1455  type = Type::DoubleTypeID;
1456  break;
1457  default: assert(0);
1458  type = Type::VoidTypeID;
1459  }
1460  Instruction *result = new DIVInst(type, s1, s2);
1461  write_variable(iptr->dst.varindex,bbindex,result);
1462  M->add_Instruction(result);
1463  }
1464  break;
1465  case ICMD_IREM:
1466  case ICMD_LREM:
1467  case ICMD_FREM:
1468  case ICMD_DREM:
1469  {
1470  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1471  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1472  Type::TypeID type;
1473  switch (iptr->opc) {
1474  case ICMD_IREM:
1475  type = Type::IntTypeID;
1476  break;
1477  case ICMD_LREM:
1478  type = Type::LongTypeID;
1479  break;
1480  case ICMD_FREM:
1481  type = Type::FloatTypeID;
1482  break;
1483  case ICMD_DREM:
1484  type = Type::DoubleTypeID;
1485  break;
1486  default: assert(0);
1487  type = Type::VoidTypeID;
1488  }
1489  Instruction *result = new REMInst(type, s1, s2);
1490  write_variable(iptr->dst.varindex,bbindex,result);
1491  M->add_Instruction(result);
1492  }
1493  break;
1494  case ICMD_ISHL:
1495  case ICMD_LSHL:
1496  case ICMD_ISHR:
1497  case ICMD_LSHR:
1498  case ICMD_IUSHR:
1499  case ICMD_LUSHR:
1500  goto _default;
1501  case ICMD_IOR:
1502  case ICMD_LOR:
1503  case ICMD_IXOR:
1504  case ICMD_LXOR:
1505  case ICMD_IAND:
1506  case ICMD_LAND:
1507  {
1508  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1509  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1510  Type::TypeID type;
1511  Instruction *result;
1512  // type
1513  switch (iptr->opc) {
1514  case ICMD_IAND:
1515  case ICMD_IOR:
1516  case ICMD_IXOR:
1517  type = Type::IntTypeID;
1518  break;
1519  case ICMD_LAND:
1520  case ICMD_LOR:
1521  case ICMD_LXOR:
1522  type = Type::LongTypeID;
1523  break;
1524  default: assert(0);
1525  type = Type::VoidTypeID;
1526  }
1527  // operation
1528  switch (iptr->opc) {
1529  case ICMD_IAND:
1530  case ICMD_LAND:
1531  result = new ANDInst(type, s1, s2);
1532  break;
1533  case ICMD_IOR:
1534  case ICMD_LOR:
1535  result = new ORInst(type, s1, s2);
1536  break;
1537  case ICMD_IXOR:
1538  case ICMD_LXOR:
1539  result = new XORInst(type, s1, s2);
1540  break;
1541  default: assert(0);
1542  result = NULL;
1543  }
1544  write_variable(iptr->dst.varindex,bbindex,result);
1545  M->add_Instruction(result);
1546  }
1547  break;
1548  case ICMD_LCMP:
1549  case ICMD_FCMPL:
1550  case ICMD_FCMPG:
1551  case ICMD_DCMPL:
1552  case ICMD_DCMPG:
1553  {
1554  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1555  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1556  CMPInst::FloatHandling handling;
1557  switch (iptr->opc) {
1558  case ICMD_FCMPL:
1559  case ICMD_DCMPL:
1560  handling = CMPInst::L;
1561  break;
1562  case ICMD_FCMPG:
1563  case ICMD_DCMPG:
1564  handling = CMPInst::G;
1565  break;
1566  default: assert(0);
1567  handling = CMPInst::DontCare;
1568  }
1569  Instruction *result = new CMPInst(s1, s2, handling);
1570  write_variable(iptr->dst.varindex,bbindex,result);
1571  M->add_Instruction(result);
1572  }
1573  break;
1574  // SHOW_S1(OS, ipt);
1575  // SHOW_S2(OS, iptr);
1576  // SHOW_DST(OS, iptr);
1577  // break;
1578 
1579  /* binary/const INT */
1580  case ICMD_IADDCONST:
1581  case ICMD_ISUBCONST:
1582  {
1583  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1584  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1585  Instruction *result;
1586  switch (iptr->opc) {
1587  case ICMD_IADDCONST:
1588  result = new ADDInst(Type::IntTypeID, s1, konst);
1589  break;
1590  case ICMD_ISUBCONST:
1591  result = new SUBInst(Type::IntTypeID, s1, konst);
1592  break;
1593  default: assert(0);
1594  result = 0;
1595  }
1596  M->add_Instruction(konst);
1597  write_variable(iptr->dst.varindex,bbindex,result);
1598  M->add_Instruction(result);
1599  }
1600  break;
1601  case ICMD_IMULCONST:
1602  {
1603  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1604  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1605  Instruction *result;
1606  result = new MULInst(Type::IntTypeID, s1, konst);
1607  M->add_Instruction(konst);
1608  write_variable(iptr->dst.varindex,bbindex,result);
1609  M->add_Instruction(result);
1610  }
1611  break;
1612  case ICMD_IMULPOW2:
1613  goto _default;
1614  case ICMD_IREMPOW2:
1615  case ICMD_IDIVPOW2:
1616  // FIXME we should lower this to a shift
1617  // XXX it the constant the divisor or the shift amount?
1618  case ICMD_IANDCONST:
1619  {
1620  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1621  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1622  Instruction *result;
1623  switch (iptr->opc) {
1624  case ICMD_IANDCONST:
1625  result = new ANDInst(Type::IntTypeID, s1, konst);
1626  break;
1627  case ICMD_IDIVPOW2:
1628  result = new DIVInst(Type::IntTypeID, s1, konst);
1629  break;
1630  case ICMD_IREMPOW2:
1631  result = new REMInst(Type::IntTypeID, s1, konst);
1632  break;
1633  default: assert(0);
1634  result = NULL;
1635  }
1636  M->add_Instruction(konst);
1637  write_variable(iptr->dst.varindex,bbindex,result);
1638  M->add_Instruction(result);
1639  }
1640  break;
1641  case ICMD_IORCONST:
1642  case ICMD_IXORCONST:
1643  case ICMD_ISHLCONST:
1644  case ICMD_ISHRCONST:
1645  case ICMD_IUSHRCONST:
1646  case ICMD_LSHLCONST:
1647  case ICMD_LSHRCONST:
1648  case ICMD_LUSHRCONST:
1649  // SHOW_S1(OS, iptr);
1650  // SHOW_INT_CONST(OS, iptr->sx.val.i);
1651  // SHOW_DST(OS, iptr);
1652  // break;
1653 
1654  /* ?ASTORECONST (trinary/const INT) */
1655 
1656  case ICMD_BASTORECONST:
1657  case ICMD_CASTORECONST:
1658  case ICMD_SASTORECONST:
1659  case ICMD_AASTORECONST:
1660  goto _default;
1661  case ICMD_IASTORECONST:
1662  case ICMD_LASTORECONST:
1663  {
1664  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1665  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1666  Instruction *konst;
1667  Type::TypeID type;
1668  switch (iptr->opc) {
1669  case ICMD_IASTORECONST:
1670  type = Type::IntTypeID;
1671  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::IntType());
1672  break;
1673  #if 0
1674  case ICMD_BASTORECONST:
1675  type = Type::ByteTypeID;
1676  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::ByteType());
1677  break;
1678  case ICMD_CASTORECONST:
1679  type = Type::CharTypeID;
1680  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::CharType());
1681  break;
1682  case ICMD_SASTORECONST:
1683  type = Type::ShortTypeID;
1684  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::ShortType());
1685  break;
1686  case ICMD_AASTORECONST:
1687  type = Type::ReferenceTypeID;
1688  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::ReferenceType());
1689  break;
1690  #endif
1691  case ICMD_LASTORECONST:
1692  type = Type::LongTypeID;
1693  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::LongType());
1694  break;
1695  default: assert(0);
1696  type = Type::VoidTypeID;
1697  konst = NULL;
1698  }
1699  M->add_Instruction(konst);
1700  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1701  assert(state_change);
1702 
1703  Instruction *ref = new AREFInst(type, s1, s2);
1704  M->add_Instruction(ref);
1705  Instruction *result = new ASTOREInst(type, ref, konst, BB[bbindex], state_change);
1706  write_variable(global_state,bbindex,result);
1707  M->add_Instruction(result);
1708  Instruction *boundscheck = new ARRAYBOUNDSCHECKInst(type, s1, s2);
1709  ref->append_dep(boundscheck);
1710  M->add_Instruction(boundscheck);
1711  }
1712  break;
1713  // SHOW_S1(OS, iptr);
1714  // SHOW_S2(OS, iptr);
1715  // SHOW_INT_CONST(OS, iptr->sx.s23.s3.constval);
1716  // break;
1717 
1718  case ICMD_ICONST:
1719  case ICMD_LCONST:
1720  case ICMD_FCONST:
1721  case ICMD_DCONST:
1722  {
1723  Instruction *I;
1724  switch (iptr->opc) {
1725  case ICMD_ICONST:
1726  I = new CONSTInst(iptr->sx.val.i,Type::IntType());
1727  break;
1728  case ICMD_LCONST:
1729  I = new CONSTInst(iptr->sx.val.l,Type::LongType());
1730  break;
1731  case ICMD_FCONST:
1732  I = new CONSTInst(iptr->sx.val.f,Type::FloatType());
1733  break;
1734  case ICMD_DCONST:
1735  I = new CONSTInst(iptr->sx.val.d,Type::DoubleType());
1736  break;
1737  default: assert(0);
1738  I = NULL;
1739  }
1740  write_variable(iptr->dst.varindex,bbindex,I);
1741  M->add_Instruction(I);
1742  }
1743  break;
1744 
1745  /* binary/const LNG */
1746  case ICMD_LADDCONST:
1747  {
1748  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1749  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1750  Instruction *result = new ADDInst(Type::LongTypeID, s1, konst);
1751  M->add_Instruction(konst);
1752  write_variable(iptr->dst.varindex,bbindex,result);
1753  M->add_Instruction(result);
1754  }
1755  break;
1756  case ICMD_LSUBCONST:
1757  {
1758  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1759  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1760  Instruction *result = new SUBInst(Type::LongTypeID, s1, konst);
1761  M->add_Instruction(konst);
1762  write_variable(iptr->dst.varindex,bbindex,result);
1763  M->add_Instruction(result);
1764  }
1765  break;
1766  case ICMD_LMULCONST:
1767  {
1768  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1769  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1770  Instruction *result = new MULInst(Type::LongTypeID, s1, konst);
1771  M->add_Instruction(konst);
1772  write_variable(iptr->dst.varindex,bbindex,result);
1773  M->add_Instruction(result);
1774  }
1775  break;
1776  case ICMD_LANDCONST:
1777  {
1778  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1779  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1780  Instruction *result;
1781  switch (iptr->opc) {
1782  case ICMD_LANDCONST:
1783  result = new ANDInst(Type::LongTypeID, s1, konst);
1784  break;
1785  default: assert(0);
1786  result = 0;
1787  }
1788  M->add_Instruction(konst);
1789  write_variable(iptr->dst.varindex,bbindex,result);
1790  M->add_Instruction(result);
1791  }
1792  break;
1793  case ICMD_LMULPOW2:
1794  goto _default;
1795  case ICMD_LDIVPOW2:
1796  {
1797  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1798  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1799  Instruction *result;
1800  switch (iptr->opc) {
1801  case ICMD_LDIVPOW2:
1802  // FIXME this is not right!
1803  result = new SUBInst(Type::LongTypeID, s1, konst);
1804  break;
1805  default: assert(0);
1806  result = 0;
1807  }
1808  M->add_Instruction(konst);
1809  write_variable(iptr->dst.varindex,bbindex,result);
1810  M->add_Instruction(result);
1811  }
1812  break;
1813  case ICMD_LREMPOW2:
1814  case ICMD_LORCONST:
1815  case ICMD_LXORCONST:
1816  // SHOW_S1(OS, iptr);
1817  // SHOW_LNG_CONST(OS, iptr->sx.val.l);
1818  // SHOW_DST(OS, iptr);
1819  // break;
1820 
1821  /* trinary/const LNG (<= pointer size) */
1822  // SHOW_S1(OS, iptr);
1823  // SHOW_S2(OS, iptr);
1824  // SHOW_ADR_CONST(OS, iptr->sx.s23.s3.constval);
1825  // break;
1826 
1827  /* const ADR */
1828  case ICMD_ACONST:
1829  // if (iptr->flags.bits & INS_FLAG_CLASS) {
1830  // SHOW_ADR_CONST(OS, iptr->sx.val.anyptr);
1831  // SHOW_CLASSREF_OR_CLASSINFO(OS, iptr->sx.val.c);
1832  // }
1833  // else if (iptr->sx.val.anyptr == NULL) {
1834  // OS << "NULL ";
1835  // }
1836  // else {
1837  // SHOW_ADR_CONST(OS, iptr->sx.val.anyptr);
1838  // SHOW_STRING(OS, iptr->sx.val.stringconst);
1839  // }
1840  // SHOW_DST(OS, iptr);
1841  // break;
1842 
1843  // SHOW_S1(OS, iptr);
1844  // SHOW_S2(OS, iptr);
1845  // printf("%p ", (void*) iptr->sx.s23.s3.constval);
1846  // break;
1847 
1848  case ICMD_GETFIELD: /* 1 -> 1 */
1849  case ICMD_PUTFIELD: /* 2 -> 0 */
1850  goto _default;
1851  case ICMD_PUTSTATIC: /* 1 -> 0 */
1852  {
1853  constant_FMIref *fmiref;
1854  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1855  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1856  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1857  assert(state_change);
1858  Instruction *putstatic = new PUTSTATICInst(s1,fmiref,INSTRUCTION_IS_RESOLVED(iptr),
1859  BB[bbindex],state_change);
1860  write_variable(global_state,bbindex,putstatic);
1861  M->add_Instruction(putstatic);
1862  }
1863  break;
1864  case ICMD_GETSTATIC: /* 0 -> 1 */
1865  {
1866  constant_FMIref *fmiref;
1867  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1868  Type::TypeID type = convert_var_type(fmiref->parseddesc.fd->type);
1869  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1870  assert(state_change);
1871  Instruction *getstatic = new GETSTATICInst(type,fmiref,INSTRUCTION_IS_RESOLVED(iptr),
1872  BB[bbindex],state_change);
1873  write_variable(iptr->dst.varindex,bbindex,getstatic);
1874  write_variable(global_state,bbindex,getstatic);
1875  M->add_Instruction(getstatic);
1876  }
1877  break;
1878  case ICMD_PUTSTATICCONST: /* 0 -> 0 */
1879  case ICMD_PUTFIELDCONST: /* 1 -> 0 */
1880  // if (opcode != ICMD_GETSTATIC && opcode != ICMD_PUTSTATICCONST) {
1881  // SHOW_S1(OS, iptr);
1882  // if (opcode == ICMD_PUTFIELD) {
1883  // SHOW_S2(OS, iptr);
1884  // }
1885  // }
1886  // INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1887  // SHOW_FIELD(OS, fmiref);
1888  //
1889  // if (opcode == ICMD_GETSTATIC || opcode == ICMD_GETFIELD) {
1890  // SHOW_DST(OS, iptr);
1891  // }
1892  // break;
1893 
1894  goto _default;
1895  case ICMD_IINC:
1896  {
1897  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1898  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1899  Instruction *result;
1900  switch (iptr->opc) {
1901  case ICMD_IINC:
1902  result = new ADDInst(Type::IntTypeID, s1, konst);
1903  break;
1904  default: assert(0);
1905  result = 0;
1906  }
1907  M->add_Instruction(konst);
1908  write_variable(iptr->dst.varindex,bbindex,result);
1909  M->add_Instruction(result);
1910  }
1911  break;
1912  // SHOW_S1_LOCAL(OS, iptr);
1913  // SHOW_INT_CONST(OS, iptr->sx.val.i);
1914  // SHOW_DST_LOCAL(OS, iptr);
1915  // break;
1916 
1917  case ICMD_IASTORE:
1918  case ICMD_SASTORE:
1919  case ICMD_BASTORE:
1920  case ICMD_CASTORE:
1921  case ICMD_LASTORE:
1922  case ICMD_DASTORE:
1923  case ICMD_FASTORE:
1924  case ICMD_AASTORE:
1925  {
1926  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1927  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1928  Value *s3 = read_variable(iptr->sx.s23.s3.varindex,bbindex);
1929  Type::TypeID type;
1930  switch (iptr->opc) {
1931  case ICMD_BASTORE:
1932  type = Type::ByteTypeID;
1933  break;
1934  case ICMD_CASTORE:
1935  type = Type::CharTypeID;
1936  break;
1937  case ICMD_SASTORE:
1938  type = Type::ShortTypeID;
1939  break;
1940  case ICMD_IASTORE:
1941  type = Type::IntTypeID;
1942  break;
1943  case ICMD_LASTORE:
1944  type = Type::LongTypeID;
1945  break;
1946  case ICMD_AASTORE:
1947  type = Type::ReferenceTypeID;
1948  break;
1949  case ICMD_FASTORE:
1950  type = Type::FloatTypeID;
1951  break;
1952  case ICMD_DASTORE:
1953  type = Type::DoubleTypeID;
1954  break;
1955  default: assert(0);
1956  type = Type::VoidTypeID;
1957  }
1958  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1959  assert(state_change);
1960  Instruction *ref = new AREFInst(s3->get_type(), s1, s2);
1961  M->add_Instruction(ref);
1962  Instruction *result = new ASTOREInst(type, ref, s3, BB[bbindex], state_change);
1963  write_variable(global_state,bbindex,result);
1964  M->add_Instruction(result);
1965  Instruction *boundscheck = new ARRAYBOUNDSCHECKInst(type, s1, s2);
1966  ref->append_dep(boundscheck);
1967  M->add_Instruction(boundscheck);
1968  }
1969  break;
1970  case ICMD_IALOAD:
1971  case ICMD_SALOAD:
1972  case ICMD_BALOAD:
1973  case ICMD_CALOAD:
1974  case ICMD_LALOAD:
1975  case ICMD_DALOAD:
1976  case ICMD_FALOAD:
1977  case ICMD_AALOAD:
1978  {
1979  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1980  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1981  Type::TypeID type;
1982  switch (iptr->opc) {
1983  case ICMD_BALOAD:
1984  type = Type::ByteTypeID;
1985  break;
1986  case ICMD_CALOAD:
1987  type = Type::CharTypeID;
1988  break;
1989  case ICMD_SALOAD:
1990  type = Type::ShortTypeID;
1991  break;
1992  case ICMD_IALOAD:
1993  type = Type::IntTypeID;
1994  break;
1995  case ICMD_LALOAD:
1996  type = Type::LongTypeID;
1997  break;
1998  case ICMD_AALOAD:
1999  type = Type::ReferenceTypeID;
2000  break;
2001  case ICMD_FALOAD:
2002  type = Type::FloatTypeID;
2003  break;
2004  case ICMD_DALOAD:
2005  type = Type::DoubleTypeID;
2006  break;
2007  default: assert(0);
2008  type = Type::VoidTypeID;
2009  }
2010  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
2011  assert(state_change);
2012  Instruction *ref = new AREFInst(type, s1, s2);
2013  M->add_Instruction(ref);
2014  Instruction *result = new ALOADInst(type, ref, BB[bbindex], state_change);
2015  write_variable(iptr->dst.varindex,bbindex,result);
2016  write_variable(global_state,bbindex,result);
2017  M->add_Instruction(result);
2018  Instruction *boundscheck = new ARRAYBOUNDSCHECKInst(type, s1, s2);
2019  ref->append_dep(boundscheck);
2020  M->add_Instruction(boundscheck);
2021  }
2022  break;
2023  // SHOW_S1(OS, iptr);
2024  // SHOW_S2(OS, iptr);
2025  // SHOW_DST(OS, iptr);
2026  // break;
2027 
2028  case ICMD_RET:
2029  goto _default;
2030  // SHOW_S1_LOCAL(OS, iptr);
2031  // if (stage >= SHOW_STACK) {
2032  // printf(" ---> L%03d", iptr->dst.block->nr);
2033  // }
2034  // break;
2035 
2036  case ICMD_ILOAD:
2037  case ICMD_LLOAD:
2038  case ICMD_FLOAD:
2039  case ICMD_DLOAD:
2040  case ICMD_ALOAD:
2041  {
2042  #if 0
2043  Instruction *I;
2044  switch (iptr->opc) {
2045  case ICMD_ILOAD:
2046  I = new LOADInst(Type::IntTypeID, iptr->s1.varindex);
2047  break;
2048  case ICMD_LLOAD:
2049  I = new LOADInst(Type::LongTypeID, iptr->s1.varindex);
2050  break;
2051  case ICMD_FLOAD:
2052  I = new LOADInst(Type::FloatTypeID, iptr->s1.varindex);
2053  break;
2054  case ICMD_DLOAD:
2055  I = new LOADInst(Type::DoubleTypeID, iptr->s1.varindex);
2056  break;
2057  default: assert(0);
2058  }
2059  #endif
2060  Value *def = read_variable(iptr->s1.varindex,bbindex);
2061  // XXX dont yet know if this can happen
2062  #if 0
2063  if (!def) {
2064  // no definition found. Initialize with zero
2065  Instruction *konst;
2066  switch (iptr->opc) {
2067  case ICMD_ILOAD:
2068  konst = new CONSTInst((int)0);
2069  break;
2070  case ICMD_LLOAD:
2071  konst = new CONSTInst((long)0);
2072  break;
2073  case ICMD_FLOAD:
2074  konst = new CONSTInst((float)0);
2075  break;
2076  case ICMD_DLOAD:
2077  konst = new CONSTInst((double)0);
2078  break;
2079  default: assert(0);
2080  }
2081  M->add_Instruction(konst);
2082  def = konst;
2083  }
2084  #else
2085  assert(def);
2086  #endif
2087  write_variable(iptr->dst.varindex,bbindex,def);
2088  }
2089  break;
2090  case ICMD_ISTORE:
2091  case ICMD_LSTORE:
2092  case ICMD_FSTORE:
2093  case ICMD_DSTORE:
2094  case ICMD_ASTORE:
2095  {
2096  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2097  write_variable(iptr->dst.varindex,bbindex,s1);
2098  }
2099  break;
2100  // SHOW_S1(OS, iptr);
2101  // SHOW_DST_LOCAL(OS, iptr);
2102  // if (stage >= SHOW_STACK && iptr->sx.s23.s3.javaindex != UNUSED)
2103  // printf(" (javaindex %d)", iptr->sx.s23.s3.javaindex);
2104  // if (iptr->flags.bits & INS_FLAG_RETADDR) {
2105  // printf(" (retaddr L%03d)", RETADDR_FROM_JAVALOCAL(iptr->sx.s23.s2.retaddrnr));
2106  // }
2107  // break;
2108 
2109  case ICMD_NEW:
2110  // SHOW_DST(OS, iptr);
2111  // break;
2112  //
2113  case ICMD_NEWARRAY:
2114  // SHOW_DST(OS, iptr);
2115  // break;
2116 
2117  case ICMD_ANEWARRAY:
2118  // SHOW_DST(OS, iptr);
2119  // break;
2120 
2121  case ICMD_MULTIANEWARRAY:
2122  // if (stage >= SHOW_STACK) {
2123  // argp = iptr->sx.s23.s2.args;
2124  // i = iptr->s1.argcount;
2125  // while (i--) {
2126  // SHOW_VARIABLE(OS, *(argp++));
2127  // }
2128  // }
2129  // else {
2130  // printf("argcount=%d ", iptr->s1.argcount);
2131  // }
2132  // class_classref_or_classinfo_print(iptr->sx.s23.s3.c);
2133  // putchar(' ');
2134  // SHOW_DST(OS, iptr);
2135  // break;
2136 
2137  case ICMD_CHECKCAST:
2138  // SHOW_S1(OS, iptr);
2139  // class_classref_or_classinfo_print(iptr->sx.s23.s3.c);
2140  // putchar(' ');
2141  // SHOW_DST(OS, iptr);
2142  // break;
2143  //
2144  case ICMD_INSTANCEOF:
2145  // SHOW_S1(OS, iptr);
2146  // SHOW_DST(OS, iptr);
2147  // break;
2148 
2149  case ICMD_INLINE_START:
2150  case ICMD_INLINE_END:
2151  case ICMD_INLINE_BODY:
2152  #if 0
2153  #if defined(ENABLE_INLINING)
2154  {
2155  insinfo_inline *ii = iptr->sx.s23.s3.inlineinfo;
2156  show_inline_info(jd, ii, opcode, stage);
2157  }
2158  #endif
2159  #endif
2160  // break;
2161 
2162  case ICMD_BUILTIN:
2163  // if (stage >= SHOW_STACK) {
2164  // argp = iptr->sx.s23.s2.args;
2165  // i = iptr->s1.argcount;
2166  // while (i--) {
2167  // if ((iptr->s1.argcount - 1 - i) == iptr->sx.s23.s3.bte->md->paramcount)
2168  // printf(" pass-through: ");
2169  // SHOW_VARIABLE(OS, *(argp++));
2170  // }
2171  // }
2172  // printf("%s ", iptr->sx.s23.s3.bte->cname);
2173  // if (iptr->sx.s23.s3.bte->md->returntype.type != TYPE_VOID) {
2174  // SHOW_DST(OS, iptr);
2175  // }
2176  // break;
2177 
2178  case ICMD_INVOKEVIRTUAL:
2179  case ICMD_INVOKESPECIAL:
2180  goto _default;
2181  case ICMD_INVOKESTATIC:
2182  {
2183  //methoddesc *md;
2184  constant_FMIref *fmiref;
2185  //INSTRUCTION_GET_METHODDESC(iptr, md);
2186  INSTRUCTION_GET_METHODREF(iptr, fmiref);
2187 
2188  // get return type
2189  Type::TypeID type;
2190  switch (fmiref->parseddesc.md->returntype.type) {
2191  case TYPE_INT:
2192  type = Type::IntTypeID;
2193  break;
2194  case TYPE_LNG:
2195  type = Type::LongTypeID;
2196  break;
2197  case TYPE_FLT:
2198  type = Type::FloatTypeID;
2199  break;
2200  case TYPE_DBL:
2201  type = Type::DoubleTypeID;
2202  break;
2203  case TYPE_VOID:
2204  type = Type::VoidTypeID;
2205  break;
2206  case TYPE_ADR:
2207  //type = Type::TypeID;
2208  //break;
2209  case TYPE_RET:
2210  //type = Type::TypeID;
2211  //break;
2212  default:
2213  type = Type::VoidTypeID;
2214  err() << BoldRed << "error: " << reset_color << " type " << BoldWhite
2215  << fmiref->parseddesc.md->returntype.type << reset_color
2216  << " not yet supported! (see vm/global.h)" << nl;
2217  assert(false);
2218  }
2219  // get arguments
2220  s4 *argp = iptr->sx.s23.s2.args;
2221  int32_t i = iptr->s1.argcount;
2222  // create instruction
2223 
2224  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
2225  assert(state_change);
2226  INVOKESTATICInst *I = new INVOKESTATICInst(type,i,fmiref,
2227  INSTRUCTION_IS_RESOLVED(iptr),BB[bbindex],state_change);
2228  LOG3("INVOKESTATICInst: " << I << " dep = " << state_change << nl);
2229  while (i--) {
2230  // TODO understand
2231  //if ((iptr->s1.argcount - 1 - i) == md->paramcount)
2232  // printf(" pass-through: ");
2233  I->append_parameter(read_variable(*(argp++),bbindex));
2234  }
2235  if (type != Type::VoidTypeID) {
2236  write_variable(iptr->dst.varindex,bbindex,I);
2237  }
2238  write_variable(global_state,bbindex,I);
2239  M->add_Instruction(I);
2240  }
2241  break;
2242  case ICMD_INVOKEINTERFACE:
2243  // if (stage >= SHOW_STACK) {
2244  // methoddesc *md;
2245  // INSTRUCTION_GET_METHODDESC(iptr, md);
2246  // argp = iptr->sx.s23.s2.args;
2247  // i = iptr->s1.argcount;
2248  // while (i--) {
2249  // if ((iptr->s1.argcount - 1 - i) == md->paramcount)
2250  // printf(" pass-through: ");
2251  // SHOW_VARIABLE(OS, *(argp++));
2252  // }
2253  // }
2254  // INSTRUCTION_GET_METHODREF(iptr, fmiref);
2255  // method_methodref_print(fmiref);
2256  // if (fmiref->parseddesc.md->returntype.type != TYPE_VOID) {
2257  // putchar(' ');
2258  // SHOW_DST(OS, iptr);
2259  // }
2260  // break;
2261 
2262  goto _default;
2263  case ICMD_IFLT:
2264  case ICMD_IFGT:
2265  case ICMD_IFGE:
2266  case ICMD_IFEQ:
2267  case ICMD_IFNE:
2268  case ICMD_IFLE:
2269  {
2270  Conditional::CondID cond;
2271  switch (iptr->opc) {
2272  case ICMD_IFLT:
2273  cond = Conditional::LT;
2274  break;
2275  case ICMD_IFGT:
2276  cond = Conditional::GT;
2277  break;
2278  case ICMD_IFEQ:
2279  cond = Conditional::EQ;
2280  break;
2281  case ICMD_IFNE:
2282  cond = Conditional::NE;
2283  break;
2284  case ICMD_IFLE:
2285  cond = Conditional::LE;
2286  break;
2287  case ICMD_IFGE:
2288  cond = Conditional::GE;
2289  break;
2290  default:
2292  cond = Conditional::NoCond;
2293  }
2294  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
2295  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2296  assert(s1);
2297  assert(BB[iptr->dst.block->nr]);
2298  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
2299  assert(trueBlock);
2300  assert(BB[bbindex+1]);
2301  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
2302  assert(falseBlock);
2303  Instruction *result = new IFInst(BB[bbindex], s1, konst, cond,
2304  trueBlock, falseBlock);
2305  M->add_Instruction(konst);
2306  M->add_Instruction(result);
2307  }
2308  break;
2309  // SHOW_S1(OS, iptr);
2310  // SHOW_INT_CONST(OS, iptr->sx.val.i);
2311  // SHOW_TARGET(OS, iptr->dst);
2312  // break;
2313 
2314  case ICMD_IF_LLT:
2315  case ICMD_IF_LGT:
2316  case ICMD_IF_LLE:
2317  case ICMD_IF_LEQ:
2318  case ICMD_IF_LNE:
2319  case ICMD_IF_LGE:
2320  {
2321  Conditional::CondID cond;
2322  switch (iptr->opc) {
2323  case ICMD_IF_LLT:
2324  cond = Conditional::LT;
2325  break;
2326  case ICMD_IF_LGT:
2327  cond = Conditional::GT;
2328  break;
2329  case ICMD_IF_LLE:
2330  cond = Conditional::LE;
2331  break;
2332  case ICMD_IF_LEQ:
2333  cond = Conditional::EQ;
2334  break;
2335  case ICMD_IF_LNE:
2336  cond = Conditional::NE;
2337  break;
2338  case ICMD_IF_LGE:
2339  cond = Conditional::GE;
2340  break;
2341  default:
2343  cond = Conditional::NoCond;
2344  }
2345  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
2346  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2347  assert(s1);
2348  assert(BB[iptr->dst.block->nr]);
2349  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
2350  assert(trueBlock);
2351  assert(BB[bbindex+1]);
2352  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
2353  assert(falseBlock);
2354  Instruction *result = new IFInst(BB[bbindex], s1, konst, cond,
2355  trueBlock, falseBlock);
2356  M->add_Instruction(konst);
2357  M->add_Instruction(result);
2358  }
2359  break;
2360  case ICMD_GOTO:
2361  {
2362  assert(BB[iptr->dst.block->nr]);
2363  BeginInst *targetBlock = BB[iptr->dst.block->nr];
2364  Instruction *result = new GOTOInst(BB[bbindex], targetBlock);
2365  M->add_Instruction(result);
2366  }
2367  break;
2368  // SHOW_TARGET(OS, iptr->dst);
2369  // break;
2370 
2371  case ICMD_JSR:
2372  // SHOW_TARGET(OS, iptr->sx.s23.s3.jsrtarget);
2373  // SHOW_DST(OS, iptr);
2374  // break;
2375 
2376  case ICMD_IFNULL:
2377  case ICMD_IFNONNULL:
2378  // SHOW_S1(OS, iptr);
2379  // SHOW_TARGET(OS, iptr->dst);
2380  // break;
2381 
2382  goto _default;
2383  case ICMD_IF_ICMPEQ:
2384  case ICMD_IF_ICMPNE:
2385  case ICMD_IF_ICMPLT:
2386  case ICMD_IF_ICMPGE:
2387  case ICMD_IF_ICMPGT:
2388  case ICMD_IF_ICMPLE:
2389  {
2390  Conditional::CondID cond;
2391  switch (iptr->opc) {
2392  case ICMD_IF_ICMPLE:
2393  cond = Conditional::LE;
2394  break;
2395  case ICMD_IF_ICMPEQ:
2396  cond = Conditional::EQ;
2397  break;
2398  case ICMD_IF_ICMPNE:
2399  cond = Conditional::NE;
2400  break;
2401  case ICMD_IF_ICMPLT:
2402  cond = Conditional::LT;
2403  break;
2404  case ICMD_IF_ICMPGE:
2405  cond = Conditional::GE;
2406  break;
2407  case ICMD_IF_ICMPGT:
2408  cond = Conditional::GT;
2409  break;
2410  default:
2412  cond = Conditional::NoCond;
2413  }
2414  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2415  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
2416  assert(s1);
2417  assert(s2);
2418  assert(BB[iptr->dst.block->nr]);
2419  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
2420  assert(trueBlock);
2421  assert(BB[bbindex+1]);
2422  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
2423  assert(falseBlock);
2424  Instruction *result = new IFInst(BB[bbindex], s1, s2, cond,
2425  trueBlock, falseBlock);
2426  M->add_Instruction(result);
2427  }
2428  break;
2429 
2430  case ICMD_IF_LCMPEQ:
2431  case ICMD_IF_LCMPNE:
2432  case ICMD_IF_LCMPLT:
2433  case ICMD_IF_LCMPGT:
2434  case ICMD_IF_LCMPGE:
2435  case ICMD_IF_LCMPLE:
2436  {
2437  Conditional::CondID cond;
2438  switch (iptr->opc) {
2439  case ICMD_IF_LCMPEQ:
2440  cond = Conditional::EQ;
2441  break;
2442  case ICMD_IF_LCMPNE:
2443  cond = Conditional::NE;
2444  break;
2445  case ICMD_IF_LCMPLT:
2446  cond = Conditional::LT;
2447  break;
2448  case ICMD_IF_LCMPGT:
2449  cond = Conditional::GT;
2450  break;
2451  case ICMD_IF_LCMPGE:
2452  cond = Conditional::GE;
2453  break;
2454  case ICMD_IF_LCMPLE:
2455  cond = Conditional::LE;
2456  break;
2457  default:
2458  cond = Conditional::NoCond;
2460  }
2461  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2462  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
2463  assert(s1);
2464  assert(s2);
2465  assert(BB[iptr->dst.block->nr]);
2466  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
2467  assert(trueBlock);
2468  assert(BB[bbindex+1]);
2469  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
2470  assert(falseBlock);
2471  Instruction *result = new IFInst(BB[bbindex], s1, s2, cond,
2472  trueBlock, falseBlock);
2473  M->add_Instruction(result);
2474  }
2475  break;
2476 
2477  case ICMD_IF_ACMPEQ:
2478  case ICMD_IF_ACMPNE:
2479  // SHOW_S1(OS, iptr);
2480  // SHOW_S2(OS, iptr);
2481  // SHOW_TARGET(OS, iptr->dst);
2482  // break;
2483  goto _default;
2484 
2485  case ICMD_TABLESWITCH:
2486  {
2487  s4 tablehigh = iptr->sx.s23.s3.tablehigh;
2488  s4 tablelow = iptr->sx.s23.s2.tablelow;
2489 
2490  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2491  TABLESWITCHInst *result = new TABLESWITCHInst(BB[bbindex], s1,
2492  TABLESWITCHInst::LOW(tablelow),
2493  TABLESWITCHInst::HIGH(tablehigh));
2494 
2495  s4 count = tablehigh - tablelow + 1;
2496  LOG("tableswitch high=" << tablehigh << " low=" << tablelow << " count=" << count << nl);
2497  branch_target_t *table = iptr->dst.table;
2498  BeginInst* def = BB[table[0].block->nr];
2499  LOG("idx: " << 0 << " BeginInst: " << BB[table[0].block->nr]
2500  << "(block.nr=" << table[0].block->nr << ")"<< nl);
2501  ++table;
2502  for (s4 i = 0; i < count ; ++i) {
2503  LOG("idx: " << i << " BeginInst: " << BB[table[i].block->nr]
2504  << "(block.nr=" << table[i].block->nr << ")"<< nl);
2505  result->append_succ(BB[table[i].block->nr]);
2506  }
2507  result->append_succ(def);
2508  M->add_Instruction(result);
2509  }
2510  break;
2511 
2512  case ICMD_LOOKUPSWITCH:
2513  {
2514  s4 lookupcount = iptr->sx.s23.s2.lookupcount;
2515 
2516  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2517  LOOKUPSWITCHInst *result = new LOOKUPSWITCHInst(BB[bbindex], s1, lookupcount);
2518 
2519  // add case targets
2520  lookup_target_t *lookup = iptr->dst.lookup;
2521  for (s4 i = 0; i < lookupcount; ++i) {
2522  // lookup->value
2523  result->append_succ(BB[lookup->target.block->nr]);
2524  result->set_match(i, LOOKUPSWITCHInst::MATCH(lookup->value));
2525  ++lookup;
2526  }
2527  // add default target
2528  BeginInst *defaultBlock = BB[iptr->sx.s23.s3.lookupdefault.block->nr];
2529  assert(defaultBlock);
2530  result->append_succ(defaultBlock);
2531 
2532  M->add_Instruction(result);
2533  }
2534  break;
2535  // SHOW_S1(OS, iptr);
2536  //
2537  // printf("count=%d, default=L%03d\n",
2538  // iptr->sx.s23.s2.lookupcount,
2539  // iptr->sx.s23.s3.lookupdefault.block->nr);
2540  //
2541  // lookup = iptr->dst.lookup;
2542  // i = iptr->sx.s23.s2.lookupcount;
2543  //
2544  // while (--i >= 0) {
2545  // printf("\t\t%d --> L%03d\n",
2546  // lookup->value,
2547  // lookup->target.block->nr);
2548  // lookup++;
2549  // }
2550  // break;
2551 
2552  case ICMD_FRETURN:
2553  case ICMD_IRETURN:
2554  case ICMD_DRETURN:
2555  case ICMD_LRETURN:
2556  {
2557  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
2558  Instruction *result = new RETURNInst(BB[bbindex], s1);
2559  M->add_Instruction(result);
2560  }
2561  break;
2562  // SHOW_S1(OS, iptr);
2563  // break;
2564  //
2565  case ICMD_RETURN:
2566  {
2567  Instruction *result = new RETURNInst(BB[bbindex]);
2568  M->add_Instruction(result);
2569  }
2570  break;
2571  case ICMD_ARETURN:
2572  case ICMD_ATHROW:
2573  // SHOW_S1(OS, iptr);
2574  // if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2575  // /* XXX this needs more work */
2576  #if 0
2577  unresolved_class_debug_dump(iptr->sx.s23.s2.uc, stdout);
2578  #endif
2579  // }
2580  // break;
2581 
2582  goto _default;
2583  case ICMD_COPY:
2584  case ICMD_MOVE:
2585  {
2586  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
2587  write_variable(iptr->dst.varindex,bbindex,s1);
2588  }
2589  break;
2590  // SHOW_S1(OS, iptr);
2591  // SHOW_DST(OS, iptr);
2592  // break;
2593  case ICMD_GETEXCEPTION:
2594  // SHOW_DST(OS, iptr);
2595  // break;
2596  #if defined(ENABLE_SSA)
2597  case ICMD_PHI:
2598  // printf("[ ");
2599  // for (i = 0; i < iptr->s1.argcount; ++i) {
2600  // SHOW_VARIABLE(OS, iptr->sx.s23.s2.iargs[i]->dst.varindex);
2601  // }
2602  // printf("] ");
2603  // SHOW_DST(OS, iptr);
2604  // if (iptr->flags.bits & (1 << 0)) OS << "used ";
2605  // if (iptr->flags.bits & (1 << 1)) OS << "redundantAll ";
2606  // if (iptr->flags.bits & (1 << 2)) OS << "redundantOne ";
2607  // break;
2608  #endif
2609  default:
2610  goto _default;
2611  }
2612  continue;
2613 
2614  _default:
2615  #if !defined(NDEBUG)
2616  ABORT_MSG(icmd_table[iptr->opc].name << " (" << iptr->opc << ")",
2617  "Operation not yet supported!");
2618  #else
2619  ABORT_MSG("Opcode: (" << iptr->opc << ")",
2620  "Operation not yet supported!");
2621  #endif
2622  }
2623 
2624  if (!BB[bbindex]->get_EndInst()) {
2625  // No end instruction yet. Adding GOTO
2626  assert(bbindex+1 < BB.size());
2627  BeginInst *targetBlock = BB[bbindex+1];
2628  Instruction *result = new GOTOInst(BB[bbindex], targetBlock);
2629  M->add_Instruction(result);
2630  }
2631 
2632  // block filled!
2633  filled_blocks[bbindex] = true;
2634  // try to seal block
2635  try_seal_block(bb);
2636  // try seal successors
2637  for(int i = 0; i < bb->successorcount; ++i) {
2638  try_seal_block(bb->successors[i]);
2639  }
2640  }
2641  #ifndef NDEBUG
2642  for(size_t i = 0; i< num_basicblocks; ++i) {
2643  if (!sealed_blocks[i]) {
2644  err() << BoldRed << "error: " << reset_color << "unsealed basic block: " << BoldWhite
2645  << i << " (" << BB[i] << ")"
2646  << reset_color << nl;
2647  assert(0 && "There is an unsealed basic block");
2648  }
2649  }
2650  #endif
2651  return true;
2652 }
2653 
2654 bool SSAConstructionPass::verify() const {
2655  for (Method::const_iterator i = M->begin(), e = M->end() ; i != e ; ++i) {
2656  Instruction *I = *i;
2657  if (!I->verify()) return false;
2658  }
2659  return true;
2660 }
2661 
2662 PassUsage& SSAConstructionPass::get_PassUsage(PassUsage &PU) const {
2663  PU.add_requires<CFGConstructionPass>();
2664  return PU;
2665 }
2666 // the address of this variable is used to identify the pass
2667 char SSAConstructionPass::ID = 0;
2668 
2669 // registrate Pass
2670 static PassRegistry<SSAConstructionPass> X("SSAConstructionPass");
2671 
2672 } // end namespace cacao
2673 } // end namespace jit
2674 } // end namespace compiler2
2675 
2676 
2677 /*
2678  * These are local overrides for various environment variables in Emacs.
2679  * Please do not remove this and leave it at the end of the file, where
2680  * Emacs will automagically detect them.
2681  * ---------------------------------------------------------------------
2682  * Local variables:
2683  * mode: c++
2684  * indent-tabs-mode: t
2685  * c-basic-offset: 4
2686  * tab-width: 4
2687  * End:
2688  * vim:noexpandtab:sw=4:ts=4:
2689  */
val_operand_t val
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
std::size_t index
basicblock * block
union varinfo::@19 vv
#define STATISTICS(x)
Wrapper for statistics only code.
Definition: statistics.hpp:975
static SetWidth setw(size_t w)
Definition: OStream.hpp:395
basicblock * basicblocks
Definition: jit.hpp:141
Definition: jit.hpp:126
Definition: stack.hpp:46
#define max(a, b)
Definition: lsra.hpp:80
s4 * invars
Definition: jit.hpp:323
void unresolved_class_debug_dump(unresolved_class *ref, FILE *file)
Definition: resolve.cpp:2982
s4 outdepth
Definition: jit.hpp:326
u2 op
Definition: disass.cpp:129
int32_t argcount
Definition: instruction.hpp:64
#define SHOW_PARSE
Definition: show.hpp:40
s4 successorcount
Definition: jit.hpp:331
void class_classref_or_classinfo_print(classref_or_classinfo c)
Definition: class.cpp:2306
const char * name
Definition: icmd.hpp:393
s4 vartop
Definition: jit.hpp:149
#define SHOW_CLASSREF_OR_CLASSINFO(OS, c)
methoddesc * md
Definition: references.hpp:75
#define ERROR_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:124
Type type
Definition: reg.hpp:44
MachineBasicBlock * BB
#define SHOW_STRING(OS, val)
#define DEBUG_COND_N(VERBOSE)
Definition: Debug.hpp:112
lookup_target_t * lookup
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
s4 icount
Definition: jit.hpp:318
#define SHOW_FIELD(OS, fmiref)
typedesc paramtypes[1]
Definition: descriptor.hpp:167
BeginInst *& block
classref_or_classinfo c
#define SHOW_INT_CONST(OS, val)
#define SHOW_CFG
Definition: show.hpp:42
branch_target_t target
Definition: instruction.hpp:57
dst_operand_t dst
flags_operand_t flags
#define SHOW_STACK
Definition: show.hpp:41
#define SHOW_S3(OS, iptr)
basicblock ** predecessors
Definition: jit.hpp:332
uint16_t u2
Definition: types.hpp:43
This file contains the statistics framework.
s4 predecessorcount
Definition: jit.hpp:330
#define INSTRUCTION_GET_FIELDREF(iptr, fref)
#define STAT_REGISTER_GROUP_VAR(type, var, init, name, description, group)
Register an statistics variable and add it to a group.
Definition: statistics.hpp:967
Simple stream class for formatted output.
Definition: OStream.hpp:141
#define RETADDR_FROM_JAVALOCAL(jl)
Definition: jit.hpp:417
#define SHOW_FLT_CONST(OS, val)
s4 indepth
Definition: jit.hpp:325
#define SHOW_DBL_CONST(OS, val)
typedesc * fd
Definition: references.hpp:74
#define SHOW_S2(OS, iptr)
MIIterator i
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
typedesc returntype
Definition: descriptor.hpp:166
#define LOG2(STMT)
Definition: logging.hpp:93
#define FOR_EACH_BASICBLOCK(jd, it)
Definition: jit.hpp:181
int32_t s4
Definition: types.hpp:45
ResetColor reset_color
Definition: OStream.cpp:61
#define SHOW_REGS
Definition: show.hpp:43
s4 * outvars
Definition: jit.hpp:324
union instruction::@12 sx
OStream & OS
#define SHOW_LNG_CONST(OS, val)
#define LOG3(STMT)
Definition: logging.hpp:94
OStream & err()
Definition: OStream.cpp:33
icmdtable_entry_t icmd_table[256]
Definition: icmd.cpp:60
#define INSTRUCTION_GET_METHODDESC(iptr, md)
MIIterator e
s1_operand_t s1
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
basicblock * block
Definition: instruction.hpp:50
#define SHOW_DST_LOCAL(OS, iptr)
#define SHOW_S1(OS, iptr)
Type::TypeID convert_var_type(int type)
Definition: Type.cpp:51
#define I(value)
Definition: codegen.c:279
Represents the result of the addition of a certain IR-variable with a certain constant.
Definition: Value.hpp:36
void method_methodref_print(constant_FMIref *mr)
Definition: method.cpp:1235
#define s3
Definition: md-asm.hpp:71
#define SHOW_VARIABLE(OS, v)
s4 flags
Definition: reg.hpp:45
#define STAT_DECLARE_GROUP(var)
Declare an external group (or subgroup).
Definition: statistics.hpp:970
const Method & M
java_handle_t * stringconst
#define FOR_EACH_INSTRUCTION(bptr, it)
Definition: jit.hpp:384
#define SHOW_S1_LOCAL(OS, iptr)
s4 nr
Definition: jit.hpp:312
static void shouldnotreach()
Definition: os.hpp:690
int8_t s1
Definition: types.hpp:39
basicblock * retaddr
Definition: reg.hpp:52
int16_t s2
Definition: types.hpp:42
OStream & out()
Definition: OStream.cpp:39
#define INSTRUCTION_IS_UNRESOLVED(iptr)
struct instruction::@12::@13 s23
basicblock ** successors
Definition: jit.hpp:333
const parseddesc_t parseddesc
Definition: references.hpp:105
#define INSTRUCTION_IS_RESOLVED(iptr)
const char * get_var_type(int type)
Definition: Type.cpp:37
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:133
static PassRegistry< BasicBlockSchedulingPass > X("BasicBlockSchedulingPass")
Nl nl
Definition: OStream.cpp:56
#define SHOW_TARGET(OS, target)
#define printf(...)
Definition: ssa2.cpp:40
#define INSTRUCTION_GET_METHODREF(iptr, mref)
LoopTreeGraph * parent
branch_target_t * table
#define SHOW_DST(OS, iptr)
#define SHOW_ADR_CONST(OS, val)