KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > scalar > UnreachableCodeEliminator


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1999 Phong Co
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 /*
21  * Modified by the Sable Research Group and others 1997-2003.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27
28 package soot.jimple.toolkits.scalar;
29 import soot.options.*;
30
31 import soot.util.*;
32 import soot.*;
33 import soot.jimple.*;
34 import java.io.*;
35 import java.util.*;
36 import soot.toolkits.graph.*;
37 import soot.toolkits.exceptions.PedanticThrowAnalysis;
38
39 public class UnreachableCodeEliminator extends BodyTransformer
40 {
41     public UnreachableCodeEliminator( Singletons.Global g ) {}
42     public static UnreachableCodeEliminator v() { return G.v().soot_jimple_toolkits_scalar_UnreachableCodeEliminator(); }
43
44     protected void internalTransform(Body b, String JavaDoc phaseName, Map options)
45     {
46         new Instance().internalTransform(b, phaseName, options);
47     }
48
49     class Instance {
50         ExceptionalUnitGraph stmtGraph;
51         HashSet visited;
52         int numPruned;
53
54         protected void internalTransform(Body b, String JavaDoc phaseName, Map options)
55         {
56             StmtBody body = (StmtBody)b;
57             
58             if (Options.v().verbose())
59                 G.v().out.println("[" + body.getMethod().getName() + "] Eliminating unreachable code...");
60
61             numPruned = 0;
62
63             if (PhaseOptions.getBoolean(options, "remove-unreachable-traps")) {
64                 stmtGraph = new ExceptionalUnitGraph(body);
65             } else {
66                 // Force a conservative ExceptionalUnitGraph() which
67
// necessarily includes an edge from every trapped Unit to
68
// its handler, so that we retain Traps in the case where
69
// trapped units remain, but the default ThrowAnalysis
70
// says that none of them can throw the caught exception.
71
stmtGraph = new ExceptionalUnitGraph(body, PedanticThrowAnalysis.v(),
72                                                     false);
73             }
74             visited = new HashSet();
75
76             // We need a map from Units that handle Traps, to a Set of their
77
// Traps, so we can remove the Traps should we remove the handler.
78
Map handlerToTraps = new HashMap();
79             for( Iterator trapIt = body.getTraps().iterator(); trapIt.hasNext(); ) {
80                 final Trap trap = (Trap) trapIt.next();
81                 Unit handler = trap.getHandlerUnit();
82                 Set handlersTraps = (Set) handlerToTraps.get(handler);
83                 if (handlersTraps == null) {
84                     handlersTraps = new ArraySet(3);
85                     handlerToTraps.put(handler, handlersTraps);
86                 }
87                 handlersTraps.add(trap);
88             }
89
90             // Used to be: "mark first statement and all its successors, recursively"
91
// Bad idea! Some methods are extremely long. It broke because the recursion reached the
92
// 3799th level.
93

94             if (!body.getUnits().isEmpty()) {
95                 LinkedList startPoints = new LinkedList();
96                 startPoints.addLast(body.getUnits().getFirst());
97
98                 visitStmts(startPoints);
99             }
100
101             Iterator stmtIt = body.getUnits().snapshotIterator();
102             while (stmtIt.hasNext())
103             {
104                 // find unmarked nodes
105
Stmt stmt = (Stmt)stmtIt.next();
106                 
107                 if (!visited.contains(stmt))
108                 {
109                     body.getUnits().remove(stmt);
110                     Set traps = (Set) handlerToTraps.get(stmt);
111                     if (traps != null) {
112                         for( Iterator trapIt = traps.iterator(); trapIt.hasNext(); ) {
113                             final Trap trap = (Trap) trapIt.next();
114                             body.getTraps().remove(trap);
115                         }
116                     }
117                     numPruned++;
118                 }
119             }
120             if (Options.v().verbose())
121                 G.v().out.println("[" + body.getMethod().getName() + "] Removed " + numPruned + " statements...");
122                 
123             // Now eliminate empty traps.
124
//
125
// For the most part, this is an atavism, an an artifact of
126
// pre-ExceptionalUnitGraph code, when the only way for a trap to
127
// become unreachable was if all its trapped units were removed, and
128
// the stmtIt loop did not remove Traps as it removed handler units.
129
// We've left this separate test for empty traps here, even though
130
// most such traps would already have been eliminated by the preceding
131
// loop, because in arbitrary bytecode you could have
132
// handler unit that was still reachable by normal control flow, even
133
// though it no longer trapped any units (though such code is unlikely
134
// to occur in practice, and certainly no in code generated from Java
135
// source.
136
{
137                 Iterator trapIt = b.getTraps().iterator();
138                 
139                 while(trapIt.hasNext())
140                 {
141                     Trap t = (Trap) trapIt.next();
142                     
143                     if(t.getBeginUnit() == t.getEndUnit())
144                         trapIt.remove();
145                 }
146             }
147             
148     } // pruneUnreachables
149

150         private void visitStmts(LinkedList st) {
151
152             // Do DFS of the unit graph, starting from the passed nodes.
153

154             while (!st.isEmpty()) {
155                 Object JavaDoc stmt = st.removeLast();
156                 if (!visited.contains(stmt)) {
157                     visited.add(stmt);
158                     Iterator succIt = stmtGraph.getSuccsOf(stmt).iterator();
159                     while (succIt.hasNext()) {
160                         Object JavaDoc o = succIt.next();
161                         if (!visited.contains(o))
162                             st.addLast(o);
163                     }
164                 }
165             }
166         } // visitStmts
167

168     }
169 } // UnreachablePruner
170
Popular Tags