Search in sources :

Example 1 with OverPosition

use of cx2x.translator.language.common.OverPosition in project claw-compiler by C2SM-RCM.

the class TransformationHelper method updateModuleSignature.

/**
   * Update the function signature in the module file to reflects local changes.
   *
   * @param xcodeml     Current XcodeML file unit.
   * @param fctDef      Function definition that has been changed.
   * @param fctType     Function type that has been changed.
   * @param modDef      Module definition holding the function definition.
   * @param claw        Pragma that has triggered the transformation.
   * @param transformer Current transformer object.
   * @throws IllegalTransformationException If the module file or the function
   *                                        cannot be located
   */
public static void updateModuleSignature(XcodeProgram xcodeml, XfunctionDefinition fctDef, XfunctionType fctType, XmoduleDefinition modDef, ClawLanguage claw, cx2x.xcodeml.transformation.Transformer transformer, boolean importFctType) throws IllegalTransformationException {
    Xmod mod;
    if (transformer.getModCache().isModuleLoaded(modDef.getName())) {
        mod = transformer.getModCache().get(modDef.getName());
    } else {
        mod = fctDef.findContainingModule();
        if (mod == null) {
            throw new IllegalTransformationException("Unable to locate module file for: " + modDef.getName(), claw.getPragma().lineNo());
        }
        transformer.getModCache().add(modDef.getName(), mod);
    }
    XfunctionType fctTypeMod;
    if (importFctType) {
        Node rawNode = mod.getDocument().importNode(fctType.element(), true);
        mod.getTypeTable().element().appendChild(rawNode);
        XfunctionType importedFctType = new XfunctionType((Element) rawNode);
        Xid importedFctTypeId = mod.createId(importedFctType.getType(), Xname.SCLASS_F_FUNC, fctDef.getName().value());
        mod.getIdentifiers().add(importedFctTypeId);
        // check if params need to be imported as well
        if (importedFctType.getParameterNb() > 0) {
            for (Xnode param : importedFctType.getParams().getAll()) {
                mod.importType(xcodeml, param.getAttribute(Xattr.TYPE));
            }
        }
        return;
    } else {
        fctTypeMod = (XfunctionType) mod.getTypeTable().get(fctDef.getName().getAttribute(Xattr.TYPE));
    }
    if (fctTypeMod == null) {
        /* Workaround for a bug in OMNI Compiler. Look at test case
       * claw/abstraction12. In this test case, the XcodeML/F intermediate
       * representation for the function call points to a FfunctionType element
       * with no parameters. Thus, we have to matchSeq the correct FfunctionType
       * for the same function/subroutine with the same name in the module
       * symbol table. */
        String errorMsg = "Unable to locate fct " + fctDef.getName().value() + " in module " + modDef.getName();
        int lineNo = claw.getPragma().lineNo();
        // If not, try to matchSeq the correct FfunctionType in the module definitions
        Xid id = mod.getIdentifiers().get(fctDef.getName().value());
        if (id == null) {
            throw new IllegalTransformationException(errorMsg, lineNo);
        }
        fctTypeMod = (XfunctionType) mod.getTypeTable().get(id.getType());
        if (fctTypeMod == null) {
            throw new IllegalTransformationException(errorMsg, lineNo);
        }
    }
    XbasicType modIntTypeIntentIn = mod.createBasicType(mod.getTypeTable().generateIntegerTypeHash(), Xname.TYPE_F_INT, Xintent.IN);
    mod.getTypeTable().add(modIntTypeIntentIn);
    List<Xnode> paramsLocal = fctType.getParams().getAll();
    List<Xnode> paramsMod = fctTypeMod.getParams().getAll();
    if (paramsLocal.size() < paramsMod.size()) {
        throw new IllegalTransformationException("Local function has more parameters than module counterpart.", claw.getPragma().lineNo());
    }
    for (int i = 0; i < paramsLocal.size(); ++i) {
        Xnode pLocal = paramsLocal.get(i);
        // Number of parameters in the module function as been
        if (pLocal.getBooleanAttribute(ClawAttr.IS_CLAW.toString())) {
            // new parameter
            Xnode param = mod.createAndAddParamIfNotExists(pLocal.value(), modIntTypeIntentIn.getType(), fctTypeMod);
            if (param != null) {
                param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
            }
        } else {
            Xnode pMod = paramsMod.get(i);
            String localType = pLocal.getAttribute(Xattr.TYPE);
            String modType = pMod.getAttribute(Xattr.TYPE);
            if (!localType.equals(modType)) {
                // Param has been update so have to replicate the change to mod file
                XbasicType lType = (XbasicType) xcodeml.getTypeTable().get(localType);
                XbasicType crtType = (XbasicType) mod.getTypeTable().get(modType);
                List<ClawDimension> dimensions = TransformationHelper.findDimensions(fctType);
                OverPosition overPos = OverPosition.fromString(pLocal.getAttribute(ClawAttr.OVER.toString()));
                if (lType.isArray()) {
                    String newType = TransformationHelper.duplicateWithDimension(lType, crtType, mod, xcodeml, overPos, dimensions);
                    pMod.setAttribute(Xattr.TYPE, newType);
                }
            }
            // Propagate the over attribute
            copyAttribute(pLocal, pMod, ClawAttr.OVER);
        }
    }
}
Also used : OverPosition(cx2x.translator.language.common.OverPosition) Node(org.w3c.dom.Node) ClawDimension(cx2x.translator.language.common.ClawDimension) IllegalTransformationException(cx2x.xcodeml.exception.IllegalTransformationException)

