use of claw.tatsu.xcodeml.abstraction.DimensionDefinition in project claw-compiler by C2SM-RCM.
the class Field method promote.
/**
* Promote a field with the information stored in the defined dimensions.
*
* @param fieldInfo Promotion information. Must contains identifier and
* dimensions.
* @param fctDef Function definition node in which the promotion is
* performed.
* @param xcodeml Current XcodeML translation unit.
* @throws IllegalTransformationException If promotion information are not
* sufficient. If types cannot be found
* in typeTable.
*/
public static void promote(PromotionInfo fieldInfo, FfunctionDefinition fctDef, XcodeProgram xcodeml) throws IllegalTransformationException {
Xid id = fctDef.getSymbolTable().get(fieldInfo.getIdentifier());
Xnode decl = fctDef.getDeclarationTable().get(fieldInfo.getIdentifier());
FbasicType crtType = xcodeml.getTypeTable().getBasicType(id);
FfunctionType tmpFctType = xcodeml.getTypeTable().getFunctionType(id);
boolean returnTypePromotion = false;
if (crtType == null && tmpFctType != null) {
// Have to retrieve function return type.
crtType = xcodeml.getTypeTable().getBasicType(tmpFctType.getReturnType());
returnTypePromotion = true;
}
if (!FortranType.isBuiltInType(id.getType()) && crtType == null) {
throw new IllegalTransformationException("Basic type of field " + fieldInfo.getIdentifier() + " could not be found");
}
FfunctionType fctType = xcodeml.getTypeTable().getFunctionType(fctDef);
if (fctType == null) {
throw new IllegalTransformationException("Function type " + fctDef.getType() + " could not be found", fctDef.lineNo());
}
if (fieldInfo.getDimensions() == null || fieldInfo.getDimensions().isEmpty()) {
throw new IllegalTransformationException("Promotion information has not " + "enough information. Dimension empty!", decl.lineNo());
}
String type = xcodeml.getTypeTable().generateHash(FortranType.ARRAY);
FbasicType newType;
if (crtType != null && crtType.isArray()) {
fieldInfo.setPromotionType(PromotionInfo.PromotionType.ARRAY_TO_ARRAY);
if (FortranType.isBuiltInType(id.getType())) {
newType = xcodeml.createBasicType(type, id.getType(), Intent.NONE);
} else {
FbasicType old = xcodeml.getTypeTable().getBasicType(id);
if (old == null) {
throw new IllegalTransformationException("Cannot find type for " + fieldInfo.getIdentifier(), decl.lineNo());
} else {
newType = old.cloneNode();
newType.setType(type);
}
}
} else {
fieldInfo.setPromotionType(PromotionInfo.PromotionType.SCALAR_TO_ARRAY);
Intent newIntent = crtType != null ? crtType.getIntent() : Intent.NONE;
if (returnTypePromotion) {
newType = xcodeml.createBasicType(type, crtType != null ? crtType.getRef() : "", newIntent);
} else {
newType = xcodeml.createBasicType(type, id.getType(), newIntent);
}
newType.copyAttributes(crtType);
}
// Save promotion information (base dimensions, target dimensions, type)
fieldInfo.setBaseDimension(newType.getDimensions());
fieldInfo.setTargetDimension(newType.getDimensions() + fieldInfo.getDimensions().size());
fieldInfo.setTargetType(newType);
if (fieldInfo.getPromotionType() == PromotionInfo.PromotionType.ARRAY_TO_ARRAY) {
if (newType.isAllAssumedShape() && (fctType.hasParam(fieldInfo.getIdentifier()) || newType.isAllocatable() || newType.isPointer())) {
for (int i = 0; i < fieldInfo.diffDimension(); ++i) {
Xnode index = xcodeml.createEmptyAssumedShaped();
newType.addDimension(index, 0);
}
} else {
int beforePositionIndex = 0;
int inMiddlePositionIndex = 1;
for (DimensionDefinition dim : fieldInfo.getDimensions()) {
switch(dim.getInsertionPosition()) {
case BEFORE:
newType.addDimension(dim.generateIndexRange(xcodeml, false, false), beforePositionIndex);
++beforePositionIndex;
// Update index to insert in middle
++inMiddlePositionIndex;
break;
case IN_MIDDLE:
newType.addDimension(dim.generateIndexRange(xcodeml, false, false), inMiddlePositionIndex);
++inMiddlePositionIndex;
break;
case AFTER:
newType.addDimension(dim.generateIndexRange(xcodeml, false, false));
break;
}
}
}
} else {
// SCALAR to ARRAY promotion
for (DimensionDefinition dim : fieldInfo.getDimensions()) {
Xnode index;
if (fieldInfo.isForcedAssumedShape()) {
index = xcodeml.createEmptyAssumedShaped();
} else {
index = dim.generateIndexRange(xcodeml, false, false);
}
newType.addDimension(index);
}
}
// Set type hash to id and declaration node
id.setType(type);
decl.matchSeq(Xcode.NAME).setType(type);
xcodeml.getTypeTable().add(newType);
if (returnTypePromotion) {
fctType.setAttribute(Xattr.RETURN_TYPE, type);
}
// Update params in function type with correct type hash
for (Xnode param : fctType.getParameters()) {
if (param.value().equals(fieldInfo.getIdentifier())) {
// Update type with new promoted type
param.setType(type);
// Save the over clause for one_column forward transformation
param.setAttribute(Xattr.PROMOTION_INFO, fieldInfo.getFormattedDimensions());
}
}
if (fctType.hasAttribute(Xattr.RESULT_NAME) && fctType.getAttribute(Xattr.RESULT_NAME).equals(fieldInfo.getIdentifier())) {
fctType.setAttribute(Xattr.PROMOTION_INFO, fieldInfo.getFormattedDimensions());
}
}
use of claw.tatsu.xcodeml.abstraction.DimensionDefinition in project claw-compiler by C2SM-RCM.
the class Field method adaptAllocate.
/**
* Adapt allocate statement with given dimension.
*
* @param promotionInfo Promotion information. Must contains identifier and
* dimensions.
* @param parent Root node from which allocate statements are looked for.
* @param xcodeml Current XcodeML translation unit.
*/
public static void adaptAllocate(PromotionInfo promotionInfo, Xnode parent, XcodeProgram xcodeml) {
if (promotionInfo.isAllocateAdapted()) {
return;
}
String arrayName = promotionInfo.getIdentifier();
// Look through all allocate statements
for (Xnode allocatedStmt : parent.matchAll(Xcode.F_ALLOCATE_STATEMENT)) {
for (Xnode alloc : allocatedStmt.matchAll(Xcode.ALLOC)) {
Xnode var = alloc.matchDirectDescendant(Xcode.VAR);
if (var != null && var.value().equals(arrayName)) {
// First arrayIndex after varRef at pos 0
int beforePositionIndex = 0;
int inMiddlePositionIndex = 1;
for (DimensionDefinition dim : promotionInfo.getDimensions()) {
switch(dim.getInsertionPosition()) {
case BEFORE:
if (beforePositionIndex == 0) {
alloc.insert(dim.generateAllocateNode(xcodeml));
} else {
alloc.child(beforePositionIndex).insertBefore(dim.generateArrayIndex(xcodeml));
}
++beforePositionIndex;
++inMiddlePositionIndex;
break;
case IN_MIDDLE:
alloc.child(inMiddlePositionIndex).insertAfter(dim.generateArrayIndex(xcodeml));
++inMiddlePositionIndex;
break;
case AFTER:
alloc.append(dim.generateArrayIndex(xcodeml));
break;
}
}
}
}
}
promotionInfo.setAllocateAdapted();
}
use of claw.tatsu.xcodeml.abstraction.DimensionDefinition in project claw-compiler by C2SM-RCM.
the class Field method adaptScalarRefToArrayRef.
/**
* Adapt all the array references of the variable in the data clause in the
* current function/subroutine definition.
*
* @param promotionInfo Object holding the promotion information.
* @param fctDef Function definition in which reference are changed.
* @param dims Dimension definition to use for array index generation.
* @param xcodeml Current XcodeML program unit in which the element will
* be created.
*/
public static void adaptScalarRefToArrayRef(PromotionInfo promotionInfo, FfunctionDefinition fctDef, List<DimensionDefinition> dims, XcodeML xcodeml) {
if (promotionInfo.isRefAdapted()) {
return;
}
List<Xnode> vars = XnodeUtil.findAllReferences(fctDef.body(), promotionInfo.getIdentifier());
Xid sId = fctDef.getSymbolTable().get(promotionInfo.getIdentifier());
FbasicType type = xcodeml.getTypeTable().getBasicType(sId);
List<Xnode> arrayIndexes = new ArrayList<>();
for (DimensionDefinition d : dims) {
arrayIndexes.add(d.generateArrayIndex(xcodeml));
}
for (Xnode var : vars) {
Xnode ref = xcodeml.createArrayRef(type, var.cloneNode());
for (Xnode ai : arrayIndexes) {
ref.append(ai, true);
}
var.insertAfter(ref);
var.delete();
}
promotionInfo.setRefAdapted();
}
use of claw.tatsu.xcodeml.abstraction.DimensionDefinition in project claw-compiler by C2SM-RCM.
the class Type method duplicateWithDimension.
/**
* Duplicates the type to update and add extra dimensions to match the base
* type.
*
* @param base Base type.
* @param toUpdate Type to update.
* @param xcodemlSrc Source XcodeML unit. Contains base dimension.
* @param xcodemlDst Destination XcodeML unit. Duplicate will be created here.
* @param dimensions List of dimensions definitions to be used.
* @return The new type hash generated.
* @throws IllegalTransformationException If action is not supported.
*/
public static FbasicType duplicateWithDimension(FbasicType base, FbasicType toUpdate, XcodeML xcodemlSrc, XcodeML xcodemlDst, List<DimensionDefinition> dimensions) throws IllegalTransformationException {
FbasicType newType = toUpdate.cloneNode();
String type = xcodemlDst.getTypeTable().generateHash(FortranType.ARRAY);
newType.setType(type);
if (base.isAllAssumedShape() && toUpdate.isAllAssumedShape()) {
int additionalDimensions = base.getDimensions() - toUpdate.getDimensions();
for (int i = 0; i < additionalDimensions; ++i) {
Xnode index = xcodemlDst.createEmptyAssumedShaped();
newType.addDimension(index, 0);
}
} else if (base.isAllAssumedShape() && !toUpdate.isAllAssumedShape()) {
for (DimensionDefinition dim : dimensions) {
switch(dim.getInsertionPosition()) {
case BEFORE:
// TODO control and validate the before/after
newType.addDimension(dim.generateIndexRange(xcodemlDst, false, false));
break;
case AFTER:
newType.addDimension(dim.generateIndexRange(xcodemlDst, false, false), 0);
break;
case IN_MIDDLE:
throw new IllegalTransformationException("Not supported yet. " + "Insertion in middle for duplicated array type.", 0);
}
}
} else {
newType.resetDimension();
for (int i = 0; i < base.getDimensions(); ++i) {
Xnode newDim = xcodemlDst.createNode(Xcode.INDEX_RANGE);
newType.append(newDim);
Xnode baseDim = base.getDimensions(i);
Xnode lowerBound = baseDim.matchSeq(Xcode.LOWER_BOUND);
Xnode upperBound = baseDim.matchSeq(Xcode.UPPER_BOUND);
if (lowerBound != null) {
Xnode newLowerBound = Type.duplicateBound(lowerBound, xcodemlSrc, xcodemlDst);
newDim.append(newLowerBound);
}
if (upperBound != null) {
Xnode newUpperBound = Type.duplicateBound(upperBound, xcodemlSrc, xcodemlDst);
newDim.append(newUpperBound);
}
newType.addDimension(newDim);
}
}
xcodemlDst.getTypeTable().add(newType);
return newType;
}
use of claw.tatsu.xcodeml.abstraction.DimensionDefinition in project claw-compiler by C2SM-RCM.
the class ModelConfig method readLayouts.
/**
* Read all the layouts defined in the model configuration.
*
* The layouts can be defined as follows:
*
* [[layouts]] id = "id" position = [ "dim1", ":" ]
*
* The ":" dimension is representing the base dimension (currently present
* dimensions)
*
* @param result The current TOML parse result object.
* @throws Exception If the result is not conform to the specifications.
*/
private void readLayouts(TomlParseResult result) throws Exception {
TomlArray layouts = result.getArray(KEY_LAYOUTS);
if (layouts == null) {
throw new Exception(String.format(ERR_NO_LAYOUTS, _modelName));
}
for (int i = 0; i < layouts.size(); ++i) {
TomlTable layout = layouts.getTable(i);
String layoutId = layout.getString(KEY_DIMENSION_ID);
if (layoutId == null) {
throw new Exception(ERR_LAYOUT_NO_ID);
}
TomlArray position = layout.getArray(KEY_LAYOUT_POSITION);
if (position == null) {
throw new Exception(String.format(ERR_LAYOUT_NO_POSITION, layoutId));
}
List<DimensionDefinition> dimensions = new ArrayList<>();
for (int j = 0; j < position.size(); ++j) {
String pos = position.getString(j);
if (pos.equals(DimensionDefinition.BASE_DIM)) {
dimensions.add(DimensionDefinition.BASE_DIMENSION);
} else {
if (!_dimensions.containsKey(pos)) {
throw new Exception(String.format(ERR_DIM_NOT_AVAIL, pos, layoutId));
}
dimensions.add(_dimensions.get(pos));
}
}
if (!dimensions.contains(DimensionDefinition.BASE_DIMENSION)) {
throw new Exception(String.format(ERR_NO_BASE_DIM, layoutId));
}
DimensionDefinition.flagInsertPosition(dimensions);
dimensions.remove(DimensionDefinition.BASE_DIMENSION);
_layouts.put(layoutId, dimensions);
}
}
Aggregations