use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class ScaGPU method transformElemental.
/**
* Apply transformation on ELEMENTAL function/subroutine.
*
* @param xcodeml Current translation unit.
* @param translator Current translator.
* @throws IllegalTransformationException If transformation fails.
*/
private void transformElemental(XcodeProgram xcodeml, ClawTranslator translator) throws Exception {
/*
* SCA in ELEMENTAL function. Only flag the function and leave the actual
* transformation until having information on the calling site from another
* translation unit.
*/
if (_fctType.isElemental()) {
_fctType.setBooleanAttribute(Xattr.WAS_ELEMENTAL, true);
if (_fctType.isFunction() && !_fctType.hasAttribute(Xattr.RESULT_NAME)) {
_arrayFieldsInOut.add(_fctDef.getName());
}
if (translator.cfg().getBooleanParameter(Configuration.SCA_ELEMENTAL_PROMOTION_ASSUMED)) {
forceAssumedShapedArrayPromotion = _fctType.isSubroutine() || !(_arrayFieldsInOut.contains(_fctType.getResultName()) || _arrayFieldsInOut.contains(_fctDef.getName()));
}
// SCA ELEMENTAL
FmoduleDefinition modDef = _fctDef.findParentModule();
if (modDef == null) {
throw new IllegalTransformationException("SCA in ELEMENTAL function " + "transformation requires module encapsulation.");
}
transformReturnStatement(xcodeml);
// Apply the common transformation
super.transform(xcodeml, translator, null);
// Remove ELEMENTAL and PURE attributes if present.
removeAttributesWithWaring(xcodeml, _fctType, Xattr.IS_ELEMENTAL);
removeAttributesWithWaring(xcodeml, _fctType, Xattr.IS_PURE);
// Apply specific steps for GPU
applySpecificTransformation(translator.cfg(), xcodeml);
// Finalize the common steps
super.finalizeTransformation(xcodeml);
}
}
use of claw.tatsu.xcodeml.exception.IllegalTransformationException 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();
}
use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class LoopHoist method transform.
/**
* @see Transformation#transform(XcodeProgram, Translator, Transformation)
*/
@Override
public void transform(XcodeProgram xcodeml, Translator translator, Transformation transformation) throws Exception {
ClawTranslator ct = (ClawTranslator) translator;
HoistedNestedDoStatement hoisted = Loop.hoist(_hoistedGroups, _clawStart.getPragma(), _clawEnd.getPragma(), xcodeml);
// Generate dynamic transformation (interchange)
ct.generateAdditionalTransformation(_clawStart, xcodeml, hoisted.getOuterStatement());
// Apply cleanup clause
if (_clawStart.hasClause(ClawClause.CLEANUP)) {
Pragma.remove(_clawStart.getCleanupClauseValue(), _clawStart.getPragma(), _clawEnd.getPragma());
}
// Apply reshape clause
if (_clawStart.hasClause(ClawClause.RESHAPE)) {
FfunctionDefinition fctDef = _clawStart.getPragma().findParentFunction();
if (fctDef == null) {
throw new IllegalTransformationException("Cannot apply reshape clause." + "Parent function definition not found.", _clawStart.getPragma().lineNo());
}
for (ReshapeInfo reshapeInfo : _clawStart.getReshapeClauseValues()) {
Field.reshape(fctDef, reshapeInfo, xcodeml);
}
}
removePragma();
}
use of claw.tatsu.xcodeml.exception.IllegalTransformationException 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.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class FieldTest method performAndAssertPromotion.
/**
* Perform the promotion transformation and assert its result.
*
* @param id Identifier of the field to be promoted.
* @param dims Dimension definitions to use.
* @param fctDef Function definition in which the promotion is performed.
* @param xcodeml Current XcodeML translation unit.
* @param base Number of dimension before the promotion.
* @param target Number of dimension after the promotion.
* @param dimensions Expected dimensions after promotion.
*/
private void performAndAssertPromotion(String id, List<DimensionDefinition> dims, FfunctionDefinition fctDef, XcodeProgram xcodeml, int base, int target, int[] dimensions) {
try {
int diff = target - base;
PromotionInfo promotionInfo = new PromotionInfo(id);
promotionInfo.setDimensions(dims);
Xnode decl = fctDef.getDeclarationTable().get(id);
assertNotNull(decl);
FbasicType bt;
if (base != 0) {
bt = xcodeml.getTypeTable().getBasicType(decl);
assertNotNull(bt);
assertTrue(bt.isArray());
assertEquals(base, bt.getDimensions());
} else {
assertEquals(FortranType.REAL, FortranType.fromString(decl.getType()));
}
// Perform the promotion
Field.promote(promotionInfo, fctDef, xcodeml);
decl = fctDef.getDeclarationTable().get(id);
assertNotNull(decl);
bt = xcodeml.getTypeTable().getBasicType(decl);
assertNotNull(bt);
assertTrue(bt.isArray());
assertEquals(target, bt.getDimensions());
assertEquals(target, dimensions.length / 2);
assertEquals(target, promotionInfo.getTargetDimension());
assertEquals(base, promotionInfo.getBaseDimension());
assertEquals(diff, promotionInfo.diffDimension());
assertEquals(bt.getType(), promotionInfo.getTargetType().getType());
if (base > 0) {
assertEquals(PromotionInfo.PromotionType.ARRAY_TO_ARRAY, promotionInfo.getPromotionType());
} else {
assertEquals(PromotionInfo.PromotionType.SCALAR_TO_ARRAY, promotionInfo.getPromotionType());
}
for (int i = 0; i < dimensions.length / 2; ++i) {
assertDimension(bt.getDimensions(i), dimensions[i * 2], dimensions[(i * 2) + 1]);
}
} catch (IllegalTransformationException itex) {
System.err.println(itex.getMessage());
fail();
}
}
Aggregations