00001 package edu.ksu.cis.bandera.jjjc.optimizer;
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.soot.*;
00036 import ca.mcgill.sable.soot.jimple.*;
00037 import ca.mcgill.sable.util.*;
00038 import java.util.*;
00039 import edu.ksu.cis.bandera.annotation.*;
00040 import ca.mcgill.sable.util.Iterator;
00041
00042 public class TemporaryLocalsReduction {
00043
00044
00045
00046
00047
00048
00049 public static void reduce(JimpleBody body, Annotation annotation) {
00050 SootClass sc = body.getMethod().getDeclaringClass();
00051 StmtList stmtList = body.getStmtList();
00052 Hashtable localToDefCount = new Hashtable();
00053 Hashtable localToUseCount = new Hashtable();
00054
00055
00056 {
00057 for (Iterator i = stmtList.iterator(); i.hasNext();) {
00058 Stmt s = (Stmt) i.next();
00059 if (s instanceof DefinitionStmt && ((DefinitionStmt) s).getLeftOp() instanceof Local) {
00060 Local l = (Local) ((DefinitionStmt) s).getLeftOp();
00061 if (!localToDefCount.containsKey(l))
00062 localToDefCount.put(l, new Integer(1));
00063 else
00064 localToDefCount.put(l, new Integer(((Integer) localToDefCount.get(l)).intValue() + 1));
00065 }
00066 for (Iterator j = s.getUseBoxes().iterator(); j.hasNext();) {
00067 ValueBox vb = (ValueBox) j.next();
00068 if (vb.getValue() instanceof Local) {
00069 Local l = (Local) vb.getValue();
00070 if (!localToUseCount.containsKey(l))
00071 localToUseCount.put(l, new Integer(1));
00072 else
00073 localToUseCount.put(l, new Integer(((Integer) localToUseCount.get(l)).intValue() + 1));
00074 }
00075 }
00076 }
00077 }
00078
00079 CompleteStmtGraph graph = new CompleteStmtGraph(stmtList);
00080 Local thisLocal = null;
00081 Stmt thisIdentityStmt = null;
00082
00083 for (Iterator i = graph.pseudoTopologicalOrderIterator(); i.hasNext();) {
00084 Stmt stmt = (Stmt) i.next();
00085 if (stmt instanceof JAssignStmt) {
00086 Value leftOp = ((JAssignStmt) stmt).getLeftOp();
00087 Value rightOp = ((JAssignStmt) stmt).getRightOp();
00088 if ((leftOp instanceof Local) && (rightOp instanceof Local)) {
00089 Local leftLocal = (Local) leftOp;
00090 Local rightLocal = (Local) rightOp;
00091 if (!leftLocal.getName().startsWith("JJJCTEMP$") && rightLocal.getName().startsWith("JJJCTEMP$")
00092 && (((Integer) localToDefCount.get(rightLocal)).intValue() == 1)) {
00093 for (Iterator j = stmtList.iterator(); j.hasNext();) {
00094 for (Iterator k = ((Stmt) j.next()).getUseAndDefBoxes().iterator(); k.hasNext();) {
00095 ValueBox vb = (ValueBox) k.next();
00096 if (vb.getValue() == rightLocal) {
00097 vb.setValue(leftLocal);
00098 }
00099 }
00100 }
00101 }
00102 } else if ((leftOp instanceof Local) && (rightOp instanceof InvokeExpr)) {
00103 Local leftLocal = (Local) leftOp;
00104 if (leftLocal.getName().startsWith("JJJCTEMP$") && (localToUseCount.get(leftLocal) == null)) {
00105 Stmt s = Jimple.v().newInvokeStmt(rightOp);
00106 try {
00107 annotation.replaceStmt(stmt, s);
00108 } catch (AnnotationException e) {}
00109 stmtList.set(stmtList.indexOf(stmt), s);
00110 body.redirectJumps(stmt, s);
00111 }
00112 }
00113 } else if (stmt instanceof JIdentityStmt) {
00114 Value leftOp = ((JIdentityStmt) stmt).getLeftOp();
00115 Value rightOp = ((JIdentityStmt) stmt).getRightOp();
00116 if (rightOp instanceof ThisRef) {
00117 if (thisLocal == null) {
00118 thisLocal = (Local) leftOp;
00119 thisIdentityStmt = stmt;
00120 } else {
00121 for (Iterator j = stmtList.iterator(); j.hasNext();) {
00122 for (Iterator k = ((Stmt) j.next()).getUseAndDefBoxes().iterator(); k.hasNext();) {
00123 ValueBox vb = (ValueBox) k.next();
00124 if (vb.getValue() == leftOp) {
00125 vb.setValue(thisLocal);
00126 }
00127 }
00128 }
00129 }
00130 }
00131 }
00132 }
00133
00134 for (Iterator i = stmtList.iterator(); i.hasNext();) {
00135 Stmt s = (Stmt) i.next();
00136 if ((s instanceof JIdentityStmt) && (((JIdentityStmt) s).getRightOp() instanceof ThisRef)
00137 && (s != thisIdentityStmt))
00138 stmtList.remove(s);
00139 }
00140 }
00141 }