use of claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement in project claw-compiler by C2SM-RCM.
the class LoopHoist method analyze.
/**
* @see Transformation#analyze(XcodeProgram, Translator)
*/
@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
if (_clawEnd == null) {
xcodeml.addError("loop-hoist directive requires an end directive.", _clawStart.getPragma().lineNo());
return false;
}
int pragmaDepthLevel = _clawStart.getPragma().depth();
// Find all the group of nested loops that can be part of the hoisting
List<HoistedNestedDoStatement> statements = XnodeUtil.findDoStatementForHoisting(_clawStart.getPragma(), _clawEnd.getPragma(), _clawStart.values(ClawClause.HOIST_INDUCTIONS));
if (statements.isEmpty()) {
xcodeml.addError("No do statement group meets the criteria of hoisting.", _clawStart.getPragma().lineNo());
return false;
}
for (HoistedNestedDoStatement hoistedNestedDoStmt : statements) {
int depth = hoistedNestedDoStmt.getOuterStatement().depth();
if (depth != pragmaDepthLevel) {
Xnode tmpIf = hoistedNestedDoStmt.getOuterStatement().matchAncestor(Xcode.F_IF_STATEMENT);
Xnode tmpSelect = hoistedNestedDoStmt.getOuterStatement().matchAncestor(Xcode.F_SELECT_CASE_STATEMENT);
Xnode tmpDo = hoistedNestedDoStmt.getOuterStatement().matchAncestor(Xcode.F_DO_STATEMENT);
if (tmpIf == null && tmpSelect == null && tmpDo == null) {
xcodeml.addError("A nested do stmt group is nested in an unsupported " + "statement for loop hoisting.", hoistedNestedDoStmt.getOuterStatement().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)) {
hoistedNestedDoStmt.setExtraction();
} else {
xcodeml.addError("Group is nested in an unsupported " + "statement for loop hoisting or depth is too high " + "(Group index starts at 0).", _clawStart.getPragma().lineNo());
return false;
}
}
_hoistedGroups.add(hoistedNestedDoStmt);
}
HoistedNestedDoStatement master = _hoistedGroups.get(0);
for (int i = 1; i < _hoistedGroups.size(); ++i) {
HoistedNestedDoStatement next = _hoistedGroups.get(i);
for (int j = 0; j < master.size(); ++j) {
// Iteration range are identical, just merge
if (j == 0 && (!Loop.hasSameIndexRange(master.get(j), next.get(j)) && Loop.hasSameIndexRangeBesidesLower(master.get(j), next.get(j)))) {
// Iteration range are identical besides lower-bound, if creation
next.setIfStatement();
} else if (!Loop.hasSameIndexRange(master.get(j), next.get(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.hasClause(ClawClause.RESHAPE)) {
FfunctionDefinition fctDef = _clawStart.getPragma().findParentFunction();
if (fctDef == null) {
xcodeml.addError("Unable to matchSeq the function/subroutine/module " + "definition including the current directive", _clawStart.getPragma().lineNo());
return false;
}
for (ReshapeInfo 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()), _clawStart.getPragma().lineNo());
return false;
}
}
}
}
return true;
}
use of claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement in project claw-compiler by C2SM-RCM.
the class XnodeUtil method findDoStatementForHoisting.
/**
* Find all the nested do statement groups following the inductions iterations
* define in inductionVars and being located between the "from" element and the
* end pragma.
*
* @param from Element from which the search is started.
* @param endPragma End pragma that terminates the search block.
* @param inductionVars Induction variables that define the nested group to
* locates.
* @return List of do statements elements (outer most loops for each nested
* group) found between the "from" element and the end pragma.
*/
public static List<HoistedNestedDoStatement> findDoStatementForHoisting(Xnode from, Xnode endPragma, List<String> inductionVars) {
/*
* s1 is selecting all the nested do statement groups that meet the criteria
* from the "from" element down to the end of the block.
*/
String s1 = "following::";
String dynamicPartS1 = "";
for (int i = inductionVars.size() - 1; i >= 0; --i) {
/*
* Here is example of there xpath query format for 1,2 and 3 nested loops
*
* FdoStatement[Var[text()="induction_var"]]
*
* FdoStatement[Var[text()="induction_var"] and
* body[FdoStatement[Var[text()="induction_var"]]]
*
* FdoStatement[Var[text()="induction_var"] and
* body[FdoStatement[Var[text()="induction_var"] and
* body[FdoStatement[Var[text()="induction_var"]]]]
*/
String tempQuery;
if (i == inductionVars.size() - 1) {
// first iteration
tempQuery = String.format("%s[%s[text()=\"%s\"]]", Xname.F_DO_STATEMENT, Xname.VAR, inductionVars.get(i));
} else {
tempQuery = String.format("%s[%s[text()=\"%s\"] and %s[%s]]", Xname.F_DO_STATEMENT, Xname.VAR, inductionVars.get(i), Xname.BODY, // Including previously formed xpath query
dynamicPartS1);
}
dynamicPartS1 = tempQuery;
}
s1 += dynamicPartS1;
List<HoistedNestedDoStatement> doStatements = new ArrayList<>();
try {
NodeList output = evaluateXpath(from.element(), s1);
for (int i = 0; i < output.getLength(); i++) {
Element el = (Element) output.item(i);
Xnode doStmt = new Xnode(el);
if (doStmt.lineNo() != 0 && doStmt.lineNo() < endPragma.lineNo() && doStmt.lineNo() > from.lineNo()) {
doStatements.add(new HoistedNestedDoStatement(doStmt, inductionVars.size()));
}
}
} catch (XPathExpressionException ignored) {
}
return doStatements;
}
use of claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement in project claw-compiler by C2SM-RCM.
the class XnodeUtilTest method xpathIntersectTest.
@Test
public void xpathIntersectTest() {
Context context = new TestContext();
assertTrue(Files.exists(TestConstant.TEST_PROGRAM));
XcodeProgram xcodeml = XcodeProgram.createFromFile(TestConstant.TEST_PROGRAM, context);
assertNotNull(xcodeml);
List<Xnode> pragmas = xcodeml.matchAll(Xcode.F_PRAGMA_STATEMENT);
assertEquals(4, pragmas.size());
Xnode loopHoistStart = new Xnode(pragmas.get(1).element());
assertNotNull(loopHoistStart);
assertTrue(loopHoistStart.value().contains("loop-hoist"));
Xnode loopHoistEnd = new Xnode(pragmas.get(2).element());
assertNotNull(loopHoistEnd);
assertTrue(loopHoistEnd.value().contains("end loop-hoist"));
List<HoistedNestedDoStatement> stmts = XnodeUtil.findDoStatementForHoisting(loopHoistStart, loopHoistEnd, Arrays.asList("j", "i"));
assertEquals(3, stmts.size());
}
use of claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement in project claw-compiler by C2SM-RCM.
the class Loop method hoist.
/**
* Perform a loop hoisting on the given nested do statements.
*
* @param hoistedGroups List of groups that will be hoisted.
* @param start Starting point of the hoisted loop.
* @param end Ending point of the hoisted loop.
* @param xcodeml Current XcodeML translation unit for node creation.
* @return Hoisted nested do statement group.
* @throws IllegalTransformationException If underlying methods throw exception.
*/
public static HoistedNestedDoStatement hoist(List<HoistedNestedDoStatement> hoistedGroups, Xnode start, Xnode end, XcodeML xcodeml) throws IllegalTransformationException {
// Perform IF extraction and IF creation for lower-bound
for (HoistedNestedDoStatement g : hoistedGroups) {
if (g.needIfStatement()) {
createIfStatementForLowerBound(xcodeml, g);
}
Loop.extractBody(g.getInnerStatement(), g.getOuterStatement());
g.getOuterStatement().delete();
}
// Do the hoisting
HoistedNestedDoStatement hoisted = hoistedGroups.get(0).cloneNestedGroup();
hoisted.getInnerStatement().body().delete();
Xnode newBody = xcodeml.createNode(Xcode.BODY);
hoisted.getInnerStatement().append(newBody);
Body.shiftIn(start, end, newBody, false);
start.insertAfter(hoisted.getOuterStatement());
return hoisted;
}
use of claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement in project claw-compiler by C2SM-RCM.
the class LoopHoist method transform.
/**
* @see Transformation#transform(XcodeProgram, Translator, Transformation)
*/
@Override
public void transform(XcodeProgram xcodeml, Translator translator, Transformation transformation) throws Exception {
ClawTranslator ct = (ClawTranslator) translator;
HoistedNestedDoStatement hoisted = Loop.hoist(_hoistedGroups, _clawStart.getPragma(), _clawEnd.getPragma(), xcodeml);
// Generate dynamic transformation (interchange)
ct.generateAdditionalTransformation(_clawStart, xcodeml, hoisted.getOuterStatement());
// Apply cleanup clause
if (_clawStart.hasClause(ClawClause.CLEANUP)) {
Pragma.remove(_clawStart.getCleanupClauseValue(), _clawStart.getPragma(), _clawEnd.getPragma());
}
// Apply reshape clause
if (_clawStart.hasClause(ClawClause.RESHAPE)) {
FfunctionDefinition fctDef = _clawStart.getPragma().findParentFunction();
if (fctDef == null) {
throw new IllegalTransformationException("Cannot apply reshape clause." + "Parent function definition not found.", _clawStart.getPragma().lineNo());
}
for (ReshapeInfo reshapeInfo : _clawStart.getReshapeClauseValues()) {
Field.reshape(fctDef, reshapeInfo, xcodeml);
}
}
removePragma();
}
Aggregations