KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > shimple > toolkits > scalar > SEvaluator


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2003 Navindra Umanee <navindra@cs.mcgill.ca>
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.shimple.toolkits.scalar;
21
22 import soot.*;
23 import soot.util.*;
24 import soot.jimple.*;
25 import soot.shimple.*;
26 import soot.jimple.toolkits.scalar.*;
27 import java.util.*;
28
29 /**
30  * Extension of soot.jimple.toolkits.scalar.Evaluator to handle Phi
31  * expressions.
32  *
33  * @author Navindra Umanee.
34  * @see soot.jimple.toolkits.scalar.Evaluator
35  * @see SConstantPropagatorAndFolder
36  **/

37 public class SEvaluator
38 {
39     /**
40      * Returns true if given value is determined to be constant valued,
41      * false otherwise
42      **/

43     public static boolean isValueConstantValued(Value op)
44     {
45         if(op instanceof PhiExpr) {
46             Iterator argsIt = ((PhiExpr) op).getValues().iterator();
47             Constant firstConstant = null;
48
49             while(argsIt.hasNext()){
50                 Value arg = (Value) argsIt.next();
51
52                 if(!(arg instanceof Constant))
53                     return false;
54
55                 if(firstConstant == null)
56                     firstConstant = (Constant) arg;
57                 else if(!firstConstant.equals(arg))
58                     return false;
59             }
60
61             return true;
62         }
63
64         return Evaluator.isValueConstantValued(op);
65     }
66
67     /**
68      * Returns the constant value of <code>op</code> if it is easy to
69      * find the constant value; else returns <code>null</code>.
70      **/

71     public static Value getConstantValueOf(Value op)
72     {
73         if(!(op instanceof PhiExpr))
74             return Evaluator.getConstantValueOf(op);
75
76         if(!(isValueConstantValued(op)))
77             return null;
78         
79         return (Value) ((PhiExpr) op).getValue(0);
80     }
81
82     /**
83      * If a normal expression contains Bottom, always return Bottom.
84      * Otherwise, if a normal expression contains Top, returns Top.
85      * Else determine the constant value of the expression if
86      * possible, if not return Bottom.
87      *
88      * <p> If a Phi expression contains Bottom, always return Bottom.
89      * Otherwise, if all the constant arguments are the same (ignoring
90      * Top and locals) return that constant or Top if no concrete
91      * constant is present, else return Bottom.
92      *
93      * @see SEvaluator.TopConstant
94      * @see SEvaluator.BottomConstant
95      **/

96     public static Constant getFuzzyConstantValueOf(Value v)
97     {
98         if(v instanceof Constant)
99             return (Constant) v;
100
101         if(v instanceof Local)
102             return BottomConstant.v();
103
104         if(!(v instanceof Expr))
105             return BottomConstant.v();
106
107         Expr expr = (Expr) v;
108         Constant constant = null;
109
110         if(expr instanceof PhiExpr){
111             PhiExpr phi = (PhiExpr) expr;
112             Iterator argsIt = phi.getValues().iterator();
113
114             while(argsIt.hasNext()){
115                 Value arg = (Value) argsIt.next();
116             
117                 if(!(arg instanceof Constant))
118                     continue;
119
120                 if(arg instanceof TopConstant)
121                     continue;
122
123                 if(constant == null)
124                     constant = (Constant) arg;
125                 else if(!constant.equals(arg)){
126                     constant = BottomConstant.v();
127                     break;
128                 }
129             }
130
131             if(constant == null)
132                 constant = TopConstant.v();
133         }
134         else{
135             Iterator valueBoxesIt = expr.getUseBoxes().iterator();
136             while(valueBoxesIt.hasNext()){
137                 Value value = ((ValueBox)valueBoxesIt.next()).getValue();
138
139                 if(value instanceof BottomConstant){
140                     constant = BottomConstant.v();
141                     break;
142                 }
143                 
144                 if(value instanceof TopConstant)
145                     constant = TopConstant.v();
146             }
147
148             if(constant == null)
149                 constant = (Constant) getConstantValueOf(expr);
150
151             if(constant == null)
152                 constant = BottomConstant.v();
153         }
154         
155         return constant;
156     }
157
158     /**
159      * Get the constant value of the expression given the assumptions
160      * in the localToConstant map (may contain Top and Bottom). Does
161      * not change expression.
162      *
163      * @see SEvaluator.TopConstant
164      * @see SEvaluator.BottomConstant
165      **/

166     public static Constant getFuzzyConstantValueOf(Value v, Map localToConstant)
167     {
168         if(v instanceof Constant)
169             return (Constant) v;
170
171         if(v instanceof Local)
172             return (Constant) localToConstant.get(v);
173
174         if(!(v instanceof Expr))
175             return BottomConstant.v();
176
177         /* clone expr and update the clone with our assumptions */
178
179         Expr expr = (Expr) v.clone();
180         Iterator useBoxIt = expr.getUseBoxes().iterator();
181
182         while(useBoxIt.hasNext()){
183             ValueBox useBox = (ValueBox) useBoxIt.next();
184             Value use = useBox.getValue();
185             if(use instanceof Local){
186                 Constant constant = (Constant) localToConstant.get(use);
187                 if(useBox.canContainValue(constant))
188                     useBox.setValue(constant);
189             }
190         }
191
192         // oops -- clear spurious pointers to the unit chain!
193
if(expr instanceof UnitBoxOwner)
194             ((UnitBoxOwner)expr).clearUnitBoxes();
195         
196         /* evaluate the expression */
197         
198         return(getFuzzyConstantValueOf(expr));
199     }
200
201     /**
202      * Head of a new hierarchy of constants -- Top and Bottom.
203      **/

204     public static abstract class MetaConstant extends Constant
205     {
206     }
207     
208     /**
209      * Top i.e. assumed to be a constant, but of unknown value.
210      **/

211     public static class TopConstant extends MetaConstant
212     {
213         private static final TopConstant constant = new TopConstant();
214         
215         private TopConstant() {}
216         
217         public static Constant v()
218         {
219             return constant;
220         }
221
222         public Type getType()
223         {
224             return UnknownType.v();
225         }
226
227         public void apply(Switch sw)
228         {
229             throw new RuntimeException JavaDoc("Not implemented.");
230         }
231     }
232     
233     /**
234      * Bottom i.e. known not to be a constant.
235      **/

236     public static class BottomConstant extends MetaConstant
237     {
238         private static final BottomConstant constant = new BottomConstant();
239         
240         private BottomConstant() {}
241
242         public static Constant v()
243         {
244             return constant;
245         }
246         
247         public Type getType()
248         {
249         return UnknownType.v();
250         }
251     
252         public void apply(Switch sw)
253         {
254             throw new RuntimeException JavaDoc("Not implemented.");
255         }
256     }
257 }
258
259
Popular Tags