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 FlatSESEEnterNode rootSESE;
21 private Set<FlatSESEEnterNode> allSESEs;
23 private Hashtable< FlatNode, Stack<FlatSESEEnterNode> > seseStacks;
24 private Hashtable< FlatNode, Set<TempDescriptor> > livenessRootView;
25 private Hashtable< FlatNode, Set<TempDescriptor> > livenessVirtualReads;
26 private Hashtable< FlatNode, VarSrcTokTable > variableResults;
27 private Hashtable< FlatNode, Set<TempDescriptor> > notAvailableResults;
28 private Hashtable< FlatNode, CodePlan > codePlans;
30 private static final int maxSESEage = 2;
33 // use these methods in BuildCode to have access to analysis results
34 public FlatSESEEnterNode getRootSESE() {
38 public Set<FlatSESEEnterNode> getAllSESEs() {
42 public int getMaxSESEage() {
46 public CodePlan getCodePlan( FlatNode fn ) {
47 CodePlan cp = codePlans.get( fn );
53 public MLPAnalysis( State state,
56 OwnershipAnalysis ownAnalysis
59 double timeStartAnalysis = (double) System.nanoTime();
63 this.callGraph = callGraph;
64 this.ownAnalysis = ownAnalysis;
66 // initialize analysis data structures
67 allSESEs = new HashSet<FlatSESEEnterNode>();
69 seseStacks = new Hashtable< FlatNode, Stack<FlatSESEEnterNode> >();
70 livenessVirtualReads = new Hashtable< FlatNode, Set<TempDescriptor> >();
71 variableResults = new Hashtable< FlatNode, VarSrcTokTable >();
72 notAvailableResults = new Hashtable< FlatNode, Set<TempDescriptor> >();
73 codePlans = new Hashtable< FlatNode, CodePlan >();
75 FlatMethod fmMain = state.getMethodFlat( tu.getMain() );
77 rootSESE = (FlatSESEEnterNode) fmMain.getNext(0);
81 // run analysis on each method that is actually called
82 // reachability analysis already computed this so reuse
83 Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
84 while( methItr.hasNext() ) {
85 Descriptor d = methItr.next();
86 FlatMethod fm = state.getMethodFlat( d );
88 // find every SESE from methods that may be called
89 // and organize them into roots and children
90 buildForestForward( fm );
94 // 2nd pass, results are saved in FlatSESEEnterNode, so
95 // intermediate results, for safety, are discarded
96 livenessAnalysisBackward( rootSESE, true, null, fmMain.getFlatExit() );
100 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
101 while( methItr.hasNext() ) {
102 Descriptor d = methItr.next();
103 FlatMethod fm = state.getMethodFlat( d );
105 // starting from roots do a forward, fixed-point
106 // variable analysis for refinement and stalls
107 variableAnalysisForward( fm );
111 // 4th pass, compute liveness contribution from
112 // virtual reads discovered in variable pass
113 livenessAnalysisBackward( rootSESE, true, null, fmMain.getFlatExit() );
117 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
118 while( methItr.hasNext() ) {
119 Descriptor d = methItr.next();
120 FlatMethod fm = state.getMethodFlat( d );
122 // compute what is not available at every program
123 // point, in a forward fixed-point pass
124 notAvailableForward( fm );
129 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
130 while( methItr.hasNext() ) {
131 Descriptor d = methItr.next();
132 FlatMethod fm = state.getMethodFlat( d );
134 // compute a plan for code injections
135 computeStallsForward( fm );
139 if( state.MLPDEBUG ) {
140 System.out.println( "" );
141 //System.out.println( "\nSESE Hierarchy\n--------------\n" ); printSESEHierarchy();
142 //System.out.println( "\nSESE Liveness\n-------------\n" ); printSESELiveness();
143 //System.out.println( "\nLiveness Root View\n------------------\n"+fmMain.printMethod( livenessRootView ) );
144 //System.out.println( "\nVariable Results\n----------------\n"+fmMain.printMethod( variableResults ) );
145 //System.out.println( "\nNot Available Results\n---------------------\n"+fmMain.printMethod( notAvailableResults ) );
146 //System.out.println( "\nCode Plans\n----------\n"+fmMain.printMethod( codePlans ) );
150 double timeEndAnalysis = (double) System.nanoTime();
151 double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
152 String treport = String.format( "The mlp analysis took %.3f sec.", dt );
153 System.out.println( treport );
157 private void buildForestForward( FlatMethod fm ) {
159 // start from flat method top, visit every node in
160 // method exactly once, find SESEs and remember
161 // roots and child relationships
162 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
163 flatNodesToVisit.add( fm );
165 Set<FlatNode> visited = new HashSet<FlatNode>();
167 Stack<FlatSESEEnterNode> seseStackFirst = new Stack<FlatSESEEnterNode>();
168 seseStacks.put( fm, seseStackFirst );
170 while( !flatNodesToVisit.isEmpty() ) {
171 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
172 FlatNode fn = fnItr.next();
174 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
175 assert seseStack != null;
177 flatNodesToVisit.remove( fn );
180 buildForest_nodeActions( fn, seseStack, fm );
182 for( int i = 0; i < fn.numNext(); i++ ) {
183 FlatNode nn = fn.getNext( i );
185 if( !visited.contains( nn ) ) {
186 flatNodesToVisit.add( nn );
188 // clone stack and send along each analysis path
189 seseStacks.put( nn, (Stack<FlatSESEEnterNode>)seseStack.clone() );
195 private void buildForest_nodeActions( FlatNode fn,
196 Stack<FlatSESEEnterNode> seseStack,
198 switch( fn.kind() ) {
200 case FKind.FlatSESEEnterNode: {
201 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
203 allSESEs.add( fsen );
204 fsen.setEnclosingFlatMeth( fm );
206 if( !seseStack.empty() ) {
207 seseStack.peek().addChild( fsen );
208 fsen.setParent( seseStack.peek() );
211 seseStack.push( fsen );
214 case FKind.FlatSESEExitNode: {
215 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
216 assert !seseStack.empty();
217 FlatSESEEnterNode fsen = seseStack.pop();
220 case FKind.FlatReturnNode: {
221 FlatReturnNode frn = (FlatReturnNode) fn;
222 if( !seseStack.empty() ) {
223 throw new Error( "Error: return statement enclosed within SESE "+
224 seseStack.peek().getPrettyIdentifier() );
231 private void printSESEHierarchy() {
232 // our forest is actually a tree now that
233 // there is an implicit root SESE
234 printSESEHierarchyTree( rootSESE, 0 );
235 System.out.println( "" );
238 private void printSESEHierarchyTree( FlatSESEEnterNode fsen, int depth ) {
239 for( int i = 0; i < depth; ++i ) {
240 System.out.print( " " );
242 System.out.println( "- "+fsen.getPrettyIdentifier() );
244 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
245 while( childItr.hasNext() ) {
246 FlatSESEEnterNode fsenChild = childItr.next();
247 printSESEHierarchyTree( fsenChild, depth + 1 );
252 private void livenessAnalysisBackward( FlatSESEEnterNode fsen,
254 Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout,
257 // start from an SESE exit, visit nodes in reverse up to
258 // SESE enter in a fixed-point scheme, where children SESEs
259 // should already be analyzed and therefore can be skipped
260 // because child SESE enter node has all necessary info
261 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
263 FlatSESEExitNode fsexn = fsen.getFlatExit();
266 flatNodesToVisit.add( fexit );
268 flatNodesToVisit.add( fsexn );
269 Hashtable<FlatNode, Set<TempDescriptor>> livenessResults=new Hashtable<FlatNode, Set<TempDescriptor>>();
272 liveout=new Hashtable<FlatSESEExitNode, Set<TempDescriptor>>();
274 while( !flatNodesToVisit.isEmpty() ) {
275 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
276 flatNodesToVisit.remove( fn );
278 Set<TempDescriptor> prev = livenessResults.get( fn );
280 // merge sets from control flow joins
281 Set<TempDescriptor> u = new HashSet<TempDescriptor>();
282 for( int i = 0; i < fn.numNext(); i++ ) {
283 FlatNode nn = fn.getNext( i );
284 Set<TempDescriptor> s = livenessResults.get( nn );
290 Set<TempDescriptor> curr = liveness_nodeActions( fn, u, fsen, toplevel, liveout);
292 // if a new result, schedule backward nodes for analysis
293 if(!curr.equals(prev)) {
294 livenessResults.put( fn, curr );
296 // don't flow backwards past current SESE enter
297 if( !fn.equals( fsen ) ) {
298 for( int i = 0; i < fn.numPrev(); i++ ) {
299 FlatNode nn = fn.getPrev( i );
300 flatNodesToVisit.add( nn );
306 Set<TempDescriptor> s = livenessResults.get( fsen );
308 fsen.addInVarSet( s );
311 // remember liveness per node from the root view as the
312 // global liveness of variables for later passes to use
313 if( toplevel == true ) {
314 livenessRootView = livenessResults;
317 // post-order traversal, so do children first
318 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
319 while( childItr.hasNext() ) {
320 FlatSESEEnterNode fsenChild = childItr.next();
321 livenessAnalysisBackward( fsenChild, false, liveout, null);
325 private Set<TempDescriptor> liveness_nodeActions( FlatNode fn,
326 Set<TempDescriptor> liveIn,
327 FlatSESEEnterNode currentSESE,
329 Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout ) {
331 switch( fn.kind() ) {
333 case FKind.FlatSESEExitNode:
334 if (toplevel==true) {
335 FlatSESEExitNode exitn=(FlatSESEExitNode) fn;
336 //update liveout set for FlatSESEExitNode
337 if (!liveout.containsKey(exitn))
338 liveout.put(exitn, new HashSet<TempDescriptor>());
339 liveout.get(exitn).addAll(liveIn);
341 // no break, sese exits should also execute default actions
344 // handle effects of statement in reverse, writes then reads
345 TempDescriptor [] writeTemps = fn.writesTemps();
346 for( int i = 0; i < writeTemps.length; ++i ) {
347 liveIn.remove( writeTemps[i] );
350 FlatSESEExitNode exitnode=currentSESE.getFlatExit();
351 Set<TempDescriptor> livetemps=liveout.get(exitnode);
352 if (livetemps.contains(writeTemps[i])) {
353 //write to a live out temp...
354 //need to put in SESE liveout set
355 currentSESE.addOutVar(writeTemps[i]);
360 TempDescriptor [] readTemps = fn.readsTemps();
361 for( int i = 0; i < readTemps.length; ++i ) {
362 liveIn.add( readTemps[i] );
365 Set<TempDescriptor> virtualReadTemps = livenessVirtualReads.get( fn );
366 if( virtualReadTemps != null ) {
367 Iterator<TempDescriptor> vrItr = virtualReadTemps.iterator();
368 while( vrItr.hasNext() ) {
369 TempDescriptor vrt = vrItr.next();
380 private void printSESELiveness() {
381 // our forest is actually a tree now that
382 // there is an implicit root SESE
383 printSESELivenessTree( rootSESE );
384 System.out.println( "" );
387 private void printSESELivenessTree( FlatSESEEnterNode fsen ) {
389 System.out.println( "SESE "+fsen.getPrettyIdentifier()+" has in-set:" );
390 Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
391 while( tItr.hasNext() ) {
392 System.out.println( " "+tItr.next() );
394 System.out.println( "and out-set:" );
395 tItr = fsen.getOutVarSet().iterator();
396 while( tItr.hasNext() ) {
397 System.out.println( " "+tItr.next() );
399 System.out.println( "" );
402 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
403 while( childItr.hasNext() ) {
404 FlatSESEEnterNode fsenChild = childItr.next();
405 printSESELivenessTree( fsenChild );
410 private void variableAnalysisForward( FlatMethod fm ) {
412 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
413 flatNodesToVisit.add( fm );
415 while( !flatNodesToVisit.isEmpty() ) {
416 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
417 flatNodesToVisit.remove( fn );
419 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
420 assert seseStack != null;
422 VarSrcTokTable prev = variableResults.get( fn );
424 // merge sets from control flow joins
425 VarSrcTokTable inUnion = new VarSrcTokTable();
426 for( int i = 0; i < fn.numPrev(); i++ ) {
427 FlatNode nn = fn.getPrev( i );
428 VarSrcTokTable incoming = variableResults.get( nn );
429 inUnion.merge( incoming );
432 VarSrcTokTable curr = null;
433 if( !seseStack.empty() ) {
434 curr = variable_nodeActions( fn, inUnion, seseStack.peek() );
437 // if a new result, schedule forward nodes for analysis
438 if( curr != null && !curr.equals( prev ) ) {
439 variableResults.put( fn, curr );
441 for( int i = 0; i < fn.numNext(); i++ ) {
442 FlatNode nn = fn.getNext( i );
443 flatNodesToVisit.add( nn );
449 private VarSrcTokTable variable_nodeActions( FlatNode fn,
450 VarSrcTokTable vstTable,
451 FlatSESEEnterNode currentSESE ) {
452 switch( fn.kind() ) {
454 case FKind.FlatSESEEnterNode: {
455 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
456 assert fsen.equals( currentSESE );
457 vstTable.age( currentSESE );
458 vstTable.assertConsistency();
461 case FKind.FlatSESEExitNode: {
462 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
463 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
464 assert currentSESE.getChildren().contains( fsen );
465 vstTable.remapChildTokens( fsen );
467 Set<TempDescriptor> liveIn = currentSESE.getInVarSet();
468 Set<TempDescriptor> virLiveIn = vstTable.removeParentAndSiblingTokens( fsen, liveIn );
469 Set<TempDescriptor> virLiveInOld = livenessVirtualReads.get( fn );
470 if( virLiveInOld != null ) {
471 virLiveIn.addAll( virLiveInOld );
473 livenessVirtualReads.put( fn, virLiveIn );
474 vstTable.assertConsistency();
477 case FKind.FlatOpNode: {
478 FlatOpNode fon = (FlatOpNode) fn;
480 if( fon.getOp().getOp() == Operation.ASSIGN ) {
481 TempDescriptor lhs = fon.getDest();
482 TempDescriptor rhs = fon.getLeft();
484 vstTable.remove( lhs );
486 Set<VariableSourceToken> forAddition = new HashSet<VariableSourceToken>();
488 Iterator<VariableSourceToken> itr = vstTable.get( rhs ).iterator();
489 while( itr.hasNext() ) {
490 VariableSourceToken vst = itr.next();
492 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
495 // if this is from a child, keep the source information
496 if( currentSESE.getChildren().contains( vst.getSESE() ) ) {
497 forAddition.add( new VariableSourceToken( ts,
504 // otherwise, it's our or an ancestor's token so we
505 // can assume we have everything we need
507 forAddition.add( new VariableSourceToken( ts,
516 vstTable.addAll( forAddition );
518 // only break if this is an ASSIGN op node,
519 // otherwise fall through to default case
520 vstTable.assertConsistency();
525 // note that FlatOpNode's that aren't ASSIGN
526 // fall through to this default case
528 TempDescriptor [] writeTemps = fn.writesTemps();
529 if( writeTemps.length > 0 ) {
532 // for now, when writeTemps > 1, make sure
533 // its a call node, programmer enforce only
534 // doing stuff like calling a print routine
535 //assert writeTemps.length == 1;
536 if( writeTemps.length > 1 ) {
537 assert fn.kind() == FKind.FlatCall ||
538 fn.kind() == FKind.FlatMethod;
543 vstTable.remove( writeTemps[0] );
545 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
546 ts.add( writeTemps[0] );
548 vstTable.add( new VariableSourceToken( ts,
556 vstTable.assertConsistency();
565 private void notAvailableForward( FlatMethod fm ) {
567 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
568 flatNodesToVisit.add( fm );
570 while( !flatNodesToVisit.isEmpty() ) {
571 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
572 flatNodesToVisit.remove( fn );
574 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
575 assert seseStack != null;
577 Set<TempDescriptor> prev = notAvailableResults.get( fn );
579 Set<TempDescriptor> inUnion = new HashSet<TempDescriptor>();
580 for( int i = 0; i < fn.numPrev(); i++ ) {
581 FlatNode nn = fn.getPrev( i );
582 Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
583 if( notAvailIn != null ) {
584 inUnion.addAll( notAvailIn );
588 Set<TempDescriptor> curr = null;
589 if( !seseStack.empty() ) {
590 curr = notAvailable_nodeActions( fn, inUnion, seseStack.peek() );
593 // if a new result, schedule forward nodes for analysis
594 if( curr != null && !curr.equals( prev ) ) {
595 notAvailableResults.put( fn, curr );
597 for( int i = 0; i < fn.numNext(); i++ ) {
598 FlatNode nn = fn.getNext( i );
599 flatNodesToVisit.add( nn );
605 private Set<TempDescriptor> notAvailable_nodeActions( FlatNode fn,
606 Set<TempDescriptor> notAvailSet,
607 FlatSESEEnterNode currentSESE ) {
609 // any temps that are removed from the not available set
610 // at this node should be marked in this node's code plan
611 // as temps to be grabbed at runtime!
613 switch( fn.kind() ) {
615 case FKind.FlatSESEEnterNode: {
616 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
617 assert fsen.equals( currentSESE );
621 case FKind.FlatSESEExitNode: {
622 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
623 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
624 assert currentSESE.getChildren().contains( fsen );
626 Set<TempDescriptor> liveTemps = livenessRootView.get( fn );
627 assert liveTemps != null;
629 VarSrcTokTable vstTable = variableResults.get( fn );
630 assert vstTable != null;
632 Set<TempDescriptor> notAvailAtEnter = notAvailableResults.get( fsen );
633 assert notAvailAtEnter != null;
635 Iterator<TempDescriptor> tdItr = liveTemps.iterator();
636 while( tdItr.hasNext() ) {
637 TempDescriptor td = tdItr.next();
639 if( vstTable.get( fsen, td ).size() > 0 ) {
640 // there is at least one child token for this variable
641 notAvailSet.add( td );
645 if( notAvailAtEnter.contains( td ) ) {
646 // wasn't available at enter, not available now
647 notAvailSet.add( td );
653 case FKind.FlatOpNode: {
654 FlatOpNode fon = (FlatOpNode) fn;
656 if( fon.getOp().getOp() == Operation.ASSIGN ) {
657 TempDescriptor lhs = fon.getDest();
658 TempDescriptor rhs = fon.getLeft();
660 // copy makes lhs same availability as rhs
661 if( notAvailSet.contains( rhs ) ) {
662 notAvailSet.add( lhs );
664 notAvailSet.remove( lhs );
667 // only break if this is an ASSIGN op node,
668 // otherwise fall through to default case
673 // note that FlatOpNode's that aren't ASSIGN
674 // fall through to this default case
676 TempDescriptor [] writeTemps = fn.writesTemps();
677 for( int i = 0; i < writeTemps.length; i++ ) {
678 TempDescriptor wTemp = writeTemps[i];
679 notAvailSet.remove( wTemp );
681 TempDescriptor [] readTemps = fn.readsTemps();
682 for( int i = 0; i < readTemps.length; i++ ) {
683 TempDescriptor rTemp = readTemps[i];
684 notAvailSet.remove( rTemp );
686 // if this variable has exactly one source, mark everything
687 // else from that source as available as well
688 VarSrcTokTable table = variableResults.get( fn );
689 Set<VariableSourceToken> srcs = table.get( rTemp );
691 if( srcs.size() == 1 ) {
692 VariableSourceToken vst = srcs.iterator().next();
694 Iterator<VariableSourceToken> availItr = table.get( vst.getSESE(),
697 while( availItr.hasNext() ) {
698 VariableSourceToken vstAlsoAvail = availItr.next();
699 notAvailSet.removeAll( vstAlsoAvail.getRefVars() );
711 private void computeStallsForward( FlatMethod fm ) {
713 // start from flat method top, visit every node in
714 // method exactly once
715 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
716 flatNodesToVisit.add( fm );
718 Set<FlatNode> visited = new HashSet<FlatNode>();
720 while( !flatNodesToVisit.isEmpty() ) {
721 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
722 FlatNode fn = fnItr.next();
724 flatNodesToVisit.remove( fn );
727 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
728 assert seseStack != null;
730 // use incoming results as "dot statement" or just
731 // before the current statement
732 VarSrcTokTable dotSTtable = new VarSrcTokTable();
733 for( int i = 0; i < fn.numPrev(); i++ ) {
734 FlatNode nn = fn.getPrev( i );
735 dotSTtable.merge( variableResults.get( nn ) );
738 // find dt-st notAvailableSet also
739 Set<TempDescriptor> dotSTnotAvailSet = new HashSet<TempDescriptor>();
740 for( int i = 0; i < fn.numPrev(); i++ ) {
741 FlatNode nn = fn.getPrev( i );
742 Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
743 if( notAvailIn != null ) {
744 dotSTnotAvailSet.addAll( notAvailIn );
748 if( !seseStack.empty() ) {
749 computeStalls_nodeActions( fn, dotSTtable, dotSTnotAvailSet, seseStack.peek() );
752 for( int i = 0; i < fn.numNext(); i++ ) {
753 FlatNode nn = fn.getNext( i );
755 if( !visited.contains( nn ) ) {
756 flatNodesToVisit.add( nn );
762 private void computeStalls_nodeActions( FlatNode fn,
763 VarSrcTokTable vstTable,
764 Set<TempDescriptor> notAvailSet,
765 FlatSESEEnterNode currentSESE ) {
766 CodePlan plan = new CodePlan();
769 switch( fn.kind() ) {
771 case FKind.FlatSESEEnterNode: {
772 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
773 plan.setSESEtoIssue( fsen );
776 case FKind.FlatSESEExitNode: {
777 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
780 case FKind.FlatOpNode: {
781 FlatOpNode fon = (FlatOpNode) fn;
783 if( fon.getOp().getOp() == Operation.ASSIGN ) {
784 // if this is an op node, don't stall, copy
785 // source and delay until we need to use value
787 // only break if this is an ASSIGN op node,
788 // otherwise fall through to default case
793 // note that FlatOpNode's that aren't ASSIGN
794 // fall through to this default case
796 // decide if we must stall for variables dereferenced at this node
797 Set<VariableSourceToken> stallSet = vstTable.getStallSet( currentSESE );
799 TempDescriptor[] readarray = fn.readsTemps();
800 for( int i = 0; i < readarray.length; i++ ) {
801 TempDescriptor readtmp = readarray[i];
803 // ignore temps that are definitely available
804 // when considering to stall on it
805 if( !notAvailSet.contains( readtmp ) ) {
809 Set<VariableSourceToken> readSet = vstTable.get( readtmp );
813 //1) Multiple token/age pairs or unknown age: Stall for
818 //2) Single token/age pair: Stall for token/age pair, and copy
819 //all live variables with same token/age pair at the same
820 //time. This is the same stuff that the notavaialable analysis
821 //marks as now available.
823 //VarSrcTokTable table = variableResults.get( fn );
824 //Set<VariableSourceToken> srcs = table.get( rTemp );
826 //XXXXXXXXXX: Note: We have to generate code to do these
827 //copies in the codeplan. Note we should only copy the
828 //variables that are live!
831 if( srcs.size() == 1 ) {
832 VariableSourceToken vst = srcs.iterator().next();
834 Iterator<VariableSourceToken> availItr = table.get( vst.getSESE(),
837 while( availItr.hasNext() ) {
838 VariableSourceToken vstAlsoAvail = availItr.next();
839 notAvailSet.removeAll( vstAlsoAvail.getRefVars() );
845 // assert notAvailSet.containsAll( writeSet );
848 for( Iterator<VariableSourceToken> readit = readSet.iterator();
849 readit.hasNext(); ) {
850 VariableSourceToken vst = readit.next();
851 if( stallSet.contains( vst ) ) {
852 if( before == null ) {
853 before = "**STALL for:";
855 before += "("+vst+" "+readtmp+")";
865 // if any variable at this node has a static source (exactly one sese)
866 // but goes to a dynamic source at a next node, write its dynamic addr
867 Set<VariableSourceToken> static2dynamicSet = new HashSet<VariableSourceToken>();
868 for( int i = 0; i < fn.numNext(); i++ ) {
869 FlatNode nn = fn.getNext( i );
870 VarSrcTokTable nextVstTable = variableResults.get( nn );
871 // the table can be null if it is one of the few IR nodes
872 // completely outside of the root SESE scope
873 if( nextVstTable != null ) {
874 static2dynamicSet.addAll( vstTable.getStatic2DynamicSet( nextVstTable ) );
878 Iterator<VariableSourceToken> vstItr = static2dynamicSet.iterator();
879 while( vstItr.hasNext() ) {
880 VariableSourceToken vst = vstItr.next();
881 if( after == null ) {
882 after = "** Write dynamic: ";
884 after += "("+vst+")";
888 codePlans.put( fn, plan );