3 import Analysis.CallGraph.*;
4 import Analysis.OwnershipAnalysis.*;
12 public class MLPAnalysis {
14 // data from the compiler
16 private TypeUtil typeUtil;
17 private CallGraph callGraph;
18 private OwnershipAnalysis ownAnalysis;
20 private SESENode rootTree;
21 private FlatSESEEnterNode rootSESE;
22 private FlatSESEExitNode rootExit;
24 private Set<FlatSESEEnterNode> allSESEs;
26 private Hashtable< FlatNode, Stack<FlatSESEEnterNode> > seseStacks;
27 private Hashtable< FlatNode, Set<TempDescriptor> > livenessRootView;
28 private Hashtable< FlatNode, Set<TempDescriptor> > livenessVirtualReads;
29 private Hashtable< FlatNode, VarSrcTokTable > variableResults;
30 private Hashtable< FlatNode, Set<TempDescriptor> > notAvailableResults;
31 private Hashtable< FlatNode, CodePlan > codePlans;
34 // use these methods in BuildCode to have access to analysis results
35 public Set<FlatSESEEnterNode> getAllSESEs() {
39 public CodePlan getCodePlan( FlatNode fn ) {
40 CodePlan cp = codePlans.get( fn );
46 public MLPAnalysis( State state,
49 OwnershipAnalysis ownAnalysis
52 double timeStartAnalysis = (double) System.nanoTime();
56 this.callGraph = callGraph;
57 this.ownAnalysis = ownAnalysis;
59 // initialize analysis data structures
60 allSESEs = new HashSet<FlatSESEEnterNode>();
62 seseStacks = new Hashtable< FlatNode, Stack<FlatSESEEnterNode> >();
63 livenessVirtualReads = new Hashtable< FlatNode, Set<TempDescriptor> >();
64 variableResults = new Hashtable< FlatNode, VarSrcTokTable >();
65 notAvailableResults = new Hashtable< FlatNode, Set<TempDescriptor> >();
66 codePlans = new Hashtable< FlatNode, CodePlan >();
69 // build an implicit root SESE to wrap contents of main method
70 rootTree = new SESENode( "root" );
71 rootSESE = new FlatSESEEnterNode( rootTree );
72 rootExit = new FlatSESEExitNode ( rootTree );
73 rootSESE.setFlatExit ( rootExit );
74 rootExit.setFlatEnter( rootSESE );
76 FlatMethod fmMain = state.getMethodFlat( tu.getMain() );
80 // run analysis on each method that is actually called
81 // reachability analysis already computed this so reuse
82 Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
83 while( methItr.hasNext() ) {
84 Descriptor d = methItr.next();
85 FlatMethod fm = state.getMethodFlat( d );
87 // find every SESE from methods that may be called
88 // and organize them into roots and children
89 buildForestForward( fm );
93 // 2nd pass, results are saved in FlatSESEEnterNode, so
94 // intermediate results, for safety, are discarded
95 livenessAnalysisBackward( rootSESE, true, null, fmMain.getFlatExit() );
99 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
100 while( methItr.hasNext() ) {
101 Descriptor d = methItr.next();
102 FlatMethod fm = state.getMethodFlat( d );
104 // starting from roots do a forward, fixed-point
105 // variable analysis for refinement and stalls
106 variableAnalysisForward( fm );
110 // 4th pass, compute liveness contribution from
111 // virtual reads discovered in variable pass
112 livenessAnalysisBackward( rootSESE, true, null, fmMain.getFlatExit() );
116 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
117 while( methItr.hasNext() ) {
118 Descriptor d = methItr.next();
119 FlatMethod fm = state.getMethodFlat( d );
121 // compute what is not available at every program
122 // point, in a forward fixed-point pass
123 notAvailableForward( fm );
128 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
129 while( methItr.hasNext() ) {
130 Descriptor d = methItr.next();
131 FlatMethod fm = state.getMethodFlat( d );
133 // compute a plan for code injections
134 computeStallsForward( fm );
138 double timeEndAnalysis = (double) System.nanoTime();
139 double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
140 String treport = String.format( "The mlp analysis took %.3f sec.", dt );
141 System.out.println( treport );
145 private void buildForestForward( FlatMethod fm ) {
147 // start from flat method top, visit every node in
148 // method exactly once, find SESEs and remember
149 // roots and child relationships
150 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
151 flatNodesToVisit.add( fm );
153 Set<FlatNode> visited = new HashSet<FlatNode>();
155 Stack<FlatSESEEnterNode> seseStackFirst = new Stack<FlatSESEEnterNode>();
156 seseStackFirst.push( rootSESE );
157 seseStacks.put( fm, seseStackFirst );
159 while( !flatNodesToVisit.isEmpty() ) {
160 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
161 FlatNode fn = fnItr.next();
163 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
164 assert seseStack != null;
166 flatNodesToVisit.remove( fn );
169 buildForest_nodeActions( fn, seseStack, fm );
171 for( int i = 0; i < fn.numNext(); i++ ) {
172 FlatNode nn = fn.getNext( i );
174 if( !visited.contains( nn ) ) {
175 flatNodesToVisit.add( nn );
177 // clone stack and send along each analysis path
178 seseStacks.put( nn, (Stack<FlatSESEEnterNode>)seseStack.clone() );
183 if( state.MLPDEBUG ) {
188 private void buildForest_nodeActions( FlatNode fn,
189 Stack<FlatSESEEnterNode> seseStack,
191 switch( fn.kind() ) {
193 case FKind.FlatSESEEnterNode: {
194 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
196 allSESEs.add( fsen );
197 fsen.setEnclosingFlatMeth( fm );
199 assert !seseStack.empty();
200 seseStack.peek().addChild( fsen );
201 fsen.setParent( seseStack.peek() );
202 seseStack.push( fsen );
205 case FKind.FlatSESEExitNode: {
206 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
207 assert !seseStack.empty();
208 FlatSESEEnterNode fsen = seseStack.pop();
211 case FKind.FlatReturnNode: {
212 FlatReturnNode frn = (FlatReturnNode) fn;
213 if( !seseStack.empty() &&
214 !seseStack.peek().equals( rootSESE ) ) {
215 throw new Error( "Error: return statement enclosed within "+seseStack.peek() );
222 private void printSESEForest() {
223 // our forest is actually a tree now that
224 // there is an implicit root SESE
225 printSESETree( rootSESE, 0 );
226 System.out.println( "" );
229 private void printSESETree( FlatSESEEnterNode fsen, int depth ) {
230 for( int i = 0; i < depth; ++i ) {
231 System.out.print( " " );
233 System.out.println( fsen.getPrettyIdentifier() );
235 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
236 while( childItr.hasNext() ) {
237 FlatSESEEnterNode fsenChild = childItr.next();
238 printSESETree( fsenChild, depth + 1 );
243 private void livenessAnalysisBackward( FlatSESEEnterNode fsen,
245 Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout,
248 // start from an SESE exit, visit nodes in reverse up to
249 // SESE enter in a fixed-point scheme, where children SESEs
250 // should already be analyzed and therefore can be skipped
251 // because child SESE enter node has all necessary info
252 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
254 FlatSESEExitNode fsexn = fsen.getFlatExit();
257 flatNodesToVisit.add( fexit );
259 flatNodesToVisit.add( fsexn );
260 Hashtable<FlatNode, Set<TempDescriptor>> livenessResults=new Hashtable<FlatNode, Set<TempDescriptor>>();
263 liveout=new Hashtable<FlatSESEExitNode, Set<TempDescriptor>>();
265 while( !flatNodesToVisit.isEmpty() ) {
266 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
267 flatNodesToVisit.remove( fn );
269 Set<TempDescriptor> prev = livenessResults.get( fn );
271 // merge sets from control flow joins
272 Set<TempDescriptor> u = new HashSet<TempDescriptor>();
273 for( int i = 0; i < fn.numNext(); i++ ) {
274 FlatNode nn = fn.getNext( i );
275 Set<TempDescriptor> s = livenessResults.get( nn );
281 Set<TempDescriptor> curr = liveness_nodeActions( fn, u, fsen, toplevel, liveout);
283 // if a new result, schedule backward nodes for analysis
284 if(!curr.equals(prev)) {
285 livenessResults.put( fn, curr );
287 // don't flow backwards past current SESE enter
288 if( !fn.equals( fsen ) ) {
289 for( int i = 0; i < fn.numPrev(); i++ ) {
290 FlatNode nn = fn.getPrev( i );
291 flatNodesToVisit.add( nn );
297 Set<TempDescriptor> s = livenessResults.get( fsen );
299 fsen.addInVarSet( s );
302 if( state.MLPDEBUG ) {
303 System.out.println( "SESE "+fsen.getPrettyIdentifier()+" has in-set:" );
304 Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
305 while( tItr.hasNext() ) {
306 System.out.println( " "+tItr.next() );
308 System.out.println( "and out-set:" );
309 tItr = fsen.getOutVarSet().iterator();
310 while( tItr.hasNext() ) {
311 System.out.println( " "+tItr.next() );
313 System.out.println( "" );
316 // remember liveness per node from the root view as the
317 // global liveness of variables for later passes to use
318 if( toplevel == true ) {
319 livenessRootView = livenessResults;
322 // post-order traversal, so do children first
323 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
324 while( childItr.hasNext() ) {
325 FlatSESEEnterNode fsenChild = childItr.next();
326 livenessAnalysisBackward( fsenChild, false, liveout, null);
330 private Set<TempDescriptor> liveness_nodeActions( FlatNode fn,
331 Set<TempDescriptor> liveIn,
332 FlatSESEEnterNode currentSESE,
334 Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout ) {
336 switch( fn.kind() ) {
338 case FKind.FlatSESEExitNode:
339 if (toplevel==true) {
340 FlatSESEExitNode exitn=(FlatSESEExitNode) fn;
341 //update liveout set for FlatSESEExitNode
342 if (!liveout.containsKey(exitn))
343 liveout.put(exitn, new HashSet<TempDescriptor>());
344 liveout.get(exitn).addAll(liveIn);
346 // no break, sese exits should also execute default actions
349 // handle effects of statement in reverse, writes then reads
350 TempDescriptor [] writeTemps = fn.writesTemps();
351 for( int i = 0; i < writeTemps.length; ++i ) {
352 liveIn.remove( writeTemps[i] );
355 FlatSESEExitNode exitnode=currentSESE.getFlatExit();
356 Set<TempDescriptor> livetemps=liveout.get(exitnode);
357 if (livetemps.contains(writeTemps[i])) {
358 //write to a live out temp...
359 //need to put in SESE liveout set
360 currentSESE.addOutVar(writeTemps[i]);
365 TempDescriptor [] readTemps = fn.readsTemps();
366 for( int i = 0; i < readTemps.length; ++i ) {
367 liveIn.add( readTemps[i] );
370 Set<TempDescriptor> virtualReadTemps = livenessVirtualReads.get( fn );
371 if( virtualReadTemps != null ) {
372 Iterator<TempDescriptor> vrItr = virtualReadTemps.iterator();
373 while( vrItr.hasNext() ) {
374 TempDescriptor vrt = vrItr.next();
386 private void variableAnalysisForward( FlatMethod fm ) {
388 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
389 flatNodesToVisit.add( fm );
391 while( !flatNodesToVisit.isEmpty() ) {
392 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
393 flatNodesToVisit.remove( fn );
395 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
396 assert seseStack != null;
398 VarSrcTokTable prev = variableResults.get( fn );
400 // merge sets from control flow joins
401 VarSrcTokTable inUnion = new VarSrcTokTable();
402 for( int i = 0; i < fn.numPrev(); i++ ) {
403 FlatNode nn = fn.getPrev( i );
404 VarSrcTokTable incoming = variableResults.get( nn );
405 inUnion.merge( incoming );
408 VarSrcTokTable curr = variable_nodeActions( fn, inUnion, seseStack.peek() );
410 // if a new result, schedule forward nodes for analysis
411 if( !curr.equals( prev ) ) {
412 variableResults.put( fn, curr );
414 for( int i = 0; i < fn.numNext(); i++ ) {
415 FlatNode nn = fn.getNext( i );
416 flatNodesToVisit.add( nn );
422 private VarSrcTokTable variable_nodeActions( FlatNode fn,
423 VarSrcTokTable vstTable,
424 FlatSESEEnterNode currentSESE ) {
425 switch( fn.kind() ) {
427 case FKind.FlatSESEEnterNode: {
428 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
429 assert fsen.equals( currentSESE );
430 vstTable.age( currentSESE );
431 vstTable.assertConsistency();
434 case FKind.FlatSESEExitNode: {
435 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
436 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
437 assert currentSESE.getChildren().contains( fsen );
438 vstTable.remapChildTokens( fsen );
440 Set<TempDescriptor> liveIn = currentSESE.getInVarSet();
441 Set<TempDescriptor> virLiveIn = vstTable.removeParentAndSiblingTokens( fsen, liveIn );
442 Set<TempDescriptor> virLiveInOld = livenessVirtualReads.get( fn );
443 if( virLiveInOld != null ) {
444 virLiveIn.addAll( virLiveInOld );
446 livenessVirtualReads.put( fn, virLiveIn );
447 vstTable.assertConsistency();
450 case FKind.FlatOpNode: {
451 FlatOpNode fon = (FlatOpNode) fn;
453 if( fon.getOp().getOp() == Operation.ASSIGN ) {
454 TempDescriptor lhs = fon.getDest();
455 TempDescriptor rhs = fon.getLeft();
457 vstTable.remove( lhs );
459 Set<VariableSourceToken> forAddition = new HashSet<VariableSourceToken>();
461 Iterator<VariableSourceToken> itr = vstTable.get( rhs ).iterator();
462 while( itr.hasNext() ) {
463 VariableSourceToken vst = itr.next();
465 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
468 // if this is from a child, keep the source information
469 if( currentSESE.getChildren().contains( vst.getSESE() ) ) {
470 forAddition.add( new VariableSourceToken( ts,
477 // otherwise, it's our or an ancestor's token so we
478 // can assume we have everything we need
480 forAddition.add( new VariableSourceToken( ts,
489 vstTable.addAll( forAddition );
491 // only break if this is an ASSIGN op node,
492 // otherwise fall through to default case
493 vstTable.assertConsistency();
498 // note that FlatOpNode's that aren't ASSIGN
499 // fall through to this default case
501 TempDescriptor [] writeTemps = fn.writesTemps();
502 if( writeTemps.length > 0 ) {
503 assert writeTemps.length == 1;
505 vstTable.remove( writeTemps[0] );
507 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
508 ts.add( writeTemps[0] );
510 vstTable.add( new VariableSourceToken( ts,
518 vstTable.assertConsistency();
527 private void notAvailableForward( FlatMethod fm ) {
529 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
530 flatNodesToVisit.add( fm );
532 while( !flatNodesToVisit.isEmpty() ) {
533 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
534 flatNodesToVisit.remove( fn );
536 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
537 assert seseStack != null;
539 Set<TempDescriptor> prev = notAvailableResults.get( fn );
541 Set<TempDescriptor> inUnion = new HashSet<TempDescriptor>();
542 for( int i = 0; i < fn.numPrev(); i++ ) {
543 FlatNode nn = fn.getPrev( i );
544 Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
545 if( notAvailIn != null ) {
546 inUnion.addAll( notAvailIn );
550 Set<TempDescriptor> curr = notAvailable_nodeActions( fn, inUnion, seseStack.peek() );
552 // if a new result, schedule forward nodes for analysis
553 if( !curr.equals( prev ) ) {
554 notAvailableResults.put( fn, curr );
556 for( int i = 0; i < fn.numNext(); i++ ) {
557 FlatNode nn = fn.getNext( i );
558 flatNodesToVisit.add( nn );
564 private Set<TempDescriptor> notAvailable_nodeActions( FlatNode fn,
565 Set<TempDescriptor> notAvailSet,
566 FlatSESEEnterNode currentSESE ) {
568 // any temps that are removed from the not available set
569 // at this node should be marked in this node's code plan
570 // as temps to be grabbed at runtime!
572 switch( fn.kind() ) {
574 case FKind.FlatSESEEnterNode: {
575 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
576 assert fsen.equals( currentSESE );
580 case FKind.FlatSESEExitNode: {
581 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
582 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
583 assert currentSESE.getChildren().contains( fsen );
585 Set<TempDescriptor> liveTemps = livenessRootView.get( fn );
586 assert liveTemps != null;
588 VarSrcTokTable vstTable = variableResults.get( fn );
589 assert vstTable != null;
591 Set<TempDescriptor> notAvailAtEnter = notAvailableResults.get( fsen );
592 assert notAvailAtEnter != null;
594 Iterator<TempDescriptor> tdItr = liveTemps.iterator();
595 while( tdItr.hasNext() ) {
596 TempDescriptor td = tdItr.next();
598 if( vstTable.get( fsen, td ).size() > 0 ) {
599 // there is at least one child token for this variable
600 notAvailSet.add( td );
604 if( notAvailAtEnter.contains( td ) ) {
605 // wasn't available at enter, not available now
606 notAvailSet.add( td );
612 case FKind.FlatOpNode: {
613 FlatOpNode fon = (FlatOpNode) fn;
615 if( fon.getOp().getOp() == Operation.ASSIGN ) {
616 TempDescriptor lhs = fon.getDest();
617 TempDescriptor rhs = fon.getLeft();
619 // copy makes lhs same availability as rhs
620 if( notAvailSet.contains( rhs ) ) {
621 notAvailSet.add( lhs );
623 notAvailSet.remove( lhs );
626 // only break if this is an ASSIGN op node,
627 // otherwise fall through to default case
632 // note that FlatOpNode's that aren't ASSIGN
633 // fall through to this default case
635 TempDescriptor [] writeTemps = fn.writesTemps();
636 for( int i = 0; i < writeTemps.length; i++ ) {
637 TempDescriptor wTemp = writeTemps[i];
638 notAvailSet.remove( wTemp );
640 TempDescriptor [] readTemps = fn.readsTemps();
641 for( int i = 0; i < readTemps.length; i++ ) {
642 TempDescriptor rTemp = readTemps[i];
643 notAvailSet.remove( rTemp );
645 // if this variable has exactly one source, mark everything
646 // else from that source as available as well
647 VarSrcTokTable table = variableResults.get( fn );
648 Set<VariableSourceToken> srcs = table.get( rTemp );
650 if( srcs.size() == 1 ) {
651 VariableSourceToken vst = srcs.iterator().next();
653 Iterator<VariableSourceToken> availItr = table.get( vst.getSESE(),
656 while( availItr.hasNext() ) {
657 VariableSourceToken vstAlsoAvail = availItr.next();
658 notAvailSet.removeAll( vstAlsoAvail.getRefVars() );
670 private void computeStallsForward( FlatMethod fm ) {
672 // start from flat method top, visit every node in
673 // method exactly once
674 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
675 flatNodesToVisit.add( fm );
677 Set<FlatNode> visited = new HashSet<FlatNode>();
679 while( !flatNodesToVisit.isEmpty() ) {
680 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
681 FlatNode fn = fnItr.next();
683 flatNodesToVisit.remove( fn );
686 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
687 assert seseStack != null;
689 // use incoming results as "dot statement" or just
690 // before the current statement
691 VarSrcTokTable dotSTtable = new VarSrcTokTable();
692 for( int i = 0; i < fn.numPrev(); i++ ) {
693 FlatNode nn = fn.getPrev( i );
694 dotSTtable.merge( variableResults.get( nn ) );
697 // find dt-st notAvailableSet also
698 Set<TempDescriptor> dotSTnotAvailSet = new HashSet<TempDescriptor>();
699 for( int i = 0; i < fn.numPrev(); i++ ) {
700 FlatNode nn = fn.getPrev( i );
701 Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
702 if( notAvailIn != null ) {
703 dotSTnotAvailSet.addAll( notAvailIn );
707 computeStalls_nodeActions( fn, dotSTtable, dotSTnotAvailSet, seseStack.peek() );
709 for( int i = 0; i < fn.numNext(); i++ ) {
710 FlatNode nn = fn.getNext( i );
712 if( !visited.contains( nn ) ) {
713 flatNodesToVisit.add( nn );
718 if( state.MLPDEBUG ) {
719 //System.out.println( fm.printMethod( livenessRootView ) );
720 //System.out.println( fm.printMethod( variableResults ) );
721 //System.out.println( fm.printMethod( notAvailableResults ) );
722 //System.out.println( fm.printMethod( codePlans ) );
726 private void computeStalls_nodeActions( FlatNode fn,
727 VarSrcTokTable vstTable,
728 Set<TempDescriptor> notAvailSet,
729 FlatSESEEnterNode currentSESE ) {
730 String before = null;
733 switch( fn.kind() ) {
735 case FKind.FlatSESEEnterNode: {
736 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
739 case FKind.FlatSESEExitNode: {
740 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
743 case FKind.FlatOpNode: {
744 FlatOpNode fon = (FlatOpNode) fn;
746 if( fon.getOp().getOp() == Operation.ASSIGN ) {
747 // if this is an op node, don't stall, copy
748 // source and delay until we need to use value
750 // only break if this is an ASSIGN op node,
751 // otherwise fall through to default case
756 // note that FlatOpNode's that aren't ASSIGN
757 // fall through to this default case
759 // decide if we must stall for variables dereferenced at this node
760 Set<VariableSourceToken> stallSet = vstTable.getStallSet( currentSESE );
762 TempDescriptor[] readarray = fn.readsTemps();
763 for( int i = 0; i < readarray.length; i++ ) {
764 TempDescriptor readtmp = readarray[i];
766 // ignore temps that are definitely available
767 // when considering to stall on it
768 if( !notAvailSet.contains( readtmp ) ) {
772 Set<VariableSourceToken> readSet = vstTable.get( readtmp );
776 //1) Multiple token/age pairs or unknown age: Stall for
781 //2) Single token/age pair: Stall for token/age pair, and copy
782 //all live variables with same token/age pair at the same
783 //time. This is the same stuff that the notavaialable analysis
784 //marks as now available.
786 //VarSrcTokTable table = variableResults.get( fn );
787 //Set<VariableSourceToken> srcs = table.get( rTemp );
789 //XXXXXXXXXX: Note: We have to generate code to do these
790 //copies in the codeplan. Note we should only copy the
791 //variables that are live!
794 if( srcs.size() == 1 ) {
795 VariableSourceToken vst = srcs.iterator().next();
797 Iterator<VariableSourceToken> availItr = table.get( vst.getSESE(),
800 while( availItr.hasNext() ) {
801 VariableSourceToken vstAlsoAvail = availItr.next();
802 notAvailSet.removeAll( vstAlsoAvail.getRefVars() );
808 // assert notAvailSet.containsAll( writeSet );
811 for( Iterator<VariableSourceToken> readit = readSet.iterator();
812 readit.hasNext(); ) {
813 VariableSourceToken vst = readit.next();
814 if( stallSet.contains( vst ) ) {
815 if( before == null ) {
816 before = "**STALL for:";
818 before += "("+vst+" "+readtmp+")";
827 // if any variable at this node has a static source (exactly one sese)
828 // but goes to a dynamic source at a next node, write its dynamic addr
829 Set<VariableSourceToken> static2dynamicSet = new HashSet<VariableSourceToken>();
830 for( int i = 0; i < fn.numNext(); i++ ) {
831 FlatNode nn = fn.getNext( i );
832 VarSrcTokTable nextVstTable = variableResults.get( nn );
833 assert nextVstTable != null;
834 static2dynamicSet.addAll( vstTable.getStatic2DynamicSet( nextVstTable ) );
836 Iterator<VariableSourceToken> vstItr = static2dynamicSet.iterator();
837 while( vstItr.hasNext() ) {
838 VariableSourceToken vst = vstItr.next();
839 if( after == null ) {
840 after = "** Write dynamic: ";
842 after += "("+vst+")";
846 if( before == null ) {
850 if( after == null ) {
854 codePlans.put( fn, new CodePlan( before, after ) );