Search in sources :

Example 16 with FfunctionDefinition

use of claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition in project claw-compiler by C2SM-RCM.

the class ArrayToFctCall method analyze.

@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
    FfunctionDefinition fctDef = _claw.getPragma().findParentFunction();
    if (fctDef == null) {
        xcodeml.addError("Cannot locate function definition.", _claw.getPragma().lineNo());
        return false;
    }
    if (!fctDef.getDeclarationTable().contains(_claw.value(ClawClause.ARRAY_NAME))) {
        xcodeml.addError(_claw.value(ClawClause.ARRAY_NAME) + " is not declared in current function/subroutine.", _claw.getPragma().lineNo());
        return false;
    }
    _replaceFct = xcodeml.getGlobalDeclarationsTable().getFunctionDefinition(_claw.value(ClawClause.FCT_NAME));
    if (_replaceFct == null) {
        FmoduleDefinition parentModule = _claw.getPragma().findParentModule();
        Optional<FfunctionDefinition> replaceFct = parentModule.getFunctionDefinition(_claw.value(ClawClause.FCT_NAME));
        if (!replaceFct.isPresent()) {
            xcodeml.addError("Function " + _claw.value(ClawClause.FCT_NAME) + " not found in current file.", _claw.getPragma().lineNo());
            return false;
        }
        _replaceFct = replaceFct.get();
    }
    // skeleton
    return true;
}
Also used : FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) FmoduleDefinition(claw.tatsu.xcodeml.xnode.fortran.FmoduleDefinition)

Example 17 with FfunctionDefinition

use of claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition in project claw-compiler by C2SM-RCM.

the class ModelData method analyze.

@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
    /*
         * Discover variable part of the model configuration and the subroutine holding
         * them
         */
    ClawTranslator trans = (ClawTranslator) translator;
    if (!trans.cfg().getModelConfig().isLoaded()) {
        xcodeml.addError("SCA model-data directive requires model configuration!", _clawStart.getPragma());
    }
    // Locate the subroutine/function in which the directive is defined
    FfunctionDefinition sub = getDirective().getPragma().findParentFunction();
    Map<String, String> modelVariables;
    if (trans.hasElement(sub) != null) {
        modelVariables = Utility.convertToMap(trans.hasElement(sub));
    } else {
        modelVariables = new HashMap<>();
    }
    for (String data : XnodeUtil.getAllVariables(getDirective().getPragma(), getEndDirective().getPragma())) {
        modelVariables.put(data, _clawStart.value(ClawClause.LAYOUT));
    }
    trans.storeElement(sub, modelVariables);
    return true;
}
Also used : FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) ClawTranslator(claw.wani.x2t.translator.ClawTranslator)

Example 18 with FfunctionDefinition

use of claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition 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)

Example 19 with FfunctionDefinition

use of claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition in project claw-compiler by C2SM-RCM.

the class ScaForward method analyzeForward.

/**
 * Analyze the directive when it is used just before a function call.
 *
 * @param xcodeml Current XcodeML file unit.
 * @return True if the analysis succeed. False otherwise.
 */
