use of cx2x.translator.common.NestedDoStatement in project claw-compiler by C2SM-RCM.
the class Parallelize method transformForCPU.
/**
* Apply CPU based transformations.
*
* @param xcodeml Current XcodeML program unit.
* @throws IllegalTransformationException If promotion of arrays fails.
*/
private void transformForCPU(XcodeProgram xcodeml) throws IllegalTransformationException {
/* Create a group of nested loop with the newly defined dimension and wrap
* every assignment statement in the column loop or including data with it.
* This is for the moment a really naive transformation idea but it is our
* start point.
* Use the first over clause to do it. */
List<ClawDimension> order = getOrderedDimensionsFromDefinition(0);
List<Xnode> assignStatements = _fctDef.body().matchAll(Xcode.FASSIGNSTATEMENT);
for (Xnode assign : assignStatements) {
Xnode lhs = assign.child(Xnode.LHS);
String lhsName = (lhs.opcode() == Xcode.VAR) ? lhs.value() : lhs.matchSeq(Xcode.VARREF, Xcode.VAR).value();
NestedDoStatement loops = null;
if (lhs.opcode() == Xcode.FARRAYREF && _arrayFieldsInOut.contains(lhsName)) {
loops = new NestedDoStatement(order, xcodeml);
assign.insertAfter(loops.getOuterStatement());
loops.getInnerStatement().body().append(assign, true);
assign.delete();
} else if (lhs.opcode() == Xcode.VAR || lhs.opcode() == Xcode.FARRAYREF && _scalarFields.contains(lhsName)) {
/* If the assignment is in the column loop and is composed with some
* promoted variables, the field must be promoted and the var reference
* switch to an array reference */
if (shouldBePromoted(assign)) {
if (!_arrayFieldsInOut.contains(lhsName)) {
_arrayFieldsInOut.add(lhsName);
PromotionInfo promotionInfo;
if (lhs.opcode() == Xcode.VAR) {
// Scalar to array
promotionInfo = TransformationHelper.promoteField(lhsName, false, false, DEFAULT_OVER, _overDimensions, _fctDef, _fctType, _claw.getDimensionValues(), _claw, xcodeml, null);
} else {
// Array to array
promotionInfo = TransformationHelper.promoteField(lhsName, true, true, DEFAULT_OVER, _overDimensions, _fctDef, _fctType, _claw.getDimensionValues(), _claw, xcodeml, null);
}
_promotions.put(lhsName, promotionInfo);
}
if (lhs.opcode() == Xcode.VAR) {
adaptScalarRefToArrayReferences(xcodeml, Collections.singletonList(lhsName), DEFAULT_OVER);
} else {
TransformationHelper.adaptArrayReferences(Collections.singletonList(lhsName), DEFAULT_OVER, _fctDef.body(), _promotions, _beforeCrt, _inMiddle, _afterCrt, xcodeml);
}
loops = new NestedDoStatement(order, xcodeml);
assign.insertAfter(loops.getOuterStatement());
loops.getInnerStatement().body().append(assign, true);
assign.delete();
}
}
if (loops != null) {
// Generate the corresponding directive around the loop
AcceleratorHelper.generateLoopDirectives(_claw, xcodeml, loops.getOuterStatement(), loops.getOuterStatement(), AcceleratorHelper.NO_COLLAPSE);
}
}
// Generate the parallel region
AcceleratorHelper.generateParallelClause(_claw, xcodeml, _fctDef.body().firstChild(), _fctDef.body().lastChild());
}
use of cx2x.translator.common.NestedDoStatement in project claw-compiler by C2SM-RCM.
the class Parallelize method transformForGPU.
/**
* Apply GPU based transformation.
*
* @param xcodeml Current XcodeML program unit.
*/
private void transformForGPU(XcodeProgram xcodeml) {
AcceleratorHelper.generateLoopSeq(_claw, xcodeml, _fctDef);
/* Create a nested loop with the new defined dimensions and wrap it around
* the whole subroutine's body. This is for the moment a really naive
* transformation idea but it is our start point.
* Use the first over clause to create it. */
NestedDoStatement loops = new NestedDoStatement(getOrderedDimensionsFromDefinition(0), xcodeml);
/* Subroutine/function can have a contains section with inner subroutines or
* functions. The newly created (nested) do statements should stop before
* this contains section if it exists. */
Xnode contains = _fctDef.body().matchSeq(Xcode.FCONTAINSSTATEMENT);
if (contains != null) {
XnodeUtil.shiftStatementsInBody(_fctDef.body().child(0), contains, loops.getInnerStatement().body());
contains.insertBefore(loops.getOuterStatement());
} else {
// No contains section, all the body is copied to the do statements.
XnodeUtil.copyBody(_fctDef.body(), loops.getInnerStatement());
_fctDef.body().delete();
Xnode newBody = new Xnode(Xcode.BODY, xcodeml);
newBody.append(loops.getOuterStatement(), false);
_fctDef.append(newBody, false);
}
// Generate the data region
List<String> presents = AcceleratorHelper.getPresentVariables(xcodeml, _fctDef);
AcceleratorHelper.generateDataRegionClause(_claw, xcodeml, presents, loops.getOuterStatement(), loops.getOuterStatement());
// Generate the parallel region
List<String> privates = AcceleratorHelper.getLocalVariables(xcodeml, _fctDef);
AcceleratorHelper.generateParallelLoopClause(_claw, xcodeml, privates, loops.getOuterStatement(), loops.getOuterStatement(), loops.getGroupSize());
AcceleratorHelper.generateRoutineDirectives(_claw, xcodeml, _fctDef);
}
use of cx2x.translator.common.NestedDoStatement in project claw-compiler by C2SM-RCM.
the class ParallelizeForward method propagatePromotion.
/**
* Propagate possible promotion in assignments statements in the parent
* subroutine of the function call.
*
* @param xcodeml Current XcodeML program unit.
* @param transformer Current transformer to store information between
* transformation.
*/
private void propagatePromotion(XcodeProgram xcodeml, ClawTransformer transformer) throws IllegalTransformationException {
// Get all the assignment statements in the function definition
XfunctionDefinition parentFctDef = XnodeUtil.findParentFunction(_fctCall);
// Retrieve information of previous forward transformation in the same fct
List<String> previouslyPromoted = Utility.convertToList(transformer.hasElement(parentFctDef));
List<Xnode> assignments = parentFctDef.matchAll(Xcode.FASSIGNSTATEMENT);
List<ClawDimension> dimensions = TransformationHelper.findDimensions(_parentFctType);
// Prepare the array index to be inserted in array references.
List<Xnode> crt = new ArrayList<>();
List<Xnode> empty = Collections.emptyList();
for (ClawDimension dim : dimensions) {
crt.add(dim.generateArrayIndex(xcodeml));
}
Collections.reverse(crt);
List<List<Xnode>> induction = new ArrayList<>();
List<List<Xnode>> emptyInd = new ArrayList<>();
induction.add(crt);
emptyInd.add(empty);
for (Xnode assignment : assignments) {
Xnode lhs = assignment.child(0);
Xnode rhs = assignment.child(1);
List<Xnode> varsInRhs = rhs.matchAll(Xcode.VAR);
for (Xnode var : varsInRhs) {
// Check if the assignment statement uses a promoted variable
if (_promotedVar.contains(var.value()) && var.matchAncestor(Xcode.FUNCTIONCALL) == null && lhs.opcode() == Xcode.FARRAYREF) {
Xnode varInLhs = lhs.matchDescendant(Xcode.VAR);
if (varInLhs == null) {
throw new IllegalTransformationException("Unable to propagate " + "promotion. Internal error.", _claw.getPragma().lineNo());
}
XbasicType varType = (XbasicType) xcodeml.getTypeTable().get(varInLhs.getAttribute(Xattr.TYPE));
// Declare the induction variable if they are not present
TransformationHelper.declareInductionVariables(dimensions, parentFctDef, xcodeml);
// Generate the do statements and move the assignment statement in
NestedDoStatement doStmt = new NestedDoStatement(dimensions, xcodeml);
assignment.insertAfter(doStmt.getOuterStatement());
doStmt.getInnerStatement().body().append(assignment, false);
PromotionInfo promotionInfo;
if (!previouslyPromoted.contains(varInLhs.value().toLowerCase())) {
// Perform the promotion on the variable
promotionInfo = TransformationHelper.promoteField(varInLhs.value(), true, true, 0, 0, parentFctDef, _parentFctType, dimensions, _claw, xcodeml, null);
_promotions.put(varInLhs.value(), promotionInfo);
// TODO if #38 is implemented, the variable has to be put either in
// TODO _promotedWithBeforeOver or _promotedWithAfterOver
_promotedWithBeforeOver.add(varInLhs.value());
} else {
promotionInfo = _promotions.get(varInLhs.value());
}
// Adapt the reference in the assignment statement
TransformationHelper.adaptArrayReferences(_promotedWithBeforeOver, 0, assignment, _promotions, induction, emptyInd, emptyInd, xcodeml);
TransformationHelper.adaptArrayReferences(_promotedWithMiddleOver, 0, assignment, _promotions, emptyInd, induction, emptyInd, xcodeml);
TransformationHelper.adaptArrayReferences(_promotedWithAfterOver, 0, assignment, _promotions, emptyInd, emptyInd, induction, xcodeml);
// If the array is a target, check if we have to promote a pointer
if (!previouslyPromoted.contains(varInLhs.value().toLowerCase())) {
adaptPointer(varType, varInLhs.value(), parentFctDef, xcodeml, promotionInfo, dimensions);
// TODO centralized info
previouslyPromoted.add(varInLhs.value().toLowerCase());
}
break;
/* if one var in the rhs of the assignment statement was
* promoted it's enough and we can switch to the next assignment
* statement. */
}
}
}
transformer.storeElement(parentFctDef, previouslyPromoted);
}
Aggregations