/**
*
*/
package xsched.analysis.wala.schedule_extraction;
import java.util.Iterator;
import org.eclipse.core.runtime.IProgressMonitor;
import xsched.analysis.wala.WalaConstants;
import com.ibm.wala.cfg.ControlFlowGraph;
import com.ibm.wala.dataflow.graph.BasicFramework;
import com.ibm.wala.dataflow.graph.DataflowSolver;
import com.ibm.wala.fixedpoint.impl.AbstractStatement;
import com.ibm.wala.ipa.cfg.PrunedCFG;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSACFG.BasicBlock;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.Acyclic;
import com.ibm.wala.util.intset.IBinaryNaturalRelation;
public class TaskScheduleSolver extends DataflowSolver<ISSABasicBlock, FlowData> {
public static NormalNodeFlowData solve(IR ir) {
try {
PrunedCFG<SSAInstruction, ISSABasicBlock> prunedCFG = AutomaticExceptionPrunedCFG.make(ir.getControlFlowGraph());
TaskScheduleSolver solver = new TaskScheduleSolver(ir, prunedCFG);
solver.solve((IProgressMonitor)null);
BasicBlock exit = ir.getControlFlowGraph().exit();
return (NormalNodeFlowData)solver.getIn(exit);
} catch (CancelException e) {
//
}
Assertions.UNREACHABLE();
return null;
};
/**
*
*/
final IR ir;
final ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg;
final IBinaryNaturalRelation backEdges;
private NormalNodeFlowData entry;
public TaskScheduleSolver(IR ir, ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg) {
super(new BasicFramework<ISSABasicBlock, FlowData>(cfg, new TransferFunctionProvider()));
this.ir = ir;
this.cfg = cfg;
this.backEdges = Acyclic.computeBackEdges(cfg, cfg.entry());
}
@Override
protected FlowData makeEdgeVariable(ISSABasicBlock src, ISSABasicBlock dst) {
assert src != null;
assert dst != null;
return backEdges.contains(src.getGraphNodeId(), dst.getGraphNodeId()) ?
new BackEdgeFlowData(src, dst) : new EdgeFlowData(src, dst);
}
@Override
protected FlowData makeNodeVariable(ISSABasicBlock n, boolean IN) {
assert n != null;
NormalNodeFlowData result;
int predNodeCount = cfg.getPredNodeCount(n);
if(IN && predNodeCount > 1) {
result = new JoinNodeFlowData(n, predNodeCount);
} else {
result = new NormalNodeFlowData(n);
}
// boolean isLoopHead = false;
// for(IntPair rel : backEdges) {
// if(rel.getY() == n.getGraphNodeId()) {
// isLoopHead = true;
// break;
// }
// }
if (IN && n.equals(cfg.entry())) {
entry = result;
result.initEmpty();
result.addLoopContext(LoopContext.emptyLoopContext());
}
return result;
}
@Override
protected void initializeWorkList() {
super.buildEquations(false, false);
/*
* Add only the entry variable to the work list.
*/
for (Iterator<?> it = getFixedPointSystem().getStatementsThatUse(entry); it.hasNext();) {
AbstractStatement<?, ?> s = (AbstractStatement<?, ?>) it.next();
addToWorkList(s);
}
}
@Override
protected void initializeVariables() {
super.initializeVariables();
//make sure we know the parameters
for(int i = 0; i < ir.getNumberOfParameters(); i++) {
TypeReference paramType = ir.getParameterType(i);
if(WalaConstants.isTaskType(paramType)) {
int ssaVariable = ir.getParameter(i);
entry.addFormalTaskParameter(ssaVariable);
}
}
}
}