CommonOmpForNode.java
package edu.udel.cis.vsl.abc.ast.node.common.omp;
import java.io.PrintStream;
import edu.udel.cis.vsl.abc.ast.IF.ASTException;
import edu.udel.cis.vsl.abc.ast.IF.DifferenceObject;
import edu.udel.cis.vsl.abc.ast.IF.DifferenceObject.DiffKind;
import edu.udel.cis.vsl.abc.ast.node.IF.ASTNode;
import edu.udel.cis.vsl.abc.ast.node.IF.SequenceNode;
import edu.udel.cis.vsl.abc.ast.node.IF.expression.ExpressionNode;
import edu.udel.cis.vsl.abc.ast.node.IF.expression.FunctionCallNode;
import edu.udel.cis.vsl.abc.ast.node.IF.omp.OmpForNode;
import edu.udel.cis.vsl.abc.ast.node.IF.statement.StatementNode;
import edu.udel.cis.vsl.abc.token.IF.Source;
/**
* This implements the OpenMP loop construct. The loop construct specifies that
* the iterations of one or more associated loops will be executed in parallel
* by threads in the team in the context of their implicit tasks. The iterations
* are distributed across threads that already exist in the team executing the
* parallel region to which the loop region binds.<br>
* The syntax of the loop construct is as follows:<br>
* <code>
* #pragma omp for [clause[[,] clause] ... ] new-line <br>
* for-loops<br>
* </code> where clause is one of the following:<br>
* <code>private(list)<br>
* firstprivate(list) <br>
* lastprivate(list) <br>
* reduction(reduction-identifier: list) <br>
* schedule(kind[, chunk_size]) <br>
* collapse(n)<br>
* ordered<br>
* nowait<br></code>
*
* @author Manchun Zheng
*
*/
public class CommonOmpForNode extends CommonOmpWorkshareNode implements OmpForNode {
/**
* The schedule specified by the optional schedule clause
* <code>schedule(kind[, chunk_size])</code>. The schedule can be one of the
* following:
* <ul>
* <li>STATIC (default)</li>
* <li>DYNAMIC</li>
* <li>GUIDED</li>
* <li>AUTO</li>
* <li>RUNTIME</li>
* </ul>
*/
private OmpScheduleKind schedule;
/**
* The number of loops of this node, specified by the optional clause
* <code>collapse(n)</code>. If <code>collapse(n)</code> is absent, collapse is
* 1 by default.
*/
private int collapse;
/**
* 0 iff the clause <code>ordered</code> is NOT present, <br>
* 1 iff it is presented without specified number of associated loops, <br>
* or the positive integer value specified as the number of associated loops.
*/
private int ordered;
/**
* Creates a new instance of CommonOmpForNode. The children are:
*
* <ul>
* <li>Children 0-7: same as {@link CommonOmpStatementNode};</li>
* <li>Child 8: ExpressionNode, the expression of chunk_size in
* <code>schedule()</code> ;</li>
* <li>Child 9: SequenceNode<FunctionCallNode>, the list of assertions to
* be checked befor entering the for loop;</li>
* <li>Child 10: FunctionCallNode, the loop invariant;</li>
* </ul>
* All children are set to null except the statement node.
*
* @param source The source code element of the OpenMP for node.
* @param statement The statement node of the OpenMP for node to be created.
*/
public CommonOmpForNode(Source source, StatementNode statement) {
super(source, OmpWorksharingNodeKind.FOR, statement);
collapse = 1;
schedule = OmpScheduleKind.NONE;
ordered = 0;
this.addChild(null);// child 8
this.addChild(null);// child 9
this.addChild(null);// child 10
}
@Override
public OmpScheduleKind schedule() {
return this.schedule;
}
@Override
public int collapse() {
return this.collapse;
}
@SuppressWarnings("unchecked")
@Override
public SequenceNode<FunctionCallNode> assertions() {
return (SequenceNode<FunctionCallNode>) this.child(9);
}
@Override
public FunctionCallNode invariant() {
return (FunctionCallNode) this.child(10);
}
@Override
protected void printBody(PrintStream out) {
out.print("OmpFor");
}
@Override
public ExpressionNode chunkSize() {
return (ExpressionNode) this.child(8);
}
@Override
public void setSchedule(OmpScheduleKind ompScheduleKind) {
this.schedule = ompScheduleKind;
}
@Override
public void setCollapse(int value) {
this.collapse = value;
}
@Override
public void setOrdered(int value) {
this.ordered = value;
}
@Override
public void setChunsize(ExpressionNode chunkSize) {
this.setChild(8, chunkSize);
}
@Override
protected void printExtras(String prefix, PrintStream out) {
String scheduleText;
ExpressionNode chunkSize = (ExpressionNode) this.child(8);
switch (schedule) {
case STATIC:
scheduleText = "static";
break;
case DYNAMIC:
scheduleText = "dynamic";
break;
case GUIDED:
scheduleText = "guided";
break;
case AUTO:
scheduleText = "auto";
break;
case RUNTIME:
scheduleText = "runtime";
break;
default:// NONE
scheduleText = null;
}
if (chunkSize != null && scheduleText != null) {
out.println();
out.print(prefix + "schedule(");
out.print(scheduleText);
out.print(",");
out.print(chunkSize.toString());
out.print(")");
}
if (collapse > 1) {
out.println();
out.print(prefix + "collapse(");
out.print(this.collapse);
out.print(")");
}
if (this.ordered > 0) {
out.println();
out.print("ordered");
if (this.ordered > 1)
out.print("(" + this.ordered + ")");
}
super.printExtras(prefix, out);
}
@Override
public void setAssertions(SequenceNode<FunctionCallNode> assertions) {
this.setChild(9, assertions);
}
@Override
public void setInvariant(FunctionCallNode invariant) {
this.setChild(9, invariant);
}
@Override
public OmpForNode copy() {
OmpForNode newForNode = new CommonOmpForNode(this.getSource(), duplicate(statementNode()));
newForNode.setCollapse(this.collapse);
newForNode.setOrdered(this.ordered);
newForNode.setSchedule(this.schedule);
return newForNode;
}
@Override
protected DifferenceObject diffWork(ASTNode that) {
if (that instanceof OmpForNode) {
OmpForNode thatFor = (OmpForNode) that;
if (this.collapse == thatFor.collapse() && this.ordered == thatFor.ordered()
&& this.schedule == thatFor.schedule())
return null;
else
return new DifferenceObject(this, that, DiffKind.OTHER, "different collapse/ordered/schedule clauses");
}
return new DifferenceObject(this, that);
}
@Override
public ASTNode setChild(int index, ASTNode child) {
if (index >= 11)
throw new ASTException("CommonOmpForNode has eleven children, but saw index " + index);
switch (index) {
case 8:
if (!(child == null || child instanceof ExpressionNode))
throw new ASTException("Child of CommonOmpForNode at index " + index
+ " must be a ExpressionNode, but saw " + child + " with type " + child.nodeKind());
break;
case 9:
if (!(child == null || child instanceof SequenceNode))
throw new ASTException("Child of CommonOmpForNode at index " + index
+ " must be a SequenceNode, but saw " + child + " with type " + child.nodeKind());
break;
case 10:
if (!(child == null || child instanceof FunctionCallNode))
throw new ASTException("Child of CommonOmpForNode at index " + index
+ " must be a FunctionCallNode, but saw " + child + " with type " + child.nodeKind());
break;
default:
break;
}
return super.setChild(index, child);
}
@Override
public boolean isOrdered() {
return this.ordered > 0;
}
@Override
public int ordered() {
return this.ordered;
}
}