Search in sources :

Example 1 with NestedDoStatement

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());
}
Also used : ClawDimension(cx2x.translator.language.common.ClawDimension) NestedDoStatement(cx2x.translator.common.NestedDoStatement)

Example 2 with NestedDoStatement

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);
}
Also used : NestedDoStatement(cx2x.translator.common.NestedDoStatement)

Example 3 with NestedDoStatement

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);
}
Also used : ClawDimension(cx2x.translator.language.common.ClawDimension) IllegalTransformationException(cx2x.xcodeml.exception.IllegalTransformationException) NestedDoStatement(cx2x.translator.common.NestedDoStatement)

Aggregations

NestedDoStatement (cx2x.translator.common.NestedDoStatement)3 ClawDimension (cx2x.translator.language.common.ClawDimension)2 IllegalTransformationException (cx2x.xcodeml.exception.IllegalTransformationException)1