use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.
the class TransformationHelper 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 xcodemlDst Destination XcodeML unit. Duplicate will be created here.
* @param xcodemlSrc Source XcodeML unit. Contains base dimension.
* @return The new type hash generated.
*/
public static String duplicateWithDimension(XbasicType base, XbasicType toUpdate, XcodeML xcodemlDst, XcodeML xcodemlSrc, OverPosition overPos, List<ClawDimension> dimensions) throws IllegalTransformationException {
XbasicType newType = toUpdate.cloneNode();
String type = xcodemlDst.getTypeTable().generateArrayTypeHash();
newType.setAttribute(Xattr.TYPE, 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()) {
switch(overPos) {
case BEFORE:
// TODO control and validate the before/after
for (ClawDimension dim : dimensions) {
newType.addDimension(dim.generateIndexRange(xcodemlDst, false), XbasicType.APPEND);
}
break;
case AFTER:
for (ClawDimension dim : dimensions) {
newType.addDimension(dim.generateIndexRange(xcodemlDst, false), 0);
}
break;
case 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 = new Xnode(Xcode.INDEXRANGE, xcodemlDst);
newType.append(newDim, false);
Xnode baseDim = base.getDimensions(i);
Xnode lowerBound = baseDim.matchSeq(Xcode.LOWERBOUND);
Xnode upperBound = baseDim.matchSeq(Xcode.UPPERBOUND);
if (lowerBound != null) {
Xnode newLowerBound = XnodeUtil.duplicateBound(lowerBound, xcodemlDst, xcodemlSrc);
newDim.append(newLowerBound, false);
}
if (upperBound != null) {
Xnode newUpperBound = XnodeUtil.duplicateBound(upperBound, xcodemlDst, xcodemlSrc);
newDim.append(newUpperBound, false);
}
newType.addDimension(newDim, XbasicType.APPEND);
}
}
xcodemlDst.getTypeTable().add(newType);
return type;
}
use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.
the class TransformationHelper method updateModuleSignature.
/**
* Update the function signature in the module file to reflects local changes.
*
* @param xcodeml Current XcodeML file unit.
* @param fctDef Function definition that has been changed.
* @param fctType Function type that has been changed.
* @param modDef Module definition holding the function definition.
* @param claw Pragma that has triggered the transformation.
* @param transformer Current transformer object.
* @throws IllegalTransformationException If the module file or the function
* cannot be located
*/
public static void updateModuleSignature(XcodeProgram xcodeml, XfunctionDefinition fctDef, XfunctionType fctType, XmoduleDefinition modDef, ClawLanguage claw, cx2x.xcodeml.transformation.Transformer transformer, boolean importFctType) throws IllegalTransformationException {
Xmod mod;
if (transformer.getModCache().isModuleLoaded(modDef.getName())) {
mod = transformer.getModCache().get(modDef.getName());
} else {
mod = fctDef.findContainingModule();
if (mod == null) {
throw new IllegalTransformationException("Unable to locate module file for: " + modDef.getName(), claw.getPragma().lineNo());
}
transformer.getModCache().add(modDef.getName(), mod);
}
XfunctionType fctTypeMod;
if (importFctType) {
Node rawNode = mod.getDocument().importNode(fctType.element(), true);
mod.getTypeTable().element().appendChild(rawNode);
XfunctionType importedFctType = new XfunctionType((Element) rawNode);
Xid importedFctTypeId = mod.createId(importedFctType.getType(), Xname.SCLASS_F_FUNC, fctDef.getName().value());
mod.getIdentifiers().add(importedFctTypeId);
// check if params need to be imported as well
if (importedFctType.getParameterNb() > 0) {
for (Xnode param : importedFctType.getParams().getAll()) {
mod.importType(xcodeml, param.getAttribute(Xattr.TYPE));
}
}
return;
} else {
fctTypeMod = (XfunctionType) mod.getTypeTable().get(fctDef.getName().getAttribute(Xattr.TYPE));
}
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().value() + " in module " + modDef.getName();
int lineNo = claw.getPragma().lineNo();
// If not, try to matchSeq the correct FfunctionType in the module definitions
Xid id = mod.getIdentifiers().get(fctDef.getName().value());
if (id == null) {
throw new IllegalTransformationException(errorMsg, lineNo);
}
fctTypeMod = (XfunctionType) mod.getTypeTable().get(id.getType());
if (fctTypeMod == null) {
throw new IllegalTransformationException(errorMsg, lineNo);
}
}
XbasicType modIntTypeIntentIn = mod.createBasicType(mod.getTypeTable().generateIntegerTypeHash(), Xname.TYPE_F_INT, Xintent.IN);
mod.getTypeTable().add(modIntTypeIntentIn);
List<Xnode> paramsLocal = fctType.getParams().getAll();
List<Xnode> paramsMod = fctTypeMod.getParams().getAll();
if (paramsLocal.size() < paramsMod.size()) {
throw new IllegalTransformationException("Local function has more parameters than module counterpart.", claw.getPragma().lineNo());
}
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(ClawAttr.IS_CLAW.toString())) {
// new parameter
Xnode param = mod.createAndAddParamIfNotExists(pLocal.value(), modIntTypeIntentIn.getType(), fctTypeMod);
if (param != null) {
param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
}
} else {
Xnode pMod = paramsMod.get(i);
String localType = pLocal.getAttribute(Xattr.TYPE);
String modType = pMod.getAttribute(Xattr.TYPE);
if (!localType.equals(modType)) {
// Param has been update so have to replicate the change to mod file
XbasicType lType = (XbasicType) xcodeml.getTypeTable().get(localType);
XbasicType crtType = (XbasicType) mod.getTypeTable().get(modType);
List<ClawDimension> dimensions = TransformationHelper.findDimensions(fctType);
OverPosition overPos = OverPosition.fromString(pLocal.getAttribute(ClawAttr.OVER.toString()));
if (lType.isArray()) {
String newType = TransformationHelper.duplicateWithDimension(lType, crtType, mod, xcodeml, overPos, dimensions);
pMod.setAttribute(Xattr.TYPE, newType);
}
}
// Propagate the over attribute
copyAttribute(pLocal, pMod, ClawAttr.OVER);
}
}
}
use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.
the class TransformationHelper method promoteField.
/**
* Promote a field with the information stored in the defined dimensions.
*
* @param fieldId Id of the field as defined in the symbol table.
* @param update If true, update current type otherwise, create a type from
* scratch.
* @param assumed If true, generate assumed dimension range, otherwise, use
* the information in the defined dimension.
* @param overIndex Over clause to be used for promotion.
* @param xcodeml Current XcodeML program unit in which the element will be
* created.
* @param overPos Force behavior as if over clause is present.
* @throws IllegalTransformationException If type cannot be found.
*/
public static PromotionInfo promoteField(String fieldId, boolean update, boolean assumed, int overIndex, int overDimensions, XfunctionDefinition fctDef, XfunctionType fctType, List<ClawDimension> dimensions, ClawLanguage claw, XcodeProgram xcodeml, OverPosition overPos) throws IllegalTransformationException {
Xid id = fctDef.getSymbolTable().get(fieldId);
Xdecl decl = fctDef.getDeclarationTable().get(fieldId);
String type = xcodeml.getTypeTable().generateArrayTypeHash();
XbasicType newType;
if (update) {
if (XnodeUtil.isBuiltInType(id.getType())) {
newType = xcodeml.createBasicType(type, id.getType(), Xintent.NONE);
} else {
XbasicType old = (XbasicType) xcodeml.getTypeTable().get(id.getType());
if (old == null) {
throw new IllegalTransformationException("Cannot matchSeq type for " + fieldId, claw.getPragma().lineNo());
} else {
newType = old.cloneNode();
newType.setType(type);
}
}
} else {
newType = xcodeml.createBasicType(type, id.getType(), Xintent.NONE);
}
PromotionInfo proInfo = new PromotionInfo(fieldId, newType.getDimensions(), newType.getDimensions() + dimensions.size(), type);
if (assumed) {
if (newType.isAllAssumedShape() && (fctType.hasParam(fieldId) || newType.isPointer())) {
for (int i = 0; i < overDimensions; ++i) {
Xnode index = xcodeml.createEmptyAssumedShaped();
newType.addDimension(index, 0);
}
} else {
if (claw.hasOverClause() || overPos != null) {
/* If the directive has an over clause, there is three possibility to
* insert the newly defined dimensions.
* 1. Insert the dimensions in the middle on currently existing ones.
* 2. Insert the dimensions before currently existing ones.
* 3. Insert the dimensions after currently existing ones. */
if (overPos == null) {
overPos = getOverPosition(claw.getOverClauseValues().get(overIndex));
}
if (overPos == OverPosition.MIDDLE) {
// Insert new dimension in middle (case 1)
int startIdx = 1;
for (ClawDimension dim : dimensions) {
Xnode index = dim.generateIndexRange(xcodeml, false);
newType.addDimension(index, startIdx++);
}
} else if (overPos == OverPosition.AFTER) {
// Insert new dimensions at the end (case 3)
for (ClawDimension dim : dimensions) {
Xnode index = dim.generateIndexRange(xcodeml, false);
newType.addDimension(index, XbasicType.APPEND);
}
} else {
// Insert new dimension at the beginning (case 2)
for (ClawDimension dim : dimensions) {
Xnode index = dim.generateIndexRange(xcodeml, false);
newType.addDimension(index, 0);
}
}
} else {
for (ClawDimension dim : dimensions) {
Xnode index = dim.generateIndexRange(xcodeml, false);
newType.addDimension(index, 0);
}
}
}
} else {
for (ClawDimension dim : dimensions) {
Xnode index = dim.generateIndexRange(xcodeml, false);
newType.addDimension(index, XbasicType.APPEND);
}
}
id.setType(type);
decl.matchSeq(Xcode.NAME).setAttribute(Xattr.TYPE, type);
xcodeml.getTypeTable().add(newType);
// Update params in function type
for (Xnode param : fctType.getParams().getAll()) {
if (param.value().equals(fieldId)) {
// Update type with new promoted type
param.setAttribute(Xattr.TYPE, type);
// Save the over clause for parallelize forward transformation
if (claw.hasOverClause()) {
param.setAttribute(ClawAttr.OVER.toString(), getOverPosition(claw.getOverClauseValues().get(overIndex)).toString());
}
}
}
if (fctType.hasAttribute(Xattr.RESULT_NAME) && fctType.getAttribute(Xattr.RESULT_NAME).equals(fieldId)) {
if (claw.hasOverClause()) {
fctType.setAttribute(ClawAttr.OVER.toString(), getOverPosition(claw.getOverClauseValues().get(overIndex)).toString());
}
}
return proInfo;
}
use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.
the class Parallelize method insertVariableToIterateOverDimension.
/**
* Insert the declaration of the different variables needed to iterate over
* the additional dimensions.
*
* @param xcodeml Current XcodeML program unit in which element are
* created.
*/
private void insertVariableToIterateOverDimension(XcodeProgram xcodeml) {
// Create type and declaration for iterations over the new dimensions
XbasicType intTypeIntentIn = xcodeml.createBasicType(xcodeml.getTypeTable().generateIntegerTypeHash(), Xname.TYPE_F_INT, Xintent.IN);
xcodeml.getTypeTable().add(intTypeIntentIn);
// For each dimension defined in the directive
for (ClawDimension dimension : _claw.getDimensionValues()) {
// Create the parameter for the lower bound
if (dimension.lowerBoundIsVar()) {
xcodeml.createIdAndDecl(dimension.getLowerBoundId(), intTypeIntentIn.getType(), Xname.SCLASS_F_PARAM, _fctDef);
// Add parameter to the local type table
Xnode param = xcodeml.createAndAddParam(dimension.getLowerBoundId(), intTypeIntentIn.getType(), _fctType);
param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
}
// Create parameter for the upper bound
if (dimension.upperBoundIsVar()) {
xcodeml.createIdAndDecl(dimension.getUpperBoundId(), intTypeIntentIn.getType(), Xname.SCLASS_F_PARAM, _fctDef);
// Add parameter to the local type table
Xnode param = xcodeml.createAndAddParam(dimension.getUpperBoundId(), intTypeIntentIn.getType(), _fctType);
param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
}
// Create induction variable declaration
xcodeml.createIdAndDecl(dimension.getIdentifier(), Xname.TYPE_F_INT, Xname.SCLASS_F_LOCAL, _fctDef);
}
}
use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.
the class Parallelize method transformForCPU.
/**
* Apply CPU based transformations.
*
* @param xcodeml Current XcodeML program unit.
* @throws IllegalTransformationException If promotion of arrays fails.
*/
private void transformForCPU(XcodeProgram xcodeml) throws IllegalTransformationException {
/* Create a group of nested loop with the newly defined dimension and wrap
* every assignment statement in the column loop or including data with it.
* This is for the moment a really naive transformation idea but it is our
* start point.
* Use the first over clause to do it. */
List<ClawDimension> order = getOrderedDimensionsFromDefinition(0);
List<Xnode> assignStatements = _fctDef.body().matchAll(Xcode.FASSIGNSTATEMENT);
for (Xnode assign : assignStatements) {
Xnode lhs = assign.child(Xnode.LHS);
String lhsName = (lhs.opcode() == Xcode.VAR) ? lhs.value() : lhs.matchSeq(Xcode.VARREF, Xcode.VAR).value();
NestedDoStatement loops = null;
if (lhs.opcode() == Xcode.FARRAYREF && _arrayFieldsInOut.contains(lhsName)) {
loops = new NestedDoStatement(order, xcodeml);
assign.insertAfter(loops.getOuterStatement());
loops.getInnerStatement().body().append(assign, true);
assign.delete();
} else if (lhs.opcode() == Xcode.VAR || lhs.opcode() == Xcode.FARRAYREF && _scalarFields.contains(lhsName)) {
/* If the assignment is in the column loop and is composed with some
* promoted variables, the field must be promoted and the var reference
* switch to an array reference */
if (shouldBePromoted(assign)) {
if (!_arrayFieldsInOut.contains(lhsName)) {
_arrayFieldsInOut.add(lhsName);
PromotionInfo promotionInfo;
if (lhs.opcode() == Xcode.VAR) {
// Scalar to array
promotionInfo = TransformationHelper.promoteField(lhsName, false, false, DEFAULT_OVER, _overDimensions, _fctDef, _fctType, _claw.getDimensionValues(), _claw, xcodeml, null);
} else {
// Array to array
promotionInfo = TransformationHelper.promoteField(lhsName, true, true, DEFAULT_OVER, _overDimensions, _fctDef, _fctType, _claw.getDimensionValues(), _claw, xcodeml, null);
}
_promotions.put(lhsName, promotionInfo);
}
if (lhs.opcode() == Xcode.VAR) {
adaptScalarRefToArrayReferences(xcodeml, Collections.singletonList(lhsName), DEFAULT_OVER);
} else {
TransformationHelper.adaptArrayReferences(Collections.singletonList(lhsName), DEFAULT_OVER, _fctDef.body(), _promotions, _beforeCrt, _inMiddle, _afterCrt, xcodeml);
}
loops = new NestedDoStatement(order, xcodeml);
assign.insertAfter(loops.getOuterStatement());
loops.getInnerStatement().body().append(assign, true);
assign.delete();
}
}
if (loops != null) {
// Generate the corresponding directive around the loop
AcceleratorHelper.generateLoopDirectives(_claw, xcodeml, loops.getOuterStatement(), loops.getOuterStatement(), AcceleratorHelper.NO_COLLAPSE);
}
}
// Generate the parallel region
AcceleratorHelper.generateParallelClause(_claw, xcodeml, _fctDef.body().firstChild(), _fctDef.body().lastChild());
}
Aggregations