use of claw.tatsu.xcodeml.xnode.fortran.FfunctionType in project claw-compiler by C2SM-RCM.
the class XnodeUtilTest method gatherArgumentsTest.
@Test
public void gatherArgumentsTest() {
Context context = new TestContext();
String arg1 = "nz";
String arg2 = "q(:,1:60)";
String arg3 = "ty%y(:,:)";
String arg4 = "z(:)";
String arg5 = "nproma";
assertTrue(Files.exists(TestConstant.TEST_ARGUMENTS));
XcodeProgram xcodeml = XcodeProgram.createFromFile(TestConstant.TEST_ARGUMENTS, context);
assertNotNull(xcodeml);
List<Xnode> functionCalls = xcodeml.matchAll(Xcode.FUNCTION_CALL);
assertEquals(1, functionCalls.size());
FunctionCall fctCall = new FunctionCall(functionCalls.get(0));
assertSame(fctCall.opcode(), Xcode.FUNCTION_CALL);
FfunctionType fctType = xcodeml.getTypeTable().getFunctionType(fctCall);
List<String> allArguments = fctCall.gatherArguments(xcodeml, fctType, xcodeml, Intent.ANY, false, false);
assertEquals(5, allArguments.size());
assertEquals(arg1, allArguments.get(0));
assertEquals(arg2, allArguments.get(1));
assertEquals(arg3, allArguments.get(2));
assertEquals(arg4, allArguments.get(3));
assertEquals(arg5, allArguments.get(4));
List<String> inArguments = fctCall.gatherArguments(xcodeml, fctType, xcodeml, Intent.IN, false, false);
assertEquals(5, inArguments.size());
assertEquals(arg1, inArguments.get(0));
assertEquals(arg2, inArguments.get(1));
assertEquals(arg3, inArguments.get(2));
assertEquals(arg4, inArguments.get(3));
assertEquals(arg5, inArguments.get(4));
List<String> outArguments = fctCall.gatherArguments(xcodeml, fctType, xcodeml, Intent.OUT, false, false);
assertEquals(3, outArguments.size());
assertEquals(arg2, outArguments.get(0));
assertEquals(arg3, outArguments.get(1));
assertEquals(arg4, outArguments.get(2));
List<String> inArrayArguments = fctCall.gatherArguments(xcodeml, fctType, xcodeml, Intent.IN, true, false);
assertEquals(3, inArrayArguments.size());
assertEquals(arg2, inArrayArguments.get(0));
assertEquals(arg3, inArrayArguments.get(1));
assertEquals(arg4, inArrayArguments.get(2));
List<String> outArrayArguments = fctCall.gatherArguments(xcodeml, fctType, xcodeml, Intent.OUT, true, false);
assertEquals(3, outArrayArguments.size());
assertEquals(arg2, outArrayArguments.get(0));
assertEquals(arg3, outArrayArguments.get(1));
assertEquals(arg4, outArrayArguments.get(2));
List<String> inOutArrayArguments = fctCall.gatherArguments(xcodeml, fctType, xcodeml, Intent.INOUT, true, false);
assertEquals(3, inOutArrayArguments.size());
assertEquals(arg2, inOutArrayArguments.get(0));
assertEquals(arg3, inOutArrayArguments.get(1));
assertEquals(arg4, inOutArrayArguments.get(2));
// TODO add test with optional arguments
}
use of claw.tatsu.xcodeml.xnode.fortran.FfunctionType in project claw-compiler by C2SM-RCM.
the class Serialization method createSavepoint.
/**
* Create function call to fs_create_savepoint
*
* @param xcodeml Current XcodeML translation unit.
* @param savepointName Name of the savepoint.
* @return Newly create functionCall node.
*/
private static Xnode createSavepoint(XcodeProgram xcodeml, String savepointName) {
FfunctionType serType = xcodeml.createSubroutineType();
// Create the char constant type
Xnode nameArg = xcodeml.createCharConstant(savepointName);
Xnode savepointArg = xcodeml.createVar(FortranType.STRUCT, SER_PPSER_SAVEPOINT, Xscope.GLOBAL);
Xnode serCall = xcodeml.createFctCall(serType, SER_FS_CREATE_SAVEPOINT);
serCall.matchDescendant(Xcode.ARGUMENTS).append(nameArg).append(savepointArg);
return xcodeml.createNode(Xcode.EXPR_STATEMENT).insert(serCall);
}
use of claw.tatsu.xcodeml.xnode.fortran.FfunctionType in project claw-compiler by C2SM-RCM.
the class Xmod method updateSignature.
/**
* Update the function signature in the module file to reflects local changes.
*
* @param moduleName Xmod name to update.
* @param xcodeml Current XcodeML file unit.
* @param fctDef Function definition that has been changed.
* @param fctType Function type that has been changed.
* @param importFctType If true, import the functionType.
* @throws IllegalTransformationException If the module file or the function
* cannot be located
*/
public static void updateSignature(String moduleName, XcodeProgram xcodeml, FfunctionDefinition fctDef, FfunctionType fctType, boolean importFctType) throws IllegalTransformationException {
final Context context = xcodeml.context();
FortranModule mod;
if (context.getModuleCache().isModuleLoaded(moduleName)) {
mod = context.getModuleCache().get(moduleName);
} else {
mod = fctDef.findContainingXmod(context);
if (mod == null) {
throw new IllegalTransformationException("Unable to locate module file for: " + moduleName);
}
context.getModuleCache().add(moduleName, mod);
}
FfunctionType fctTypeMod;
if (importFctType) {
// TODO should be part of XcodeML
Xnode importedNode = mod.importNode(fctType);
mod.getTypeTable().append(importedNode);
FfunctionType importedFctType = new FfunctionType(importedNode);
Xid importedFctTypeId = mod.createId(importedFctType.getType(), XstorageClass.F_FUNC, fctDef.getName());
mod.getIdentifiers().add(importedFctTypeId);
// check if params need to be imported as well
if (!importedFctType.getParameters().isEmpty()) {
for (Xnode param : importedFctType.getParameters()) {
mod.importType(xcodeml, param.getType());
}
}
return;
} else {
fctTypeMod = mod.findFunctionType(fctDef.getName());
}
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() + " in module " + moduleName;
/*
* If not, try to matchSeq the correct FfunctionType in the module definitions
*/
fctTypeMod = mod.findFunctionType(fctDef.getName());
if (fctTypeMod == null) {
throw new IllegalTransformationException(errorMsg);
}
}
FbasicType modIntTypeIntentIn = mod.createBasicType(FortranType.INTEGER, Intent.IN);
mod.getTypeTable().add(modIntTypeIntentIn);
List<Xnode> paramsLocal = fctType.getParameters();
List<Xnode> paramsMod = fctTypeMod.getParameters();
if (paramsLocal.size() < paramsMod.size()) {
throw new IllegalTransformationException("Local function has more parameters than module counterpart.");
}
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(Xattr.IS_INSERTED)) {
// new parameter
Xnode param = mod.createAndAddParamIfNotExists(pLocal.value(), modIntTypeIntentIn.getType(), fctTypeMod);
if (param != null) {
param.setBooleanAttribute(Xattr.IS_INSERTED, true);
}
} else {
Xnode pMod = paramsMod.get(i);
String localType = pLocal.getType();
String modType = pMod.getType();
if (!localType.equals(modType)) {
// Param has been updated so have to replicate the change to mod file
FbasicType lType = xcodeml.getTypeTable().getBasicType(pLocal);
FbasicType crtType = mod.getTypeTable().getBasicType(pMod);
if (pLocal.hasAttribute(Xattr.PROMOTION_INFO)) {
PromotionInfo promotionInfo = new PromotionInfo();
promotionInfo.readDimensionsFromString(pLocal.getAttribute(Xattr.PROMOTION_INFO));
if (lType.isArray()) {
FbasicType newType = Type.duplicateWithDimension(lType, crtType, xcodeml, mod, promotionInfo.getDimensions());
pMod.setType(newType);
}
}
}
// Copy the promotion information
pLocal.copyAttribute(pMod, Xattr.PROMOTION_INFO);
}
}
// Sync attribute between local fct type and module fct type.
for (Xattr attr : SYNCABLE_ATTR) {
fctType.syncBooleanAttribute(fctTypeMod, attr);
}
}
use of claw.tatsu.xcodeml.xnode.fortran.FfunctionType in project claw-compiler by C2SM-RCM.
the class XcodeML method createSubroutineType.
/**
* Create a FfunctionType representing a subroutine and add it to the type
* table.
*
* @return Newly created node.
*/
public FfunctionType createSubroutineType() {
FfunctionType subroutine = createFunctionType(getTypeTable().generateHash(FortranType.FUNCTION), Xname.TYPE_F_VOID);
getTypeTable().add(subroutine);
return subroutine;
}
use of claw.tatsu.xcodeml.xnode.fortran.FfunctionType in project claw-compiler by C2SM-RCM.
the class LoopExtraction method transform.
/**
* Apply the transformation. A loop extraction is applied in the following
* steps: 1) Duplicate the function targeted by the transformation 2) Extract
* the loop body in the duplicated function and remove the loop. 3) Adapt
* function call and demote array references in the duplicated function body. 4)
* Optional: Add a LoopFusion transformation to the transformations' queue.
*
* @param xcodeml The XcodeML on which the transformations are applied.
* @param translator The translator used to applied the transformations.
* @param transformation Only for dependent transformation. The other
* transformation part of the transformation.
* @throws IllegalTransformationException if the transformation cannot be
* applied.
*/
@Override
public void transform(XcodeProgram xcodeml, Translator translator, Transformation transformation) throws Exception {
ClawTranslator ct = (ClawTranslator) translator;
final Context context = ct.context();
/*
* DUPLICATE THE FUNCTION
*/
// Duplicate function definition
FfunctionDefinition clonedFctDef = _fctDefToExtract.cloneNode();
String newFctTypeHash = xcodeml.getTypeTable().generateHash(FortranType.FUNCTION);
String newFctName = clonedFctDef.getName() + ClawConstant.EXTRACTION_SUFFIX + translator.getNextTransformationCounter();
clonedFctDef.name().setValue(newFctName);
clonedFctDef.name().setType(newFctTypeHash);
// Update the symbol table in the fct definition
Xid fctId = clonedFctDef.getSymbolTable().get(_fctDefToExtract.getName());
fctId.setType(newFctTypeHash);
fctId.setName(newFctName);
// Get the fctType in typeTable
FfunctionType fctType = xcodeml.getTypeTable().getFunctionType(_fctDefToExtract);
FfunctionType newFctType = fctType.cloneNode();
newFctType.setType(newFctTypeHash);
xcodeml.getTypeTable().add(newFctType);
// Get the id from the global symbols table
Xid globalFctId = xcodeml.getGlobalSymbolsTable().get(_fctDefToExtract.getName());
// If the fct is define in the global symbol table, duplicate it
if (globalFctId != null) {
Xid newFctId = globalFctId.cloneNode();
newFctId.setType(newFctTypeHash);
newFctId.setName(newFctName);
xcodeml.getGlobalSymbolsTable().add(newFctId);
}
// Insert the duplicated function declaration
_fctDefToExtract.insertAfter(clonedFctDef);
// Find the loop that will be extracted
Xnode loopInClonedFct = locateDoStatement(clonedFctDef);
Message.debug(context, "loop-extract transformation: " + _claw.getPragma().value());
Message.debug(context, " created subroutine: " + clonedFctDef.getName());
/*
* REMOVE BODY FROM THE LOOP AND DELETE THE LOOP
*/
// 1. append body into fct body after loop
Loop.extractBody(loopInClonedFct);
// 2. delete loop
loopInClonedFct.delete();
/*
* ADAPT FUNCTION CALL AND DEMOTE ARRAY REFERENCES IN THE BODY OF THE FUNCTION
*/
// Wrap function call with loop
Xnode extractedLoop = wrapCallWithLoop(xcodeml, _extractedLoop);
Message.debug(context, " call wrapped with loop: " + _fctCall.matchDirectDescendant(Xcode.NAME).value() + " --> " + clonedFctDef.getName());
// Change called fct name
_fctCall.matchDirectDescendant(Xcode.NAME).setValue(newFctName);
_fctCall.matchDirectDescendant(Xcode.NAME).setType(newFctTypeHash);
// Adapt function call parameters and function declaration
XdeclTable fctDeclarations = clonedFctDef.getDeclarationTable();
XsymbolTable fctSymbols = clonedFctDef.getSymbolTable();
Message.debug(context, " Start to apply mapping: " + _claw.getMappings().size());
for (ClawMapping mapping : _claw.getMappings()) {
Message.debug(context, "Apply mapping (" + mapping.getMappedDimensions() + ") ");
for (ClawMappingVar var : mapping.getMappedVariables()) {
Message.debug(context, " Var: " + var);
Optional<Xnode> argument = _fctCall.findArg(var.getArgMapping());
if (!argument.isPresent()) {
continue;
}
/*
* Case 1: Var --> ArrayRef Var --> ArrayRef transformation 1. Check that the
* variable used as array index exists in the current scope (XdeclTable). If so,
* get its type value. Create a Var element for the arrayIndex. Create the
* arrayIndex element with Var as child.
*
* 2. Get the reference type of the base variable. 2.1 Create the varRef element
* with the type of base variable 2.2 insert clone of base variable in varRef 3.
* Create arrayRef element with varRef + arrayIndex
*/
if (argument.get().is(Xcode.VAR)) {
FbasicType type = xcodeml.getTypeTable().getBasicType(argument.get());
// Demotion cannot be applied as type dimension is smaller
if (type.getDimensions() < mapping.getMappedDimensions()) {
throw new IllegalTransformationException("mapping dimensions too big. Mapping " + mapping.toString() + " is wrong ...", _claw.getPragma().lineNo());
}
Xnode newArg = xcodeml.createNode(Xcode.F_ARRAY_REF);
newArg.setType(type.getRef());
Xnode varRef = xcodeml.createNode(Xcode.VAR_REF);
varRef.setType(argument.get().getType());
varRef.append(argument.get(), true);
newArg.append(varRef);
// create arrayIndex
for (ClawMappingVar mappingVar : mapping.getMappingVariables()) {
Xnode arrayIndex = xcodeml.createNode(Xcode.ARRAY_INDEX);
// Find the mapping var in the local table (fct scope)
Xnode mappingVarDecl = _fctDef.getDeclarationTable().get(mappingVar.getArgMapping());
// Add to arrayIndex
Xnode newMappingVar = xcodeml.createVar(mappingVarDecl.getType(), mappingVarDecl.matchSeq(Xcode.NAME).value(), Xscope.LOCAL);
arrayIndex.append(newMappingVar);
newArg.append(arrayIndex);
}
argument.get().insertAfter(newArg);
argument.get().delete();
}
// Case 2: ArrayRef (n arrayIndex) --> ArrayRef (n+m arrayIndex)
// Change variable declaration in extracted fct
Xnode varDecl = fctDeclarations.get(var.getFctMapping());
Xid id = fctSymbols.get(var.getFctMapping());
FbasicType varDeclType = xcodeml.getTypeTable().getBasicType(varDecl);
// Case 1: variable is demoted to scalar then take the ref type
if (varDeclType.getDimensions() == mapping.getMappedDimensions()) {
Xnode newVarDecl = xcodeml.createNode(Xcode.VAR_DECL);
newVarDecl.append(xcodeml.createName(var.getFctMapping(), varDeclType.getRef()));
fctDeclarations.replace(newVarDecl, var.getFctMapping());
id.setType(varDeclType.getRef());
}
}
// Loop mapped variables
}
// Loop over mapping clauses
// Adapt array reference in function body
List<Xnode> arrayReferences = clonedFctDef.body().matchAll(Xcode.F_ARRAY_REF);
for (Xnode ref : arrayReferences) {
if (!Xnode.isOfCode(ref.matchSeq(Xcode.VAR_REF).child(0), Xcode.VAR)) {
continue;
}
String mappedVar = ref.matchSeq(Xcode.VAR_REF, Xcode.VAR).value();
if (_fctMappingMap.containsKey(mappedVar)) {
ClawMapping mapping = _fctMappingMap.get(mappedVar);
boolean changeRef = true;
int mappingIndex = 0;
for (Xnode e : ref.children()) {
if (e.is(Xcode.ARRAY_INDEX)) {
List<Xnode> children = e.children();
if (!children.isEmpty() && Xnode.isOfCode(children.get(0), Xcode.VAR)) {
String varName = e.matchSeq(Xcode.VAR).value();
if (varName.equals(mapping.getMappingVariables().get(mappingIndex).getFctMapping())) {
++mappingIndex;
} else {
changeRef = false;
}
}
}
}
if (changeRef) {
// TODO Var ref should be extracted only if the reference can be
// totally demoted
ref.insertBefore(ref.matchSeq(Xcode.VAR_REF, Xcode.VAR).cloneNode());
ref.delete();
}
}
}
// Generate directive pragmas if needed
Xnode grip = null;
if (_claw.hasClause(ClawClause.ACC)) {
/*
* TODO see TODO in ExpandNotation OpenACC and OpenMP loop construct are pretty
* different ... have to look how to do that properly. See issue #22
*/
grip = Directive.generateAcceleratorClause(xcodeml, extractedLoop, _claw.value(ClawClause.ACC));
}
if (_claw.hasClause(ClawClause.PARALLEL)) {
Directive.generateParallelRegion(xcodeml, (grip == null) ? extractedLoop : grip, extractedLoop);
}
// TODO must be triggered by a clause
// Directive.generateRoutineDirectives(_claw, xcodeml, clonedFctDef);
// Add any additional transformation defined in the directive clauses
ct.generateAdditionalTransformation(_claw, xcodeml, extractedLoop);
removePragma();
transformed();
}
Aggregations