Search in sources :

Example 1 with NestedDoStatement

use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.

the class ScaGPU method applySpecificTransformation.

/**
 * Apply specific transformation steps for GPU target.
 *
 * @param xcodeml Current translation unit.
 * @throws IllegalTransformationException If any transformation fails.
 */
private void applySpecificTransformation(Configuration cfg, XcodeProgram xcodeml) throws IllegalTransformationException {
    final Context context = xcodeml.context();
    AcceleratorConfiguration config = cfg.accelerator();
    if (_fctDef.hasEmptyBody()) {
        // Nothing to do in this function
        return;
    }
    /*
         * 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;
    if (forceAssumedShapedArrayPromotion) {
        if (_promotions.isEmpty()) {
            throw new IllegalTransformationException("Cannot assume shape of " + "array in elemental function/subroutine.", _claw.getPragma().lineNo());
        }
        PromotionInfo pi = _promotions.entrySet().iterator().next().getValue();
        loops = new NestedDoStatement(_claw.getDefaultLayoutReversed(cfg), pi, xcodeml);
    } else {
        loops = new NestedDoStatement(_claw.getDefaultLayoutReversed(cfg), 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.F_CONTAINS_STATEMENT);
    if (contains != null) {
        Xnode parallelRegionStart;
        if (_specialParallelRegionStart == null) {
            parallelRegionStart = Directive.findParallelRegionStart(context, _fctDef, null);
        } else {
            parallelRegionStart = _specialParallelRegionStart;
        }
        Xnode parallelRegionEnd = Directive.findParallelRegionEnd(context, _fctDef, contains);
        Body.shiftIn(parallelRegionStart, parallelRegionEnd, loops.getInnerStatement().body(), true);
        contains.insertBefore(loops.getOuterStatement());
    } else {
        // No contains section, all the body is copied to the do statements.
        Xnode parallelRegionStart;
        if (_specialParallelRegionStart == null) {
            parallelRegionStart = Directive.findParallelRegionStart(context, _fctDef, null);
        } else {
            parallelRegionStart = _specialParallelRegionStart;
        }
        Xnode parallelRegionEnd = Directive.findParallelRegionEnd(context, _fctDef, null);
        // Define a hook from where we can insert the new do statement
        Xnode hook = parallelRegionEnd != null ? parallelRegionEnd.nextSibling() : null;
        Body.shiftIn(parallelRegionStart, parallelRegionEnd, loops.getInnerStatement().body(), true);
        // Hook is null then we append the do statement to the current fct body
        if (hook == null) {
            _fctDef.body().append(loops.getOuterStatement());
        } else {
            // Insert new do statement before the hook element
            hook.insertBefore(loops.getOuterStatement());
        }
    }
    // TODO nodep passing!
    int collapse = Directive.generateLoopSeq(xcodeml, loops.getInnerStatement().body(), CompilerDirective.CLAW.getPrefix() + " nodep");
    // Prepare variables list for present/pcreate clauses and handle
    // promotion/privatize local strategy
    List<String> presentList = _fctDef.getPresentVariables(xcodeml);
    List<String> privateList = Collections.emptyList();
    List<String> createList = Collections.emptyList();
    if (config.getLocalStrategy() == AcceleratorLocalStrategy.PRIVATE) {
        privateList = applyPrivateStrategy(xcodeml);
    } else if (config.getLocalStrategy() == AcceleratorLocalStrategy.PROMOTE) {
        createList = applyPromoteStrategy(cfg, xcodeml);
    }
    // Generate the data region
    Xblock doStmtBlock = new Xblock(loops.getOuterStatement());
    Directive.generateDataRegionClause(xcodeml, presentList, createList, doStmtBlock);
    // Generate the parallel region
    Directive.generateParallelLoopClause(xcodeml, privateList, loops.getOuterStatement(), loops.getOuterStatement(), null, loops.size() + collapse);
    Directive.generateRoutineDirectives(xcodeml, _fctDef);
}
Also used : Context(claw.tatsu.common.Context) Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) AcceleratorConfiguration(claw.tatsu.directive.configuration.AcceleratorConfiguration) IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) Xblock(claw.tatsu.xcodeml.abstraction.Xblock) NestedDoStatement(claw.tatsu.xcodeml.abstraction.NestedDoStatement) PromotionInfo(claw.tatsu.xcodeml.abstraction.PromotionInfo)

Example 2 with NestedDoStatement

use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.

the class LoopFusion method analyze.

/**
 * Loop fusion analysis: - Without collapse clause: check whether the pragma
 * statement is followed by a do statement. - With collapse clause: Find the n
 * do statements following the pragma.
 *
 * @param xcodeml    The XcodeML on which the transformations are applied.
 * @param translator The translator used to applied the transformations.
 * @return True if a do statement is found. False otherwise.
 */
@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
    Xnode outerLoop = _claw.getPragma().matchSibling(Xcode.F_DO_STATEMENT);
    if (outerLoop == null) {
        xcodeml.addError("Do statement missing after directive.", _claw.getPragma().lineNo());
        return false;
    }
    _doStmt = new NestedDoStatement(outerLoop, _claw.getCollapseValue());
    // With collapse clause
    if (_claw.hasClause(ClawClause.COLLAPSE) && _claw.getCollapseValue() > 0 && _claw.getCollapseValue() > _doStmt.size()) {
        xcodeml.addError("not enough do statements for collapse value", _claw.getPragma().lineNo());
        return false;
    }
    return true;
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) NestedDoStatement(claw.tatsu.xcodeml.abstraction.NestedDoStatement)