Example 2 with OverPosition

use of cx2x.translator.language.common.OverPosition in project claw-compiler by C2SM-RCM.

the class ParallelizeForward method transformStd.

/**
   * Do the standard transformation for the forward directive. This
   * transformation adapt the function call and replicates any necessary changes
   * to the containing subroutine.
   *
   * @param xcodeml     Current XcodeML file unit.
   * @param transformer Current transformer.
   * @throws Exception If something goes wrong.
   */
private void transformStd(XcodeProgram xcodeml, Transformer transformer) throws Exception {
    XfunctionDefinition fDef = XnodeUtil.findParentFunction(_claw.getPragma());
    if (fDef == null) {
        throw new IllegalTransformationException("Parallelize directive is not " + "nested in a function/subroutine.", _claw.getPragma().lineNo());
    }
    _parentFctType = (XfunctionType) xcodeml.getTypeTable().get(fDef.getName().getAttribute(Xattr.TYPE));
    List<Xnode> params = _fctType.getParams().getAll();
    /* Compute the position of the first new arguments. In the case of a
     * type-bound procedure call, the first parameter declared in the procedure
     * is not actually passed as an argument. In this case, we add an offset of
     * one to the starting arguments.
     * TODO the check might be change to fit with the XcodeML/F2008 specs. The
     * TODO cont: attribute data_ref will probably be gone and replaced by a
     * TODO cont: FmemberRef element
     */
    int argOffset = 0;
    if (params.get(0).getAttribute(Xattr.TYPE).startsWith(Xtype.PREFIX_STRUCT) && _fctCall.firstChild().opcode().equals(Xcode.FMEMBERREF)) {
        argOffset = 1;
    }
    // 1. Adapt function call with potential new arguments
    for (int i = 0; i < params.size(); i++) {
        Xnode p = params.get(i);
        String var = p.value();
        String type;
        XbasicType paramType = (XbasicType) xcodeml.getTypeTable().get(p.getAttribute(Xattr.TYPE));
        if (!p.getBooleanAttribute(ClawAttr.IS_CLAW.toString())) {
            continue;
        }
        if (!fDef.getSymbolTable().contains(var)) {
            if (_flatten && !paramType.getBooleanAttribute(Xattr.IS_OPTIONAL)) {
                throw new IllegalTransformationException("Variable " + var + " must" + " be locally defined where the last call to parallelize if made.", _claw.getPragma().lineNo());
            }
            // Size variable have to be declared
            XbasicType intTypeIntentIn = xcodeml.createBasicType(xcodeml.getTypeTable().generateIntegerTypeHash(), Xname.TYPE_F_INT, Xintent.IN);
            xcodeml.getTypeTable().add(intTypeIntentIn);
            xcodeml.createIdAndDecl(var, intTypeIntentIn.getType(), Xname.SCLASS_F_PARAM, fDef);
            type = intTypeIntentIn.getType();
            Xnode param = xcodeml.createAndAddParam(var, type, _parentFctType);
            param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
        } else {
            // Var exists already. Add to the parameters if not here.
            type = fDef.getSymbolTable().get(var).getType();
            /* If flatten mode, we do not add extra parameters to the function
         * definition */
            if (!_flatten) {
                Xnode param = xcodeml.createAndAddParamIfNotExists(var, type, _parentFctType);
                if (param != null) {
                    param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
                }
            }
        }
        // Add variable in the function call before the optional parameters
        Xnode arg = xcodeml.createNamedValue(var);
        Xnode namedValVar = xcodeml.createVar(type, var, Xscope.LOCAL);
        arg.append(namedValVar, false);
        Xnode arguments = _fctCall.matchSeq(Xcode.ARGUMENTS);
        Xnode hook = arguments.child((i - 1) - argOffset);
        hook.insertAfter(arg);
    }
    // In flatten mode, arguments are demoted if needed.
    if (_flatten) {
        Xnode arguments = _fctCall.matchSeq(Xcode.ARGUMENTS);
        for (Xnode arg : arguments.children()) {
            if (arg.opcode() == Xcode.FARRAYREF && arg.matchDirectDescendant(Arrays.asList(Xcode.INDEXRANGE, Xcode.ARRAYINDEX)) != null) {
                Xnode var = arg.matchSeq(Xcode.VARREF, Xcode.VAR);
                if (var != null) {
                    arg.insertAfter(var.cloneNode());
                    arg.delete();
                }
            }
        }
    } else {
        // 2. Adapt function/subroutine in which the function call is nested
        for (Xnode pBase : _fctType.getParams().getAll()) {
            String original_param = pBase.value();
            if (_fctCallMapping.containsKey(original_param)) {
                original_param = _fctCallMapping.get(original_param);
            }
            Xnode pUpdate = null;
            for (Xnode param : _parentFctType.getParams().getAll()) {
                if (original_param.equals(param.value())) {
                    pUpdate = param;
                }
            }
            if (pUpdate == null) {
                // field is not a parameter but maybe out field
                Xdecl d = fDef.getDeclarationTable().get(original_param);
                if (d != null) {
                    pUpdate = d.matchSeq(Xcode.NAME);
                }
            // TODO handle deferred shape
            }
            if (pUpdate != null) {
                if (pUpdate.getAttribute(Xattr.TYPE) == null || XnodeUtil.isBuiltInType(pUpdate.getAttribute(Xattr.TYPE))) {
                    continue;
                }
                XbasicType typeBase = (_localFct) ? (XbasicType) xcodeml.getTypeTable().get(pBase.getAttribute(Xattr.TYPE)) : (XbasicType) _mod.getTypeTable().get(pBase.getAttribute(Xattr.TYPE));
                XbasicType typeToUpdate = (XbasicType) xcodeml.getTypeTable().get(pUpdate.getAttribute(Xattr.TYPE));
                int targetDim = typeBase.getDimensions();
                int baseDim = typeToUpdate.getDimensions();
                // Types have different dimensions
                if (typeBase.getDimensions() > typeToUpdate.getDimensions()) {
                    // TODO check intent rules
                    /*if(!isParam && typeToUpdate.getIntent() != Xintent.OUT){
              continue;
            }*/
                    List<ClawDimension> dimensions = TransformationHelper.findDimensions(_fctType);
                    OverPosition overPos = OverPosition.fromString(pBase.getAttribute(ClawAttr.OVER.toString()));
                    String type = _localFct ? TransformationHelper.duplicateWithDimension(typeBase, typeToUpdate, xcodeml, xcodeml, overPos, dimensions) : TransformationHelper.duplicateWithDimension(typeBase, typeToUpdate, xcodeml, _mod, overPos, dimensions);
                    pUpdate.setAttribute(Xattr.TYPE, type);
                    Xid id = fDef.getSymbolTable().get(original_param);
                    if (id != null) {
                        id.setAttribute(Xattr.TYPE, type);
                    }
                    Xdecl varDecl = fDef.getDeclarationTable().get(original_param);
                    if (varDecl != null) {
                        varDecl.matchSeq(Xcode.NAME).setAttribute(Xattr.TYPE, type);
                    }
                    _promotedVar.add(original_param);
                    addPromotedVar(original_param, overPos);
                    _promotions.put(original_param, new PromotionInfo(pBase.value(), baseDim, targetDim, type));
                }
            }
        }
        if (!_parentFctType.getBooleanAttribute(Xattr.IS_PRIVATE)) {
            // 3. Replicate the change in a potential module file
            XmoduleDefinition modDef = fDef.findParentModule();
            TransformationHelper.updateModuleSignature(xcodeml, fDef, _parentFctType, modDef, _claw, transformer, false);
        } else if (_fctCall.matchSeq(Xcode.NAME).hasAttribute(Xattr.DATAREF)) {
            /* The function/subroutine is private but accessible through the type
         * as a type-bound procedure. In this case, the function is not in the
         * type table of the .xmod file. We need to insert it first and then
         * we can update it. */
            XmoduleDefinition modDef = fDef.findParentModule();
            TransformationHelper.updateModuleSignature(xcodeml, fDef, _parentFctType, modDef, _claw, transformer, true);
        }
    }
    updateResultVar(xcodeml);
    propagatePromotion(xcodeml, (ClawTransformer) transformer);
}
Also used : OverPosition(cx2x.translator.language.common.OverPosition) ClawDimension(cx2x.translator.language.common.ClawDimension) IllegalTransformationException(cx2x.xcodeml.exception.IllegalTransformationException)

Example 3 with OverPosition

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

Aggregations

ClawDimension (cx2x.translator.language.common.ClawDimension)3 OverPosition (cx2x.translator.language.common.OverPosition)3 IllegalTransformationException (cx2x.xcodeml.exception.IllegalTransformationException)3 Node (org.w3c.dom.Node)1