KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > flow > CombineIfGotoExpressions


1 /* CombineIfGotoExpressions Copyright (C) 1998-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: CombineIfGotoExpressions.java,v 4.15.2.1 2002/05/28 17:34:08 hoenicke Exp $
18  */

19
20 package jode.flow;
21 import java.util.Vector JavaDoc;
22 import jode.expr.*;
23 import jode.type.Type;
24
25 public class CombineIfGotoExpressions {
26
27     public static boolean transform(ConditionalBlock cb,
28                                     StructuredBlock last) {
29         if (cb.jump == null
30             || !(last.outer instanceof SequentialBlock))
31             return false;
32
33         SequentialBlock sequBlock = (SequentialBlock) cb.outer;
34         Expression firstCond, secondCond;
35
36         secondCond = cb.getInstruction();
37         Expression lastCombined = secondCond;
38             
39         while (sequBlock.subBlocks[0] instanceof InstructionBlock) {
40             InstructionBlock ib =
41                 (InstructionBlock) sequBlock.subBlocks[0];
42
43             if (!(sequBlock.outer instanceof SequentialBlock))
44                 return false;
45
46             Expression expr = ib.getInstruction();
47             if (!(expr instanceof CombineableOperator)
48         || (lastCombined.canCombine((CombineableOperator)expr)
49             + secondCond.canCombine((CombineableOperator)expr) <= 0))
50                 /* Tricky, the above is true, iff one of the two
51                  * Expressions conflict, or both fail. */

52                 return false;
53
54             lastCombined = expr;
55
56             sequBlock = (SequentialBlock) sequBlock.outer;
57         }
58         
59         if (sequBlock.subBlocks[0] instanceof ConditionalBlock) {
60
61             ConditionalBlock cbprev =
62                 (ConditionalBlock) sequBlock.subBlocks[0];
63
64             Jump prevJump = cbprev.trueBlock.jump;
65
66             int operator;
67             if (prevJump.destination == cb.jump.destination) {
68                 operator = BinaryOperator.LOG_AND_OP;
69                 firstCond = cbprev.getInstruction().negate();
70             } else if (prevJump.destination == cb.trueBlock.jump.destination) {
71                 operator = BinaryOperator.LOG_OR_OP;
72                 firstCond = cbprev.getInstruction();
73             } else
74                 return false;
75
76             /* We have changed some instructions above. We may never
77              * return with a failure now.
78              */

79
80             sequBlock = (SequentialBlock) cb.outer;
81             while (sequBlock.subBlocks[0] instanceof InstructionBlock) {
82                 /* Now combine the expression. Everything should
83                  * succeed, because we have checked above. */

84                 InstructionBlock ib =
85                      (InstructionBlock) sequBlock.subBlocks[0];
86
87                 Expression expr = ib.getInstruction();
88
89                 secondCond = secondCond.combine((CombineableOperator) expr);
90                 sequBlock = (SequentialBlock) sequBlock.outer;
91             }
92
93             cb.flowBlock.removeSuccessor(prevJump);
94             prevJump.prev.removeJump();
95             Expression cond = new BinaryOperator(Type.tBoolean, operator)
96         .addOperand(secondCond).addOperand(firstCond);
97             cb.setInstruction(cond);
98             cb.moveDefinitions(sequBlock, last);
99             last.replace(sequBlock);
100             return true;
101         }
102         return false;
103     }
104 }
105
Popular Tags