Example 3 with NestedDoStatement

use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.

the class LoopInterchange method analyze.

/**
 * Loop fusion analysis: - Find the different do statement that will be
 * reordered. - Check the validity of the new ordering option.
 *
 * @param xcodeml    The XcodeML on which the transformations are applied.
 * @param translator The translator used to applied the transformations.
 * @return True if the transformation can be performed. False otherwise.
 */
@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
    // Find next loop after pragma
    Xnode outerDoStatement = _claw.getPragma().matchSibling(Xcode.F_DO_STATEMENT);
    if (outerDoStatement == null) {
        xcodeml.addError("top level loop not found", _claw.getPragma().lineNo());
        return false;
    }
    int nestedLevel = _claw.values(ClawClause.INTERCHANGE_INDEXES) != null ? _claw.values(ClawClause.INTERCHANGE_INDEXES).size() : 2;
    _doStmts = new NestedDoStatement(outerDoStatement, nestedLevel);
    if (_claw.values(ClawClause.INTERCHANGE_INDEXES) != null) {
        if (_claw.values(ClawClause.INTERCHANGE_INDEXES).size() != 3) {
            xcodeml.addError("new-order option has not enough parameters", _claw.getPragma().lineNo());
        }
        List<String> inductions = _doStmts.getInductionVariables();
        for (String idx : _claw.values(ClawClause.INTERCHANGE_INDEXES)) {
            if (!inductions.contains(idx.toLowerCase())) {
                xcodeml.addError("invalid induction variable in new-order option. " + idx, _claw.getPragma().lineNo());
                return false;
            }
        }
    } else {
        if (_doStmts.size() < 2) {
            xcodeml.addError("Not enough nested do statements to reorder", _claw.getPragma().lineNo());
        }
    }
    return true;
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) NestedDoStatement(claw.tatsu.xcodeml.abstraction.NestedDoStatement)

Example 4 with NestedDoStatement

use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.

the class ScaCPUvectorizeGroup method generateDoStatements.

/**
 * Generate new DO statement at flagged location.
 *
 * @param xcodeml Current translation unit.
 * @param blocks  List of vectorization friendly blocks.
 */
private void generateDoStatements(Configuration cfg, XcodeProgram xcodeml, List<VectorBlock> blocks) throws IllegalTransformationException {
    for (VectorBlock block : blocks) {
        NestedDoStatement loops = new NestedDoStatement(_claw.getDefaultLayoutReversed(cfg), xcodeml);
        if (block.isSingleStatement()) {
            block.getStartStmt().insertAfter(loops.getOuterStatement());
            loops.getInnerStatement().body().append(block.getStartStmt(), true);
            block.getStartStmt().delete();
        } else {
            block.getEndStmt().insertAfter(loops.getOuterStatement());
            Body.shiftIn(block.getStartStmt(), block.getEndStmt(), loops.getInnerStatement().body(), true);
        }
        Directive.generateLoopDirectives(xcodeml, loops.getOuterStatement(), loops.getOuterStatement(), Directive.NO_COLLAPSE);
    }
}
Also used : NestedDoStatement(claw.tatsu.xcodeml.abstraction.NestedDoStatement)

Example 5 with NestedDoStatement

