use of cx2x.translator.language.common.ClawMappingVar 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 transformer The transformer 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, Transformer transformer, Transformation transformation) throws Exception {
/*
* DUPLICATE THE FUNCTION
*/
// Duplicate function definition
XfunctionDefinition clonedFctDef = _fctDefToExtract.cloneNode();
String newFctTypeHash = xcodeml.getTypeTable().generateFctTypeHash();
String newFctName = clonedFctDef.getName().value() + ClawConstant.EXTRACTION_SUFFIX + transformer.getNextTransformationCounter();
clonedFctDef.getName().setValue(newFctName);
clonedFctDef.getName().setAttribute(Xattr.TYPE, newFctTypeHash);
// Update the symbol table in the fct definition
Xid fctId = clonedFctDef.getSymbolTable().get(_fctDefToExtract.getName().value());
fctId.setType(newFctTypeHash);
fctId.setName(newFctName);
// Get the fctType in typeTable
XfunctionType fctType = (XfunctionType) xcodeml.getTypeTable().get(_fctDefToExtract.getName().getAttribute(Xattr.TYPE));
XfunctionType 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().value());
// 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);
if (XmOption.isDebugOutput()) {
System.out.println("loop-extract transformation: " + _claw.getPragma().value());
System.out.println(" created subroutine: " + clonedFctDef.getName().value());
}
/*
* REMOVE BODY FROM THE LOOP AND DELETE THE LOOP
*/
// 1. append body into fct body after loop
XnodeUtil.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);
if (XmOption.isDebugOutput()) {
System.out.println(" call wrapped with loop: " + _fctCall.matchDirectDescendant(Xcode.NAME).value() + " --> " + clonedFctDef.getName().value());
}
// Change called fct name
_fctCall.matchDirectDescendant(Xcode.NAME).setValue(newFctName);
_fctCall.matchDirectDescendant(Xcode.NAME).setAttribute(Xattr.TYPE, newFctTypeHash);
// Adapt function call parameters and function declaration
XdeclTable fctDeclarations = clonedFctDef.getDeclarationTable();
XsymbolTable fctSymbols = clonedFctDef.getSymbolTable();
Utility.debug(" Start to apply mapping: " + _claw.getMappings().size());
for (ClawMapping mapping : _claw.getMappings()) {
Utility.debug("Apply mapping (" + mapping.getMappedDimensions() + ") ");
for (ClawMappingVar var : mapping.getMappedVariables()) {
Utility.debug(" Var: " + var);
Xnode argument = XnodeUtil.findArg(var.getArgMapping(), _fctCall);
if (argument == null) {
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.opcode() == Xcode.VAR) {
XbasicType type = (XbasicType) xcodeml.getTypeTable().get(argument.getAttribute(Xattr.TYPE));
// 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 = new Xnode(Xcode.FARRAYREF, xcodeml);
newArg.setAttribute(Xattr.TYPE, type.getRef());
Xnode varRef = new Xnode(Xcode.VARREF, xcodeml);
varRef.setAttribute(Xattr.TYPE, argument.getAttribute(Xattr.TYPE));
varRef.append(argument, true);
newArg.append(varRef, false);
// create arrayIndex
for (ClawMappingVar mappingVar : mapping.getMappingVariables()) {
Xnode arrayIndex = new Xnode(Xcode.ARRAYINDEX, xcodeml);
// Find the mapping var in the local table (fct scope)
Xdecl mappingVarDecl = _fctDef.getDeclarationTable().get(mappingVar.getArgMapping());
// Add to arrayIndex
Xnode newMappingVar = new Xnode(Xcode.VAR, xcodeml);
newMappingVar.setAttribute(Xattr.SCLASS, Xscope.LOCAL.toString());
newMappingVar.setAttribute(Xattr.TYPE, mappingVarDecl.matchSeq(Xcode.NAME).getAttribute(Xattr.TYPE));
newMappingVar.setValue(mappingVarDecl.matchSeq(Xcode.NAME).value());
arrayIndex.append(newMappingVar, false);
newArg.append(arrayIndex, false);
}
argument.insertAfter(newArg);
argument.delete();
}
// Case 2: ArrayRef (n arrayIndex) --> ArrayRef (n+m arrayIndex)
/*else if(argument.opcode() == Xcode.FARRAYREF) {
// TODO
}*/
// Change variable declaration in extracted fct
Xdecl varDecl = fctDeclarations.get(var.getFctMapping());
Xid id = fctSymbols.get(var.getFctMapping());
XbasicType varDeclType = (XbasicType) xcodeml.getTypeTable().get(varDecl.matchSeq(Xcode.NAME).getAttribute(Xattr.TYPE));
// Case 1: variable is demoted to scalar then take the ref type
if (varDeclType.getDimensions() == mapping.getMappedDimensions()) {
Xnode tempName = new Xnode(Xcode.NAME, xcodeml);
tempName.setValue(var.getFctMapping());
tempName.setAttribute(Xattr.TYPE, varDeclType.getRef());
Xdecl newVarDecl = new Xdecl(new Xnode(Xcode.VARDECL, xcodeml).element());
newVarDecl.append(tempName, false);
fctDeclarations.replace(newVarDecl, var.getFctMapping());
id.setType(varDeclType.getRef());
}
/* else {
// Case 2: variable is not totally demoted then create new type
// TODO
}*/
}
// Loop mapped variables
}
// Loop over mapping clauses
// Adapt array reference in function body
List<Xnode> arrayReferences = clonedFctDef.body().matchAll(Xcode.FARRAYREF);
for (Xnode ref : arrayReferences) {
if (!(ref.matchSeq(Xcode.VARREF).child(0).opcode() == Xcode.VAR)) {
continue;
}
String mappedVar = ref.matchSeq(Xcode.VARREF, 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.opcode() == Xcode.ARRAYINDEX) {
List<Xnode> children = e.children();
if (children.size() > 0 && children.get(0).opcode() == 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.VARREF, Xcode.VAR).cloneNode());
ref.delete();
}
}
}
// Generate accelerator pragmas if needed
AcceleratorHelper.generateAdditionalDirectives(_claw, xcodeml, extractedLoop, extractedLoop);
// TODO must be triggered by a clause
//AcceleratorHelper.generateRoutineDirectives(_claw, xcodeml, clonedFctDef);
// Add any additional transformation defined in the directive clauses
TransformationHelper.generateAdditionalTransformation(_claw, xcodeml, transformer, extractedLoop);
_claw.getPragma().delete();
this.transformed();
}
Aggregations