private boolean analyzeForward(XcodeProgram xcodeml) {
    final Context context = xcodeml.context();
    if (_fCall == null) {
        xcodeml.addError("Directive is not followed by a fct call.", _claw.getPragma());
        return false;
    }
    detectParameterMapping(context, _fCall);
    _calledFctName = _fCall.getFctName();
    FfunctionDefinition fctDef = xcodeml.getGlobalDeclarationsTable().getFunctionDefinition(_calledFctName);
    FfunctionDefinition parentFctDef = _claw.getPragma().findParentFunction();
    if (parentFctDef == null) {
        xcodeml.addError("SCA directive is not nested in a " + "function/subroutine.", _claw.getPragma());
        return false;
    }
    FmoduleDefinition parentModule = parentFctDef.findParentModule();
    if (_fCall.isTbpCall()) {
        /*
             * If type is a FbasicType element for a type-bound procedure, we have to
             * matchSeq the correct function in the typeTable. TODO if there is a rename.
             * TODO generic call
             */
        Xid id = parentModule.getSymbolTable().get(_calledFctName);
        if (id == null) {
            List<Xnode> uses = parentFctDef.getDeclarationTable().uses();
            uses.addAll(parentModule.getDeclarationTable().uses());
            if (!findInModule(context, uses)) {
                xcodeml.addError("Function definition not found in module ", _claw.getPragma());
                return false;
            }
        } else {
            _fctType = xcodeml.getTypeTable().getFunctionType(id);
        }
    } else {
        if (xcodeml.getTypeTable().isFunctionType(_fCall)) {
            _fctType = xcodeml.getTypeTable().getFunctionType(_fCall);
        } else {
            xcodeml.addError("Unsupported type of XcodeML/F element for the function " + _calledFctName, _claw.getPragma());
            return false;
        }
    }
    /*
         * Workaround for a bug in OMNI Compiler. Look at test case claw/abstraction10.
         * 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.
         */
    if (_fctType.getParameters().isEmpty()) {
        /*
             * If not, try to matchSeq the correct FfunctionType in the module definitions
             */
        Xid id = (parentModule == null) ? null : parentModule.getSymbolTable().get(_calledFctName);
        if (id == null) {
            // Function is not located in the current module.
            List<Xnode> uses = parentFctDef.getDeclarationTable().uses();
            if (parentModule != null) {
                uses.addAll(parentModule.getDeclarationTable().uses());
            }
            if (!findInModule(context, uses)) {
                xcodeml.addError(String.format("Function definition %s not found in module.", _calledFctName), _claw.getPragma());
                return false;
            }
        } else {
            _fctType = xcodeml.getTypeTable().getFunctionType(id);
            if (_fctType == null) {
                xcodeml.addError("Called function cannot be found in the same module ", _claw.getPragma());
                return false;
            }
        }
    }
    // end of workaround
    _callingFctName = parentFctDef.getName();
    if (_fctType != null && fctDef != null) {
        _localFct = true;
    } else {
        // Has been found already
        if (_fctType != null && _calledFctName == null) {
            return true;
        }
        // Get all the use statements in the fct and module definitions
        List<Xnode> uses = parentFctDef.getDeclarationTable().uses();
        if (parentModule != null) {
            uses.addAll(parentModule.getDeclarationTable().uses());
        }
        // Try to locate the fct in the modules defined in use statements
        if (findInModule(context, uses)) {
            return true;
        }
        xcodeml.addError("Function signature not found in the current module.", _claw.getPragma());
        return false;
    }
    return true;
}
Also used : Context(claw.tatsu.common.Context) Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) Xid(claw.tatsu.xcodeml.xnode.common.Xid) FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) FmoduleDefinition(claw.tatsu.xcodeml.xnode.fortran.FmoduleDefinition)

Example 20 with FfunctionDefinition

use of claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition in project claw-compiler by C2SM-RCM.

the class FieldTest method promoteTest.

