use of claw.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class ScaGPU method applySpecificTransformation.
/**
* Apply specific transformation steps for GPU target.
*
* @param xcodeml Current translation unit.
* @throws IllegalTransformationException If any transformation fails.
*/
private void applySpecificTransformation(Configuration cfg, XcodeProgram xcodeml) throws IllegalTransformationException {
final Context context = xcodeml.context();
AcceleratorConfiguration config = cfg.accelerator();
if (_fctDef.hasEmptyBody()) {
// Nothing to do in this function
return;
}
/*
* Create a nested loop with the new defined dimensions and wrap it around the
* whole subroutine's body. This is for the moment a really naive transformation
* idea but it is our start point. Use the first over clause to create it.
*/
NestedDoStatement loops;
if (forceAssumedShapedArrayPromotion) {
if (_promotions.isEmpty()) {
throw new IllegalTransformationException("Cannot assume shape of " + "array in elemental function/subroutine.", _claw.getPragma().lineNo());
}
PromotionInfo pi = _promotions.entrySet().iterator().next().getValue();
loops = new NestedDoStatement(_claw.getDefaultLayoutReversed(cfg), pi, xcodeml);
} else {
loops = new NestedDoStatement(_claw.getDefaultLayoutReversed(cfg), xcodeml);
}
/*
* Subroutine/function can have a contains section with inner subroutines or
* functions. The newly created (nested) do statements should stop before this
* contains section if it exists.
*/
Xnode contains = _fctDef.body().matchSeq(Xcode.F_CONTAINS_STATEMENT);
if (contains != null) {
Xnode parallelRegionStart;
if (_specialParallelRegionStart == null) {
parallelRegionStart = Directive.findParallelRegionStart(context, _fctDef, null);
} else {
parallelRegionStart = _specialParallelRegionStart;
}
Xnode parallelRegionEnd = Directive.findParallelRegionEnd(context, _fctDef, contains);
Body.shiftIn(parallelRegionStart, parallelRegionEnd, loops.getInnerStatement().body(), true);
contains.insertBefore(loops.getOuterStatement());
} else {
// No contains section, all the body is copied to the do statements.
Xnode parallelRegionStart;
if (_specialParallelRegionStart == null) {
parallelRegionStart = Directive.findParallelRegionStart(context, _fctDef, null);
} else {
parallelRegionStart = _specialParallelRegionStart;
}
Xnode parallelRegionEnd = Directive.findParallelRegionEnd(context, _fctDef, null);
// Define a hook from where we can insert the new do statement
Xnode hook = parallelRegionEnd != null ? parallelRegionEnd.nextSibling() : null;
Body.shiftIn(parallelRegionStart, parallelRegionEnd, loops.getInnerStatement().body(), true);
// Hook is null then we append the do statement to the current fct body
if (hook == null) {
_fctDef.body().append(loops.getOuterStatement());
} else {
// Insert new do statement before the hook element
hook.insertBefore(loops.getOuterStatement());
}
}
// TODO nodep passing!
int collapse = Directive.generateLoopSeq(xcodeml, loops.getInnerStatement().body(), CompilerDirective.CLAW.getPrefix() + " nodep");
// Prepare variables list for present/pcreate clauses and handle
// promotion/privatize local strategy
List<String> presentList = _fctDef.getPresentVariables(xcodeml);
List<String> privateList = Collections.emptyList();
List<String> createList = Collections.emptyList();
if (config.getLocalStrategy() == AcceleratorLocalStrategy.PRIVATE) {
privateList = applyPrivateStrategy(xcodeml);
} else if (config.getLocalStrategy() == AcceleratorLocalStrategy.PROMOTE) {
createList = applyPromoteStrategy(cfg, xcodeml);
}
// Generate the data region
Xblock doStmtBlock = new Xblock(loops.getOuterStatement());
Directive.generateDataRegionClause(xcodeml, presentList, createList, doStmtBlock);
// Generate the parallel region
Directive.generateParallelLoopClause(xcodeml, privateList, loops.getOuterStatement(), loops.getOuterStatement(), null, loops.size() + collapse);
Directive.generateRoutineDirectives(xcodeml, _fctDef);
}
use of claw.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class VectorBlock method fillUpWrittenVariables.
private void fillUpWrittenVariables(Xnode root) {
List<Xnode> assignStatements = root.matchAll(Xcode.F_ASSIGN_STATEMENT);
for (Xnode assign : assignStatements) {
AssignStatement as = new AssignStatement(assign.element());
_writtenVariables.add(as.getLhsName());
}
}
use of claw.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class VectorBlock method gatherWrittenVariables.
/**
* Collect all variables written within the block.
*/
private void gatherWrittenVariables() {
if (_writtenVariables == null) {
_writtenVariables = new HashSet<>();
}
if (isSingleStatement()) {
fillUpWrittenVariables(_startStmt);
} else {
Xnode crt = getStartStmt();
while (!crt.equals(getEndStmt())) {
fillUpWrittenVariables(crt);
crt = crt.nextSibling();
}
if (crt.equals(getEndStmt())) {
fillUpWrittenVariables(crt);
}
}
}
use of claw.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class IfExtract method transform.
@Override
public void transform(XcodeProgram xcodeml, Translator translator, Transformation other) throws Exception {
// Copy the body of the if statement inside the body of the do statement
Xnode thenBlock = _ifStmt.matchDirectDescendant(Xcode.THEN);
Xnode thenDoStmt = _doStmt.cloneNode();
Body.append(thenDoStmt.body(), thenBlock.body());
// Copy the if statement and clean its body
Xnode newIfStmt = _ifStmt.cloneNode();
Xnode newThen = newIfStmt.matchDirectDescendant(Xcode.THEN);
for (Xnode n : newThen.body().children()) {
n.delete();
}
// Add the new if statement after the do statement
_doStmt.insertAfter(newIfStmt);
// Insert the do statement in the new if-then statement
newThen.body().insert(thenDoStmt, false);
Xnode elseBlock = _ifStmt.matchDirectDescendant(Xcode.ELSE);
if (elseBlock != null) {
Xnode elseDoStmt = _doStmt.cloneNode();
Body.append(elseDoStmt.body(), elseBlock.body());
Xnode newElse = newIfStmt.matchDirectDescendant(Xcode.ELSE);
for (Xnode n : newElse.body().children()) {
n.delete();
}
newElse.body().insert(elseDoStmt, false);
Xnode duplicateIf = elseDoStmt.body().matchDirectDescendant(Xcode.F_IF_STATEMENT);
XnodeUtil.safeDelete(duplicateIf);
}
// Delete the old statements and pragma
Xnode duplicateIf = thenDoStmt.body().matchDirectDescendant(Xcode.F_IF_STATEMENT);
duplicateIf.delete();
XnodeUtil.safeDelete(_ifStmt);
XnodeUtil.safeDelete(_doStmt);
removePragma();
}
use of claw.tatsu.xcodeml.xnode.common.Xnode 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 translator The translator 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, Translator translator, Transformation transformation) throws Exception {
ClawTranslator ct = (ClawTranslator) translator;
final Context context = ct.context();
/*
* DUPLICATE THE FUNCTION
*/
// Duplicate function definition
FfunctionDefinition clonedFctDef = _fctDefToExtract.cloneNode();
String newFctTypeHash = xcodeml.getTypeTable().generateHash(FortranType.FUNCTION);
String newFctName = clonedFctDef.getName() + ClawConstant.EXTRACTION_SUFFIX + translator.getNextTransformationCounter();
clonedFctDef.name().setValue(newFctName);
clonedFctDef.name().setType(newFctTypeHash);
// Update the symbol table in the fct definition
Xid fctId = clonedFctDef.getSymbolTable().get(_fctDefToExtract.getName());
fctId.setType(newFctTypeHash);
fctId.setName(newFctName);
// Get the fctType in typeTable
FfunctionType fctType = xcodeml.getTypeTable().getFunctionType(_fctDefToExtract);
FfunctionType 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());
// 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);
Message.debug(context, "loop-extract transformation: " + _claw.getPragma().value());
Message.debug(context, " created subroutine: " + clonedFctDef.getName());
/*
* REMOVE BODY FROM THE LOOP AND DELETE THE LOOP
*/
// 1. append body into fct body after loop
Loop.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);
Message.debug(context, " call wrapped with loop: " + _fctCall.matchDirectDescendant(Xcode.NAME).value() + " --> " + clonedFctDef.getName());
// Change called fct name
_fctCall.matchDirectDescendant(Xcode.NAME).setValue(newFctName);
_fctCall.matchDirectDescendant(Xcode.NAME).setType(newFctTypeHash);
// Adapt function call parameters and function declaration
XdeclTable fctDeclarations = clonedFctDef.getDeclarationTable();
XsymbolTable fctSymbols = clonedFctDef.getSymbolTable();
Message.debug(context, " Start to apply mapping: " + _claw.getMappings().size());
for (ClawMapping mapping : _claw.getMappings()) {
Message.debug(context, "Apply mapping (" + mapping.getMappedDimensions() + ") ");
for (ClawMappingVar var : mapping.getMappedVariables()) {
Message.debug(context, " Var: " + var);
Optional<Xnode> argument = _fctCall.findArg(var.getArgMapping());
if (!argument.isPresent()) {
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.get().is(Xcode.VAR)) {
FbasicType type = xcodeml.getTypeTable().getBasicType(argument.get());
// 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 = xcodeml.createNode(Xcode.F_ARRAY_REF);
newArg.setType(type.getRef());
Xnode varRef = xcodeml.createNode(Xcode.VAR_REF);
varRef.setType(argument.get().getType());
varRef.append(argument.get(), true);
newArg.append(varRef);
// create arrayIndex
for (ClawMappingVar mappingVar : mapping.getMappingVariables()) {
Xnode arrayIndex = xcodeml.createNode(Xcode.ARRAY_INDEX);
// Find the mapping var in the local table (fct scope)
Xnode mappingVarDecl = _fctDef.getDeclarationTable().get(mappingVar.getArgMapping());
// Add to arrayIndex
Xnode newMappingVar = xcodeml.createVar(mappingVarDecl.getType(), mappingVarDecl.matchSeq(Xcode.NAME).value(), Xscope.LOCAL);
arrayIndex.append(newMappingVar);
newArg.append(arrayIndex);
}
argument.get().insertAfter(newArg);
argument.get().delete();
}
// Case 2: ArrayRef (n arrayIndex) --> ArrayRef (n+m arrayIndex)
// Change variable declaration in extracted fct
Xnode varDecl = fctDeclarations.get(var.getFctMapping());
Xid id = fctSymbols.get(var.getFctMapping());
FbasicType varDeclType = xcodeml.getTypeTable().getBasicType(varDecl);
// Case 1: variable is demoted to scalar then take the ref type
if (varDeclType.getDimensions() == mapping.getMappedDimensions()) {
Xnode newVarDecl = xcodeml.createNode(Xcode.VAR_DECL);
newVarDecl.append(xcodeml.createName(var.getFctMapping(), varDeclType.getRef()));
fctDeclarations.replace(newVarDecl, var.getFctMapping());
id.setType(varDeclType.getRef());
}
}
// Loop mapped variables
}
// Loop over mapping clauses
// Adapt array reference in function body
List<Xnode> arrayReferences = clonedFctDef.body().matchAll(Xcode.F_ARRAY_REF);
for (Xnode ref : arrayReferences) {
if (!Xnode.isOfCode(ref.matchSeq(Xcode.VAR_REF).child(0), Xcode.VAR)) {
continue;
}
String mappedVar = ref.matchSeq(Xcode.VAR_REF, 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.is(Xcode.ARRAY_INDEX)) {
List<Xnode> children = e.children();
if (!children.isEmpty() && Xnode.isOfCode(children.get(0), 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.VAR_REF, Xcode.VAR).cloneNode());
ref.delete();
}
}
}
// Generate directive pragmas if needed
Xnode grip = null;
if (_claw.hasClause(ClawClause.ACC)) {
/*
* TODO see TODO in ExpandNotation OpenACC and OpenMP loop construct are pretty
* different ... have to look how to do that properly. See issue #22
*/
grip = Directive.generateAcceleratorClause(xcodeml, extractedLoop, _claw.value(ClawClause.ACC));
}
if (_claw.hasClause(ClawClause.PARALLEL)) {
Directive.generateParallelRegion(xcodeml, (grip == null) ? extractedLoop : grip, extractedLoop);
}
// TODO must be triggered by a clause
// Directive.generateRoutineDirectives(_claw, xcodeml, clonedFctDef);
// Add any additional transformation defined in the directive clauses
ct.generateAdditionalTransformation(_claw, xcodeml, extractedLoop);
removePragma();
transformed();
}
Aggregations