From: jjenista Date: Thu, 9 Apr 2009 16:30:59 +0000 (+0000) Subject: stable introduction of mlp analysis, infrastructure for variable analysis in place X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=069411fae418c98aeae537e1b028c405f4a3abb0;p=IRC.git stable introduction of mlp analysis, infrastructure for variable analysis in place --- diff --git a/Robust/src/Analysis/MLP/MLPAnalysis.java b/Robust/src/Analysis/MLP/MLPAnalysis.java index 2970bd92..27c3921e 100644 --- a/Robust/src/Analysis/MLP/MLPAnalysis.java +++ b/Robust/src/Analysis/MLP/MLPAnalysis.java @@ -16,11 +16,16 @@ public class MLPAnalysis { private CallGraph callGraph; private OwnershipAnalysis ownAnalysis; - public MLPAnalysis(State state, - TypeUtil tu, - CallGraph callGraph, - OwnershipAnalysis ownAnalysis - ) { + + private Stack seseStack; + private Set seseRoots; + + + public MLPAnalysis( State state, + TypeUtil tu, + CallGraph callGraph, + OwnershipAnalysis ownAnalysis + ) { double timeStartAnalysis = (double) System.nanoTime(); @@ -29,6 +34,39 @@ public class MLPAnalysis { this.callGraph = callGraph; this.ownAnalysis = ownAnalysis; + // initialize analysis data structures + seseStack = new Stack (); + seseRoots = new HashSet(); + + // run analysis on each method that is actually called + // reachability analysis already computed this so reuse + Iterator methItr = ownAnalysis.descriptorsToAnalyze.iterator(); + while( methItr.hasNext() ) { + Descriptor d = methItr.next(); + + FlatMethod fm; + if( d instanceof MethodDescriptor ) { + fm = state.getMethodFlat( (MethodDescriptor) d); + } else { + assert d instanceof TaskDescriptor; + fm = state.getMethodFlat( (TaskDescriptor) d); + } + + // find every SESE from methods that may be called + // and organize them into roots and children + buildForestForward( fm ); + } + + Iterator seseItr = seseRoots.iterator(); + while( seseItr.hasNext() ) { + FlatSESEEnterNode fsen = seseItr.next(); + + // do a post-order traversal of the forest so that + // a child is analyzed before a parent. Start from + // SESE's exit and do a backward data-flow analysis + // for the source of variables + computeReadAndWriteSetBackward( fsen ); + } double timeEndAnalysis = (double) System.nanoTime(); double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) ); @@ -37,43 +75,192 @@ public class MLPAnalysis { } - Stack seseStack; + private void buildForestForward( FlatMethod fm ) { - protected void analyze() { - seseStack = new Stack(); + Set flatNodesToVisit = new HashSet(); + flatNodesToVisit.add( fm ); - /* - if( !seseStack.empty() ) { - seseStack.peek().addInVar( tmp ); - seseStack.peek().addOutVar( out_temp ); + Set visited = new HashSet(); + + while( !flatNodesToVisit.isEmpty() ) { + FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next(); + flatNodesToVisit.remove( fn ); + visited.add( fn ); + + //System.out.println( " "+fn ); + + analyzeFlatNode( fn, true ); + + for( int i = 0; i < fn.numNext(); i++ ) { + FlatNode nn = fn.getNext( i ); + + if( !visited.contains( nn ) ) { + flatNodesToVisit.add( nn ); + } } - */ + } + } - /* - if( !seseStack.empty() ) { - throw new Error("Error: return statement enclosed within SESE "+seseStack.peek()); + + private void computeReadAndWriteSetBackward( FlatSESEEnterNode fsen ) { + + } + + + private void analyzeFlatNode( FlatNode fn, boolean buildForest ) { + + TempDescriptor lhs; + TempDescriptor rhs; + FieldDescriptor fld; + + // use node type to decide what alterations to make + // to the ownership graph + switch( fn.kind() ) { + + case FKind.FlatSESEEnterNode: { + FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn; + + if( buildForest ) { + if( seseStack.empty() ) { + seseRoots.add( fsen ); + } else { + seseStack.peek().addChild( fsen ); + } + seseStack.push( fsen ); } - */ - - /* - if( sn.isStart() ) { - FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn); - sn.setFlatEnter(fsen); - seseStack.push(fsen); - return new NodePair(fsen, fsen); - } + } break; - FlatSESEExitNode fsexn=new FlatSESEExitNode(sn); - sn.setFlatExit(fsexn); - FlatSESEEnterNode fsen=sn.getStart().getFlatEnter(); - fsexn.setFlatEnter(fsen); - sn.getStart().getFlatEnter().setFlatExit( fsexn ); - assert !seseStack.empty(); - assert fsen == seseStack.pop(); - if( !seseStack.empty() ) { - seseStack.peek().addInVarSet ( fsen.getInVarSet() ); - seseStack.peek().addOutVarSet( fsen.getOutVarSet() ); - } - */ + case FKind.FlatSESEExitNode: { + FlatSESEExitNode fsexn = (FlatSESEExitNode) fn; + + if( buildForest ) { + assert !seseStack.empty(); + seseStack.pop(); + } + + //FlatSESEEnterNode fsen = fsexn.getFlatEnter(); + //assert fsen == seseStack.pop(); + //seseStack.peek().addInVarSet ( fsen.getInVarSet() ); + //seseStack.peek().addOutVarSet( fsen.getOutVarSet() ); + } break; + + /* + case FKind.FlatMethod: { + FlatMethod fm = (FlatMethod) fn; + } break; + + case FKind.FlatOpNode: { + FlatOpNode fon = (FlatOpNode) fn; + if( fon.getOp().getOp() == Operation.ASSIGN ) { + lhs = fon.getDest(); + rhs = fon.getLeft(); + + } + } break; + + case FKind.FlatCastNode: { + FlatCastNode fcn = (FlatCastNode) fn; + lhs = fcn.getDst(); + rhs = fcn.getSrc(); + + TypeDescriptor td = fcn.getType(); + assert td != null; + + } break; + + case FKind.FlatFieldNode: { + FlatFieldNode ffn = (FlatFieldNode) fn; + lhs = ffn.getDst(); + rhs = ffn.getSrc(); + fld = ffn.getField(); + if( !fld.getType().isImmutable() || fld.getType().isArray() ) { + + } + } break; + + case FKind.FlatSetFieldNode: { + FlatSetFieldNode fsfn = (FlatSetFieldNode) fn; + lhs = fsfn.getDst(); + fld = fsfn.getField(); + rhs = fsfn.getSrc(); + if( !fld.getType().isImmutable() || fld.getType().isArray() ) { + + } + } break; + + case FKind.FlatElementNode: { + FlatElementNode fen = (FlatElementNode) fn; + lhs = fen.getDst(); + rhs = fen.getSrc(); + if( !lhs.getType().isImmutable() || lhs.getType().isArray() ) { + + assert rhs.getType() != null; + assert rhs.getType().isArray(); + + TypeDescriptor tdElement = rhs.getType().dereference(); + //FieldDescriptor fdElement = getArrayField( tdElement ); + + } + } break; + + case FKind.FlatSetElementNode: { + FlatSetElementNode fsen = (FlatSetElementNode) fn; + lhs = fsen.getDst(); + rhs = fsen.getSrc(); + if( !rhs.getType().isImmutable() || rhs.getType().isArray() ) { + + assert lhs.getType() != null; + assert lhs.getType().isArray(); + + TypeDescriptor tdElement = lhs.getType().dereference(); + //FieldDescriptor fdElement = getArrayField( tdElement ); + } + } break; + + case FKind.FlatNew: { + FlatNew fnn = (FlatNew) fn; + lhs = fnn.getDst(); + if( !lhs.getType().isImmutable() || lhs.getType().isArray() ) { + //AllocationSite as = getAllocationSiteFromFlatNewPRIVATE( fnn ); + } + } break; + + case FKind.FlatCall: { + FlatCall fc = (FlatCall) fn; + MethodDescriptor md = fc.getMethod(); + FlatMethod flatm = state.getMethodFlat( md ); + + + if( md.isStatic() ) { + + } else { + // if the method descriptor is virtual, then there could be a + // set of possible methods that will actually be invoked, so + // find all of them and merge all of their results together + TypeDescriptor typeDesc = fc.getThis().getType(); + Set possibleCallees = callGraph.getMethods( md, typeDesc ); + + Iterator i = possibleCallees.iterator(); + while( i.hasNext() ) { + MethodDescriptor possibleMd = (MethodDescriptor) i.next(); + FlatMethod pflatm = state.getMethodFlat( possibleMd ); + + } + } + + } break; + + case FKind.FlatReturnNode: { + FlatReturnNode frn = (FlatReturnNode) fn; + rhs = frn.getReturnTemp(); + if( rhs != null && !rhs.getType().isImmutable() ) { + + } + if( !seseStack.empty() ) { + throw new Error( "Error: return statement enclosed within SESE "+seseStack.peek() ); + } + } break; + */ + } // end switch } } diff --git a/Robust/src/Analysis/MLP/VariableSourceToken.java b/Robust/src/Analysis/MLP/VariableSourceToken.java new file mode 100644 index 00000000..fe43742a --- /dev/null +++ b/Robust/src/Analysis/MLP/VariableSourceToken.java @@ -0,0 +1,58 @@ +package Analysis.MLP; + +import IR.*; +import IR.Flat.*; +import java.util.*; +import java.io.*; + +public class VariableSourceToken { + + private FlatSESEEnterNode sese; + private TempDescriptor var; + private Integer age; + + public VariableSourceToken( FlatSESEEnterNode sese, + TempDescriptor var, + Integer age ) { + this.sese = sese; + this.var = var; + this.age = age; + } + + public FlatSESEEnterNode getSESE() { + return sese; + } + + public TempDescriptor getVar() { + return var; + } + + public Integer getAge() { + return age; + } + + + public boolean equals( Object o ) { + if( o == null ) { + return false; + } + + if( !(o instanceof VariableSourceToken) ) { + return false; + } + + VariableSourceToken vst = (VariableSourceToken) o; + + return var.equals( vst.var ) && + age.equals( vst.age ); + } + + public int hashCode() { + return (var.hashCode() << 2) ^ age.intValue(); + } + + + public String toString() { + return "["+var+", "+age+"]"; + } +} diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java index 14a099bf..df464d43 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java @@ -294,7 +294,7 @@ public class OwnershipAnalysis { // descriptorsToAnalyze identifies the set of tasks and methods // that are reachable from the program tasks, this set is initialized // and then remains static - private HashSet descriptorsToAnalyze; + public HashSet descriptorsToAnalyze; // descriptorsToVisit is initialized to descriptorsToAnalyze and is // reduced by visiting a descriptor during analysis. When dependents diff --git a/Robust/src/IR/Flat/FlatSESEEnterNode.java b/Robust/src/IR/Flat/FlatSESEEnterNode.java index 46cb62c8..1373659c 100644 --- a/Robust/src/IR/Flat/FlatSESEEnterNode.java +++ b/Robust/src/IR/Flat/FlatSESEEnterNode.java @@ -1,21 +1,24 @@ package IR.Flat; +import Analysis.MLP.VariableSourceToken; import IR.Tree.SESENode; -import java.util.HashSet; +import java.util.*; public class FlatSESEEnterNode extends FlatNode { private static int identifier=0; private int id; protected FlatSESEExitNode exit; protected SESENode treeNode; - protected HashSet inVars; - protected HashSet outVars; + protected Set children; + protected Set inVars; + protected Set outVars; protected FlatMethod enclosing; public FlatSESEEnterNode( SESENode sn ) { this.id = identifier++; treeNode = sn; - inVars = new HashSet(); - outVars = new HashSet(); + children = new HashSet(); + inVars = new HashSet(); + outVars = new HashSet(); } public void rewriteUse() { @@ -24,27 +27,35 @@ public class FlatSESEEnterNode extends FlatNode { public void rewriteDef() { } - public void addInVar( TempDescriptor td ) { - inVars.add( td ); + public void addChild( FlatSESEEnterNode child ) { + children.add( child ); } - public void addOutVar( TempDescriptor td ) { - outVars.add( td ); + public Set getChildren() { + return children; } - public void addInVarSet( HashSet s ) { + public void addInVar( VariableSourceToken vst ) { + inVars.add( vst ); + } + + public void addOutVar( VariableSourceToken vst ) { + outVars.add( vst ); + } + + public void addInVarSet( Set s ) { inVars.addAll( s ); } - public void addOutVarSet( HashSet s ) { + public void addOutVarSet( Set s ) { outVars.addAll( s ); } - public HashSet getInVarSet() { + public Set getInVarSet() { return inVars; } - public HashSet getOutVarSet() { + public Set getOutVarSet() { return outVars; } diff --git a/Robust/src/IR/Flat/FlatSESEExitNode.java b/Robust/src/IR/Flat/FlatSESEExitNode.java index eb77cbce..61b968db 100644 --- a/Robust/src/IR/Flat/FlatSESEExitNode.java +++ b/Robust/src/IR/Flat/FlatSESEExitNode.java @@ -21,7 +21,7 @@ public class FlatSESEExitNode extends FlatNode { enter = fsen; } - public FlatSESEEnterNode getSESEEnter() { + public FlatSESEEnterNode getFlatEnter() { return enter; }