KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > javaToJimple > toolkits > CondTransformer


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2005 Jennifer Lhotak
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 package soot.javaToJimple.toolkits;
21
22 import soot.*;
23 import soot.jimple.*;
24 import java.util.*;
25
26 public class CondTransformer extends BodyTransformer {
27     public CondTransformer (Singletons.Global g) {}
28     public static CondTransformer v() {
29         return G.v().soot_javaToJimple_toolkits_CondTransformer();
30     }
31
32     private static final int SEQ_LENGTH = 6;
33     private Stmt [] stmtSeq = new Stmt[SEQ_LENGTH];
34     private boolean sameGoto = true;
35
36     protected void internalTransform(Body b, String JavaDoc phaseName, Map options){
37
38         //G.v().out.println("running cond and/or transformer");
39
boolean change = true;
40         /*
41          * the idea is to look for groups of statements of the form
42          * if cond goto L0
43          * if cond goto L0
44          * z0 = 1
45          * goto L1
46          * L0: z0 = 0
47          * L1: if z0 == 0 goto L2
48          * conseq
49          * L2: altern
50          *
51          * and transform to
52          * if cond goto L0
53          * if cond goto L0
54          * conseq
55          * L0: altern
56          *
57          */

58         
59         while (change){
60             Iterator it = b.getUnits().iterator();
61             int pos = 0;
62             while (it.hasNext()){
63                 change = false;
64                 Stmt s = (Stmt)it.next();
65                 if (testStmtSeq(s, pos)) {
66                     pos++;
67                 }
68                 if (pos == 6) {
69                     // found seq now transform then continue
70
//G.v().out.println("found sequence will transform");
71
change = true;
72                     break;
73                 }
74             }
75             if (change){
76                 transformBody(b, (Stmt)it.next());
77                 pos = 0;
78                 stmtSeq = new Stmt[SEQ_LENGTH];
79             }
80         }
81     }
82
83     private void transformBody(Body b, Stmt next){
84         // change target of stmts 0 and 1 to target of stmt 5
85
// remove stmts 2, 3, 4, 5
86
Stmt newTarget = null;
87         Stmt oldTarget = null;
88         if (sameGoto){
89             newTarget = ((IfStmt)stmtSeq[5]).getTarget();
90         }
91         else {
92             newTarget = next;
93             oldTarget = ((IfStmt)stmtSeq[5]).getTarget();
94         }
95         ((IfStmt)stmtSeq[0]).setTarget(newTarget);
96         ((IfStmt)stmtSeq[1]).setTarget(newTarget);
97         
98         for (int i = 2; i <= 5; i++){
99             b.getUnits().remove(stmtSeq[i]);
100         }
101         if (!sameGoto){
102             b.getUnits().insertAfter(Jimple.v().newGotoStmt(oldTarget), stmtSeq[1]);
103         }
104     }
105
106     private boolean testStmtSeq(Stmt s, int pos){
107         switch(pos){
108             case 0: {
109                         if (s instanceof IfStmt){
110                             stmtSeq[pos] = s;
111                             return true;
112                         }
113                         break;
114                     }
115             case 1: {
116                         if (s instanceof IfStmt){
117                             if (sameTarget(stmtSeq[pos-1], s)){
118                                 stmtSeq[pos] = s;
119                                 return true;
120                             }
121                         }
122                         break;
123                     }
124             case 2: {
125                         if (s instanceof AssignStmt){
126                             stmtSeq[pos] = s;
127                             if ((((AssignStmt)s).getRightOp() instanceof IntConstant) && (((IntConstant)((AssignStmt)s).getRightOp())).value == 0){
128                                 sameGoto = false;
129                             }
130                             return true;
131                         }
132                         break;
133                     }
134             case 3: {
135                         if (s instanceof GotoStmt){
136                             stmtSeq[pos] = s;
137                             return true;
138                         }
139                         break;
140                     }
141             case 4: {
142                         if (s instanceof AssignStmt){
143                             if (isTarget(((IfStmt)stmtSeq[0]).getTarget(), s) && sameLocal(stmtSeq[2], s)){
144                                 stmtSeq[pos] = s;
145                                 return true;
146                             }
147                         }
148                         break;
149                     }
150             case 5: {
151                         if (s instanceof IfStmt){
152                             if (isTarget((Stmt)((GotoStmt)stmtSeq[3]).getTarget(), s) && sameCondLocal(stmtSeq[4], s) && (((IfStmt)s).getCondition() instanceof EqExpr)){
153                                 stmtSeq[pos] = s;
154                                 return true;
155                             }
156                             else if (isTarget((Stmt)((GotoStmt)stmtSeq[3]).getTarget(), s) && sameCondLocal(stmtSeq[4], s)){
157                                  stmtSeq[pos] = s;
158                                  sameGoto = false;
159                                  return true;
160                             }
161                         }
162                         break;
163                     }
164        
165             default: {
166                          break;
167                      }
168         }
169         return false;
170     }
171
172     private boolean sameTarget(Stmt s1, Stmt s2){
173         IfStmt is1 = (IfStmt)s1;
174         IfStmt is2 = (IfStmt)s2;
175         if (is1.getTarget().equals(is2.getTarget())){
176             return true;
177         }
178         return false;
179     }
180
181     private boolean isTarget(Stmt s1, Stmt s){
182         if (s1.equals(s)){
183             return true;
184         }
185         return false;
186     }
187
188     private boolean sameLocal(Stmt s1, Stmt s2){
189         AssignStmt as1 = (AssignStmt)s1;
190         AssignStmt as2 = (AssignStmt)s2;
191         if (as1.getLeftOp().equals(as2.getLeftOp())){
192             return true;
193         }
194         return false;
195     }
196
197     private boolean sameCondLocal(Stmt s1, Stmt s2){
198         AssignStmt as1 = (AssignStmt)s1;
199         IfStmt is2 = (IfStmt)s2;
200         if (is2.getCondition() instanceof BinopExpr){
201             BinopExpr bs2 = (BinopExpr)is2.getCondition();
202             if (as1.getLeftOp().equals(bs2.getOp1())){
203                 return true;
204             }
205         }
206         return false;
207     }
208 }
209
Popular Tags