use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.

the class ScaForward method propagatePromotion.

/**
 * Propagate possible promotion in assignments statements in the parent
 * subroutine of the function call.
 *
 * @param xcodeml    Current XcodeML program unit.
 * @param translator Current translator to store information between
 *                   transformation.
 */
private void propagatePromotion(XcodeProgram xcodeml, ClawTranslator translator) throws IllegalTransformationException {
    // Get all the assignment statements in the function definition
    FfunctionDefinition parentFctDef = _fCall.findParentFunction();
    // Retrieve information of previous forward transformation in the same fct
    List<String> previouslyPromoted = Utility.convertToList(translator.hasElement(parentFctDef));
    List<Xnode> assignments = parentFctDef.matchAll(Xcode.F_ASSIGN_STATEMENT);
    // Find promotion info that can be used.
    // TODO define how default promotion is encoded in xmod file. For the
    // TODO moment using the first information found in fctType.
    PromotionInfo defaultInfo = Function.readPromotionInfo(_fctType, InsertionPosition.BEFORE);
    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.FUNCTION_CALL) == null && Xnode.isOfCode(lhs, Xcode.F_ARRAY_REF)) {
                Xnode varInLhs = lhs.matchDescendant(Xcode.VAR);
                if (varInLhs == null) {
                    throw new IllegalTransformationException("Unable to propagate " + "promotion. Internal error.", _claw.getPragma().lineNo());
                }
                // Declare the induction variable if they are not present
                for (DimensionDefinition dim : defaultInfo.getDimensions()) {
                    if (parentFctDef.getDeclarationTable().get(dim.getIdentifier()) == null) {
                        xcodeml.createIdAndDecl(dim.getIdentifier(), FortranType.INTEGER, XstorageClass.F_LOCAL, parentFctDef, DeclarationPosition.LAST);
                    }
                }
                // Generate the do statements and move the assignment statement in
                NestedDoStatement doStmt = new NestedDoStatement(defaultInfo.getDimensions(), xcodeml);
                assignment.insertAfter(doStmt.getOuterStatement());
                doStmt.getInnerStatement().body().append(assignment);
                PromotionInfo promotionInfo;
                if (!previouslyPromoted.contains(varInLhs.value())) {
                    // Perform the promotion on the variable
                    promotionInfo = new PromotionInfo(varInLhs.value(), defaultInfo.getDimensions());
                    Field.promote(promotionInfo, parentFctDef, xcodeml);
                    _promotions.put(promotionInfo.getIdentifier(), promotionInfo);
                } else {
                    promotionInfo = _promotions.get(varInLhs.value());
                }
                _promotedVar.add(varInLhs.value());
                // Adapt the reference in the assignment statement
                for (String id : _promotedVar) {
                    _promotions.get(id).resetFlags();
                    Field.adaptArrayRef(_promotions.get(id), assignment, false, xcodeml);
                }
                // If the array is a target, check if we have to promote a pointer
                if (!previouslyPromoted.contains(varInLhs.value())) {
                    Field.adaptPointer(xcodeml, parentFctDef, _promotions, promotionInfo);
                    previouslyPromoted.add(varInLhs.value());
                }
                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.
                     */
            }
        }
    }
    translator.storeElement(parentFctDef, previouslyPromoted);
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) PromotionInfo(claw.tatsu.xcodeml.abstraction.PromotionInfo) NestedDoStatement(claw.tatsu.xcodeml.abstraction.NestedDoStatement) DimensionDefinition(claw.tatsu.xcodeml.abstraction.DimensionDefinition)

Aggregations

NestedDoStatement (claw.tatsu.xcodeml.abstraction.NestedDoStatement)6 Xnode (claw.tatsu.xcodeml.xnode.common.Xnode)5 PromotionInfo (claw.tatsu.xcodeml.abstraction.PromotionInfo)2 IllegalTransformationException (claw.tatsu.xcodeml.exception.IllegalTransformationException)2 Context (claw.tatsu.common.Context)1 AcceleratorConfiguration (claw.tatsu.directive.configuration.AcceleratorConfiguration)1 DimensionDefinition (claw.tatsu.xcodeml.abstraction.DimensionDefinition)1 FunctionCall (claw.tatsu.xcodeml.abstraction.FunctionCall)1 Xblock (claw.tatsu.xcodeml.abstraction.Xblock)1 FfunctionDefinition (claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition)1