@Test
public void promoteTest() {
    DimensionDefinition dim1 = new DimensionDefinition("dim1", "1", "30");
    DimensionDefinition dim2 = new DimensionDefinition("dim2", "1", "40");
    List<DimensionDefinition> dimensions1 = Collections.singletonList(dim1);
    List<DimensionDefinition> dimensions2 = Arrays.asList(dim1, dim2);
    Context context = new TestContext();
    XcodeProgram xcodeml = XcodeProgram.createFromFile(TestConstant.TEST_PROMOTION, context);
    assertNotNull(xcodeml);
    List<FfunctionDefinition> fctDefs = xcodeml.getAllFctDef();
    assertEquals(1, fctDefs.size());
    FfunctionDefinition fctDef = fctDefs.get(0);
    assertEquals("sub1", fctDef.getName());
    // Scalar to array promotion with 1 additional dimension
    dim1.setInsertionPosition(InsertionPosition.BEFORE);
    performAndAssertPromotion("s1", dimensions1, fctDef, xcodeml, 0, 1, new int[] { 1, 30 });
    dim1.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    performAndAssertPromotion("s2", dimensions1, fctDef, xcodeml, 0, 1, new int[] { 1, 30 });
    dim1.setInsertionPosition(InsertionPosition.AFTER);
    performAndAssertPromotion("s3", dimensions1, fctDef, xcodeml, 0, 1, new int[] { 1, 30 });
    // Scalar to array promotion with 2 additional dimension
    dim1.setInsertionPosition(InsertionPosition.BEFORE);
    dim2.setInsertionPosition(InsertionPosition.BEFORE);
    performAndAssertPromotion("s4", dimensions2, fctDef, xcodeml, 0, 2, new int[] { 1, 30, 1, 40 });
    dim1.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    dim2.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    performAndAssertPromotion("s5", dimensions2, fctDef, xcodeml, 0, 2, new int[] { 1, 30, 1, 40 });
    dim1.setInsertionPosition(InsertionPosition.AFTER);
    dim2.setInsertionPosition(InsertionPosition.AFTER);
    performAndAssertPromotion("s6", dimensions2, fctDef, xcodeml, 0, 2, new int[] { 1, 30, 1, 40 });
    // Promotion with 1 additional dimension
    dim1.setInsertionPosition(InsertionPosition.BEFORE);
    performAndAssertPromotion("a", dimensions1, fctDef, xcodeml, 2, 3, new int[] { 1, 30, 1, 10, 1, 20 });
    dim1.setInsertionPosition(InsertionPosition.AFTER);
    performAndAssertPromotion("b", dimensions1, fctDef, xcodeml, 2, 3, new int[] { 1, 10, 1, 20, 1, 30 });
    dim1.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    performAndAssertPromotion("c", dimensions1, fctDef, xcodeml, 2, 3, new int[] { 1, 10, 1, 30, 1, 20 });
    // Promotion with 2 additional dimensions at the same position
    dim1.setInsertionPosition(InsertionPosition.BEFORE);
    dim2.setInsertionPosition(InsertionPosition.BEFORE);
    performAndAssertPromotion("d", dimensions2, fctDef, xcodeml, 2, 4, new int[] { 1, 30, 1, 40, 1, 10, 1, 20 });
    dim1.setInsertionPosition(InsertionPosition.AFTER);
    dim2.setInsertionPosition(InsertionPosition.AFTER);
    performAndAssertPromotion("e", dimensions2, fctDef, xcodeml, 2, 4, new int[] { 1, 10, 1, 20, 1, 30, 1, 40 });
    dim1.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    dim2.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    performAndAssertPromotion("f", dimensions2, fctDef, xcodeml, 2, 4, new int[] { 1, 10, 1, 30, 1, 40, 1, 20 });
    // Promotion with 2 additional dimensions at different position
    dim1.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    dim2.setInsertionPosition(InsertionPosition.AFTER);
    performAndAssertPromotion("g", dimensions2, fctDef, xcodeml, 2, 4, new int[] { 1, 10, 1, 30, 1, 20, 1, 40 });
    dim1.setInsertionPosition(InsertionPosition.BEFORE);
    dim2.setInsertionPosition(InsertionPosition.IN_MIDDLE);
    performAndAssertPromotion("h", dimensions2, fctDef, xcodeml, 2, 4, new int[] { 1, 30, 1, 10, 1, 40, 1, 20 });
    dim1.setInsertionPosition(InsertionPosition.BEFORE);
    dim2.setInsertionPosition(InsertionPosition.AFTER);
    performAndAssertPromotion("i", dimensions2, fctDef, xcodeml, 2, 4, new int[] { 1, 30, 1, 10, 1, 20, 1, 40 });
}
Also used : Context(claw.tatsu.common.Context) TestContext(helper.Utils.TestContext) FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) TestContext(helper.Utils.TestContext) DimensionDefinition(claw.tatsu.xcodeml.abstraction.DimensionDefinition) XcodeProgram(claw.tatsu.xcodeml.xnode.common.XcodeProgram) Test(org.junit.Test)

Aggregations

FfunctionDefinition (claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition)27 Xnode (claw.tatsu.xcodeml.xnode.common.Xnode)16 Context (claw.tatsu.common.Context)13 IllegalTransformationException (claw.tatsu.xcodeml.exception.IllegalTransformationException)11 Test (org.junit.Test)10 TestContext (helper.Utils.TestContext)9 XcodeProgram (claw.tatsu.xcodeml.xnode.common.XcodeProgram)6 FmoduleDefinition (claw.tatsu.xcodeml.xnode.fortran.FmoduleDefinition)6 ClawTranslator (claw.wani.x2t.translator.ClawTranslator)6 Xid (claw.tatsu.xcodeml.xnode.common.Xid)4 DimensionDefinition (claw.tatsu.xcodeml.abstraction.DimensionDefinition)3 FunctionCall (claw.tatsu.xcodeml.abstraction.FunctionCall)3 PromotionInfo (claw.tatsu.xcodeml.abstraction.PromotionInfo)3 Xblock (claw.tatsu.xcodeml.abstraction.Xblock)3 HoistedNestedDoStatement (claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement)2 ReshapeInfo (claw.tatsu.xcodeml.abstraction.ReshapeInfo)2 FbasicType (claw.tatsu.xcodeml.xnode.fortran.FbasicType)2 FfunctionType (claw.tatsu.xcodeml.xnode.fortran.FfunctionType)2 Configuration (claw.wani.x2t.configuration.Configuration)2 Transformation (claw.shenron.transformation.Transformation)1