00001 package edu.ksu.cis.bandera.prog;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import ca.mcgill.sable.util.*;
00036 import ca.mcgill.sable.soot.*;
00037 import ca.mcgill.sable.soot.jimple.*;
00038
00039 import edu.ksu.cis.bandera.util.GenericSet;
00040 import edu.ksu.cis.bandera.prog.Index;
00041
00042 public class PostdomAnalysis extends AbstractDom
00043 {
00044 private Map stmtToPostdoms;
00045 private Map stmtToImmediatePostdom;
00046
00047 public PostdomAnalysis(StmtList statementsList, StmtGraph sg)
00048 {
00049 super(statementsList, sg);
00050 stmtToPostdoms = new HashMap(stmtList.size() *2 +1, 0.7f);
00051
00052 postdominatorsMap();
00053 stmtToImmediatePostdom = computeImmedDom(stmtToPostdoms);
00054 }
00055 private GenericSet exitNodes()
00056 {
00057 GenericSet exitNodeSet = new GenericSet();
00058 List tails = stmtGraph.getTails();
00059 Iterator tailIt = tails.iterator();
00060
00061 while (tailIt.hasNext())
00062 {
00063 Stmt tail = (Stmt) tailIt.next();
00064 Index tailIndex = new Index(stmtList.indexOf(tail));
00065 exitNodeSet.addElemToSet(tailIndex);
00066 }
00067
00068
00069
00070
00071
00072
00073 Iterator stmtIt = stmtList.iterator();
00074 while (stmtIt.hasNext())
00075 {
00076 Stmt retStmt = (Stmt) stmtIt.next();
00077 if ((retStmt instanceof ReturnStmt) || (retStmt instanceof ReturnVoidStmt))
00078 {
00079 List succs = stmtGraph.getSuccsOf(retStmt);
00080 if (succs.size() != 0)
00081
00082
00083 {
00084 Index retStmtIndex = new Index(stmtList.indexOf(retStmt));
00085 exitNodeSet.addElemToSet(retStmtIndex);
00086 }
00087 }
00088 }
00089
00090 return exitNodeSet;
00091 }
00092 private GenericSet exitNodesWithoutThrow(GenericSet exitNodeSet)
00093 {
00094 if (exitNodeSet == null)
00095 {
00096 System.out.println("exitNodeSet should not be null in exitNodesWithoutThrow method in IndexMaps.java");
00097 System.exit(0);
00098 }
00099
00100 GenericSet nodeSet = new GenericSet();
00101
00102 for (int i = 0; i < exitNodeSet.size(); i++)
00103 {
00104 Index exitIndex = (Index) exitNodeSet.setRef(i);
00105 Stmt exitStmt = (Stmt) stmtList.get(exitIndex.index());
00106 if (!(exitStmt instanceof ThrowStmt))
00107 nodeSet.addElemToSet(exitIndex);
00108 }
00109
00110 return nodeSet;
00111 }
00112 public Index immediatePostdomOf(Stmt s)
00113 {
00114 return (Index) stmtToImmediatePostdom.get(s);
00115 }
00116 private Index indefiniteFrom()
00117 {
00118 BackEdgeAnalysis bea = new BackEdgeAnalysis(stmtList, stmtGraph);
00119 List backEdgesList = bea.backEdgeList();
00120
00121 Iterator edgeIt = backEdgesList.iterator();
00122 while (edgeIt.hasNext())
00123 {
00124 Edge edge = (Edge) edgeIt.next();
00125 if (edge.isPossibleIndefiniteLoop())
00126 return edge.fromNode;
00127 }
00128
00129 return AbstractDom.specialExitNode;
00130 }
00131 private void postdominatorsMap()
00132 {
00133 boolean change = true;
00134 GenericSet postDominators;
00135 GenericSet tempPostdoms;
00136 Stmt keyStmt;
00137 Index stmtIndex;
00138 LinkedList workList = new LinkedList();
00139 GenericSet visitedNode = new GenericSet();
00140
00141
00142
00143
00144
00145 GenericSet exitNodeList = exitNodes();
00146 GenericSet exitNodesNoThrow = exitNodesWithoutThrow(exitNodeList);
00147
00148 if (exitNodesNoThrow.size() == 0)
00149 {
00150 Index indefiniteNode = indefiniteFrom();
00151 if (indefiniteNode.equals(AbstractDom.specialExitNode))
00152 {
00153 System.out.println("Can not find out the exit node or the infinite loop");
00154 System.exit(0);
00155 }
00156 workList.addFirst(indefiniteNode);
00157
00158 keyStmt = (Stmt) stmtList.get(indefiniteNode.index());
00159 postDominators = new GenericSet(indefiniteNode);
00160 stmtToPostdoms.put(keyStmt, postDominators);
00161 }
00162 else
00163 {
00164 for (int i=0; i< exitNodesNoThrow.size(); i++)
00165 {
00166 stmtIndex = (Index) exitNodesNoThrow.setRef(i);
00167 workList.addFirst(stmtIndex);
00168
00169 keyStmt = (Stmt) stmtList.get(stmtIndex.index());
00170 postDominators = new GenericSet(stmtIndex);
00171 stmtToPostdoms.put(keyStmt, postDominators);
00172 }
00173 }
00174
00175
00176
00177
00178 GenericSet initialWorkList = new GenericSet();
00179 for (int i=0; i<workList.size(); i++)
00180 {
00181 initialWorkList.addElemToSet((Index) workList.get(i));
00182 }
00183
00184 GenericSet startNodes = getStartNodes();
00185
00186
00187 for (int i = 0; i< startNodes.size(); i++)
00188 {
00189 stmtIndex = (Index) startNodes.setRef(i);
00190 workList.addFirst(stmtIndex);
00191 }
00192
00193 postDominators = indexSetWithoutExceptionHandling();
00194
00195 while (workList.size() != 0)
00196 {
00197 Index nodeIndex = (Index) workList.removeFirst();
00198 visitedNode.addElemToSet(nodeIndex);
00199 Stmt nodeStmt = (Stmt) stmtList.get(nodeIndex.index());
00200
00201 if (! initialWorkList.contains(nodeIndex))
00202 stmtToPostdoms.put(nodeStmt, postDominators);
00203
00204 List nodeStmtSuccs = stmtGraph.getSuccsOf(nodeStmt);
00205 List newSuccs = removeExceptionCaught(nodeStmtSuccs);
00206 Iterator succIt = newSuccs.iterator();
00207 while (succIt.hasNext())
00208 {
00209 Stmt succStmt = (Stmt) succIt.next();
00210 Index succIndex = new Index(stmtList.indexOf(succStmt));
00211 if (workList.contains(succIndex) ||
00212 visitedNode.contains(succIndex))
00213 {
00214 }
00215 else workList.addLast(succIndex);
00216 }
00217 }
00218
00219 while (change)
00220 {
00221 change = false;
00222 workList = new LinkedList();
00223 visitedNode = new GenericSet();
00224
00225
00226 for (int i=0; i<initialWorkList.size(); i++)
00227 {
00228 workList.addFirst((Index) initialWorkList.setRef(i));
00229 }
00230 for (int i = 0; i< startNodes.size(); i++)
00231 {
00232 stmtIndex = (Index) startNodes.setRef(i);
00233 workList.addFirst(stmtIndex);
00234 }
00235
00236
00237
00238 while (workList.size() != 0)
00239 {
00240 stmtIndex = (Index) workList.removeFirst();
00241 visitedNode.addElemToSet(stmtIndex);
00242
00243 keyStmt = (Stmt) stmtList.get(stmtIndex.index());
00244 postDominators = (GenericSet) stmtToPostdoms.get(keyStmt);
00245 tempPostdoms = new GenericSet();
00246 tempPostdoms = tempPostdoms.union(postDominators);
00247
00248 List realSuccs = stmtGraph.getSuccsOf(keyStmt);
00249
00250 List succs = removeExceptionCaught(realSuccs);
00251
00252 for (int i = 0; i < succs.size(); i++)
00253 {
00254 Stmt succStmt = (Stmt) succs.get(i);
00255 GenericSet succDom = (GenericSet) stmtToPostdoms.get(succStmt);
00256
00257
00258 tempPostdoms = tempPostdoms.intersect(succDom);
00259 }
00260
00261 tempPostdoms.addElemToSet(stmtIndex);
00262
00263 if (! tempPostdoms.equals(postDominators))
00264 {
00265 change = true;
00266 stmtToPostdoms.remove(keyStmt);
00267 stmtToPostdoms.put(keyStmt, tempPostdoms);
00268 }
00269
00270
00271
00272 for (int i=0; i<succs.size(); i++)
00273 {
00274 Stmt succStmt = (Stmt) succs.get(i);
00275 Index succIndex = new Index(stmtList.indexOf(succStmt));
00276 if (workList.contains(succIndex) ||
00277 visitedNode.contains(succIndex))
00278 {
00279 }
00280 else workList.addLast(succIndex);
00281 }
00282 }
00283 }
00284
00285 }
00286 public GenericSet postdomsOf(Stmt stmt)
00287 {
00288 return (GenericSet) stmtToPostdoms.get(stmt);
00289 }
00290 public Map stmtToImmediatePostdom()
00291 {
00292 return stmtToImmediatePostdom;
00293 }
00294 public Map stmtToPostdominatorsMap()
00295 {
00296 return stmtToPostdoms;
00297 }
00298 }