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;
}
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;
}
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);
}
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;
}
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 });
}
Aggregations