}
//This method computes which temps are live into the second part
- public Set<TempDescriptor> liveinto(LocalityBinding lb, FlatAtomicEnterNode faen, Set<FlatNode> liveset) {
+ public Set<TempDescriptor> liveinto(LocalityBinding lb, FlatAtomicEnterNode faen, Set<FlatNode> recordset) {
MethodDescriptor md=lb.getMethod();
FlatMethod fm=state.getMethodFlat(md);
Set<FlatNode> atomicnodes=faen.getReachableSet(faen.getExits());
//Compute second part set of nodes
Set<FlatNode> secondpart=new HashSet<FlatNode>();
secondpart.addAll(getNotReady(lb));
- secondpart.addAll(liveset);
+ secondpart.addAll(recordset);
//make it just this transaction
secondpart.retainAll(atomicnodes);
for(Iterator<FlatNode> fnit=secondpart.iterator();fnit.hasNext();) {
FlatNode fn=fnit.next();
-
+ if (recordset.contains(fn))
+ continue;
TempDescriptor readset[]=fn.readsTemps();
for(int i=0;i<readset.length;i++) {
TempDescriptor rtmp=readset[i];
return livenodes;
}
- //Returns null if more than one possible next
- public static Set<FlatNode> getNext(FlatNode fn, int i, HashSet<FlatNode> delayset) {
+ public static Set<FlatNode> getBranchNodes(FlatNode fn, int i, Set<FlatNode> delayset) {
+ FlatNode fnnext=fn.getNext(i);
+ HashSet<FlatNode> reachable=new HashSet<FlatNode>();
+
+ if (delayset.contains(fnnext)) {
+ reachable.add(fnnext);
+ return reachable;
+ }
+
+ Stack<FlatNode> nodes=new Stack<FlatNode>();
+ HashSet<FlatNode> visited=new HashSet<FlatNode>();
+ nodes.push(fnnext);
+ visited.add(fn);//don't go back to the start node
+
+ while(!nodes.isEmpty()) {
+ FlatNode fn2=nodes.pop();
+ if (visited.contains(fn2))
+ continue;
+ visited.add(fn2);
+ for (int j=0;j<fn2.numNext();j++) {
+ FlatNode fn2next=fn2.getNext(j);
+ if (delayset.contains(fn2next)) {
+ reachable.add(fn2next);
+ } else
+ nodes.push(fn2next);
+ }
+ }
+ return reachable;
+ }
+
+ public static Set<FlatNode> getNext(FlatNode fn, int i, Set<FlatNode> delayset) {
FlatNode fnnext=fn.getNext(i);
HashSet<FlatNode> reachable=new HashSet<FlatNode>();
nodelayarrayrdset.addAll(typeanalysis.expandSet(gft.getArraysRdAll(mdcall)));
}
- // Can't delay branches
+ //Delay branches if possible
if (fn.kind()==FKind.FlatCondBranch) {
- isnodelay=true;
+ Set<FlatNode> leftset=getBranchNodes(fn, 0, cannotdelay);
+ Set<FlatNode> rightset=getBranchNodes(fn, 1, cannotdelay);
+ if (leftset.size()>0&&rightset.size()>0&&
+ !leftset.equals(rightset))
+ isnodelay=true;
}
//Check for field conflicts
Set<FlatNode> storeset=null;
HashSet<FlatNode> genset=null;
+ Set<FlatNode> unionset=null;
if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
storeset=delaycomp.livecode(lb);
} else {
genset.addAll(delaycomp.getNotReady(lb));
}
+ unionset=new HashSet<FlatNode>();
+ unionset.addAll(storeset);
+ unionset.addAll(genset);
}
/* Do the actual code generation */
} else if (current_node.numNext()==2) {
/* Branch */
if (state.DELAYCOMP) {
+ boolean computeside=false;
if (firstpass) {
//need to record which way it should go
- output.print(" ");
- if (storeset!=null&&storeset.contains(current_node)) {
- //need to store which way branch goes
- generateStoreFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
- } else
- generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ if (genset==null||genset.contains(current_node)) {
+ if (storeset!=null&&storeset.contains(current_node)) {
+ //need to store which way branch goes
+ generateStoreFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ } else
+ generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ } else {
+ //which side to execute
+ computeside=true;
+ }
} else {
- if (storeset.contains(current_node)) {
+ if (genset.contains(current_node)) {
+ generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ } else if (storeset.contains(current_node)) {
//need to do branch
output.println("RESTOREANDBRANCH(L"+nodetolabel.get(current_node.getNext(1))+");");
+ } else {
+ //which side to execute
+ computeside=true;
+ }
+ }
+ if (computeside) {
+ Set<FlatNode> leftset=DelayComputation.getBranchNodes(current_node, 0, unionset);
+ int branch=0;
+ if (leftset.size()==0)
+ branch=1;
+ if (visited.contains(current_node.getNext(branch))) {
+ //already visited -- build jump
+ output.println("goto L"+nodetolabel.get(current_node.getNext(branch))+";");
+ current_node=null;
+ } else {
+ current_node=current_node.getNext(branch);
}
+ } else {
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(current_node.getNext(1));
+ if (visited.contains(current_node.getNext(0))) {
+ output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
+ current_node=null;
+ } else
+ current_node=current_node.getNext(0);
}
} else {
output.print(" ");
generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(current_node.getNext(1));
+ if (visited.contains(current_node.getNext(0))) {
+ output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
+ current_node=null;
+ } else
+ current_node=current_node.getNext(0);
}
- if (!visited.contains(current_node.getNext(1)))
- tovisit.add(current_node.getNext(1));
- if (visited.contains(current_node.getNext(0))) {
- output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
- current_node=null;
- } else
- current_node=current_node.getNext(0);
} else throw new Error();
}
}