import Analysis.Liveness;
import Analysis.ArrayReferencees;
import Analysis.RBlockRelationAnalysis;
+import Analysis.RBlockStatusAnalysis;
import IR.*;
import IR.Flat.*;
import IR.Tree.Modifiers;
public Liveness liveness;
public ArrayReferencees arrayReferencees;
public RBlockRelationAnalysis rblockRel;
+ public RBlockStatusAnalysis rblockStatus;
public TypeUtil typeUtil;
public int allocationDepth;
CallGraph cg,
Liveness l,
ArrayReferencees ar,
- RBlockRelationAnalysis rra
+ RBlockRelationAnalysis rra,
+ RBlockStatusAnalysis rsa
) {
- init( s, tu, cg, l, ar, rra );
+ init( s, tu, cg, l, ar, rra, rsa );
}
protected void init( State state,
CallGraph callGraph,
Liveness liveness,
ArrayReferencees arrayReferencees,
- RBlockRelationAnalysis rra
+ RBlockRelationAnalysis rra,
+ RBlockStatusAnalysis rsa
) {
analysisComplete = false;
this.liveness = liveness;
this.arrayReferencees = arrayReferencees;
this.rblockRel = rra;
+ this.rblockStatus = rsa;
if( rblockRel != null ) {
doEffectsAnalysis = true;
lhs = fon.getDest();
rhs = fon.getLeft();
rg.assignTempXEqualToTempY( lhs, rhs );
+
+ if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+ if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+ // x gets status of y
+ if(rg.getAccessibleVar().contains(rhs)){
+ rg.addAccessibleVar(lhs);
+ }
+ }
+ }
+
}
break;
rg.assignTempXEqualToTempYFieldF( lhs, rhs, fld );
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
- effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld );
+ effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld );
+
+ if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+ // x=y.f, stall y if not accessible
+ // contributes read effects on stall site of y
+ // after this, x and y are accessbile.
+
+ rg.addAccessibleVar(lhs);
+ rg.addAccessibleVar(rhs);
+ }
}
}
break;
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fld, strongUpdate );
+
+ if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+ // x.y=f , stall x and y if they are not accessible
+ // also contribute write effects on stall site of x
+
+ // accessible status update
+ rg.addAccessibleVar(lhs);
+ rg.addAccessibleVar(rhs);
+ }
+
}
}
break;
rg.assignTempXEqualToTempYFieldF( lhs, rhs, fdElement );
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
- effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement );
+ effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement );
+
+ if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+ // x=y.f, stall y if not accessible
+ // contributes read effects on stall site of y
+ // after this, x and y are accessbile.
+
+ rg.addAccessibleVar(lhs);
+ rg.addAccessibleVar(rhs);
+ }
+
}
}
break;
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fdElement,
false );
+
+ if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+ // x.y=f , stall x and y if they are not accessible
+ // also contribute write effects on stall site of x
+
+ // accessible status update
+ rg.addAccessibleVar(lhs);
+ rg.addAccessibleVar(rhs);
+ }
+
}
}
break;
if( shouldAnalysisTrack( lhs.getType() ) ) {
AllocSite as = getAllocSiteFromFlatNewPRIVATE( fnn );
rg.assignTempEqualToNewAlloc( lhs, as );
+
+ if (doEffectsAnalysis && fmContaining != fmAnalysisEntry) {
+ if (rblockStatus.isInCriticalRegion(fmContaining, fn)) {
+ // after creating new object, lhs is accessible
+ rg.addAccessibleVar(lhs);
+ }
+ }
+
}
break;
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
rg.removeInContextTaints( fsexn.getFlatEnter() );
+ // sese exit clears all mappings of accessible vars and stall sites
+ // need to wipe out stall site taints
+ rg.clearAccessibleVarSet();
}
break;
public void assignTempXEqualToTempY( TempDescriptor x,
TempDescriptor y ) {
assignTempXEqualToCastedTempY( x, y, null );
-
- // x gets status of y
- // if it is in region,
- //if(accessibleVars.contains(y)){
- // accessibleVars.add(x);
- //}
+
}
public void assignTempXEqualToCastedTempY( TempDescriptor x,
globalSweep();
}
}
-
- // accessible status update
- // if it is in region,
- //accessibleVars.add(x);
- //accessibleVars.add(y);
+
}
globalSweep();
}
}
-
-
- // after x.y=f , stall x and y if they are not accessible
- // also contribute write effects on stall site of x
- // accessible status update
- // if it is in region
- //accessibleVars.add(x);
- //accessibleVars.add(y);
return edgeRemovedByStrongUpdate;
}
int conflictType = ConflictGraph.NON_WRITE_CONFLICT;
- // if node A has write effects on reading/writing regions of node B
Hashtable<AllocSite, Set<Effect>> alloc2readEffectsA = nodeA.getReadEffectSet();
Hashtable<AllocSite, Set<Effect>> alloc2writeEffectsA = nodeA.getWriteEffectSet();
Hashtable<AllocSite, Set<Effect>> alloc2readEffectsB = nodeB.getReadEffectSet();
Hashtable<AllocSite, Set<Effect>> alloc2writeEffectsB = nodeB.getWriteEffectSet();
+ // if node A has write effects on reading/writing regions of node B
conflictType = updateConflictType(conflictType, determineConflictType(alloc2writeEffectsA,
alloc2readEffectsB));
conflictType = updateConflictType(conflictType, determineConflictType(alloc2writeEffectsA,
Effect effectB = (Effect) iterator2.next();
if (effectA.getAffectedAllocSite().equals(effectB.getAffectedAllocSite())
- && effectA.getField().equals(effectB.getField())) {
+ && effectA.getField().equals(effectB.getField())) {
// possible conflict
/*
* if(og.isReachable(asA, asB, effectA.getAffectedAllocSite())){
import Analysis.ArrayReferencees;
import Analysis.Liveness;
import Analysis.RBlockRelationAnalysis;
+import Analysis.RBlockStatusAnalysis;
import Analysis.CallGraph.CallGraph;
import Analysis.Disjoint.DisjointAnalysis;
import Analysis.Disjoint.Effect;
private TypeUtil typeUtil;
private CallGraph callGraph;
private RBlockRelationAnalysis rblockRel;
+ private RBlockStatusAnalysis rblockStatus;
private DisjointAnalysis disjointAnalysisTaints;
private DisjointAnalysis disjointAnalysisReach;
// 1st pass, find basic rblock relations
rblockRel = new RBlockRelationAnalysis(state, typeUtil, callGraph);
+
+ rblockStatus = new RBlockStatusAnalysis(state, typeUtil, callGraph, rblockRel);
+
// 2nd pass, liveness, in-set out-set (no virtual reads yet!)
Iterator<FlatSESEEnterNode> rootItr = rblockRel.getRootSESEs().iterator();
// 5th pass, use disjointness with NO FLAGGED REGIONS
// to compute taints and effects
disjointAnalysisTaints = new DisjointAnalysis(state, typeUtil, callGraph, liveness,
- arrayReferencees, rblockRel);
+ arrayReferencees, rblockRel, rblockStatus);
// 6th pass, not available analysis FOR VARIABLES!
methItr = descriptorsToAnalyze.iterator();
--- /dev/null
+package Analysis;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Map.Entry;
+
+import Analysis.CallGraph.CallGraph;
+import IR.MethodDescriptor;
+import IR.State;
+import IR.TypeUtil;
+import IR.Flat.FKind;
+import IR.Flat.FlatMethod;
+import IR.Flat.FlatNode;
+import IR.Flat.FlatSESEEnterNode;
+import IR.Flat.FlatSESEExitNode;
+
+public class RBlockStatusAnalysis {
+
+ // compiler data
+ State state;
+ TypeUtil typeUtil;
+ CallGraph callGraph;
+ RBlockRelationAnalysis rra;
+
+ // per method-per node-rblock stacks
+ protected Hashtable<FlatMethod, Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>>> fm2statusmap;
+
+ public RBlockStatusAnalysis(State state, TypeUtil typeUtil, CallGraph callGraph,
+ RBlockRelationAnalysis rra) {
+ this.state = state;
+ this.typeUtil = typeUtil;
+ this.callGraph = callGraph;
+ this.rra = rra;
+
+ fm2statusmap =
+ new Hashtable<FlatMethod, Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>>>();
+
+ MethodDescriptor mdSourceEntry = typeUtil.getMain();
+ FlatMethod fmMain = state.getMethodFlat(mdSourceEntry);
+
+ // add all methods transitively reachable from the
+ // source's main to set for analysis
+ Set<MethodDescriptor> descriptorsToAnalyze = callGraph.getAllMethods(mdSourceEntry);
+
+ descriptorsToAnalyze.add(mdSourceEntry);
+
+ analyzeMethods(descriptorsToAnalyze);
+
+ // analyzeMethodsDebug(descriptorsToAnalyze);
+ }
+
+ protected void analyzeMethods(Set<MethodDescriptor> descriptorsToAnalyze) {
+
+ Iterator<MethodDescriptor> mdItr = descriptorsToAnalyze.iterator();
+ while (mdItr.hasNext()) {
+ FlatMethod fm = state.getMethodFlat(mdItr.next());
+
+ Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> fn2seseStatus =
+ computeRBlockStatus(fm);
+
+ fm2statusmap.put(fm, fn2seseStatus);
+ }
+ }
+
+ public Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> computeRBlockStatus(
+ FlatMethod fm) {
+
+ Hashtable<FlatNode, Stack<FlatSESEEnterNode>> seseStacks =
+ new Hashtable<FlatNode, Stack<FlatSESEEnterNode>>();
+
+ Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> fn2seseStatus =
+ new Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>>();
+
+ LinkedList<FlatNode> flatNodesToVisit = new LinkedList<FlatNode>();
+ flatNodesToVisit.add(fm);
+
+ Stack<FlatSESEEnterNode> seseStackFirst = new Stack<FlatSESEEnterNode>();
+ seseStacks.put(fm, seseStackFirst);
+
+ while (!flatNodesToVisit.isEmpty()) {
+ Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
+ FlatNode fn = fnItr.next();
+
+ Hashtable<FlatSESEEnterNode, Boolean> prevResult = fn2seseStatus.get(fn);
+
+ Hashtable<FlatSESEEnterNode, Boolean> currentResult =
+ new Hashtable<FlatSESEEnterNode, Boolean>();
+
+ for (int i = 0; i < fn.numPrev(); i++) {
+ FlatNode prevFlatNode = fn.getPrev(i);
+ Hashtable<FlatSESEEnterNode, Boolean> incoming = fn2seseStatus.get(prevFlatNode);
+ if (incoming != null) {
+ merge(currentResult, incoming);
+ }
+ }
+
+ flatNodesToVisit.remove(fn);
+
+ nodeActions(fn, fm, currentResult);
+
+ // if we have a new result, schedule forward nodes for
+ // analysis
+ if (prevResult == null || !currentResult.equals(prevResult)) {
+ fn2seseStatus.put(fn, currentResult);
+ for (int i = 0; i < fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+ flatNodesToVisit.addFirst(nn);
+ }
+ }
+ }
+
+ return fn2seseStatus;
+ }
+
+ private void merge(Hashtable<FlatSESEEnterNode, Boolean> current,
+ Hashtable<FlatSESEEnterNode, Boolean> incoming) {
+
+ Iterator inIter = incoming.entrySet().iterator();
+ while (inIter.hasNext()) {
+ Entry inEntry = (Entry) inIter.next();
+ FlatSESEEnterNode seseContaining = (FlatSESEEnterNode) inEntry.getKey();
+ Boolean isAfter = (Boolean) inEntry.getValue();
+
+ Boolean currentIsAfter = current.get(seseContaining);
+ if (currentIsAfter == null || currentIsAfter == Boolean.FALSE) {
+ current.put(seseContaining, isAfter);
+ }
+ }
+
+ }
+
+ public boolean isInCriticalRegion(FlatMethod fmContaining, FlatNode fn) {
+ FlatSESEEnterNode seseContaining = rra.getRBlockStacks(fmContaining, fn).peek();
+ Hashtable<FlatNode, Hashtable<FlatSESEEnterNode, Boolean>> statusMap =
+ fm2statusmap.get(fmContaining);
+ Hashtable<FlatSESEEnterNode, Boolean> status = statusMap.get(fn);
+
+ if(status.get(seseContaining).booleanValue()==true){
+ System.out.println(fn+" is in the critical region in according to "+seseContaining);
+ }
+
+ return status.get(seseContaining).booleanValue();
+ }
+
+ protected void nodeActions(FlatNode fn, FlatMethod fm,
+ Hashtable<FlatSESEEnterNode, Boolean> status) {
+ switch (fn.kind()) {
+
+ case FKind.FlatSESEExitNode: {
+ FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
+ FlatSESEEnterNode fsen = fsexn.getFlatEnter();
+ if (fsen.getParent() != null) {
+ status.put(fsen.getParent(), Boolean.TRUE);
+ }
+ }
+ break;
+
+ default: {
+ if (!(fn instanceof FlatMethod)) {
+ Stack<FlatSESEEnterNode> seseStack = rra.getRBlockStacks(fm, fn);
+ if (!seseStack.isEmpty()) {
+ FlatSESEEnterNode currentParent = seseStack.peek();
+ if (!status.containsKey(currentParent)) {
+ status.put(currentParent, Boolean.FALSE);
+ }
+ }
+ }
+
+ }
+ break;
+ }
+
+ }
+
+ /*
+ * DEBUG
+ */
+ protected void analyzeMethodsDebug(Set<MethodDescriptor> descriptorsToAnalyze) {
+
+ Iterator<MethodDescriptor> mdItr = descriptorsToAnalyze.iterator();
+ while (mdItr.hasNext()) {
+ FlatMethod fm = state.getMethodFlat(mdItr.next());
+ printStatusMap(fm);
+
+ }
+ }
+
+ protected void printStatusMap(FlatMethod fm) {
+
+ Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
+ flatNodesToVisit.add(fm);
+
+ Set<FlatNode> visited = new HashSet<FlatNode>();
+
+ while (!flatNodesToVisit.isEmpty()) {
+ Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
+ FlatNode fn = fnItr.next();
+
+ flatNodesToVisit.remove(fn);
+ visited.add(fn);
+
+ System.out.println("------------------");
+ System.out.println("fn=" + fn);
+ System.out.println(fm2statusmap.get(fm).get(fn));
+
+ for (int i = 0; i < fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+
+ if (!visited.contains(nn)) {
+ flatNodesToVisit.add(nn);
+
+ }
+ }
+ }
+
+ }
+
+}