KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > toolkits > base > AST > transformations > OrAggregatorThree


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2005 Nomair A. Naeem
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.dava.toolkits.base.AST.transformations;
21
22 import soot.*;
23 import java.util.*;
24 import soot.jimple.*;
25 import soot.dava.internal.AST.*;
26 import soot.dava.internal.asg.*;
27 import soot.dava.internal.javaRep.*;
28
29 /*
30   Nomair A. Naeem 21-FEB-2005
31   The class is responsible to do the following transformation on the AST
32   if(cond1){ if(cond1 || cond2)
33      A A
34   } }
35   if(cond2){
36      A
37   }
38
39   Notice that this kind of conversion is only possible if A is an
40   abrupt edge like:
41      a, break label_0;
42      b, continue label_0;
43      c, return;
44
45   i.e. we need to make sure that the A bodies are single statements
46   and that too an abrupt control flow
47
48   Also note that in the new aggregated or condition it is very important
49   that cond2 be checked AFTER cond1 has been checked and failed.
50   The reason for this being side effects that these conditions can cause.
51
52 */

53 public class OrAggregatorThree {
54
55
56     public static void checkAndTransform(ASTNode node,ASTIfNode ifOne,ASTIfNode ifTwo, int nodeNumber,int subBodyNumber){
57
58     if(!(node instanceof ASTIfElseNode)){
59         //these are the nodes which always have one subBody
60
List subBodies = node.get_SubBodies();
61         if(subBodies.size()!=1){
62         //there is something wrong
63
throw new RuntimeException JavaDoc("Please report this benchmark to the programmer");
64         }
65         List onlySubBody = (List)subBodies.get(0);
66
67         /*
68           The onlySubBody contains the Two consective if nodes
69           at location given by nodeNumber and nodeNumber+1
70         */

71         
72         //match the pattern and get the newBody
73
List newBody = createNewNodeBody(onlySubBody,nodeNumber,ifOne,ifTwo);
74
75
76         if(newBody==null){
77         //something went wrong, pattern didnt match or some other problem
78
return;
79         }
80         if(node instanceof ASTMethodNode){
81         ((ASTMethodNode)node).replaceBody(newBody);
82         G.v().ASTTransformations_modified = true;
83         //System.out.println("OR AGGREGATOR THREE");
84
}
85         else if(node instanceof ASTSynchronizedBlockNode){
86         ((ASTSynchronizedBlockNode)node).replaceBody(newBody);
87         G.v().ASTTransformations_modified = true;
88         //System.out.println("OR AGGREGATOR THREE");
89
}
90         else if(node instanceof ASTLabeledBlockNode){
91         ((ASTLabeledBlockNode)node).replaceBody(newBody);
92         G.v().ASTTransformations_modified = true;
93         //System.out.println("OR AGGREGATOR THREE");
94
}
95         else if(node instanceof ASTUnconditionalLoopNode){
96         ((ASTUnconditionalLoopNode)node).replaceBody(newBody);
97         G.v().ASTTransformations_modified = true;
98         //System.out.println("OR AGGREGATOR THREE");
99
}
100         else if(node instanceof ASTIfNode){
101         ((ASTIfNode)node).replaceBody(newBody);
102         G.v().ASTTransformations_modified = true;
103         //System.out.println("OR AGGREGATOR THREE");
104
}
105         else if(node instanceof ASTWhileNode){
106         ((ASTWhileNode)node).replaceBody(newBody);
107         G.v().ASTTransformations_modified = true;
108         //System.out.println("OR AGGREGATOR THREE");
109
}
110         else if(node instanceof ASTDoWhileNode){
111         ((ASTDoWhileNode)node).replaceBody(newBody);
112         G.v().ASTTransformations_modified = true;
113         //System.out.println("OR AGGREGATOR THREE");
114
}
115         else {
116         //there is no other case something is wrong if we get here
117
return;
118         }
119     }
120     else{//its an ASTIfElseNode
121
//if its an ASIfElseNode then check which Subbody has the labeledBlock
122
if(subBodyNumber!=0 && subBodyNumber!=1){
123         //something bad is happening dont do nothin
124
//System.out.println("Error-------not modifying AST");
125
return;
126         }
127         List subBodies = node.get_SubBodies();
128         if(subBodies.size()!=2){
129         //there is something wrong
130
throw new RuntimeException JavaDoc("Please report this benchmark to the programmer");
131         }
132
133         List toModifySubBody = (List)subBodies.get(subBodyNumber);
134
135         /*
136           The toModifySubBody contains the two consective if nodes in question
137           at location given by the nodeNumber and nodeNumer+1
138         */

139         List newBody = createNewNodeBody(toModifySubBody,nodeNumber,ifOne,ifTwo);
140         if(newBody==null){
141         //something went wrong, the pattern didnt match or something else
142
return;
143         }
144         if(subBodyNumber==0){
145         //the if body was modified
146
//System.out.println("OR AGGREGATOR THREE");
147
G.v().ASTTransformations_modified = true;
148         ((ASTIfElseNode)node).replaceBody(newBody,(List)subBodies.get(1));
149         }
150         else if(subBodyNumber==1){
151         //else body was modified
152
//System.out.println("OR AGGREGATOR THREE");
153
G.v().ASTTransformations_modified = true;
154         ((ASTIfElseNode)node).replaceBody((List)subBodies.get(0),newBody);
155         }
156         else{//realllly shouldnt come here
157
//something bad is happening dont do nothin
158
//System.out.println("Error-------not modifying AST");
159
return;
160         }
161
162     }//end of ASTIfElseNode
163
}
164
165
166     /*
167       This method does the following:
168       1, check that the OrAggregatorThree pattern matches for node ifOne and ifTwo
169       2, if pattern does not match return null
170       3, if pattern matches create and return a newSubBody which has:
171          a, ifOne with its condition ORED with that of ifTwo
172      b, ifTwo has been removed from the subBody
173     */

174
175     public static List createNewNodeBody(List oldSubBody,int nodeNumber,ASTIfNode ifOne ,ASTIfNode ifTwo){
176     if(!matchPattern(ifOne,ifTwo)){
177         //pattern did not match
178
return null;
179     }
180     
181     //create a new SubBody
182
List newSubBody = new ArrayList();
183     
184     //this is an iterator of ASTNodes
185
Iterator it = oldSubBody.iterator();
186     
187     //copy to newSubBody all nodes until you get to nodeNumber
188
int index=0;
189     while(index!=nodeNumber ){
190         if(!it.hasNext()){
191         return null;
192         }
193         newSubBody.add(it.next());
194         index++;
195     }
196
197     //at this point the iterator is pointing to the ASTIFNode
198
//just to make sure check this
199
ASTNode isItIfOne = (ASTNode)it.next();
200
201     if(!(isItIfOne instanceof ASTIfNode)){
202         //something is wrong
203
return null;
204     }
205
206     //get the next node that should also be an ASTIfNode
207
ASTNode isItIfTwo = (ASTNode)it.next();
208     if(!(isItIfTwo instanceof ASTIfNode)){
209         //something is wrong
210
return null;
211     }
212
213
214     //double check by invoking matchPattern on these
215
//if speed is an issue this check can be removed
216
if(!matchPattern((ASTIfNode)isItIfOne,(ASTIfNode)isItIfTwo)){
217         //pattern did not match
218
return null;
219     }
220     
221     //we are sure that we have the two nodes
222

223     //create new node
224
ASTIfNode firstOne = (ASTIfNode)isItIfOne;
225     ASTIfNode secondOne = (ASTIfNode)isItIfTwo;
226     
227     //create new condition
228
ASTCondition firstCond = firstOne.get_Condition();
229     ASTCondition secondCond = secondOne.get_Condition();
230
231     ASTCondition newCond = new ASTOrCondition(firstCond,secondCond);
232
233     ASTIfNode newNode = new ASTIfNode(firstOne.get_Label(),newCond,firstOne.getIfBody());
234     
235     //add the new node
236
newSubBody.add(newNode);
237
238
239     //add any remaining nodes in the oldSubBody to the new one
240
while(it.hasNext()){
241         newSubBody.add(it.next());
242     }
243
244     //newSubBody is ready return it
245
return newSubBody;
246     }
247
248
249     /*
250       Given two IfNodes as input the pattern checks the following:
251       a, each if node has a single ASTSTatementSequenceNode in the body
252       b, Each StatementSequenceNode is a single statement
253       c, The statement is the same in both nodes
254       d, The statement is an abrupt control flow statement
255     */

256     private static boolean matchPattern(ASTIfNode one, ASTIfNode two){
257     List subBodiesOne=one.get_SubBodies();
258     List subBodiesTwo=two.get_SubBodies();
259     
260     if(subBodiesOne.size()!=1 || subBodiesTwo.size()!=1){
261         //these are both if nodes they should always have one subBody
262
return false;
263     }
264     List onlySubBodyOne = (List)subBodiesOne.get(0);
265     List onlySubBodyTwo = (List)subBodiesTwo.get(0);
266
267     if(onlySubBodyOne.size()!=1 || onlySubBodyTwo.size()!=1){
268         //these subBodies are expected to have a single StatementSequenceNode
269
return false;
270     }
271     
272     ASTNode onlyASTNodeOne = (ASTNode)onlySubBodyOne.get(0);
273     ASTNode onlyASTNodeTwo = (ASTNode)onlySubBodyTwo.get(0);
274
275     if( !(onlyASTNodeOne instanceof ASTStatementSequenceNode) || !(onlyASTNodeTwo instanceof ASTStatementSequenceNode)){
276         //need both of these nodes to be StatementSequnceNodes
277
return false;
278     }
279
280     ASTStatementSequenceNode stmtSeqOne = (ASTStatementSequenceNode)onlyASTNodeOne;
281     ASTStatementSequenceNode stmtSeqTwo = (ASTStatementSequenceNode)onlyASTNodeTwo;
282
283     List stmtsOne = stmtSeqOne.getStatements();
284     List stmtsTwo = stmtSeqTwo.getStatements();
285
286     if(stmtsOne.size()!=1 || stmtsTwo.size()!=1){
287         //there should only be one statement
288
return false;
289     }
290
291     AugmentedStmt asOne = (AugmentedStmt)stmtsOne.get(0);
292     AugmentedStmt asTwo = (AugmentedStmt)stmtsTwo.get(0);
293
294
295     Stmt s1 = asOne.get_Stmt();
296     Stmt s2 = asTwo.get_Stmt();
297
298     if(s1.toString().compareTo(s2.toString())!=0){
299         //the two stmts are not the same
300
return false;
301     }
302
303     //check if they are abrupt statements
304
if(s1 instanceof DAbruptStmt && s2 instanceof DAbruptStmt){
305         //takes care of break <label> and continue <label>
306
return true;
307     }
308     else if(s1 instanceof ReturnStmt && s2 instanceof ReturnStmt){
309         //takes care of return <var>
310
return true;
311     }
312     else if (s1 instanceof ReturnVoidStmt && s2 instanceof ReturnVoidStmt){
313         //takes care of return;
314
return true;
315     }
316     else
317         return false;
318     }
319 }
Popular Tags