KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > shimple > toolkits > graph > SimpleGlobalValueNumberer


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.graph;
21
22 import soot.*;
23 import soot.jimple.*;
24 import soot.util.*;
25 import soot.shimple.*;
26 import soot.toolkits.graph.*;
27 import java.util.*;
28 import soot.shimple.toolkits.graph.ValueGraph.Node;
29
30 public class SimpleGlobalValueNumberer implements GlobalValueNumberer
31 {
32     protected BlockGraph cfg;
33     protected ValueGraph vg;
34     protected Set partitions;
35     protected Map nodeToPartition;
36
37     protected int currentPartitionNumber;
38     
39     public SimpleGlobalValueNumberer(BlockGraph cfg)
40     {
41         this.cfg = cfg;
42         vg = new ValueGraph(cfg);
43         partitions = new HashSet(); // not deterministic
44
nodeToPartition = new HashMap();
45         currentPartitionNumber = 0;
46         
47         initPartition();
48         iterPartition();
49     }
50
51     // testing
52
public static void main(String JavaDoc[] args)
53     {
54         // assumes 2 args: Class + Method
55

56         Scene.v().loadClassAndSupport(args[0]);
57         SootClass sc = Scene.v().getSootClass(args[0]);
58         SootMethod sm = sc.getMethod(args[1]);
59         Body b = sm.retrieveActiveBody();
60         ShimpleBody sb = Shimple.v().newBody(b);
61         CompleteBlockGraph cfg = new CompleteBlockGraph(sb);
62         SimpleGlobalValueNumberer sgvn = new SimpleGlobalValueNumberer(cfg);
63         System.out.println(sgvn);
64     }
65     
66     public int getGlobalValueNumber(Local local)
67     {
68         Node node = vg.getNode(local);
69         return ((Partition)nodeToPartition.get(node)).getPartitionNumber();
70     }
71     
72     public boolean areEqual(Local local1, Local local2)
73     {
74         Node node1 = vg.getNode(local1);
75         Node node2 = vg.getNode(local2);
76
77         return (nodeToPartition.get(node1) == nodeToPartition.get(node2));
78     }
79     
80     protected void initPartition()
81     {
82         Map labelToPartition = new HashMap();
83         
84         Iterator topNodesIt = vg.getTopNodes().iterator();
85         while(topNodesIt.hasNext()){
86             Node node = (Node) topNodesIt.next();
87             String JavaDoc label = node.getLabel();
88             
89             Partition partition = (Partition) labelToPartition.get(label);
90             if(partition == null){
91                 partition = new Partition();
92                 partitions.add(partition);
93                 labelToPartition.put(label, partition);
94             }
95
96             partition.add(node);
97             nodeToPartition.put(node, partition);
98         }
99     }
100
101     protected List newPartitions;
102     
103     protected void iterPartition()
104     {
105         newPartitions = new ArrayList();
106
107         Iterator partitionsIt = partitions.iterator();
108         while(partitionsIt.hasNext()){
109             Partition partition = (Partition) partitionsIt.next();
110             processPartition(partition);
111         }
112
113         partitions.addAll(newPartitions);
114     }
115
116     protected void processPartition(Partition partition)
117     {
118         int size = partition.size();
119
120         if(size == 0)
121             return;
122
123         Node firstNode = (Node) partition.get(0);
124         Partition newPartition = new Partition();
125         boolean processNewPartition = false;
126         
127         for(int i = 1; i < size; i++){
128             Node node = (Node) partition.get(i);
129
130             if(!childrenAreInSamePartition(firstNode, node)){
131                 partition.remove(i);
132                 size--;
133                 newPartition.add(node);
134                 newPartitions.add(newPartition);
135                 nodeToPartition.put(node, newPartition);
136                 processNewPartition = true;
137             }
138         }
139
140         if(processNewPartition)
141             processPartition(newPartition);
142     }
143     
144     protected boolean childrenAreInSamePartition(Node node1, Node node2)
145     {
146         boolean ordered = node1.isOrdered();
147         if(ordered != node2.isOrdered())
148             throw new RuntimeException JavaDoc("Assertion failed.");
149
150         List children1 = node1.getChildren();
151         List children2 = node2.getChildren();
152
153         int numberOfChildren = children1.size();
154         if(children2.size() != numberOfChildren)
155             return false;
156         
157         if(ordered){
158             for(int i = 0; i < numberOfChildren; i++){
159                 Node child1 = (Node) children1.get(i);
160                 Node child2 = (Node) children2.get(i);
161                 if(nodeToPartition.get(child1) != nodeToPartition.get(child2))
162                     return false;
163             }
164         }
165         else{
166             for(int i = 0; i < numberOfChildren; i++){
167                 Node child1 = (Node) children1.get(i);
168                 for(int j = i; j < numberOfChildren; j++){
169                     Node child2 = (Node) children2.get(j);
170
171                     if(nodeToPartition.get(child1) ==
172                        nodeToPartition.get(child2)){
173                         if(j != i){
174                             children2.remove(j);
175                             children2.add(i, child2);
176                         }
177                         break;
178                     }
179
180                     // last iteration, no match
181
if((j + 1) == numberOfChildren)
182                         return false;
183                 }
184             }
185         }
186
187         return true;
188     }
189
190     public String JavaDoc toString()
191     {
192         StringBuffer JavaDoc tmp = new StringBuffer JavaDoc();
193
194         Body b = cfg.getBody();
195         Iterator localsIt = b.getLocals().iterator();
196
197         while(localsIt.hasNext()){
198             Local local = (Local)localsIt.next();
199             tmp.append(local + "\t" + getGlobalValueNumber(local) + "\n");
200         }
201
202         /*
203         Iterator partitionsIt = partitions.iterator();
204         while(partitionsIt.hasNext()){
205             Partition partition = (Partition) partitionsIt.next();
206             int partitionNumber = partition.getPartitionNumber();
207             
208             Iterator partitionIt = partition.iterator();
209             while(partitionIt.hasNext()){
210                 Local local = vg.getLocal((Node)partitionIt.next());
211                 if(local == null)
212                     continue;
213                 tmp.append(local + "\t" + partitionNumber + "\n");
214             }
215         }
216         */

217         
218         return tmp.toString();
219     }
220     
221     protected class Partition extends ArrayList
222     {
223         protected int partitionNumber;
224         
225         protected Partition()
226         {
227             super();
228             partitionNumber = currentPartitionNumber++;
229         }
230
231         protected int getPartitionNumber()
232         {
233             return partitionNumber;
234         }
235     }
236 }
237
Popular Tags