Search in sources :

Example 1 with HoistedNestedDoStatement

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;
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) HoistedNestedDoStatement(claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement) ReshapeInfo(claw.tatsu.xcodeml.abstraction.ReshapeInfo)

Example 2 with HoistedNestedDoStatement

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;
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) XPathExpressionException(javax.xml.xpath.XPathExpressionException) NodeList(org.w3c.dom.NodeList) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) HoistedNestedDoStatement(claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement)

Example 3 with HoistedNestedDoStatement

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());
}
Also used : Context(claw.tatsu.common.Context) TestContext(helper.Utils.TestContext) TestContext(helper.Utils.TestContext) HoistedNestedDoStatement(claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement) Test(org.junit.Test)

Example 4 with HoistedNestedDoStatement

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;
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) HoistedNestedDoStatement(claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement)

Example 5 with HoistedNestedDoStatement

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();
}
Also used : FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) ClawTranslator(claw.wani.x2t.translator.ClawTranslator) HoistedNestedDoStatement(claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement) ReshapeInfo(claw.tatsu.xcodeml.abstraction.ReshapeInfo)

Aggregations

HoistedNestedDoStatement (claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement)5 Xnode (claw.tatsu.xcodeml.xnode.common.Xnode)3 ReshapeInfo (claw.tatsu.xcodeml.abstraction.ReshapeInfo)2 FfunctionDefinition (claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition)2 Context (claw.tatsu.common.Context)1 IllegalTransformationException (claw.tatsu.xcodeml.exception.IllegalTransformationException)1 ClawTranslator (claw.wani.x2t.translator.ClawTranslator)1 TestContext (helper.Utils.TestContext)1 ArrayList (java.util.ArrayList)1 XPathExpressionException (javax.xml.xpath.XPathExpressionException)1 Test (org.junit.Test)1 Element (org.w3c.dom.Element)1 NodeList (org.w3c.dom.NodeList)1