* Removed all Id tags.
[cacao.git] / src / vm / jit / optimizing / ifconv.c
1 /* src/vm/jit/ifconv/ifconv.c - if-conversion
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31
32 #include "vm/types.h"
33
34 #include "vm/vm.h"
35
36 #include "vm/jit/codegen-common.h"
37 #include "vm/jit/jit.h"
38 #include "vm/jit/reg.h"
39 #include "vm/jit/show.h"
40
41 #include "vmcore/method.h"
42
43
44 /* patterns for a total number of 3 instructions ******************************/
45
46 #define IFCONV_PATTERN_3_SIZE    sizeof(ifconv_pattern_3) / (sizeof(s4) * 3 * 2)
47
48 static s4 ifconv_pattern_3[][2][3] = {
49         /* PATTERN 1 */
50
51         {
52                 {
53                         ICMD_ICONST,
54                         ICMD_GOTO,
55
56                         ICMD_ICONST,
57                 },
58                 {
59                         ICMD_ICONST,
60                         ICMD_NOP,
61
62                         ICMD_ICONST,
63                 }
64         },
65 };
66
67
68 /* patterns for a total number of 4 instructions ******************************/
69
70 #define IFCONV_PATTERN_4_SIZE    sizeof(ifconv_pattern_4) / (sizeof(s4) * 4 * 2)
71
72 static s4 ifconv_pattern_4[][2][4] = {
73         /* PATTERN 1 */
74
75         {
76                 {
77                         ICMD_ICONST,
78                         ICMD_IRETURN,
79
80                         ICMD_ICONST,
81                         ICMD_IRETURN
82                 },
83                 {
84                         ICMD_ICONST,
85                         ICMD_NOP,
86
87                         ICMD_ICONST,
88                         ICMD_IRETURN
89                 }
90         },
91 };
92
93
94 /* ifconv_condition_complement *************************************************
95
96    Table of conditions and their complement.  Index with:
97
98    (ICMD_IFxx - ICMD_IFEQ)
99
100    ATTENTION: Don't change order!  It depends on the Java bytecode opcode!
101
102 *******************************************************************************/
103
104 static s4 ifconv_condition_complement[6] = {
105         /* !ICMD_IFEQ */    ICMD_IFNE,
106         /* !ICMD_IFNE */    ICMD_IFEQ,
107         /* !ICMD_IFLT */    ICMD_IFGE,
108         /* !ICMD_IFGE */    ICMD_IFLT,
109         /* !ICMD_IFGT */    ICMD_IFLE,
110         /* !ICMD_IFLE */    ICMD_IFGT,
111 };
112
113
114 /* ifconv_static ***************************************************************
115
116    Does if-conversion with static data based on pattern matching.
117
118 *******************************************************************************/
119
120 static void check(jitdata *jd, basicblock *bptr);
121
122 bool ifconv_static(jitdata *jd)
123 {
124         methodinfo  *m;
125         basicblock  *bptr;
126         instruction *iptr;
127         instruction *tiptr;
128         s4           bcount;
129         s4           icount;
130         s4          *pattern;
131         s4           patternsize;
132         s4          *p;
133         u2           opcode;
134         u2           condition;
135         u2           complement;
136         s4           i;
137         s4           j;
138
139         /* get required compiler data */
140
141         m  = jd->m;
142
143         /* iterate over all basic blocks */
144
145         bptr   = jd->basicblocks;
146         bcount = jd->basicblockcount;
147
148         for (; bcount >= 0; bcount--, bptr++) {
149                 /* Deleted basic blocks are just skipped. */
150
151                 if (bptr->flags == BBDELETED)
152                         continue;
153
154                 /* We need at least 3 basic blocks including the current one. */
155
156                 if (bcount < 3)
157                         continue;
158
159                 /* Only look at the last instruction of the current basic
160                    block.  All conditional branch instructions are suitable
161                    for if-conversion. */
162
163                 iptr   = bptr->iinstr + bptr->icount - 1;
164
165                 switch (iptr->opc) {
166                 case ICMD_IFNULL:
167                 case ICMD_IFNONNULL:
168
169                 case ICMD_IF_ICMPEQ:
170                 case ICMD_IF_ICMPNE:
171                 case ICMD_IF_ICMPLT:
172                 case ICMD_IF_ICMPGE:
173                 case ICMD_IF_ICMPGT:
174                 case ICMD_IF_ICMPLE:
175
176                 case ICMD_IFEQ:
177                 case ICMD_IFNE:
178                 case ICMD_IFLT:
179                 case ICMD_IFGE:
180                 case ICMD_IFGT:
181                 case ICMD_IFLE:
182
183                 case ICMD_LCMP:
184
185                 case ICMD_IF_LEQ:
186                 case ICMD_IF_LNE:
187                 case ICMD_IF_LLT:
188                 case ICMD_IF_LGE:
189                 case ICMD_IF_LGT:
190                 case ICMD_IF_LLE:
191
192                 case ICMD_IF_LCMPEQ:
193                 case ICMD_IF_LCMPNE:
194                 case ICMD_IF_LCMPLT:
195                 case ICMD_IF_LCMPGE:
196                 case ICMD_IF_LCMPGT:
197                 case ICMD_IF_LCMPLE:
198
199                 case ICMD_IF_ACMPEQ:
200                 case ICMD_IF_ACMPNE:
201                         /* basic blocks can only have 1 predecessor */
202
203                         if ((bptr[1].predecessorcount != 1) ||
204                                 (bptr[2].predecessorcount != 1))
205                                 break;
206
207                         check(jd, bptr);
208
209                         /* only use a fixed size of instructions */
210
211                         icount = bptr[1].icount + bptr[2].icount;
212
213                         /* we only convert less than or equal 4 instructions */
214
215                         if (icount > 4)
216                                 break;
217
218                         /* check which pattern to use */
219
220                         switch (icount) {
221                         case 2:
222                                 /* just skip basic blocks with length 1 */
223
224                                 pattern     = NULL;
225                                 patternsize = 0;
226                                 break;
227
228                         case 3:
229                                 pattern     = (s4 *) ifconv_pattern_3;
230                                 patternsize = IFCONV_PATTERN_3_SIZE;
231                                 break;
232
233                         case 4:
234                                 pattern     = (s4 *) ifconv_pattern_4;
235                                 patternsize = IFCONV_PATTERN_4_SIZE;
236                                 break;
237
238                         default:
239                                 /* keep compiler happy */
240
241                                 pattern     = NULL;
242                                 patternsize = 0;
243
244                                 /* that should not happen */
245
246                                 vm_abort("ifconv_static: invalid instruction count %d", icount);
247                         }
248
249                         /* Iterate over all patterns of the given pattern. */
250
251                         for (i = 0; i < patternsize; i++) {
252                                 /* Check the first and the second basic block at the
253                                    same time.  The instructions _MUST NOT_ be
254                                    reordered in the array before. */
255
256                                 tiptr = bptr[1].iinstr;
257
258                                 for (j = 0; j < icount; j++, tiptr++) {
259                                         /* get the opcode */
260
261                                         p = pattern + (icount * 2 * i) + (icount * 0) + j;
262
263                                         opcode = *p;
264
265                                         if (tiptr->opc != opcode)
266                                                 goto nomatch;
267                                 }
268
269                                 /* found a matching pattern */
270
271 #if !defined(NDEBUG)
272                                 method_println(m);
273 #if 0
274                                 show_basicblock(jd, &bptr[0]);
275                                 show_basicblock(jd, &bptr[1]);
276                                 show_basicblock(jd, &bptr[2]);
277                                 show_basicblock(jd, &bptr[3]);
278 #endif
279 #endif
280
281                                 /* check the condition */
282
283                                 switch (iptr->opc) {
284                                 case ICMD_IFEQ:
285                                 case ICMD_IF_ICMPEQ:
286                                 case ICMD_IF_LEQ:
287                                 case ICMD_IF_LCMPEQ:
288                                 case ICMD_IF_ACMPEQ:
289                                 case ICMD_IFNULL:
290                                         condition = ICMD_IFEQ;
291                                         break;
292
293                                 case ICMD_IFNE:
294                                 case ICMD_IF_ICMPNE:
295                                 case ICMD_IF_LNE:
296                                 case ICMD_IF_LCMPNE:
297                                 case ICMD_IF_ACMPNE:
298                                 case ICMD_IFNONNULL:
299                                         condition = ICMD_IFNE;
300                                         break;
301
302                                 case ICMD_IFLT:
303                                 case ICMD_IF_ICMPLT:
304                                 case ICMD_IF_LLT:
305                                 case ICMD_IF_LCMPLT:
306                                         condition = ICMD_IFLT;
307                                         break;
308
309                                 case ICMD_IFGE:
310                                 case ICMD_IF_ICMPGE:
311                                 case ICMD_IF_LGE:
312                                 case ICMD_IF_LCMPGE:
313                                         condition = ICMD_IFGE;
314                                         break;
315
316                                 case ICMD_IFGT:
317                                 case ICMD_IF_ICMPGT:
318                                 case ICMD_IF_LGT:
319                                 case ICMD_IF_LCMPGT:
320                                         condition = ICMD_IFGT;
321                                         break;
322
323                                 case ICMD_IFLE:
324                                 case ICMD_IF_ICMPLE:
325                                 case ICMD_IF_LLE:
326                                 case ICMD_IF_LCMPLE:
327                                         condition = ICMD_IFLE;
328                                         break;
329
330                                 case ICMD_LCMP:
331                                         assert(0);
332
333                                 default:
334                                         /* keep compiler happy */
335
336                                         condition = 0;
337
338                                         vm_abort("ifconv_static: invalid opcode: %d", iptr->opc);
339                                 }
340
341                                 /* get the condition array index */
342
343                                 complement = ifconv_condition_complement[condition - ICMD_IFEQ];
344         
345                                 /* Set the new instructions, first basic block 1... */
346
347                                 tiptr = bptr[1].iinstr;
348                                 j = 0;
349
350                                 for (; j < bptr[1].icount; j++, tiptr++) {
351                                         /* get the replacing opcode */
352
353                                         p = pattern + (icount * 2 * i) + (icount * 1) + j;
354
355                                         opcode = *p;
356
357                                         /* If we add a NOP, skip the current instruction
358                                            and set the stack of the next instruction
359                                            to the previous one. */
360
361                                         if (opcode == ICMD_NOP) {
362                                                 tiptr[1].dst = tiptr[-1].dst;
363                                         }
364
365                                         /* For the first basic block we have to set the
366                                            complementary condition. */
367
368 /*                                      tiptr->opc = opcode | (complement << 8); */
369                                         tiptr->opc = opcode;
370                                 }
371
372                                 /* ...then basic block 2.  We split this step, as we
373                                    have to set different conditions in the blocks. */
374
375                                 for (; j < bptr[1].icount + bptr[2].icount; j++, tiptr++) {
376                                         p = pattern + (icount * 2 * i) + (icount * 1) + j;
377
378                                         /* For the first basic block we have to set the
379                                            complementary condition. */
380
381                                         tiptr->opc = *p | (condition << 8);
382
383                                         /* if we add a NOP, set the stacks correctly */
384
385                                         if (tiptr->opc == ICMD_NOP) {
386                                                 assert(0);
387                                         }
388                                 }
389
390                                 /* tag the conditional branch instruction as conditional */
391
392                                 iptr->opc |= condition << 8;
393
394                                 /* add the instructions to the current basic block */
395
396                                 bptr->icount += icount;
397
398 #if !defined(NDEBUG)
399                                 method_println(m);
400 #if 0
401                                 show_basicblock(jd, &bptr[0]);
402 #endif
403 #endif
404
405                                 /* delete the 2 following basic blocks */
406
407                                 bptr[1].flags = BBDELETED;
408                                 bptr[2].flags = BBDELETED;
409                                 bptr[1].icount = 0;
410                                 bptr[2].icount = 0;
411
412                                 /* we had a match, exit this iteration */
413
414                                 break;
415
416                         nomatch:
417                                 ;
418                         }
419                 }
420         }
421
422         /* everything's ok */
423
424         return true;
425 }
426
427 static void check(jitdata *jd, basicblock *bptr)
428 {
429         methodinfo *m;
430         int pattern = 0;
431
432         /* get required compiler data */
433
434         m  = jd->m;
435
436         /*
437           generated by jikes.
438
439           java.lang.reflect.Modifier.isPublic(I)Z
440
441           [            ] L000(5 - 0) flags=1:
442           [         i00]     0 (line:   227)  ICONST          0 (0x00000000)
443           [     l00 i00]     1 (line:   227)  ILOAD           0
444           [     r15 i00]     2 (line:   227)  IANDCONST       1 (0x00000001)
445           [     r15 i00]     3 (line:   227)  NOP            
446           [         i00]     4 (line:   227)  IFEQ            0 (0x00000000) L002
447
448           [         i00] L001(2 - 1) flags=1:
449           [            ]     0 (line:   227)  POP            
450           [         i00]     1 (line:   227)  ICONST          1 (0x00000001)
451
452           [         i00] L002(1 - 2) flags=1:
453           [            ]     0 (line:   227)  IRETURN        
454         */
455                                                                 
456         if ((bptr[1].icount == 2) &&
457                 (bptr[1].iinstr[0].opc == ICMD_POP) &&
458                 (bptr[1].iinstr[1].opc == ICMD_ICONST))
459                 {
460                         pattern = 1;
461                 }
462
463         /*
464           generated by ecj.
465
466           java.util.Hashtable.isEmpty()Z PUBLIC SYNCHRONIZED
467
468           [    ] L000(3 - 0) flags=1:
469           [ l00]     0 (line:   292)  ALOAD           0
470           [ rdi]     1 (line:   292)  GETFIELD        36, java.util.Hashtable.size (type I
471           )
472           [    ]     2 (line:   292)  IFNE            0 (0x00000000) L002
473
474           [    ] L001(2 - 1) flags=1:
475           [ rdi]     0 (line:   292)  ICONST          1 (0x00000001)
476           [    ]     1 (line:   292)  IRETURN        
477
478           [    ] L002(2 - 1) flags=1:
479           [ rdi]     0 (line:   292)  ICONST          0 (0x00000000)
480           [    ]     1 (line:   292)  IRETURN        
481         */
482
483         if ((bptr[1].icount == 2) &&
484                 (bptr[1].iinstr[0].opc == ICMD_ICONST) &&
485                 (bptr[1].iinstr[1].opc == ICMD_IRETURN) &&
486
487                 (bptr[2].icount == 2) &&
488                 (bptr[2].iinstr[0].opc == ICMD_ICONST) &&
489                 (bptr[2].iinstr[1].opc == ICMD_IRETURN))
490                 {
491                         pattern = 2;
492                 }
493
494         /*
495           this seems to be the most common and simplest if, check for all types
496         */
497
498         /* xCONST */
499
500         if ((bptr[1].icount == 2) &&
501                 (bptr[1].iinstr[0].opc == ICMD_ICONST) &&
502                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
503
504                 (bptr[2].icount == 1) &&
505                 (bptr[2].iinstr[0].opc == ICMD_ICONST))
506                 {
507                         pattern = 3;
508                 }
509
510         if ((bptr[1].icount == 2) &&
511                 (bptr[1].iinstr[0].opc == ICMD_LCONST) &&
512                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
513
514                 (bptr[2].icount == 1) &&
515                 (bptr[2].iinstr[0].opc == ICMD_LCONST))
516                 {
517                         pattern = 4;
518                 }
519
520         if ((bptr[1].icount == 2) &&
521                 (bptr[1].iinstr[0].opc == ICMD_ACONST) &&
522                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
523
524                 (bptr[2].icount == 1) &&
525                 (bptr[2].iinstr[0].opc == ICMD_ACONST))
526                 {
527                         pattern = 5;
528                 }
529
530         if ((bptr[1].icount == 2) &&
531                 (bptr[1].iinstr[0].opc == ICMD_FCONST) &&
532                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
533
534                 (bptr[2].icount == 1) &&
535                 (bptr[2].iinstr[0].opc == ICMD_FCONST))
536                 {
537                         pattern = 6;
538                 }
539
540         if ((bptr[1].icount == 2) &&
541                 (bptr[1].iinstr[0].opc == ICMD_DCONST) &&
542                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
543
544                 (bptr[2].icount == 1) &&
545                 (bptr[2].iinstr[0].opc == ICMD_DCONST))
546                 {
547                         pattern = 7;
548                 }
549
550         /* xLOAD */
551
552
553         if ((bptr[1].icount == 2) &&
554                 (bptr[1].iinstr[0].opc == ICMD_ILOAD) &&
555                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
556
557                 (bptr[2].icount == 1) &&
558                 (bptr[2].iinstr[0].opc == ICMD_ILOAD))
559                 {
560                         pattern = 8;
561                 }
562
563         if ((bptr[1].icount == 2) &&
564                 (bptr[1].iinstr[0].opc == ICMD_LLOAD) &&
565                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
566
567                 (bptr[2].icount == 1) &&
568                 (bptr[2].iinstr[0].opc == ICMD_LLOAD))
569                 {
570                         pattern = 9;
571                 }
572
573         if ((bptr[1].icount == 2) &&
574                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
575                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
576
577                 (bptr[2].icount == 1) &&
578                 (bptr[2].iinstr[0].opc == ICMD_ALOAD))
579                 {
580                         pattern = 10;
581                 }
582
583         if ((bptr[1].icount == 2) &&
584                 (bptr[1].iinstr[0].opc == ICMD_FLOAD) &&
585                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
586
587                 (bptr[2].icount == 1) &&
588                 (bptr[2].iinstr[0].opc == ICMD_FLOAD))
589                 {
590                         pattern = 11;
591                 }
592
593         if ((bptr[1].icount == 2) &&
594                 (bptr[1].iinstr[0].opc == ICMD_DLOAD) &&
595                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
596
597                 (bptr[2].icount == 1) &&
598                 (bptr[2].iinstr[0].opc == ICMD_DLOAD))
599                 {
600                         pattern = 12;
601                 }
602
603         /* xCONST, GOTO - xLOAD */
604
605         if ((bptr[1].icount == 2) &&
606                 (bptr[1].iinstr[0].opc == ICMD_ICONST) &&
607                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
608
609                 (bptr[2].icount == 1) &&
610                 (bptr[2].iinstr[0].opc == ICMD_ILOAD))
611                 {
612                         pattern = 13;
613                 }
614
615         if ((bptr[1].icount == 2) &&
616                 (bptr[1].iinstr[0].opc == ICMD_LCONST) &&
617                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
618
619                 (bptr[2].icount == 1) &&
620                 (bptr[2].iinstr[0].opc == ICMD_LLOAD))
621                 {
622                         pattern = 14;
623                 }
624
625         if ((bptr[1].icount == 2) &&
626                 (bptr[1].iinstr[0].opc == ICMD_ACONST) &&
627                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
628
629                 (bptr[2].icount == 1) &&
630                 (bptr[2].iinstr[0].opc == ICMD_ALOAD))
631                 {
632                         pattern = 15;
633                 }
634
635         if ((bptr[1].icount == 2) &&
636                 (bptr[1].iinstr[0].opc == ICMD_FCONST) &&
637                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
638
639                 (bptr[2].icount == 1) &&
640                 (bptr[2].iinstr[0].opc == ICMD_FLOAD))
641                 {
642                         pattern = 16;
643                 }
644
645         if ((bptr[1].icount == 2) &&
646                 (bptr[1].iinstr[0].opc == ICMD_DCONST) &&
647                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
648
649                 (bptr[2].icount == 1) &&
650                 (bptr[2].iinstr[0].opc == ICMD_DLOAD))
651                 {
652                         pattern = 17;
653                 }
654
655         /* xLOAD, GOTO - xCONST */
656
657         if ((bptr[1].icount == 2) &&
658                 (bptr[1].iinstr[0].opc == ICMD_ILOAD) &&
659                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
660
661                 (bptr[2].icount == 1) &&
662                 (bptr[2].iinstr[0].opc == ICMD_ICONST))
663                 {
664                         pattern = 18;
665                 }
666
667         if ((bptr[1].icount == 2) &&
668                 (bptr[1].iinstr[0].opc == ICMD_LLOAD) &&
669                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
670
671                 (bptr[2].icount == 1) &&
672                 (bptr[2].iinstr[0].opc == ICMD_LCONST))
673                 {
674                         pattern = 19;
675                 }
676
677         if ((bptr[1].icount == 2) &&
678                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
679                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
680
681                 (bptr[2].icount == 1) &&
682                 (bptr[2].iinstr[0].opc == ICMD_ACONST))
683                 {
684                         pattern = 20;
685                 }
686
687         if ((bptr[1].icount == 2) &&
688                 (bptr[1].iinstr[0].opc == ICMD_FLOAD) &&
689                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
690
691                 (bptr[2].icount == 1) &&
692                 (bptr[2].iinstr[0].opc == ICMD_FCONST))
693                 {
694                         pattern = 21;
695                 }
696
697         if ((bptr[1].icount == 2) &&
698                 (bptr[1].iinstr[0].opc == ICMD_DLOAD) &&
699                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
700
701                 (bptr[2].icount == 1) &&
702                 (bptr[2].iinstr[0].opc == ICMD_DCONST))
703                 {
704                         pattern = 22;
705                 }
706
707         /*
708           check for different ISTORE destinations or handle them properly
709         */
710
711         if ((bptr[1].icount == 3) &&
712                 (bptr[1].iinstr[0].opc == ICMD_ICONST) &&
713                 (bptr[1].iinstr[1].opc == ICMD_ISTORE) &&
714                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
715
716                 (bptr[2].icount == 2) &&
717                 (bptr[2].iinstr[0].opc == ICMD_ICONST) &&
718                 (bptr[2].iinstr[1].opc == ICMD_ISTORE))
719                 {
720                         pattern = 23;
721                 }
722
723         if ((bptr[1].icount == 3) &&
724                 (bptr[1].iinstr[0].opc == ICMD_ILOAD) &&
725                 (bptr[1].iinstr[1].opc == ICMD_ISTORE) &&
726                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
727
728                 (bptr[2].icount == 2) &&
729                 (bptr[2].iinstr[0].opc == ICMD_ILOAD) &&
730                 (bptr[2].iinstr[1].opc == ICMD_ISTORE))
731                 {
732                         pattern = 24;
733                 }
734
735         if ((bptr[1].icount == 3) &&
736                 (bptr[1].iinstr[0].opc == ICMD_ICONST) &&
737                 (bptr[1].iinstr[1].opc == ICMD_ISTORE) &&
738                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
739
740                 (bptr[2].icount == 2) &&
741                 (bptr[2].iinstr[0].opc == ICMD_ILOAD) &&
742                 (bptr[2].iinstr[1].opc == ICMD_ISTORE))
743                 {
744                         pattern = 25;
745                 }
746
747
748         /* ALOAD, GETFIELD - ALOAD, GETFIELD */
749
750         if ((bptr[1].icount == 3) &&
751                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
752                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
753                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
754
755                 (bptr[2].icount == 2) &&
756                 (bptr[2].iinstr[0].opc == ICMD_ALOAD) &&
757                 (bptr[2].iinstr[1].opc == ICMD_GETFIELD))
758                 {
759                         pattern = 26;
760                 }
761
762
763         /* ALOAD, ICONST, PUTFIELD - ALOAD, ICONST, PUTFIELD */
764
765         if ((bptr[1].icount == 4) &&
766                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
767                 (bptr[1].iinstr[1].opc == ICMD_ICONST) &&
768                 (bptr[1].iinstr[2].opc == ICMD_PUTFIELD) &&
769                 (bptr[1].iinstr[3].opc == ICMD_GOTO) &&
770
771                 (bptr[2].icount == 3) &&
772                 (bptr[2].iinstr[0].opc == ICMD_ALOAD) &&
773                 (bptr[2].iinstr[1].opc == ICMD_ICONST) &&
774                 (bptr[2].iinstr[2].opc == ICMD_PUTFIELD)
775                 )
776                 {
777                         pattern = 27;
778                 }
779
780         if ((bptr[1].icount == 4) &&
781                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
782                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
783                 (bptr[1].iinstr[2].opc == ICMD_ASTORE) &&
784                 (bptr[1].iinstr[3].opc == ICMD_GOTO) &&
785
786                 (bptr[2].icount == 3) &&
787                 (bptr[2].iinstr[0].opc == ICMD_ALOAD) &&
788                 (bptr[2].iinstr[1].opc == ICMD_GETFIELD) &&
789                 (bptr[2].iinstr[2].opc == ICMD_ASTORE)
790                 )
791                 {
792                         pattern = 28;
793                 }
794
795         if ((bptr[1].icount == 2) &&
796                 (bptr[1].iinstr[0].opc == ICMD_GETSTATIC) &&
797                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
798
799                 (bptr[2].icount == 1) &&
800                 (bptr[2].iinstr[0].opc == ICMD_GETSTATIC))
801                 {
802                         pattern = 29;
803                 }
804
805         if ((bptr[1].icount == 3) &&
806                 (bptr[1].iinstr[0].opc == ICMD_GETSTATIC) &&
807                 (bptr[1].iinstr[1].opc == ICMD_ASTORE) &&
808                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
809
810                 (bptr[2].icount == 2) &&
811                 (bptr[2].iinstr[0].opc == ICMD_GETSTATIC) &&
812                 (bptr[2].iinstr[1].opc == ICMD_ASTORE))
813                 {
814                         pattern = 30;
815                 }
816
817         if ((bptr[1].icount == 2) &&
818                 (bptr[1].iinstr[0].opc == ICMD_GETSTATIC) &&
819                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
820
821                 (bptr[2].icount == 1) &&
822                 (bptr[2].iinstr[0].opc == ICMD_ALOAD))
823                 {
824                         pattern = 31;
825                 }
826
827         if ((bptr[1].icount == 2) &&
828                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
829                 (bptr[1].iinstr[1].opc == ICMD_GOTO) &&
830
831                 (bptr[2].icount == 1) &&
832                 (bptr[2].iinstr[0].opc == ICMD_GETSTATIC))
833                 {
834                         pattern = 32;
835                 }
836
837
838         if ((bptr[1].icount == 3) &&
839                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
840                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
841                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
842
843                 (bptr[2].icount == 1) &&
844                 (bptr[2].iinstr[0].opc == ICMD_ICONST))
845                 {
846                         pattern = 33;
847                 }
848
849         if ((bptr[1].icount == 3) &&
850                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
851                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
852                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
853
854                 (bptr[2].icount == 1) &&
855                 (bptr[2].iinstr[0].opc == ICMD_LCONST))
856                 {
857                         pattern = 34;
858                 }
859
860         if ((bptr[1].icount == 3) &&
861                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
862                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
863                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
864
865                 (bptr[2].icount == 1) &&
866                 (bptr[2].iinstr[0].opc == ICMD_ACONST))
867                 {
868                         pattern = 35;
869                 }
870
871         if ((bptr[1].icount == 3) &&
872                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
873                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
874                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
875
876                 (bptr[2].icount == 1) &&
877                 (bptr[2].iinstr[0].opc == ICMD_ILOAD))
878                 {
879                         pattern = 36;
880                 }
881
882         if ((bptr[1].icount == 3) &&
883                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
884                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
885                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
886
887                 (bptr[2].icount == 1) &&
888                 (bptr[2].iinstr[0].opc == ICMD_LLOAD))
889                 {
890                         pattern = 37;
891                 }
892
893         if ((bptr[1].icount == 3) &&
894                 (bptr[1].iinstr[0].opc == ICMD_ALOAD) &&
895                 (bptr[1].iinstr[1].opc == ICMD_GETFIELD) &&
896                 (bptr[1].iinstr[2].opc == ICMD_GOTO) &&
897
898                 (bptr[2].icount == 1) &&
899                 (bptr[2].iinstr[0].opc == ICMD_ALOAD))
900                 {
901                         pattern = 38;
902                 }
903
904         /*
905
906         CHECK 3   : (BB:   0) IFEQ            javax.swing.plaf.basic.BasicInternalFrameTitlePane.paintTitleBackground(Ljava/awt/Graphics;)V PROTECTED
907         [ ?   ?   ?   ?   ?  ] L001(instruction count: 4, predecessors: 1):
908         [ ?   ?   ?   ?   ?  ]     0 (line:   909)  ALOAD           0
909         [ ?   ?   ?   ?   ?  ]     1 (line:   909)  GETFIELD        (NOT RESOLVED), javax.swing.plaf.basic.BasicInternalFrameTitlePane.selectedTitleColor (type Ljava/awt/Color;)
910         [ ?   ?   ?   ?   ?  ]     2 (line:   909)  ASTORE          4
911         [ ?   ?   ?   ?   ?  ]     3 (line:   909)  GOTO            op1=41
912         [ ?   ?   ?   ?   ?  ] L002(instruction count: 3, predecessors: 1):
913         [ ?   ?   ?   ?   ?  ]     0 (line:   911)  ALOAD           0
914         [ ?   ?   ?   ?   ?  ]     1 (line:   911)  GETFIELD        (NOT RESOLVED), javax.swing.plaf.basic.BasicInternalFrameTitlePane.notSelectedTitleColor (type Ljava/awt/Color;)
915         [ ?   ?   ?   ?   ?  ]     2 (line:   911)  ASTORE          4
916
917
918         CHECK 3   : (BB:   3) IFEQ            javax.swing.plaf.basic.BasicTreeUI$MouseHandler.mousePressed(Ljava/awt/event/MouseEvent;)V PUBLIC
919         [ ?   ?   ?   ?   ?  ] L004(instruction count: 4, predecessors: 1):
920         [ ?   ?   ?   ?   ?  ]     0 (line:  2244)  ACONST          0x3602d30, String = "Tree.openIcon"
921         [ ?   ?   ?   ?   ?  ]     1 (line:  2244)  INVOKESTATIC    (NOT RESOLVED) javax.swing.UIManager.getIcon(Ljava/lang/Object;)Ljavax/swing/Icon;
922         [ ?   ?   ?   ?   ?  ]     2 (line:  2244)  ASTORE          8
923         [ ?   ?   ?   ?   ?  ]     3 (line:  2244)  GOTO            op1=155
924         [ ?   ?   ?   ?   ?  ] L005(instruction count: 3, predecessors: 1):
925         [ ?   ?   ?   ?   ?  ]     0 (line:  2246)  ACONST          0x3602e00, String = "Tree.closedIcon"
926         [ ?   ?   ?   ?   ?  ]     1 (line:  2246)  INVOKESTATIC    (NOT RESOLVED) javax.swing.UIManager.getIcon(Ljava/lang/Object;)Ljavax/swing/Icon;
927         [ ?   ?   ?   ?   ?  ]     2 (line:  2246)  ASTORE          8
928
929
930         CHECK 3   : (BB:   2) IFEQ            javax.naming.CompoundName.initializeSyntax()V PRIVATE FINAL
931         [ ?   ?   ?   ?  ] L003(instruction count: 4, predecessors: 1):
932         [ ?   ?   ?   ?  ]     0 (line:   445)  ALOAD           0
933         [ ?   ?   ?   ?  ]     1 (line:   445)  ICONST          1 (0x00000001)
934         [ ?   ?   ?   ?  ]     2 (line:   445)  PUTFIELD        (NOT RESOLVED), javax.naming.CompoundName.direction (type I)
935         [ ?   ?   ?   ?  ]     3 (line:   445)  GOTO            op1=51
936         [ ?   ?   ?   ?  ] L004(instruction count: 3, predecessors: 1):
937         [ ?   ?   ?   ?  ]     0 (line:   449)  ALOAD           0
938         [ ?   ?   ?   ?  ]     1 (line:   449)  ICONST          0 (0x00000000)
939         [ ?   ?   ?   ?  ]     2 (line:   449)  PUTFIELD        (NOT RESOLVED), javax.naming.CompoundName.direction (type I)
940
941
942         CHECK 3   : (BB:  15) IFNE            java.awt.Scrollbar.setValues(IIII)V PUBLIC SYNCHRONIZED
943         [ ?   ?   ?   ?   ?  ] L016(instruction count: 4, predecessors: 1):
944         [ ?   ?   ?   ?   ?  ]     0 (line:   371)  ALOAD           0
945         [ ?   ?   ?   ?   ?  ]     1 (line:   371)  ICONST          1 (0x00000001)
946         [ ?   ?   ?   ?   ?  ]     2 (line:   371)  PUTFIELD        (NOT RESOLVED), java.awt.Scrollbar.lineIncrement (type I)
947         [ ?   ?   ?   ?   ?  ]     3 (line:   371)  GOTO            op1=152
948         [ ?   ?   ?   ?   ?  ] L017(instruction count: 3, predecessors: 1):
949         [ ?   ?   ?   ?   ?  ]     0 (line:   373)  ALOAD           0
950         [ ?   ?   ?   ?   ?  ]     1 (line:   373)  ILOAD           6
951         [ ?   ?   ?   ?   ?  ]     2 (line:   373)  PUTFIELD        (NOT RESOLVED), java.awt.Scrollbar.lineIncrement (type I)
952
953
954         CHECK 3   : (BB:   1) IFEQ            javax.swing.JInternalFrame.setIcon(Z)V PUBLIC
955         [ ?   ?   ?   ?  ] L002(instruction count: 4, predecessors: 1):
956         [ ?   ?   ?   ?  ]     0 (line:  1395)  ALOAD           0
957         [ ?   ?   ?   ?  ]     1 (line:  1395)  ICONST          25552 (0x000063d0)
958         [ ?   ?   ?   ?  ]     2 (line:  1395)  INVOKEVIRTUAL   (NOT RESOLVED) javax.swing.JInternalFrame.fireInternalFrameEvent(I)V
959         [ ?   ?   ?   ?  ]     3 (line:  1395)  GOTO            op1=61
960         [ ?   ?   ?   ?  ] L003(instruction count: 3, predecessors: 1):
961         [ ?   ?   ?   ?  ]     0 (line:  1397)  ALOAD           0
962         [ ?   ?   ?   ?  ]     1 (line:  1397)  ICONST          25553 (0x000063d1)
963         [ ?   ?   ?   ?  ]     2 (line:  1397)  INVOKEVIRTUAL   (NOT RESOLVED) javax.swing.JInternalFrame.fireInternalFrameEvent(I)V
964
965         */
966
967 #if !defined(NDEBUG)
968         if (pattern != 0) {
969                 printf("PATTERN %02d: (BB: %3d) ", pattern, jd->basicblockcount - bptr->nr);
970                 method_println(m);
971
972                 /*                                                              if (pattern == 27) { */
973                 /*                                                                      show_basicblock(m, cd, &bptr[1]); */
974                 /*                                                                      show_basicblock(m, cd, &bptr[2]); */
975                 /*                                                              } */
976
977                 fflush(stdout);
978
979         } else {
980                 if ((bptr[1].icount == 2) &&
981                         (bptr[2].icount == 1) &&
982
983                         (bptr[1].iinstr[1].opc == ICMD_GOTO))
984                         {
985                                 printf("CHECK 1   : (BB: %3d) ", jd->basicblockcount - bptr->nr);
986                                 method_println(m);
987 #if 0
988                                 show_basicblock(jd, &bptr[1]);
989                                 show_basicblock(jd, &bptr[2]);
990 #endif
991                                 fflush(stdout);
992                         }
993
994                 if ((bptr[1].icount == 3) &&
995                         (bptr[2].icount == 2) &&
996
997                         (bptr[1].iinstr[2].opc == ICMD_GOTO))
998                         {
999                                 printf("CHECK 2   : (BB: %3d) ", jd->basicblockcount - bptr->nr);
1000                                 method_println(m);
1001 #if 0
1002                                 show_basicblock(jd, &bptr[1]);
1003                                 show_basicblock(jd, &bptr[2]);
1004 #endif
1005                                 fflush(stdout);
1006                         }
1007
1008                 if ((bptr[1].icount == 4) &&
1009                         (bptr[2].icount == 3) &&
1010
1011                         (bptr[1].iinstr[3].opc == ICMD_GOTO))
1012                         {
1013                                 printf("CHECK 3   : (BB: %3d) ", jd->basicblockcount - bptr->nr);
1014                                 method_println(m);
1015 #if 0
1016                                 show_basicblock(jd, &bptr[1]);
1017                                 show_basicblock(jd, &bptr[2]);
1018 #endif
1019                                 fflush(stdout);
1020                         }
1021
1022                 if ((bptr[1].icount == 3) &&
1023                         (bptr[2].icount == 1) &&
1024
1025                         (bptr[1].iinstr[2].opc == ICMD_GOTO))
1026                         {
1027                                 printf("CHECK 4   : (BB: %3d) ", jd->basicblockcount - bptr->nr);
1028                                 method_println(m);
1029 #if 0
1030                                 show_basicblock(jd, &bptr[1]);
1031                                 show_basicblock(jd, &bptr[2]);
1032 #endif
1033                                 fflush(stdout);
1034                         }
1035         }
1036 #endif /* !defined(NDEBUG) */
1037 }
1038
1039
1040 /*
1041  * These are local overrides for various environment variables in Emacs.
1042  * Please do not remove this and leave it at the end of the file, where
1043  * Emacs will automagically detect them.
1044  * ---------------------------------------------------------------------
1045  * Local variables:
1046  * mode: c
1047  * indent-tabs-mode: t
1048  * c-basic-offset: 4
1049  * tab-width: 4
1050  * End:
1051  * vim:noexpandtab:sw=4:ts=4:
1052  */