KickJava   Java API By Example, From Geeks To Geeks.

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


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.SET.*;
26 import soot.dava.internal.AST.*;
27 import soot.dava.internal.asg.*;
28 import soot.dava.internal.javaRep.*;
29 import soot.dava.toolkits.base.AST.analysis.*;
30
31
32 /*
33   Nomair A. Naeem 21-FEB-2005
34   The class is responsible to one of the following two transformation on the AST
35
36   PRIORITY 1:
37   if(cond1){ if(cond1 || cond2) if(cond1 || cond2){
38      A A A
39   } } }
40   else{ ---> else{ --->
41      if(cond2){ empty else body
42         A }
43      }
44   }
45
46 The removal of the empty else body is done by a different Transformation since
47 we need a reference to the parent node of this if
48
49
50   PRIORITY 2:
51   If the above pattern fails to match the following pattern is checked:
52
53   if(cond1){ if(!cond1){
54      break label_1; Body1
55   } ----> }
56   else{ else{
57       Body1 break label_1
58   } }
59
60  The idea behind this is that this type of flipping of conditions
61  will help in moving a condition into a cycle node
62
63   TO MAKE CODE EFFECIENT BLOCK THE ANALYSIS TO GOING INTO STATEMENTS
64   this is done by overriding the caseASTStatementSequenceNode
65 */

66 public class OrAggregatorTwo extends DepthFirstAdapter{
67
68     
69     
70     public OrAggregatorTwo(){
71         DEBUG=false;
72     }
73     public OrAggregatorTwo(boolean verbose){
74     super(verbose);
75         DEBUG=false;
76     }
77
78     public void caseASTStatementSequenceNode(ASTStatementSequenceNode node){
79     }
80
81     public void outASTIfElseNode(ASTIfElseNode node){
82     //check whether the else body has another if and nothing else
83

84     List ifBody = node.getIfBody();
85     List elseBody = node.getElseBody();
86
87     List innerIfBody=checkElseHasOnlyIf(elseBody);
88     
89     if(innerIfBody==null){
90         //pattern 1 did not match
91

92
93         //check for pattern 2
94
matchPatternTwo(node);
95
96         return;
97     }
98     //pattern 1 is fine till now
99
//compare the ifBody with the innerIfBody
100
//They need to match exactly
101

102     if(ifBody.toString().compareTo(innerIfBody.toString())!=0){
103         matchPatternTwo(node);
104         return;
105     }
106
107     ASTCondition leftCond = node.get_Condition();
108     ASTCondition rightCond= getRightCond(elseBody);
109     ASTCondition newCond = new ASTOrCondition(leftCond,rightCond);
110
111     /*
112       The outer if and inner if could both have labels.
113       Note that if the inner if had a label which was broken from inside its body
114       the two bodies would not have been the same since the outerifbody could not have
115       the same label.
116
117       We therefore keep the outerIfElse label
118     */

119     //System.out.println("OR AGGREGATOR TWO");
120
node.set_Condition(newCond);
121     
122     /*
123       Always have to follow with a parse to remove unwanted empty ElseBodies
124     */

125     node.replaceElseBody(new ArrayList());
126
127
128     G.v().ASTTransformations_modified = true;
129     }
130
131
132     public ASTCondition getRightCond(List elseBody){
133     //We know from checkElseHasOnlyIf that there is only one node
134
//in this body and it is an ASTIfNode
135
ASTIfNode innerIfNode = (ASTIfNode)elseBody.get(0);
136     return innerIfNode.get_Condition();
137     }
138
139
140
141     public List checkElseHasOnlyIf(List elseBody){
142     if(elseBody.size()!=1){
143         //there should only be on IfNode here
144
return null;
145     }
146     //there is only one node check that its a ASTIFNode
147
ASTNode temp = (ASTNode)elseBody.get(0);
148     if(!(temp instanceof ASTIfNode)){
149         //should have been an If node to match the pattern
150
return null;
151     }
152     ASTIfNode innerIfNode = (ASTIfNode)temp;
153     List innerIfBody = innerIfNode.getIfBody();
154     return innerIfBody;
155     }
156
157
158
159
160     public void matchPatternTwo(ASTIfElseNode node){
161         debug("OrAggregatorTwo","matchPatternTwo","Did not match patternOne...trying patternTwo");
162     List ifBody = node.getIfBody();
163     if(ifBody.size()!=1){
164         //we are only interested if size is one
165
return;
166     }
167     ASTNode onlyNode=(ASTNode)ifBody.get(0);
168     if(!(onlyNode instanceof ASTStatementSequenceNode)){
169         //only interested in StmtSeq nodes
170
return;
171     }
172     ASTStatementSequenceNode stmtNode=(ASTStatementSequenceNode)onlyNode;
173     List statements = stmtNode.getStatements();
174     if(statements.size()!=1){
175         //there is more than one statement
176
return;
177     }
178
179     //there is only one statement
180
AugmentedStmt as = (AugmentedStmt)statements.get(0);
181     Stmt stmt = as.get_Stmt();
182
183     if(!(stmt instanceof DAbruptStmt)){
184         //this is not a break/continue stmt
185
return;
186     }
187     DAbruptStmt abStmt = (DAbruptStmt)stmt;
188     if(!(abStmt.is_Break() || abStmt.is_Continue())){
189         //not a break/continue
190
return;
191     }
192
193     //pattern matched
194
//flip condition and switch bodies
195
ASTCondition cond = node.get_Condition();
196     cond.flip();
197
198     List elseBody = node.getElseBody();
199     SETNodeLabel label = node.get_Label();
200
201     node.replace(label,cond,elseBody,ifBody);
202     debug("","","REVERSED CONDITIONS AND BODIES");
203     debug("","","elseBody is"+elseBody);
204     debug("","","ifBody is"+ifBody);
205     
206     G.v().ASTIfElseFlipped = true;
207     }
208
209
210 }
Popular Tags