package Analysis.Loops;
-import IR.Flat.*;
-import IR.TypeUtil;
-import IR.MethodDescriptor;
-import IR.Operation;
-import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import java.util.Vector;
-import java.util.Iterator;
-import java.util.Hashtable;
+
+import IR.Operation;
+import IR.TypeUtil;
+import IR.Flat.FlatMethod;
+import IR.Flat.FlatNode;
+import IR.Flat.FlatOpNode;
+import IR.Flat.TempDescriptor;
+import IR.Flat.TempMap;
public class LoopOptimize {
- LoopInvariant loopinv;
+ private LoopInvariant loopinv;
+ private GlobalFieldType gft;
+ private TypeUtil typeutil;
+ private Map<FlatMethod, LoopInvariant> fm2loopinv;
+
+ private Hashtable<FlatNode, FlatNode> ntoomap;
+ private Hashtable<FlatNode, FlatNode> clonemap;
+ private Hashtable<FlatNode, FlatNode> map;
+
public LoopOptimize(GlobalFieldType gft, TypeUtil typeutil) {
- loopinv=new LoopInvariant(typeutil,gft);
+ this.gft = gft;
+ this.typeutil = typeutil;
+ fm2loopinv = new HashMap<FlatMethod, LoopInvariant>();
}
- Hashtable<FlatNode, FlatNode> ntoomap;
- Hashtable<FlatNode, FlatNode> clonemap;
- Hashtable<FlatNode, FlatNode> map;
public void optimize(FlatMethod fm) {
+ loopinv = new LoopInvariant(typeutil, gft);
loopinv.analyze(fm);
+ fm2loopinv.put(fm, loopinv);
+
ntoomap=new Hashtable<FlatNode, FlatNode>();
map=new Hashtable<FlatNode, FlatNode>();
clonemap=new Hashtable<FlatNode, FlatNode>();
}
}
}
+
+ public LoopInvariant getLoopInvariant(FlatMethod fm){
+ return fm2loopinv.get(fm);
+ }
}
/**
* Constructor for Loop Termination Analysis
- *
- * @param fm
- * FlatMethod for termination analysis
- * @param loopInv
- * LoopInvariants for given method
*/
- public LoopTerminate(FlatMethod fm, LoopInvariant loopInv) {
- this.fm = fm;
- this.loopInv = loopInv;
+ public LoopTerminate() {
this.inductionSet = new HashSet<TempDescriptor>();
this.inductionVar2DefNode = new HashMap<TempDescriptor, FlatNode>();
this.derivedVar2basicInduction = new HashMap<TempDescriptor, TempDescriptor>();
/**
* starts loop termination analysis
+ *
+ * @param fm
+ * FlatMethod for termination analysis
+ * @param loopInv
+ * LoopInvariants for given method
*/
- public void terminateAnalysis() {
+ public void terminateAnalysis(FlatMethod fm, LoopInvariant loopInv) {
+ this.fm = fm;
+ this.loopInv = loopInv;
Loops loopFinder = loopInv.root;
recurse(fm, loopFinder);
}
}
}
+
+ if (lowestLoc == null) {
+ lowestLoc = new CompositeLocation(Location.createBottomLocation(md));
+ }
+
return lowestLoc;
}
compLoc = checkLocationFromSubBlockNode(md, nametable, (SubBlockNode) bsn);
break;
- // case Kind.ContinueBreakNode:
- // checkLocationFromContinueBreakNode(md, nametable,(ContinueBreakNode)
- // bsn);
- // return null;
+ case Kind.ContinueBreakNode:
+ compLoc = new CompositeLocation();
+ break;
+
}
return compLoc;
}
import java.util.StringTokenizer;
import java.util.Vector;
+import Analysis.Loops.LoopOptimize;
+import Analysis.Loops.LoopTerminate;
import IR.AnnotationDescriptor;
import IR.ClassDescriptor;
import IR.MethodDescriptor;
import IR.State;
import IR.TypeUtil;
+import IR.Flat.FlatMethod;
public class SSJavaAnalysis {
public static final String RETURNLOC = "RETURNLOC";
public static final String LOC = "LOC";
public static final String DELTA = "DELTA";
+ public static final String TERMINATE = "TERMINATE";
+
State state;
TypeUtil tu;
FlowDownCheck flowDownChecker;
// method -> local variable lattice
Hashtable<MethodDescriptor, MethodLattice<String>> md2lattice;
+ // method set that does not have loop termination analysis
+ Hashtable<MethodDescriptor, Integer> skipLoopTerminate;
+
public SSJavaAnalysis(State state, TypeUtil tu) {
this.state = state;
this.tu = tu;
this.cd2methodDefault = new Hashtable<ClassDescriptor, MethodLattice<String>>();
this.md2lattice = new Hashtable<MethodDescriptor, MethodLattice<String>>();
this.md2needAnnotation = new Hashtable<MethodDescriptor, Boolean>();
+ this.skipLoopTerminate = new Hashtable<MethodDescriptor, Integer>();
}
public void doCheck() {
doMethodAnnotationCheck();
parseLocationAnnotation();
doFlowDownCheck();
- doLoopCheck();
+ doDefinitelyWrittenCheck();
doSingleReferenceCheck();
}
flowDownChecker.flowDownCheck();
}
- public void doLoopCheck() {
+ public void doDefinitelyWrittenCheck() {
DefinitelyWrittenCheck checker = new DefinitelyWrittenCheck(state);
checker.definitelyWrittenCheck();
}
new MethodLattice<String>(SSJavaLattice.TOP, SSJavaLattice.BOTTOM);
md2lattice.put(md, locOrder);
parseMethodLatticeDefinition(cd, an.getValue(), locOrder);
+ } else if (an.getMarker().equals(TERMINATE)) {
+ // developer explicitly wants to skip loop termination analysis
+ String value = an.getValue();
+ int maxIteration = 0;
+ if (value != null) {
+ maxIteration = Integer.parseInt(value);
+ }
+ skipLoopTerminate.put(md, new Integer(maxIteration));
}
}
}
return md2needAnnotation;
}
+ public void doLoopTerminationCheck(LoopOptimize lo) {
+ LoopTerminate lt = new LoopTerminate();
+ Set<MethodDescriptor> mdSet = md2needAnnotation.keySet();
+ for (Iterator iterator = mdSet.iterator(); iterator.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator.next();
+ if (!skipLoopTerminate.containsKey(md)) {
+ FlatMethod fm = state.getMethodFlat(md);
+ lt.terminateAnalysis(fm, lo.getLoopInvariant(fm));
+ }
+ }
+
+ }
+
}
CallGraph callgraph=jb!=null?jb:(state.TASK?new BaseCallGraph(state, tu):new JavaCallGraph(state, tu));
// SSJava
+ SSJavaAnalysis ssjava=new SSJavaAnalysis(state,tu);
if(state.SSJAVA) {
- SSJavaAnalysis ssjava=new SSJavaAnalysis(state,tu);
ssjava.doCheck();
State.logEvent("Done SSJava Checking");
}
}
}
State.logEvent("Done Optimizing");
+
+ if(state.SSJAVA) {
+ ssjava.doLoopTerminationCheck(lo);
+ }
}
if (state.FLATIRGRAPH) {