use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class ExpandNotation method generateDoStmtNotation.
/**
* Generate the corresponding do statements for the array notations. A do
* statement is generated per dimension of the arrays. Iteration index range are
* computed with array dimensions.
*
* @param xcodeml The XcodeML on which the transformations are applied.
* @param translator The translator used to applied the transformations.
* @param fctDef The function definition in which the array notation is
* nested.
* @param ranges The list of iteration ranges to be applied to the created
* do statements.
* @param statements The list of assign statements (array notation) that will be
* included in the nested do statements.
* @param doStmtGrip Grip for the code insertion. Do statements will be inserted
* after the grip element.
* @return Block surrounding the do statements generated.
*/
private Xblock generateDoStmtNotation(XcodeProgram xcodeml, ClawTranslator translator, FfunctionDefinition fctDef, List<Xnode> ranges, List<Xnode> statements, Xnode doStmtGrip) throws IllegalTransformationException {
String[] inductionVars = new String[ranges.size()];
Xnode[] doStmts = new Xnode[ranges.size()];
Xnode var = statements.get(0).matchSeq(Xcode.F_ARRAY_REF, Xcode.VAR_REF, Xcode.VAR);
if (var == null) {
var = statements.get(0).matchSeq(Xcode.F_ARRAY_REF, Xcode.VAR_REF, Xcode.F_MEMBER_REF);
}
// 1. Create do statements with induction variables
for (int i = 0; i < ranges.size(); ++i) {
// 1.1 Create induction variables
if (_clawStart.hasClause(ClawClause.INDUCTION)) {
// Use user names
inductionVars[i] = _clawStart.values(ClawClause.INDUCTION).get(i);
} else {
// generate new names
inductionVars[i] = "claw_induction_" + translator.getNextTransformationCounter();
}
// 2.2 inject a new entry in the symbol table
if (!fctDef.getSymbolTable().contains(inductionVars[i])) {
Xid inductionVarId = xcodeml.createId(FortranType.INTEGER, XstorageClass.F_LOCAL, inductionVars[i]);
fctDef.getSymbolTable().add(inductionVarId, false);
}
// 2.3 inject a new entry in the declaration table
if (!fctDef.getDeclarationTable().contains(inductionVars[i])) {
Xnode inductionVarDecl = xcodeml.createVarDecl(FortranType.INTEGER, inductionVars[i]);
fctDef.getDeclarationTable().add(inductionVarDecl);
}
// 2.4 create do statements
Xnode inductionVar = xcodeml.createVar(FortranType.INTEGER, inductionVars[i], Xscope.LOCAL);
Xnode range;
if (ranges.get(i).getBooleanAttribute(Xattr.IS_ASSUMED_SHAPE)) {
// Allocatable array
// dimension argument of size starts at one
range = xcodeml.createRangeForAssumedShapeArray(var, 1, i + 1);
} else {
range = ranges.get(i).cloneNode();
}
doStmts[i] = xcodeml.createDoStmt(inductionVar, range);
statements.get(0).copyEnhancedInfo(doStmts[i]);
if (i == 0) {
// most outer loop goes after the pragma
doStmtGrip.insertAfter(doStmts[i]);
} else {
// others loop go in the previous one
doStmts[i - 1].body().append(doStmts[i]);
}
}
for (Xnode stmt : statements) {
// 3. Adapt array reference with induction variables
List<Xnode> allArrayRef = stmt.matchAll(Xcode.F_ARRAY_REF);
for (Xnode arrayRef : allArrayRef) {
for (int i = 0; i < arrayRef.children().size() - 1; ++i) {
Xnode el = arrayRef.child(i + 1);
if (Xnode.isOfCode(el, Xcode.INDEX_RANGE) && i < doStmts.length) {
String induction = doStmts[i].matchSeq(Xcode.VAR).value();
Xnode inductionVar = xcodeml.createVar(FortranType.INTEGER, induction, Xscope.LOCAL);
Xnode arrayIdx = xcodeml.createNode(Xcode.ARRAY_INDEX);
arrayIdx.append(inductionVar);
el.insertAfter(arrayIdx);
el.delete();
}
}
}
stmt.matchAll(Xcode.FUNCTION_CALL).stream().map(FunctionCall::new).filter(x -> x.isIntrinsicCall(Xintrinsic.SUM)).forEach(FunctionCall::adaptIntrinsicSumCall);
stmt.matchAll(Xcode.FUNCTION_CALL).stream().map(FunctionCall::new).filter(x -> x.isIntrinsicCall(Xintrinsic.SPREAD)).forEach(FunctionCall::adaptIntrinsicSpreadCall);
// 4. Move assignment statement inside the most inner loop
doStmts[ranges.size() - 1].body().append(stmt, true);
stmt.delete();
}
// Add any additional transformation defined in the directive clauses
translator.generateAdditionalTransformation(_clawStart, xcodeml, doStmts[0]);
return new Xblock(doStmts[0]);
}
use of claw.tatsu.xcodeml.exception.IllegalTransformationException 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.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class Loop method swapIterationRange.
/**
* Swap the iteration range information of two do statement.
*
* @param e1 First do statement.
* @param e2 Second do statement.
* @throws IllegalTransformationException if necessary elements are missing to
* apply the transformation.
*/
private static void swapIterationRange(Xnode e1, Xnode e2) throws IllegalTransformationException {
// The two nodes must be do statement
if (!Xnode.isOfCode(e1, Xcode.F_DO_STATEMENT) || !Xnode.isOfCode(e2, Xcode.F_DO_STATEMENT)) {
throw new IllegalTransformationException("Only two do statement can be " + "swap iteration ranges.");
}
Xnode inductionVar1 = e1.matchDirectDescendant(Xcode.VAR);
Xnode inductionVar2 = e2.matchDirectDescendant(Xcode.VAR);
Xnode indexRange1 = e1.matchDirectDescendant(Xcode.INDEX_RANGE);
Xnode indexRange2 = e2.matchDirectDescendant(Xcode.INDEX_RANGE);
if (inductionVar1 == null || inductionVar2 == null || indexRange1 == null || indexRange2 == null) {
throw new IllegalTransformationException("Induction variable or index " + "range missing.");
}
Xnode low1 = indexRange1.matchSeq(Xcode.LOWER_BOUND).child(0);
Xnode up1 = indexRange1.matchSeq(Xcode.UPPER_BOUND).child(0);
Xnode s1 = indexRange1.matchSeq(Xcode.STEP).child(0);
Xnode low2 = indexRange2.matchSeq(Xcode.LOWER_BOUND).child(0);
Xnode up2 = indexRange2.matchSeq(Xcode.UPPER_BOUND).child(0);
Xnode s2 = indexRange2.matchSeq(Xcode.STEP).child(0);
// Set the range of loop2 to loop1
inductionVar2.insertAfter(inductionVar1.cloneNode());
low2.insertAfter(low1.cloneNode());
up2.insertAfter(up1.cloneNode());
s2.insertAfter(s1.cloneNode());
inductionVar1.insertAfter(inductionVar2.cloneNode());
low1.insertAfter(low2.cloneNode());
up1.insertAfter(up2.cloneNode());
s1.insertAfter(s2.cloneNode());
inductionVar1.delete();
inductionVar2.delete();
low1.delete();
up1.delete();
s1.delete();
low2.delete();
up2.delete();
s2.delete();
}
use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class Loop method reorder.
/**
* Perform a do statements reordering based on the new order specified by
* induction variables.
*
* i,j,k → k,j,i
*
* @param nestedGroup The nested group of do statements to be
* reordered.
* @param newInductionVarOrder New order of the induction variables. E.g. k,j,i.
* @throws IllegalTransformationException If reordering acton is not supported.
*/
public static void reorder(Context context, NestedDoStatement nestedGroup, List<String> newInductionVarOrder) throws IllegalTransformationException {
// Check that new order is possible
if (nestedGroup.size() == 2) {
// simple swap
swapIterationRange(nestedGroup.getOuterStatement(), nestedGroup.getInnerStatement());
Message.debug(context, "Loop reordering: single swap operation");
} else if (nestedGroup.size() == 3) {
int newPosition = nestedGroup.computeSwappingIndices(newInductionVarOrder);
Message.debug(context, "Loop reordering: potential double swap operation " + newPosition);
switch(newPosition) {
case // Double swap: i,j,k -> j,k,i
201:
swapIterationRange(nestedGroup.get(0), nestedGroup.get(1));
swapIterationRange(nestedGroup.get(1), nestedGroup.get(2));
break;
case // Double swap: i,j,k -> k,i,j
120:
swapIterationRange(nestedGroup.get(0), nestedGroup.get(2));
swapIterationRange(nestedGroup.get(2), nestedGroup.get(1));
break;
case // Single swap: i,j,k -> i,k,j
21:
swapIterationRange(nestedGroup.get(1), nestedGroup.get(2));
break;
case // Single swap: i,j,k -> k,j,i
210:
swapIterationRange(nestedGroup.get(0), nestedGroup.get(2));
break;
case // Single swap: i,j,k -> j,i,k
102:
swapIterationRange(nestedGroup.get(0), nestedGroup.get(1));
break;
default:
// Do nothing.
break;
}
} else {
throw new IllegalTransformationException("Currently unsupported " + "reorder operation.");
}
}
use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.
the class Loop method extractBody.
/**
* Extract the body of a do statement and place it after the reference node.
*
* @param loop The do statement containing the body to be extracted.
* @param ref Element after which statement are shifted.
* @throws IllegalTransformationException If node passed as arguments are
* incompatible with the transformation.
*/
private static void extractBody(Xnode loop, Xnode ref) throws IllegalTransformationException {
if (ref == null || !Xnode.isOfCode(loop, Xcode.F_DO_STATEMENT)) {
throw new IllegalTransformationException(String.format("%s for Loop.extractBody. opcode: %s", TatsuConstant.ERROR_INCOMPATIBLE, loop == null ? "null" : loop.opcode()));
}
Xnode body = loop.body();
if (body == null) {
return;
}
Xnode refNode = ref;
for (Xnode child : body.children()) {
refNode.insertAfter(child);
refNode = child;
}
}
Aggregations