From: jjenista Date: Fri, 11 Nov 2011 00:38:51 +0000 (+0000) Subject: got 2nd case of def reach up and running, one to go X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=99f78adda93990d4a4172c914ab7d23172bd5c59;p=IRC.git got 2nd case of def reach up and running, one to go --- diff --git a/Robust/src/Analysis/Disjoint/DefiniteReachAnalysis.java b/Robust/src/Analysis/Disjoint/DefiniteReachAnalysis.java index e327fcec..90b09b81 100644 --- a/Robust/src/Analysis/Disjoint/DefiniteReachAnalysis.java +++ b/Robust/src/Analysis/Disjoint/DefiniteReachAnalysis.java @@ -41,6 +41,14 @@ public class DefiniteReachAnalysis { } + public Set edgesToElidePropagation( TempDescriptor x, + TempDescriptor y, + FlatNode fn ) { + return makeIn( fn ).edgesToElidePropagation( x, y ); + } + + + private void addPartialResult( FlatNode fn, DefiniteReachState state ) { fn2state.put( fn, state ); fnHasPartial.add( fn ); diff --git a/Robust/src/Analysis/Disjoint/DefiniteReachState.java b/Robust/src/Analysis/Disjoint/DefiniteReachState.java index 72238d9b..09f2ff4d 100644 --- a/Robust/src/Analysis/Disjoint/DefiniteReachState.java +++ b/Robust/src/Analysis/Disjoint/DefiniteReachState.java @@ -51,6 +51,18 @@ public class DefiniteReachState { // // Entries mean x.f points directly at what // y points at. + public class FdEntry { + TempDescriptor y; + FieldDescriptor f0; + TempDescriptor z; + public FdEntry( TempDescriptor y, + FieldDescriptor f0, + TempDescriptor z ) { + this.y = y; + this.f0 = f0; + this.z = z; + } + } private static MultiViewMapBuilder FdBuilder; private static BitSet viewFd0; private static BitSet viewFd2; @@ -122,6 +134,39 @@ public class DefiniteReachState { } + public Set edgesToElidePropagation( TempDescriptor x, + TempDescriptor y ) { + // return the set of edges that definite reach analysis tells + // us we can elide propagating reach info across during the + // store: x.f = y + + Set out = new HashSet(); + + // we have to know something about y + DefReachKnown known = Rs.get( y ); + if( known == null || known == DefReachKnown.UNKNOWN ) { + return out; + } + + // find all 'y points at' entries in Fd + MultiKey keyY = MultiKey.factory( y ); + Map mapY0 = Fd.get( viewFd0, keyY ); + + for( MultiKey fullKeyY : mapY0.keySet() ) { + // if y.f0 points at z, and z is already reachable from x, + // include the edge y.f0->z + FieldDescriptor f0 = (FieldDescriptor) fullKeyY.get( 1 ); + TempDescriptor z = (TempDescriptor) fullKeyY.get( 2 ); + + if( isAlreadyReachable( z, x ) ) { + out.add( new FdEntry( y, f0, z ) ); + } + } + + return out; + } + + public void methodEntry( Set parameters ) { diff --git a/Robust/src/Analysis/Disjoint/DisjointAnalysis.java b/Robust/src/Analysis/Disjoint/DisjointAnalysis.java index 3128519e..99eb4f62 100644 --- a/Robust/src/Analysis/Disjoint/DisjointAnalysis.java +++ b/Robust/src/Analysis/Disjoint/DisjointAnalysis.java @@ -1306,6 +1306,7 @@ public class DisjointAnalysis implements HeapAnalysis { Set edgeKeysForLoad; Set edgeKeysRemoved; Set edgeKeysAdded; + Set edgesToElideFromProp; //Stores the flatnode's reach graph at enter ReachGraph rgOnEnter = new ReachGraph(); @@ -1496,13 +1497,15 @@ public class DisjointAnalysis implements HeapAnalysis { boolean strongUpdate = false; - alreadyReachable = false; - edgeKeysRemoved = null; - edgeKeysAdded = null; + alreadyReachable = false; + edgeKeysRemoved = null; + edgeKeysAdded = null; + edgesToElideFromProp = null; if( doDefiniteReachAnalysis ) { - alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn ); - edgeKeysRemoved = new HashSet(); - edgeKeysAdded = new HashSet(); + alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn ); + edgeKeysRemoved = new HashSet(); + edgeKeysAdded = new HashSet(); + edgesToElideFromProp = definiteReachAnalysis.edgesToElidePropagation( lhs, rhs, fn ); } // before transfer func, possibly inject @@ -1534,7 +1537,8 @@ public class DisjointAnalysis implements HeapAnalysis { fn, alreadyReachable, edgeKeysRemoved, - edgeKeysAdded ); + edgeKeysAdded, + edgesToElideFromProp ); if( doDefiniteReachAnalysis ) { definiteReachAnalysis.store( fn, lhs, @@ -1613,13 +1617,15 @@ public class DisjointAnalysis implements HeapAnalysis { tdElement = lhs.getType().dereference(); fdElement = getArrayField(tdElement); - alreadyReachable = false; - edgeKeysRemoved = null; - edgeKeysAdded = null; + alreadyReachable = false; + edgeKeysRemoved = null; + edgeKeysAdded = null; + edgesToElideFromProp = null; if( doDefiniteReachAnalysis ) { - alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn ); - edgeKeysRemoved = new HashSet(); - edgeKeysAdded = new HashSet(); + alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn ); + edgeKeysRemoved = new HashSet(); + edgeKeysAdded = new HashSet(); + edgesToElideFromProp = definiteReachAnalysis.edgesToElidePropagation( lhs, rhs, fn ); } // before transfer func, possibly inject @@ -1653,7 +1659,8 @@ public class DisjointAnalysis implements HeapAnalysis { fn, alreadyReachable, edgeKeysRemoved, - edgeKeysAdded ); + edgeKeysAdded, + edgesToElideFromProp ); } if( doDefiniteReachAnalysis ) { diff --git a/Robust/src/Analysis/Disjoint/ReachGraph.java b/Robust/src/Analysis/Disjoint/ReachGraph.java index 8de46b97..7a4522d7 100644 --- a/Robust/src/Analysis/Disjoint/ReachGraph.java +++ b/Robust/src/Analysis/Disjoint/ReachGraph.java @@ -428,6 +428,7 @@ public class ReachGraph { null, false, null, + null, null ); } @@ -597,7 +598,8 @@ public class ReachGraph { FlatNode currentProgramPoint, boolean alreadyReachable, Set edgeKeysRemoved, - Set edgeKeysAdded + Set edgeKeysAdded, + Set edgesToElideFromPropFd ) { VariableNode lnX = getVariableNodeFromTemp(x); @@ -644,6 +646,51 @@ public class ReachGraph { } + // definite reachability analysis can elide some edges from + // propagating reach information + Set edgesToElideFromProp = null; + if( edgesToElideFromPropFd != null ) { + edgesToElideFromProp = new HashSet(); + Iterator itrY = lnY.iteratorToReferencees(); + while( itrY.hasNext() ) { + HeapRegionNode hrnSrc = itrY.next().getDst(); + + Iterator itrhrn = hrnSrc.iteratorToReferencees(); + while( itrhrn.hasNext() ) { + RefEdge edgeToElide = itrhrn.next(); + String f0 = edgeToElide.getField(); + HeapRegionNode hrnDst = edgeToElide.getDst(); + + // does this graph edge match a statically-named edge + // that def reach says we don't have to prop over? + for( DefiniteReachState.FdEntry entry : edgesToElideFromPropFd ) { + if( !entry.f0.getSymbol().equals( f0 ) ) { + continue; + } + boolean refByZ = false; + Iterator itrRef = hrnDst.iteratorToReferencers(); + while( itrRef.hasNext() ) { + RefEdge edgeZ = itrRef.next(); + if( edgeZ.getSrc() instanceof VariableNode ) { + VariableNode vnZ = (VariableNode) edgeZ.getSrc(); + if( vnZ.getTempDescriptor().equals( entry.z ) ) { + refByZ = true; + break; + } + } + } + if( refByZ ) { + // this graph edge matches the def reach edge, mark it for + // no propagation + edgesToElideFromProp.add( edgeToElide ); + } + } + } + } + } + + + // definite reachability analysis can elide reachability propagation if( !alreadyReachable ) { @@ -672,7 +719,11 @@ public class ReachGraph { // propagate tokens over nodes starting from hrnSrc, and it will // take care of propagating back up edges from any touched nodes ChangeSet Cy = Canonical.unionUpArityToChangeSet(O, R); - propagateTokensOverNodes(hrnY, Cy, nodesWithNewAlpha, edgesWithNewBeta); + propagateTokensOverNodes( hrnY, + Cy, + nodesWithNewAlpha, + edgesWithNewBeta, + edgesToElideFromProp ); // then propagate back just up the edges from hrn ChangeSet Cx = Canonical.unionUpArityToChangeSet(R, O); @@ -688,9 +739,10 @@ public class ReachGraph { edgePlannedChanges.put(edgeUpstream, Cx); } - propagateTokensOverEdges(todoEdges, - edgePlannedChanges, - edgesWithNewBeta); + propagateTokensOverEdges( todoEdges, + edgePlannedChanges, + edgesWithNewBeta, + edgesToElideFromProp ); } } } @@ -1187,7 +1239,8 @@ public class ReachGraph { protected void propagateTokensOverNodes(HeapRegionNode nPrime, ChangeSet c0, HashSet nodesWithNewAlpha, - HashSet edgesWithNewBeta) { + HashSet edgesWithNewBeta, + Set edgesToElideProp ) { HashSet todoNodes = new HashSet(); @@ -1211,6 +1264,10 @@ public class ReachGraph { Iterator referItr = n.iteratorToReferencers(); while( referItr.hasNext() ) { RefEdge edge = referItr.next(); + + if( edgesToElideProp != null && edgesToElideProp.contains( edge ) ) { + continue; + } todoEdges.add(edge); if( !edgePlannedChanges.containsKey(edge) ) { @@ -1229,6 +1286,11 @@ public class ReachGraph { Iterator refeeItr = n.iteratorToReferencees(); while( refeeItr.hasNext() ) { RefEdge edgeF = refeeItr.next(); + + if( edgesToElideProp != null && edgesToElideProp.contains( edgeF ) ) { + continue; + } + HeapRegionNode m = edgeF.getDst(); ChangeSet changesToPass = ChangeSet.factory(); @@ -1291,14 +1353,15 @@ public class ReachGraph { propagateTokensOverEdges(todoEdges, edgePlannedChanges, - edgesWithNewBeta - ); + edgesWithNewBeta, + edgesToElideProp); } protected void propagateTokensOverEdges(HashSet todoEdges, Hashtable edgePlannedChanges, - HashSet edgesWithNewBeta) { + HashSet edgesWithNewBeta, + Set edgesToElideProp ) { // first propagate all change tuples everywhere they can go while( !todoEdges.isEmpty() ) { @@ -1334,6 +1397,10 @@ public class ReachGraph { while( referItr.hasNext() ) { RefEdge edgeF = referItr.next(); + if( edgesToElideProp != null && edgesToElideProp.contains( edgeF ) ) { + continue; + } + if( !edgePlannedChanges.containsKey(edgeF) ) { edgePlannedChanges.put(edgeF, ChangeSet.factory() @@ -2920,9 +2987,10 @@ public class ReachGraph { // of the caller graph edges HashSet edgesUpdated = new HashSet(); - propagateTokensOverEdges(edgesForPropagation, // source edges - edgePlannedChanges, // map src edge to change set - edgesUpdated); // list of updated edges + propagateTokensOverEdges( edgesForPropagation, // source edges + edgePlannedChanges, // map src edge to change set + edgesUpdated, // list of updated edges + null ); // commit beta' (beta<-betaNew) Iterator edgeItr = edgesUpdated.iterator(); @@ -3555,7 +3623,8 @@ public class ReachGraph { propagateTokensOverEdges(edgesForPropagation, edgePlannedChanges, - edgesUpdated); + edgesUpdated, + null); // at the end of the 1st phase reference edges have // beta, betaNew that correspond to beta and betaR