KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > flow > CreatePrePostIncExpression


1 /* CreatePrePostIncExpression 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: CreatePrePostIncExpression.java,v 3.15.2.1 2002/05/28 17:34:09 hoenicke Exp $
18  */

19
20 package jode.flow;
21 import jode.expr.*;
22 import jode.type.Type;
23
24 public class CreatePrePostIncExpression {
25
26     public static boolean transform(InstructionContainer ic,
27                                     StructuredBlock last)
28     {
29         return (createLocalPrePostInc(ic, last) || createPostInc(ic, last));
30     }
31     
32     public static boolean createLocalPrePostInc(InstructionContainer ic,
33                                                 StructuredBlock last) {
34         /* Situations:
35          *
36          * PUSH local_x -> PUSH local_x++
37      * IINC local_x, +/-1
38      *
39      * IINC local_x, +/-1
40          * PUSH local_x -> PUSH ++local_x
41          */

42
43         if (!(last.outer instanceof SequentialBlock)
44             || !(last.outer.getSubBlocks()[0] instanceof InstructionBlock))
45         return false;
46         
47     Expression instr1 = ((InstructionBlock)
48                  last.outer.getSubBlocks()[0]).getInstruction();
49     Expression instr2 = ic.getInstruction();
50     
51     IIncOperator iinc;
52     LocalLoadOperator load;
53     boolean isPost;
54     if (instr1 instanceof IIncOperator
55         && instr2 instanceof LocalLoadOperator) {
56         iinc = (IIncOperator) instr1;
57         load = (LocalLoadOperator) instr2;
58         isPost = false;
59     } else if (instr1 instanceof LocalLoadOperator
60            && instr2 instanceof IIncOperator) {
61         load = (LocalLoadOperator) instr1;
62         iinc = (IIncOperator) instr2;
63         isPost = true;
64     } else
65         return false;
66     
67     int op;
68     if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP)
69         op = Operator.INC_OP;
70     else if (iinc.getOperatorIndex() == iinc.SUB_OP + iinc.OPASSIGN_OP)
71         op = Operator.DEC_OP;
72     else
73         return false;
74     
75     if (iinc.getValue() == -1)
76         op ^= 1;
77     else if (iinc.getValue() != 1)
78         return false;
79     
80     if (!iinc.lvalueMatches(load))
81         return false;
82     
83     Type type = load.getType().intersection(Type.tUInt);
84     iinc.makeNonVoid();
85     Operator ppop =
86         new PrePostFixOperator(type, op, iinc.getLValue(), isPost);
87     
88     ic.setInstruction(ppop);
89     ic.moveDefinitions(last.outer, last);
90     last.replace(last.outer);
91     return true;
92     }
93     
94     public static boolean createPostInc(InstructionContainer ic,
95                                         StructuredBlock last) {
96
97         /* Situation:
98          *
99          * PUSH load/storeOps (optional/
100      * not checked) PUSH load/storeOps
101          * DUP load/storeOps (optional) PUSH store++/--
102          * PUSH load(stack)
103          * DUP_X(storeOps count) ->
104          * store(stack) = stack_0 +/- 1
105          */

106
107         if (!(ic.getInstruction() instanceof StoreInstruction))
108             return false;
109         
110         StoreInstruction store = (StoreInstruction) ic.getInstruction();
111
112     /* Make sure that the lvalue part of the store is
113      * not yet resolved (and note that the rvalue part
114      * should also have 1 remaining operand)
115      */

116     Expression lvalue = store.getSubExpressions()[0];
117     int lvalueCount = lvalue.getFreeOperandCount();
118     if (!((Operator)lvalue).isFreeOperator()
119         || !store.isVoid()
120         || !(store.getSubExpressions()[1] instanceof BinaryOperator))
121         return false;
122
123         BinaryOperator binOp = (BinaryOperator) store.getSubExpressions()[1];
124         if (binOp.getSubExpressions() == null
125         || !(binOp.getSubExpressions()[0] instanceof NopOperator)
126         || !(binOp.getSubExpressions()[1] instanceof ConstOperator))
127             return false;
128
129         ConstOperator constOp = (ConstOperator) binOp.getSubExpressions()[1];
130         int op;
131         if (binOp.getOperatorIndex() == store.ADD_OP)
132             op = Operator.INC_OP;
133         else if (binOp.getOperatorIndex() == store.SUB_OP)
134             op = Operator.DEC_OP;
135         else
136             return false;
137           
138         if (!constOp.isOne(lvalue.getType()))
139             return false;
140
141         if (!(last.outer instanceof SequentialBlock))
142             return false;
143         SequentialBlock sb = (SequentialBlock)last.outer;
144         if (!(sb.subBlocks[0] instanceof SpecialBlock))
145             return false;
146             
147         SpecialBlock dup = (SpecialBlock) sb.subBlocks[0];
148         if (dup.type != SpecialBlock.DUP
149             || dup.count != lvalue.getType().stackSize()
150             || dup.depth != lvalueCount)
151             return false;
152
153         if (!(sb.outer instanceof SequentialBlock))
154             return false;
155         sb = (SequentialBlock) sb.outer;
156         if (!(sb.subBlocks[0] instanceof InstructionBlock))
157             return false;
158         InstructionBlock ib = (InstructionBlock) sb.subBlocks[0];
159
160         if (!(ib.getInstruction() instanceof Operator)
161             || !store.lvalueMatches((Operator) ib.getInstruction()))
162             return false;
163
164         if (lvalueCount > 0) {
165             if (!(sb.outer instanceof SequentialBlock))
166                 return false;
167             sb = (SequentialBlock) sb.outer;
168             if (!(sb.subBlocks[0] instanceof SpecialBlock))
169                 return false;
170             SpecialBlock dup2 = (SpecialBlock) sb.subBlocks[0];
171             if (dup2.type != SpecialBlock.DUP
172                 || dup2.count != lvalueCount
173                 || dup2.depth != 0)
174                 return false;
175         }
176         ic.setInstruction
177         (new PrePostFixOperator(lvalue.getType(), op,
178                     store.getLValue(), true));
179         ic.moveDefinitions(sb, last);
180         last.replace(sb);
181     return true;
182     }
183 }
184
Popular Tags