From: yeom Date: Mon, 28 Jun 2010 17:52:17 +0000 (+0000) Subject: add more steps to OoO analysis X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f8e86902374985ffa6505db1c3650d3e5f179807;p=IRC.git add more steps to OoO analysis --- diff --git a/Robust/src/Analysis/Disjoint/DisjointAnalysis.java b/Robust/src/Analysis/Disjoint/DisjointAnalysis.java index 9cde75ff..86dc5366 100644 --- a/Robust/src/Analysis/Disjoint/DisjointAnalysis.java +++ b/Robust/src/Analysis/Disjoint/DisjointAnalysis.java @@ -4,6 +4,7 @@ import Analysis.CallGraph.*; import Analysis.Liveness; import Analysis.ArrayReferencees; import Analysis.RBlockRelationAnalysis; +import Analysis.RBlockStatusAnalysis; import IR.*; import IR.Flat.*; import IR.Tree.Modifiers; @@ -334,6 +335,7 @@ public class DisjointAnalysis { public Liveness liveness; public ArrayReferencees arrayReferencees; public RBlockRelationAnalysis rblockRel; + public RBlockStatusAnalysis rblockStatus; public TypeUtil typeUtil; public int allocationDepth; @@ -557,9 +559,10 @@ public class DisjointAnalysis { 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, @@ -567,7 +570,8 @@ public class DisjointAnalysis { CallGraph callGraph, Liveness liveness, ArrayReferencees arrayReferencees, - RBlockRelationAnalysis rra + RBlockRelationAnalysis rra, + RBlockStatusAnalysis rsa ) { analysisComplete = false; @@ -578,6 +582,7 @@ public class DisjointAnalysis { this.liveness = liveness; this.arrayReferencees = arrayReferencees; this.rblockRel = rra; + this.rblockStatus = rsa; if( rblockRel != null ) { doEffectsAnalysis = true; @@ -1064,6 +1069,16 @@ public class DisjointAnalysis { 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; @@ -1087,7 +1102,16 @@ public class DisjointAnalysis { 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; @@ -1103,6 +1127,16 @@ public class DisjointAnalysis { 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; @@ -1122,7 +1156,17 @@ public class DisjointAnalysis { 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; @@ -1150,6 +1194,16 @@ public class DisjointAnalysis { 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; @@ -1160,6 +1214,14 @@ public class DisjointAnalysis { 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; @@ -1174,6 +1236,9 @@ public class DisjointAnalysis { 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; diff --git a/Robust/src/Analysis/Disjoint/ReachGraph.java b/Robust/src/Analysis/Disjoint/ReachGraph.java index 71a6f983..5e0e217e 100644 --- a/Robust/src/Analysis/Disjoint/ReachGraph.java +++ b/Robust/src/Analysis/Disjoint/ReachGraph.java @@ -378,12 +378,7 @@ public class ReachGraph { 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, @@ -510,11 +505,7 @@ public class ReachGraph { globalSweep(); } } - - // accessible status update - // if it is in region, - //accessibleVars.add(x); - //accessibleVars.add(y); + } @@ -682,14 +673,6 @@ public class ReachGraph { 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; } diff --git a/Robust/src/Analysis/OoOJava/ConflictGraph.java b/Robust/src/Analysis/OoOJava/ConflictGraph.java index 224790a0..35017612 100644 --- a/Robust/src/Analysis/OoOJava/ConflictGraph.java +++ b/Robust/src/Analysis/OoOJava/ConflictGraph.java @@ -144,12 +144,12 @@ public class ConflictGraph { int conflictType = ConflictGraph.NON_WRITE_CONFLICT; - // if node A has write effects on reading/writing regions of node B Hashtable> alloc2readEffectsA = nodeA.getReadEffectSet(); Hashtable> alloc2writeEffectsA = nodeA.getWriteEffectSet(); Hashtable> alloc2readEffectsB = nodeB.getReadEffectSet(); Hashtable> 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, @@ -184,7 +184,7 @@ public class ConflictGraph { 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())){ diff --git a/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java b/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java index 81021b1a..d052f23f 100644 --- a/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java +++ b/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java @@ -12,6 +12,7 @@ import java.util.Map.Entry; import Analysis.ArrayReferencees; import Analysis.Liveness; import Analysis.RBlockRelationAnalysis; +import Analysis.RBlockStatusAnalysis; import Analysis.CallGraph.CallGraph; import Analysis.Disjoint.DisjointAnalysis; import Analysis.Disjoint.Effect; @@ -39,6 +40,7 @@ public class OoOJavaAnalysis { private TypeUtil typeUtil; private CallGraph callGraph; private RBlockRelationAnalysis rblockRel; + private RBlockStatusAnalysis rblockStatus; private DisjointAnalysis disjointAnalysisTaints; private DisjointAnalysis disjointAnalysisReach; @@ -121,6 +123,9 @@ public class OoOJavaAnalysis { // 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 rootItr = rblockRel.getRootSESEs().iterator(); @@ -151,7 +156,7 @@ public class OoOJavaAnalysis { // 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(); diff --git a/Robust/src/Analysis/RBlockStatusAnalysis.java b/Robust/src/Analysis/RBlockStatusAnalysis.java new file mode 100644 index 00000000..01858600 --- /dev/null +++ b/Robust/src/Analysis/RBlockStatusAnalysis.java @@ -0,0 +1,222 @@ +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>> 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>>(); + + MethodDescriptor mdSourceEntry = typeUtil.getMain(); + FlatMethod fmMain = state.getMethodFlat(mdSourceEntry); + + // add all methods transitively reachable from the + // source's main to set for analysis + Set descriptorsToAnalyze = callGraph.getAllMethods(mdSourceEntry); + + descriptorsToAnalyze.add(mdSourceEntry); + + analyzeMethods(descriptorsToAnalyze); + + // analyzeMethodsDebug(descriptorsToAnalyze); + } + + protected void analyzeMethods(Set descriptorsToAnalyze) { + + Iterator mdItr = descriptorsToAnalyze.iterator(); + while (mdItr.hasNext()) { + FlatMethod fm = state.getMethodFlat(mdItr.next()); + + Hashtable> fn2seseStatus = + computeRBlockStatus(fm); + + fm2statusmap.put(fm, fn2seseStatus); + } + } + + public Hashtable> computeRBlockStatus( + FlatMethod fm) { + + Hashtable> seseStacks = + new Hashtable>(); + + Hashtable> fn2seseStatus = + new Hashtable>(); + + LinkedList flatNodesToVisit = new LinkedList(); + flatNodesToVisit.add(fm); + + Stack seseStackFirst = new Stack(); + seseStacks.put(fm, seseStackFirst); + + while (!flatNodesToVisit.isEmpty()) { + Iterator fnItr = flatNodesToVisit.iterator(); + FlatNode fn = fnItr.next(); + + Hashtable prevResult = fn2seseStatus.get(fn); + + Hashtable currentResult = + new Hashtable(); + + for (int i = 0; i < fn.numPrev(); i++) { + FlatNode prevFlatNode = fn.getPrev(i); + Hashtable 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 current, + Hashtable 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> statusMap = + fm2statusmap.get(fmContaining); + Hashtable 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 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 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 descriptorsToAnalyze) { + + Iterator mdItr = descriptorsToAnalyze.iterator(); + while (mdItr.hasNext()) { + FlatMethod fm = state.getMethodFlat(mdItr.next()); + printStatusMap(fm); + + } + } + + protected void printStatusMap(FlatMethod fm) { + + Set flatNodesToVisit = new HashSet(); + flatNodesToVisit.add(fm); + + Set visited = new HashSet(); + + while (!flatNodesToVisit.isEmpty()) { + Iterator 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); + + } + } + } + + } + +}