use of cx2x.xcodeml.exception.IllegalTransformationException 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);
}
use of cx2x.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class LoopHoist method analyze.
/**
* @see Transformation#analyze(XcodeProgram, Transformer)
*/
@Override
public boolean analyze(XcodeProgram xcodeml, Transformer transformer) {
int _pragmaDepthLevel = _clawStart.getPragma().depth();
_nestedLevel = _clawStart.getHoistInductionVars().size();
// Find all the group of nested loops that can be part of the hoisting
List<Xnode> statements = XnodeUtil.findDoStatement(_clawStart.getPragma(), _clawEnd.getPragma(), _clawStart.getHoistInductionVars());
if (statements.size() == 0) {
xcodeml.addError("No do statement group meets the criteria of hoisting.", _clawStart.getPragma().lineNo());
return false;
}
for (int i = 0; i < statements.size(); i++) {
Xnode[] group = new Xnode[_nestedLevel];
LoopHoistDoStmtGroup g = new LoopHoistDoStmtGroup(group);
try {
reloadDoStmts(g, statements.get(i));
} catch (IllegalTransformationException e) {
xcodeml.addError("Group " + i + " of do statements do not meet the" + " criteria of loop hoisting (Group index starts at 0).", _clawStart.getPragma().lineNo());
return false;
}
LoopHoistDoStmtGroup crtGroup = new LoopHoistDoStmtGroup(group);
int depth = group[0].depth();
if (depth != _pragmaDepthLevel) {
Xnode tmpIf = group[0].matchAncestor(Xcode.FIFSTATEMENT);
Xnode tmpSelect = group[0].matchAncestor(Xcode.FSELECTCASESTATEMENT);
Xnode tmpDo = group[0].matchAncestor(Xcode.FDOSTATEMENT);
if (tmpIf == null && tmpSelect == null && tmpDo == null) {
xcodeml.addError("Group " + i + " is nested in an unsupported " + "statement for loop hoisting (Group index starts at 0).", _clawStart.getPragma().lineNo());
return false;
}
int ifDepth = (tmpIf != null) ? tmpIf.depth() : Xnode.UNDEF_DEPTH;
int selectDepth = (tmpSelect != null) ? tmpSelect.depth() : Xnode.UNDEF_DEPTH;
int doDepth = (tmpDo != null) ? tmpDo.depth() : Xnode.UNDEF_DEPTH;
if ((_pragmaDepthLevel <= ifDepth || _pragmaDepthLevel <= selectDepth || _pragmaDepthLevel <= doDepth) && (ifDepth < depth || selectDepth < depth || doDepth < depth)) {
crtGroup.setExtraction();
} else {
xcodeml.addError("Group " + i + " is nested in an unsupported " + "statement for loop hoisting or depth is too high " + "(Group index starts at 0).", _clawStart.getPragma().lineNo());
return false;
}
}
_doGroup.add(crtGroup);
}
LoopHoistDoStmtGroup master = _doGroup.get(0);
for (int i = 1; i < _doGroup.size(); ++i) {
LoopHoistDoStmtGroup next = _doGroup.get(i);
for (int j = 0; j < master.getDoStmts().length; ++j) {
// Iteration range are identical, just merge
if (j == 0 && (!XnodeUtil.hasSameIndexRange(master.getDoStmts()[j], next.getDoStmts()[j]) && XnodeUtil.hasSameIndexRangeBesidesLower(master.getDoStmts()[j], next.getDoStmts()[j]))) {
// Iteration range are identical besides lower-bound, if creation
next.setIfStatement();
} else if (!XnodeUtil.hasSameIndexRange(master.getDoStmts()[j], next.getDoStmts()[j])) {
// Iteration range are too different, stop analysis
xcodeml.addError("Iteration range of do statements group " + i + " differs from group 0. Loop hoisting aborted.", _clawStart.getPragma().lineNo());
return false;
}
}
}
// Check reshape mandatory points
if (_clawStart.hasReshapeClause()) {
XfunctionDefinition fctDef = XnodeUtil.findParentFunction(_clawStart.getPragma());
if (fctDef == null) {
xcodeml.addError("Unable to matchSeq the function/subroutine/module " + "definition including the current directive", _clawStart.getPragma().lineNo());
return false;
}
for (ClawReshapeInfo r : _clawStart.getReshapeClauseValues()) {
if (!fctDef.getSymbolTable().contains(r.getArrayName()) || !fctDef.getDeclarationTable().contains(r.getArrayName())) {
// Check in the parent def if present
if (!checkUpperDefinition(fctDef, r.getArrayName())) {
xcodeml.addError(String.format("Reshape variable %s not found in " + "the definition of %s", r.getArrayName(), fctDef.getName().value()), _clawStart.getPragma().lineNo());
return false;
}
}
}
}
return true;
}
use of cx2x.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class LoopFusion method transform.
/**
* Apply the loop fusion transformation.
*
* @param xcodeml The XcodeML on which the transformations are
* applied.
* @param transformer The transformer used to applied the transformations.
* @param transformation The other loop fusion unit to be merge with this
* one.
* @throws IllegalTransformationException if the transformation cannot be
* applied.
*/
@Override
public void transform(XcodeProgram xcodeml, Transformer transformer, Transformation transformation) throws IllegalTransformationException {
if (!(transformation instanceof LoopFusion)) {
throw new IllegalTransformationException("Incompatible transformation", _claw.getPragma().lineNo());
}
LoopFusion other = (LoopFusion) transformation;
// Apply different transformation if the collapse clause is used
if (_claw != null && _claw.hasCollapseClause() && _claw.getCollapseValue() > 0) {
// Merge the most inner loop with the most inner loop of the other fusion
// unit
int innerDoStmtIdx = _claw.getCollapseValue() - 1;
if (_doStmts[innerDoStmtIdx] == null || other.getDoStmtAtIndex(innerDoStmtIdx) == null) {
throw new IllegalTransformationException("Cannot apply transformation, one or both do stmt are invalid.", _claw.getPragma().lineNo());
}
XnodeUtil.appendBody(_doStmts[innerDoStmtIdx].body(), other.getDoStmtAtIndex(innerDoStmtIdx).body());
} else {
// Without collapse clause, only first do statements are considered.
XnodeUtil.appendBody(_doStmts[0].body(), other.getDoStmtAtIndex(0).body());
}
other.finalizeTransformation();
// Delete the pragma statement
XnodeUtil.safeDelete(_claw.getPragma());
}
use of cx2x.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class ParallelizeForward method updateResultVar.
/**
* Apply promotion to the result return variable of a forward call.
*
* @param xcodeml Current XcodeML program unit.
* @throws IllegalTransformationException If XcodeML transformation cannot be
* done.
*/
private void updateResultVar(XcodeProgram xcodeml) throws IllegalTransformationException {
if (_isNestedInAssignment) {
Xnode assignment = _claw.getPragma().nextSibling();
if (assignment == null || !_fctType.hasAttribute(ClawAttr.OVER.toString())) {
return;
}
OverPosition overPos = OverPosition.fromString(_fctType.getAttribute(ClawAttr.OVER.toString()));
Xnode lhs = assignment.child(0);
// TODO handle the case when the array ref is a var directly
Xnode varInLhs = lhs.matchDescendant(Xcode.VAR);
List<ClawDimension> dimensions = TransformationHelper.findDimensions(_parentFctType);
XfunctionDefinition parentFctDef = XnodeUtil.findParentFunction(_fctCall);
XbasicType varType = (XbasicType) xcodeml.getTypeTable().get(varInLhs.getAttribute(Xattr.TYPE));
PromotionInfo promotionInfo;
if (!_promotions.containsKey(varInLhs.value())) {
// Perform the promotion on the variable
promotionInfo = TransformationHelper.promoteField(varInLhs.value(), true, true, 0, 0, parentFctDef, _parentFctType, dimensions, _claw, xcodeml, overPos);
_promotions.put(varInLhs.value(), promotionInfo);
addPromotedVar(varInLhs.value(), overPos);
} else {
promotionInfo = _promotions.get(varInLhs.value());
}
// Adapt array index to reflect the new return type
if (lhs.opcode() == Xcode.FARRAYREF) {
for (int i = 0; i < promotionInfo.diffDimension(); ++i) {
Xnode indexRange = xcodeml.createEmptyAssumedShaped();
lhs.append(indexRange, false);
}
/*} else if(lhs.opcode() == Xcode.VAR) {
// TODO avoid array var without colon notation
/* throw new IllegalTransformationException("Use the colon notation "
+ "for the return variable. This notation is not supported." +
_claw.getPragma().value()); */
} else {
throw new IllegalTransformationException("Unsupported return " + "variable for promotion.", _claw.getPragma().lineNo());
}
// If the array is a target, check if we have to promote a pointer
adaptPointer(varType, varInLhs.value(), parentFctDef, xcodeml, promotionInfo, dimensions);
}
}
use of cx2x.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class XcodeML method write.
/**
* Write the XcodeML to file or std out
*
* @param outputFile Path of the output file or null to output on std out
* @param indent Number of spaces used for the indentation
* @throws IllegalTransformationException if XML file cannot be written.
*/
public void write(String outputFile, int indent) throws IllegalTransformationException {
try {
cleanEmptyTextNodes(this.getDocument());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(indent));
DOMSource source = new DOMSource(this.getDocument());
if (outputFile == null) {
// Output to console
StreamResult console = new StreamResult(System.out);
transformer.transform(source, console);
} else {
// Output to file
StreamResult console = new StreamResult(new File(outputFile));
transformer.transform(source, console);
}
} catch (Exception ignored) {
throw new IllegalTransformationException("Cannot output file: " + outputFile, 0);
}
}
Aggregations