use of cx2x.translator.language.common.OverPosition 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.OverPosition in project claw-compiler by C2SM-RCM.
the class ParallelizeForward method transformStd.
/**
* Do the standard transformation for the forward directive. This
* transformation adapt the function call and replicates any necessary changes
* to the containing subroutine.
*
* @param xcodeml Current XcodeML file unit.
* @param transformer Current transformer.
* @throws Exception If something goes wrong.
*/
private void transformStd(XcodeProgram xcodeml, Transformer transformer) throws Exception {
XfunctionDefinition fDef = XnodeUtil.findParentFunction(_claw.getPragma());
if (fDef == null) {
throw new IllegalTransformationException("Parallelize directive is not " + "nested in a function/subroutine.", _claw.getPragma().lineNo());
}
_parentFctType = (XfunctionType) xcodeml.getTypeTable().get(fDef.getName().getAttribute(Xattr.TYPE));
List<Xnode> params = _fctType.getParams().getAll();
/* Compute the position of the first new arguments. In the case of a
* type-bound procedure call, the first parameter declared in the procedure
* is not actually passed as an argument. In this case, we add an offset of
* one to the starting arguments.
* TODO the check might be change to fit with the XcodeML/F2008 specs. The
* TODO cont: attribute data_ref will probably be gone and replaced by a
* TODO cont: FmemberRef element
*/
int argOffset = 0;
if (params.get(0).getAttribute(Xattr.TYPE).startsWith(Xtype.PREFIX_STRUCT) && _fctCall.firstChild().opcode().equals(Xcode.FMEMBERREF)) {
argOffset = 1;
}
// 1. Adapt function call with potential new arguments
for (int i = 0; i < params.size(); i++) {
Xnode p = params.get(i);
String var = p.value();
String type;
XbasicType paramType = (XbasicType) xcodeml.getTypeTable().get(p.getAttribute(Xattr.TYPE));
if (!p.getBooleanAttribute(ClawAttr.IS_CLAW.toString())) {
continue;
}
if (!fDef.getSymbolTable().contains(var)) {
if (_flatten && !paramType.getBooleanAttribute(Xattr.IS_OPTIONAL)) {
throw new IllegalTransformationException("Variable " + var + " must" + " be locally defined where the last call to parallelize if made.", _claw.getPragma().lineNo());
}
// Size variable have to be declared
XbasicType intTypeIntentIn = xcodeml.createBasicType(xcodeml.getTypeTable().generateIntegerTypeHash(), Xname.TYPE_F_INT, Xintent.IN);
xcodeml.getTypeTable().add(intTypeIntentIn);
xcodeml.createIdAndDecl(var, intTypeIntentIn.getType(), Xname.SCLASS_F_PARAM, fDef);
type = intTypeIntentIn.getType();
Xnode param = xcodeml.createAndAddParam(var, type, _parentFctType);
param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
} else {
// Var exists already. Add to the parameters if not here.
type = fDef.getSymbolTable().get(var).getType();
/* If flatten mode, we do not add extra parameters to the function
* definition */
if (!_flatten) {
Xnode param = xcodeml.createAndAddParamIfNotExists(var, type, _parentFctType);
if (param != null) {
param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
}
}
}
// Add variable in the function call before the optional parameters
Xnode arg = xcodeml.createNamedValue(var);
Xnode namedValVar = xcodeml.createVar(type, var, Xscope.LOCAL);
arg.append(namedValVar, false);
Xnode arguments = _fctCall.matchSeq(Xcode.ARGUMENTS);
Xnode hook = arguments.child((i - 1) - argOffset);
hook.insertAfter(arg);
}
// In flatten mode, arguments are demoted if needed.
if (_flatten) {
Xnode arguments = _fctCall.matchSeq(Xcode.ARGUMENTS);
for (Xnode arg : arguments.children()) {
if (arg.opcode() == Xcode.FARRAYREF && arg.matchDirectDescendant(Arrays.asList(Xcode.INDEXRANGE, Xcode.ARRAYINDEX)) != null) {
Xnode var = arg.matchSeq(Xcode.VARREF, Xcode.VAR);
if (var != null) {
arg.insertAfter(var.cloneNode());
arg.delete();
}
}
}
} else {
// 2. Adapt function/subroutine in which the function call is nested
for (Xnode pBase : _fctType.getParams().getAll()) {
String original_param = pBase.value();
if (_fctCallMapping.containsKey(original_param)) {
original_param = _fctCallMapping.get(original_param);
}
Xnode pUpdate = null;
for (Xnode param : _parentFctType.getParams().getAll()) {
if (original_param.equals(param.value())) {
pUpdate = param;
}
}
if (pUpdate == null) {
// field is not a parameter but maybe out field
Xdecl d = fDef.getDeclarationTable().get(original_param);
if (d != null) {
pUpdate = d.matchSeq(Xcode.NAME);
}
// TODO handle deferred shape
}
if (pUpdate != null) {
if (pUpdate.getAttribute(Xattr.TYPE) == null || XnodeUtil.isBuiltInType(pUpdate.getAttribute(Xattr.TYPE))) {
continue;
}
XbasicType typeBase = (_localFct) ? (XbasicType) xcodeml.getTypeTable().get(pBase.getAttribute(Xattr.TYPE)) : (XbasicType) _mod.getTypeTable().get(pBase.getAttribute(Xattr.TYPE));
XbasicType typeToUpdate = (XbasicType) xcodeml.getTypeTable().get(pUpdate.getAttribute(Xattr.TYPE));
int targetDim = typeBase.getDimensions();
int baseDim = typeToUpdate.getDimensions();
// Types have different dimensions
if (typeBase.getDimensions() > typeToUpdate.getDimensions()) {
// TODO check intent rules
/*if(!isParam && typeToUpdate.getIntent() != Xintent.OUT){
continue;
}*/
List<ClawDimension> dimensions = TransformationHelper.findDimensions(_fctType);
OverPosition overPos = OverPosition.fromString(pBase.getAttribute(ClawAttr.OVER.toString()));
String type = _localFct ? TransformationHelper.duplicateWithDimension(typeBase, typeToUpdate, xcodeml, xcodeml, overPos, dimensions) : TransformationHelper.duplicateWithDimension(typeBase, typeToUpdate, xcodeml, _mod, overPos, dimensions);
pUpdate.setAttribute(Xattr.TYPE, type);
Xid id = fDef.getSymbolTable().get(original_param);
if (id != null) {
id.setAttribute(Xattr.TYPE, type);
}
Xdecl varDecl = fDef.getDeclarationTable().get(original_param);
if (varDecl != null) {
varDecl.matchSeq(Xcode.NAME).setAttribute(Xattr.TYPE, type);
}
_promotedVar.add(original_param);
addPromotedVar(original_param, overPos);
_promotions.put(original_param, new PromotionInfo(pBase.value(), baseDim, targetDim, type));
}
}
}
if (!_parentFctType.getBooleanAttribute(Xattr.IS_PRIVATE)) {
// 3. Replicate the change in a potential module file
XmoduleDefinition modDef = fDef.findParentModule();
TransformationHelper.updateModuleSignature(xcodeml, fDef, _parentFctType, modDef, _claw, transformer, false);
} else if (_fctCall.matchSeq(Xcode.NAME).hasAttribute(Xattr.DATAREF)) {
/* The function/subroutine is private but accessible through the type
* as a type-bound procedure. In this case, the function is not in the
* type table of the .xmod file. We need to insert it first and then
* we can update it. */
XmoduleDefinition modDef = fDef.findParentModule();
TransformationHelper.updateModuleSignature(xcodeml, fDef, _parentFctType, modDef, _claw, transformer, true);
}
}
updateResultVar(xcodeml);
propagatePromotion(xcodeml, (ClawTransformer) transformer);
}
use of cx2x.translator.language.common.OverPosition in project claw-compiler by C2SM-RCM.
the class ParallelizeForward method updateResultVar.
/**
* Apply promotion to the result return variable of a forward call.
*
* @param xcodeml Current XcodeML program unit.
* @throws IllegalTransformationException If XcodeML transformation cannot be
* done.
*/
private void updateResultVar(XcodeProgram xcodeml) throws IllegalTransformationException {
if (_isNestedInAssignment) {
Xnode assignment = _claw.getPragma().nextSibling();
if (assignment == null || !_fctType.hasAttribute(ClawAttr.OVER.toString())) {
return;
}
OverPosition overPos = OverPosition.fromString(_fctType.getAttribute(ClawAttr.OVER.toString()));
Xnode lhs = assignment.child(0);
// TODO handle the case when the array ref is a var directly
Xnode varInLhs = lhs.matchDescendant(Xcode.VAR);
List<ClawDimension> dimensions = TransformationHelper.findDimensions(_parentFctType);
XfunctionDefinition parentFctDef = XnodeUtil.findParentFunction(_fctCall);
XbasicType varType = (XbasicType) xcodeml.getTypeTable().get(varInLhs.getAttribute(Xattr.TYPE));
PromotionInfo promotionInfo;
if (!_promotions.containsKey(varInLhs.value())) {
// Perform the promotion on the variable
promotionInfo = TransformationHelper.promoteField(varInLhs.value(), true, true, 0, 0, parentFctDef, _parentFctType, dimensions, _claw, xcodeml, overPos);
_promotions.put(varInLhs.value(), promotionInfo);
addPromotedVar(varInLhs.value(), overPos);
} else {
promotionInfo = _promotions.get(varInLhs.value());
}
// Adapt array index to reflect the new return type
if (lhs.opcode() == Xcode.FARRAYREF) {
for (int i = 0; i < promotionInfo.diffDimension(); ++i) {
Xnode indexRange = xcodeml.createEmptyAssumedShaped();
lhs.append(indexRange, false);
}
/*} else if(lhs.opcode() == Xcode.VAR) {
// TODO avoid array var without colon notation
/* throw new IllegalTransformationException("Use the colon notation "
+ "for the return variable. This notation is not supported." +
_claw.getPragma().value()); */
} else {
throw new IllegalTransformationException("Unsupported return " + "variable for promotion.", _claw.getPragma().lineNo());
}
// If the array is a target, check if we have to promote a pointer
adaptPointer(varType, varInLhs.value(), parentFctDef, xcodeml, promotionInfo, dimensions);
}
}
Aggregations