1 package Analysis.Locality;
2 import Analysis.Liveness;
3 import Analysis.ReachingDefs;
5 import IR.MethodDescriptor;
6 import IR.TypeDescriptor;
7 import IR.FieldDescriptor;
9 import Analysis.Loops.GlobalFieldType;
10 import java.util.HashSet;
11 import java.util.Hashtable;
13 import java.util.List;
14 import java.util.Arrays;
15 import java.util.Stack;
16 import java.util.Iterator;
18 public class DelayComputation {
20 LocalityAnalysis locality;
21 TypeAnalysis typeanalysis;
23 DiscoverConflicts dcopts;
24 Hashtable<LocalityBinding, HashSet<FlatNode>> notreadymap;
25 Hashtable<LocalityBinding, HashSet<FlatNode>> cannotdelaymap;
26 Hashtable<LocalityBinding, HashSet<FlatNode>> othermap;
28 public DelayComputation(LocalityAnalysis locality, State state, TypeAnalysis typeanalysis, GlobalFieldType gft) {
29 this.locality=locality;
31 this.typeanalysis=typeanalysis;
33 this.notreadymap=new Hashtable<LocalityBinding, HashSet<FlatNode>>();
34 this.cannotdelaymap=new Hashtable<LocalityBinding, HashSet<FlatNode>>();
35 this.othermap=new Hashtable<LocalityBinding, HashSet<FlatNode>>();
38 public DiscoverConflicts getConflicts() {
42 public void doAnalysis() {
43 Set<LocalityBinding> localityset=locality.getLocalityBindings();
44 for(Iterator<LocalityBinding> lbit=localityset.iterator();lbit.hasNext();) {
45 analyzeMethod(lbit.next());
48 dcopts=new DiscoverConflicts(locality, state, typeanalysis, cannotdelaymap);
52 for(Iterator<LocalityBinding> lbit=localityset.iterator();lbit.hasNext();) {
53 LocalityBinding lb=lbit.next();
55 MethodDescriptor md=lb.getMethod();
56 FlatMethod fm=state.getMethodFlat(md);
60 if (lb.getHasAtomic()) {
61 HashSet<FlatNode> cannotdelay=cannotdelaymap.get(lb);
62 HashSet<FlatNode> notreadyset=computeNotReadySet(lb, cannotdelay);
63 HashSet<FlatNode> otherset=new HashSet<FlatNode>();
64 otherset.addAll(fm.getNodeSet());
65 otherset.removeAll(notreadyset);
66 otherset.removeAll(cannotdelay);
67 notreadymap.put(lb, notreadyset);
68 othermap.put(lb, otherset);
72 //(1) Cannot delay set -- stuff that must be done before commit
73 //(2) Not ready set -- stuff that must wait until commit
74 //(3) everything else -- stuff that should be done before commit
78 public HashSet<FlatNode> getNotReady(LocalityBinding lb) {
79 return notreadymap.get(lb);
82 public HashSet<FlatNode> getCannotDelay(LocalityBinding lb) {
83 return cannotdelaymap.get(lb);
86 public HashSet<FlatNode> getOther(LocalityBinding lb) {
87 return othermap.get(lb);
90 //This method computes which temps are live into the second part
91 public Set<TempDescriptor> alltemps(LocalityBinding lb, FlatAtomicEnterNode faen, Set<FlatNode> recordset) {
92 MethodDescriptor md=lb.getMethod();
93 FlatMethod fm=state.getMethodFlat(md);
94 Set<FlatNode> atomicnodes=faen.getReachableSet(faen.getExits());
96 //Compute second part set of nodes
97 Set<FlatNode> secondpart=new HashSet<FlatNode>();
98 secondpart.addAll(getNotReady(lb));
99 secondpart.addAll(recordset);
101 //make it just this transaction
102 secondpart.retainAll(atomicnodes);
104 HashSet<TempDescriptor> tempset=new HashSet<TempDescriptor>();
106 for(Iterator<FlatNode> fnit=secondpart.iterator();fnit.hasNext();) {
107 FlatNode fn=fnit.next();
108 List<TempDescriptor> writes=Arrays.asList(fn.writesTemps());
109 tempset.addAll(writes);
110 if (!recordset.contains(fn)) {
111 List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
112 tempset.addAll(reads);
119 //This method computes which temps are live into the second part
120 public Set<TempDescriptor> liveinto(LocalityBinding lb, FlatAtomicEnterNode faen, Set<FlatNode> recordset) {
121 MethodDescriptor md=lb.getMethod();
122 FlatMethod fm=state.getMethodFlat(md);
123 Set<FlatNode> atomicnodes=faen.getReachableSet(faen.getExits());
125 //Compute second part set of nodes
126 Set<FlatNode> secondpart=new HashSet<FlatNode>();
127 secondpart.addAll(getNotReady(lb));
128 secondpart.addAll(recordset);
130 //make it just this transaction
131 secondpart.retainAll(atomicnodes);
133 Set<TempDescriptor> liveinto=new HashSet<TempDescriptor>();
135 Hashtable<FlatNode, Hashtable<TempDescriptor, Set<FlatNode>>> reachingdefs=ReachingDefs.computeReachingDefs(fm, Liveness.computeLiveTemps(fm));
137 for(Iterator<FlatNode> fnit=secondpart.iterator();fnit.hasNext();) {
138 FlatNode fn=fnit.next();
139 if (recordset.contains(fn))
141 TempDescriptor readset[]=fn.readsTemps();
142 for(int i=0;i<readset.length;i++) {
143 TempDescriptor rtmp=readset[i];
144 Set<FlatNode> fnset=reachingdefs.get(fn).get(rtmp);
145 for(Iterator<FlatNode> fnit2=fnset.iterator();fnit2.hasNext();) {
146 FlatNode fn2=fnit2.next();
147 if (secondpart.contains(fn2))
149 //otherwise we mark this as live in
158 //This method computes which temps are live out of the second part
159 public Set<TempDescriptor> liveoutvirtualread(LocalityBinding lb, FlatAtomicEnterNode faen) {
160 MethodDescriptor md=lb.getMethod();
161 FlatMethod fm=state.getMethodFlat(md);
162 Set<FlatNode> exits=faen.getExits();
163 Hashtable<FlatNode, Set<TempDescriptor>> livemap=Liveness.computeLiveTemps(fm);
164 Hashtable<FlatNode, Hashtable<TempDescriptor, Set<FlatNode>>> reachingdefs=ReachingDefs.computeReachingDefs(fm, Liveness.computeLiveTemps(fm));
166 Set<FlatNode> atomicnodes=faen.getReachableSet(faen.getExits());
168 Set<FlatNode> secondpart=new HashSet<FlatNode>(getNotReady(lb));
169 secondpart.retainAll(atomicnodes);
171 Set<TempDescriptor> liveset=new HashSet<TempDescriptor>();
172 //Have list of all live temps
174 for(Iterator<FlatNode> fnit=exits.iterator();fnit.hasNext();) {
175 FlatNode fn=fnit.next();
176 Set<TempDescriptor> tempset=livemap.get(fn);
177 Hashtable<TempDescriptor, Set<FlatNode>> reachmap=reachingdefs.get(fn);
178 //Look for reaching defs for all live variables that are in the secondpart
180 for(Iterator<TempDescriptor> tmpit=tempset.iterator();tmpit.hasNext();) {
181 TempDescriptor tmp=tmpit.next();
182 Set<FlatNode> fnset=reachmap.get(tmp);
183 boolean outsidenode=false;
184 boolean insidenode=false;
186 for(Iterator<FlatNode> fnit2=fnset.iterator();fnit2.hasNext();) {
187 FlatNode fn2=fnit2.next();
188 if (secondpart.contains(fn2)) {
190 } else if (!atomicnodes.contains(fn2)) {
193 if (outsidenode&&insidenode) {
203 //This method computes which temps are live out of the second part
204 public Set<TempDescriptor> liveout(LocalityBinding lb, FlatAtomicEnterNode faen) {
205 MethodDescriptor md=lb.getMethod();
206 FlatMethod fm=state.getMethodFlat(md);
207 Set<FlatNode> exits=faen.getExits();
208 Hashtable<FlatNode, Set<TempDescriptor>> livemap=Liveness.computeLiveTemps(fm);
209 Hashtable<FlatNode, Hashtable<TempDescriptor, Set<FlatNode>>> reachingdefs=ReachingDefs.computeReachingDefs(fm, livemap);
211 Set<FlatNode> atomicnodes=faen.getReachableSet(faen.getExits());
213 Set<FlatNode> secondpart=new HashSet<FlatNode>(getNotReady(lb));
214 secondpart.retainAll(atomicnodes);
216 Set<TempDescriptor> liveset=new HashSet<TempDescriptor>();
217 //Have list of all live temps
219 for(Iterator<FlatNode> fnit=exits.iterator();fnit.hasNext();) {
220 FlatNode fn=fnit.next();
221 Set<TempDescriptor> tempset=livemap.get(fn);
222 Hashtable<TempDescriptor, Set<FlatNode>> reachmap=reachingdefs.get(fn);
223 //Look for reaching defs for all live variables that are in the secondpart
225 for(Iterator<TempDescriptor> tmpit=tempset.iterator();tmpit.hasNext();) {
226 TempDescriptor tmp=tmpit.next();
227 Set<FlatNode> fnset=reachmap.get(tmp);
229 System.out.println("null temp set for"+fn+" tmp="+tmp);
230 System.out.println(fm.printMethod());
232 for(Iterator<FlatNode> fnit2=fnset.iterator();fnit2.hasNext();) {
233 FlatNode fn2=fnit2.next();
234 if (secondpart.contains(fn2)) {
244 //This method computes which nodes from the first part of the
245 //transaction must store their output for the second part
246 //Note that many nodes don't need to...
248 public Set<FlatNode> livecode(LocalityBinding lb) {
249 if (!othermap.containsKey(lb))
251 MethodDescriptor md=lb.getMethod();
252 FlatMethod fm=state.getMethodFlat(md);
254 HashSet<FlatNode> delayedset=notreadymap.get(lb);
255 HashSet<FlatNode> otherset=othermap.get(lb);
256 HashSet<FlatNode> cannotdelayset=cannotdelaymap.get(lb);
257 Hashtable<FlatNode,Set<TempDescriptor>> livemap=Liveness.computeLiveTemps(fm);
258 Hashtable<FlatNode, Hashtable<TempDescriptor, Set<FlatNode>>> reachingdefsmap=ReachingDefs.computeReachingDefs(fm, livemap);
259 HashSet<FlatNode> unionset=new HashSet<FlatNode>(delayedset);
261 Hashtable<FlatNode, Hashtable<TempDescriptor, HashSet<FlatNode>>> map=new Hashtable<FlatNode, Hashtable<TempDescriptor, HashSet<FlatNode>>>();
263 HashSet<FlatNode> livenodes=new HashSet<FlatNode>();
265 for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
266 FlatNode fn=fnit.next();
267 if (fn.kind()==FKind.FlatAtomicExitNode) {
268 Set<TempDescriptor> livetemps=livemap.get(fn);
269 Hashtable<TempDescriptor, Set<FlatNode>> tempmap=reachingdefsmap.get(fn);
270 for(Iterator<TempDescriptor> tmpit=livetemps.iterator();tmpit.hasNext();) {
271 TempDescriptor tmp=tmpit.next();
272 Set<FlatNode> fnset=tempmap.get(tmp);
273 boolean inpart1=false;
274 boolean inpart2=false;
275 for(Iterator<FlatNode> fnit2=fnset.iterator();fnit2.hasNext();) {
276 FlatNode fn2=fnit2.next();
277 if (delayedset.contains(fn2)) {
281 } else if (otherset.contains(fn2)||cannotdelayset.contains(fn2)) {
287 if (inpart1&&inpart2) {
288 for(Iterator<FlatNode> fnit2=fnset.iterator();fnit2.hasNext();) {
289 FlatNode fn2=fnit2.next();
290 if (otherset.contains(fn2)||cannotdelayset.contains(fn2)) {
300 HashSet<FlatNode> toanalyze=new HashSet<FlatNode>();
303 while(!toanalyze.isEmpty()) {
304 FlatNode fn=toanalyze.iterator().next();
305 toanalyze.remove(fn);
306 Hashtable<TempDescriptor, HashSet<FlatNode>> tmptofn=new Hashtable<TempDescriptor, HashSet<FlatNode>>();
308 //Don't process non-atomic nodes
309 if (locality.getAtomic(lb).get(fn).intValue()==0) {
310 if (!map.containsKey(fn)) {
311 map.put(fn, new Hashtable<TempDescriptor, HashSet<FlatNode>>());
313 for(int i=0;i<fn.numNext();i++)
314 toanalyze.add(fn.getNext(i));
319 //Do merge on incoming edges
320 for(int i=0;i<fn.numPrev();i++) {
321 FlatNode fnprev=fn.getPrev(i);
322 Hashtable<TempDescriptor, HashSet<FlatNode>> prevmap=map.get(fnprev);
324 for(Iterator<TempDescriptor> tmpit=prevmap.keySet().iterator();tmpit.hasNext();) {
325 TempDescriptor tmp=tmpit.next();
326 if (!tmptofn.containsKey(tmp))
327 tmptofn.put(tmp, new HashSet<FlatNode>());
328 tmptofn.get(tmp).addAll(prevmap.get(tmp));
332 if (delayedset.contains(fn)) {
334 TempDescriptor readset[]=fn.readsTemps();
335 for(int i=0;i<readset.length;i++) {
336 TempDescriptor tmp=readset[i];
337 if (tmptofn.containsKey(tmp)) {
338 livenodes.addAll(tmptofn.get(tmp)); // add live nodes
339 unionset.addAll(tmptofn.get(tmp));
344 TempDescriptor writeset[]=fn.writesTemps();
345 for(int i=0;i<writeset.length;i++) {
346 TempDescriptor tmp=writeset[i];
350 //We write -- our reads are done
351 TempDescriptor writeset[]=fn.writesTemps();
352 for(int i=0;i<writeset.length;i++) {
353 TempDescriptor tmp=writeset[i];
354 HashSet<FlatNode> set=new HashSet<FlatNode>();
355 tmptofn.put(tmp,set);
358 if (fn.numNext()>1) {
359 //We have a conditional branch...need to handle this carefully
360 Set<FlatNode> set0=getNext(fn, 0, unionset, lb, locality, false);
361 Set<FlatNode> set1=getNext(fn, 1, unionset, lb, locality, false);
362 if (!set0.equals(set1)||set0.size()>1) {
363 //This branch is important--need to remember how it goes
369 if (!map.containsKey(fn)||!map.get(fn).equals(tmptofn)) {
370 map.put(fn, tmptofn);
372 for(int i=0;i<fn.numNext();i++)
373 toanalyze.add(fn.getNext(i));
379 public static Set<FlatNode> getNext(FlatNode fn, int i, Set<FlatNode> delayset, LocalityBinding lb, LocalityAnalysis locality, boolean contpastnode) {
380 Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
381 FlatNode fnnext=fn.getNext(i);
382 HashSet<FlatNode> reachable=new HashSet<FlatNode>();
384 if (delayset.contains(fnnext)||atomictable.get(fnnext).intValue()==0) {
385 reachable.add(fnnext);
388 Stack<FlatNode> nodes=new Stack<FlatNode>();
389 HashSet<FlatNode> visited=new HashSet<FlatNode>();
394 while(!nodes.isEmpty()) {
395 FlatNode fn2=nodes.pop();
396 if (visited.contains(fn2))
399 for (int j=0;j<fn2.numNext();j++) {
400 FlatNode fn2next=fn2.getNext(j);
401 if (delayset.contains(fn2next)||atomictable.get(fn2next).intValue()==0) {
402 reachable.add(fn2next);
410 public void analyzeMethod(LocalityBinding lb) {
411 MethodDescriptor md=lb.getMethod();
412 FlatMethod fm=state.getMethodFlat(md);
413 HashSet<FlatNode> cannotdelay=new HashSet<FlatNode>();
414 Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
416 //We are in a transaction already...
417 //skip past this method or something
421 HashSet<FlatNode> toanalyze=new HashSet<FlatNode>();
422 toanalyze.addAll(fm.getNodeSet());
424 //Build the hashtables
425 Hashtable<FlatNode, HashSet<TempDescriptor>> nodelaytemps=new Hashtable<FlatNode, HashSet<TempDescriptor>>();
426 Hashtable<FlatNode, HashSet<FieldDescriptor>> nodelayfieldswr=new Hashtable<FlatNode, HashSet<FieldDescriptor>>();
427 Hashtable<FlatNode, HashSet<TypeDescriptor>> nodelayarrayswr=new Hashtable<FlatNode, HashSet<TypeDescriptor>>();
428 Hashtable<FlatNode, HashSet<FieldDescriptor>> nodelayfieldsrd=new Hashtable<FlatNode, HashSet<FieldDescriptor>>();
429 Hashtable<FlatNode, HashSet<TypeDescriptor>> nodelayarraysrd=new Hashtable<FlatNode, HashSet<TypeDescriptor>>();
431 //Effect of adding something to nodelay set is to move it up past everything in delay set
432 //Have to make sure we can do this commute
434 while(!toanalyze.isEmpty()) {
435 FlatNode fn=toanalyze.iterator().next();
436 toanalyze.remove(fn);
438 boolean isatomic=atomictable.get(fn).intValue()>0;
442 boolean isnodelay=false;
444 /* Compute incoming nodelay sets */
445 HashSet<TempDescriptor> nodelaytempset=new HashSet<TempDescriptor>();
446 HashSet<FieldDescriptor> nodelayfieldwrset=new HashSet<FieldDescriptor>();
447 HashSet<TypeDescriptor> nodelayarraywrset=new HashSet<TypeDescriptor>();
448 HashSet<FieldDescriptor> nodelayfieldrdset=new HashSet<FieldDescriptor>();
449 HashSet<TypeDescriptor> nodelayarrayrdset=new HashSet<TypeDescriptor>();
450 for(int i=0;i<fn.numNext();i++) {
451 if (nodelaytemps.containsKey(fn.getNext(i)))
452 nodelaytempset.addAll(nodelaytemps.get(fn.getNext(i)));
453 //do field/array write sets
454 if (nodelayfieldswr.containsKey(fn.getNext(i)))
455 nodelayfieldwrset.addAll(nodelayfieldswr.get(fn.getNext(i)));
456 if (nodelayarrayswr.containsKey(fn.getNext(i)))
457 nodelayarraywrset.addAll(nodelayarrayswr.get(fn.getNext(i)));
459 if (nodelayfieldsrd.containsKey(fn.getNext(i)))
460 nodelayfieldrdset.addAll(nodelayfieldsrd.get(fn.getNext(i)));
461 if (nodelayarrayswr.containsKey(fn.getNext(i)))
462 nodelayarraywrset.addAll(nodelayarrayswr.get(fn.getNext(i)));
465 /* Check our temp write set */
467 TempDescriptor writeset[]=fn.writesTemps();
468 for(int i=0;i<writeset.length;i++) {
469 TempDescriptor tmp=writeset[i];
470 if (nodelaytempset.contains(tmp)) {
471 //We are writing to a nodelay temp
472 //Therefore we are nodelay
474 //Kill temp we wrote to
475 nodelaytempset.remove(tmp);
479 //See if flatnode is definitely no delay
480 if (fn.kind()==FKind.FlatCall) {
482 //Have to deal with fields/arrays
483 FlatCall fcall=(FlatCall)fn;
484 MethodDescriptor mdcall=fcall.getMethod();
485 nodelayfieldwrset.addAll(gft.getFieldsAll(mdcall));
486 nodelayarraywrset.addAll(typeanalysis.expandSet(gft.getArraysAll(mdcall)));
487 //Have to deal with field/array reads
488 nodelayfieldrdset.addAll(gft.getFieldsRdAll(mdcall));
489 nodelayarrayrdset.addAll(typeanalysis.expandSet(gft.getArraysRdAll(mdcall)));
492 //Delay branches if possible
493 if (fn.kind()==FKind.FlatCondBranch) {
494 Set<FlatNode> leftset=getNext(fn, 0, cannotdelay, lb, locality,true);
495 Set<FlatNode> rightset=getNext(fn, 1, cannotdelay, lb, locality,true);
496 if (leftset.size()>0&&rightset.size()>0&&
497 !leftset.equals(rightset)||leftset.size()>1)
501 //Check for field conflicts
502 if (fn.kind()==FKind.FlatSetFieldNode) {
503 FieldDescriptor fd=((FlatSetFieldNode)fn).getField();
505 if (nodelayfieldwrset.contains(fd))
508 if (nodelayfieldrdset.contains(fd))
512 if (fn.kind()==FKind.FlatFieldNode) {
513 FieldDescriptor fd=((FlatFieldNode)fn).getField();
515 if (nodelayfieldwrset.contains(fd))
519 //Check for array conflicts
520 if (fn.kind()==FKind.FlatSetElementNode) {
521 TypeDescriptor td=((FlatSetElementNode)fn).getDst().getType();
522 //check for write conflicts
523 if (nodelayarraywrset.contains(td))
525 //check for read conflicts
526 if (nodelayarrayrdset.contains(td))
529 if (fn.kind()==FKind.FlatElementNode) {
530 TypeDescriptor td=((FlatElementNode)fn).getSrc().getType();
531 //check for write conflicts
532 if (nodelayarraywrset.contains(td))
536 //If we are no delay, then the temps we read are no delay
538 /* Add our read set */
539 TempDescriptor readset[]=fn.readsTemps();
540 for(int i=0;i<readset.length;i++) {
541 TempDescriptor tmp=readset[i];
542 nodelaytempset.add(tmp);
546 /* Do we write to fields */
547 if (fn.kind()==FKind.FlatSetFieldNode) {
548 nodelayfieldwrset.add(((FlatSetFieldNode)fn).getField());
550 /* Do we read from fields */
551 if (fn.kind()==FKind.FlatFieldNode) {
552 nodelayfieldrdset.add(((FlatFieldNode)fn).getField());
555 /* Do we write to arrays */
556 if (fn.kind()==FKind.FlatSetElementNode) {
557 //have to do expansion
558 nodelayarraywrset.addAll(typeanalysis.expand(((FlatSetElementNode)fn).getDst().getType()));
560 /* Do we read from arrays */
561 if (fn.kind()==FKind.FlatElementNode) {
562 //have to do expansion
563 nodelayarrayrdset.addAll(typeanalysis.expand(((FlatElementNode)fn).getSrc().getType()));
566 //Need to know which objects to lock on
568 case FKind.FlatSetFieldNode: {
569 FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
570 nodelaytempset.add(fsfn.getDst());
573 case FKind.FlatSetElementNode: {
574 FlatSetElementNode fsen=(FlatSetElementNode)fn;
575 nodelaytempset.add(fsen.getDst());
578 case FKind.FlatFieldNode: {
579 FlatFieldNode ffn=(FlatFieldNode)fn;
580 nodelaytempset.add(ffn.getSrc());
583 case FKind.FlatElementNode: {
584 FlatElementNode fen=(FlatElementNode)fn;
585 nodelaytempset.add(fen.getSrc());
591 boolean changed=false;
592 //See if we need to propagate changes
593 if (!nodelaytemps.containsKey(fn)||
594 !nodelaytemps.get(fn).equals(nodelaytempset)) {
595 nodelaytemps.put(fn, nodelaytempset);
599 //See if we need to propagate changes
600 if (!nodelayfieldswr.containsKey(fn)||
601 !nodelayfieldswr.get(fn).equals(nodelayfieldwrset)) {
602 nodelayfieldswr.put(fn, nodelayfieldwrset);
606 //See if we need to propagate changes
607 if (!nodelayfieldsrd.containsKey(fn)||
608 !nodelayfieldsrd.get(fn).equals(nodelayfieldrdset)) {
609 nodelayfieldsrd.put(fn, nodelayfieldrdset);
613 //See if we need to propagate changes
614 if (!nodelayarrayswr.containsKey(fn)||
615 !nodelayarrayswr.get(fn).equals(nodelayarraywrset)) {
616 nodelayarrayswr.put(fn, nodelayarraywrset);
620 //See if we need to propagate changes
621 if (!nodelayarraysrd.containsKey(fn)||
622 !nodelayarraysrd.get(fn).equals(nodelayarrayrdset)) {
623 nodelayarraysrd.put(fn, nodelayarrayrdset);
628 for(int i=0;i<fn.numPrev();i++)
629 toanalyze.add(fn.getPrev(i));
632 if (lb.getHasAtomic()) {
633 cannotdelaymap.put(lb, cannotdelay);
638 //1) we acquire locks too early to object we don't need to yet
639 //2) we don't realize that certain operations have side effects
641 public HashSet<FlatNode> computeNotReadySet(LocalityBinding lb, HashSet<FlatNode> cannotdelay) {
642 //You are in not ready set if:
643 //I. You read a not ready temp
644 //II. You access a field or element and
645 //(A). You are not in the cannot delay set
646 //(B). You read a field/element in the transactional set
647 //(C). The source didn't have a transactional read on it
649 MethodDescriptor md=lb.getMethod();
650 FlatMethod fm=state.getMethodFlat(md);
651 Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
653 HashSet<FlatNode> notreadynodes=new HashSet<FlatNode>();
654 HashSet<FlatNode> toanalyze=new HashSet<FlatNode>();
655 toanalyze.addAll(fm.getNodeSet());
656 Hashtable<FlatNode, HashSet<TempDescriptor>> notreadymap=new Hashtable<FlatNode, HashSet<TempDescriptor>>();
658 while(!toanalyze.isEmpty()) {
659 FlatNode fn=toanalyze.iterator().next();
660 toanalyze.remove(fn);
661 boolean isatomic=atomictable.get(fn).intValue()>0;
666 //Compute initial notready set
667 HashSet<TempDescriptor> notreadyset=new HashSet<TempDescriptor>();
668 for(int i=0;i<fn.numPrev();i++) {
669 if (notreadymap.containsKey(fn.getPrev(i)))
670 notreadyset.addAll(notreadymap.get(fn.getPrev(i)));
674 boolean notready=false;
676 //Test our read set first
677 TempDescriptor readset[]=fn.readsTemps();
678 for(int i=0;i<readset.length;i++) {
679 TempDescriptor tmp=readset[i];
680 if (notreadyset.contains(tmp)) {
686 if (!notready&&!cannotdelay.contains(fn)) {
688 case FKind.FlatFieldNode: {
689 FlatFieldNode ffn=(FlatFieldNode)fn;
690 if (!dcopts.getFields().contains(ffn.getField())) {
693 TempDescriptor tmp=ffn.getSrc();
694 Set<TempFlatPair> tfpset=dcopts.getMap(lb).get(fn).get(tmp);
696 for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
697 TempFlatPair tfp=tfpit.next();
698 if (!dcopts.getNeedSrcTrans(lb, tfp.f)) {
699 //if a source didn't need a translation and we are
700 //accessing it, it did...so therefore we are note
709 case FKind.FlatSetFieldNode: {
710 FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
711 TempDescriptor tmp=fsfn.getDst();
712 Hashtable<TempDescriptor, Set<TempFlatPair>> tmpmap=dcopts.getMap(lb).get(fn);
713 Set<TempFlatPair> tfpset=tmpmap!=null?tmpmap.get(tmp):null;
716 for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
717 TempFlatPair tfp=tfpit.next();
718 if (!dcopts.getNeedSrcTrans(lb, tfp.f)) {
719 //if a source didn't need a translation and we are
720 //accessing it, it did...so therefore we are note
729 case FKind.FlatElementNode: {
730 FlatElementNode fen=(FlatElementNode)fn;
731 if (!dcopts.getArrays().contains(fen.getSrc().getType())) {
734 TempDescriptor tmp=fen.getSrc();
735 Set<TempFlatPair> tfpset=dcopts.getMap(lb).get(fn).get(tmp);
737 for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
738 TempFlatPair tfp=tfpit.next();
739 if (!dcopts.getNeedSrcTrans(lb, tfp.f)) {
740 //if a source didn't need a translation and we are
741 //accessing it, it did...so therefore we are note
750 case FKind.FlatSetElementNode: {
751 FlatSetElementNode fsen=(FlatSetElementNode)fn;
752 TempDescriptor tmp=fsen.getDst();
753 Set<TempFlatPair> tfpset=dcopts.getMap(lb).get(fn).get(tmp);
755 for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
756 TempFlatPair tfp=tfpit.next();
757 if (!dcopts.getNeedSrcTrans(lb, tfp.f)) {
758 //if a source didn't need a translation and we are
759 //accessing it, it did...so therefore we are note
771 //Fix up things based on our status
774 notreadynodes.add(fn);
776 TempDescriptor writeset[]=fn.writesTemps();
777 for(int i=0;i<writeset.length;i++) {
778 TempDescriptor tmp=writeset[i];
779 notreadyset.add(tmp);
783 TempDescriptor writeset[]=fn.writesTemps();
784 for(int i=0;i<writeset.length;i++) {
785 TempDescriptor tmp=writeset[i];
786 notreadyset.remove(tmp);
790 //See if we need to propagate changes
791 if (!notreadymap.containsKey(fn)||
792 !notreadymap.get(fn).equals(notreadyset)) {
793 notreadymap.put(fn, notreadyset);
794 for(int i=0;i<fn.numNext();i++)
795 toanalyze.add(fn.getNext(i));
798 return notreadynodes;
799 } //end of computeNotReadySet