use of claw.tatsu.xcodeml.abstraction.NestedDoStatement 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.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.
the class LoopFusion method analyze.
/**
* Loop fusion analysis: - Without collapse clause: check whether the pragma
* statement is followed by a do statement. - With collapse clause: Find the n
* do statements following the pragma.
*
* @param xcodeml The XcodeML on which the transformations are applied.
* @param translator The translator used to applied the transformations.
* @return True if a do statement is found. False otherwise.
*/
@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
Xnode outerLoop = _claw.getPragma().matchSibling(Xcode.F_DO_STATEMENT);
if (outerLoop == null) {
xcodeml.addError("Do statement missing after directive.", _claw.getPragma().lineNo());
return false;
}
_doStmt = new NestedDoStatement(outerLoop, _claw.getCollapseValue());
// With collapse clause
if (_claw.hasClause(ClawClause.COLLAPSE) && _claw.getCollapseValue() > 0 && _claw.getCollapseValue() > _doStmt.size()) {
xcodeml.addError("not enough do statements for collapse value", _claw.getPragma().lineNo());
return false;
}
return true;
}
use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.
the class LoopInterchange method analyze.
/**
* Loop fusion analysis: - Find the different do statement that will be
* reordered. - Check the validity of the new ordering option.
*
* @param xcodeml The XcodeML on which the transformations are applied.
* @param translator The translator used to applied the transformations.
* @return True if the transformation can be performed. False otherwise.
*/
@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
// Find next loop after pragma
Xnode outerDoStatement = _claw.getPragma().matchSibling(Xcode.F_DO_STATEMENT);
if (outerDoStatement == null) {
xcodeml.addError("top level loop not found", _claw.getPragma().lineNo());
return false;
}
int nestedLevel = _claw.values(ClawClause.INTERCHANGE_INDEXES) != null ? _claw.values(ClawClause.INTERCHANGE_INDEXES).size() : 2;
_doStmts = new NestedDoStatement(outerDoStatement, nestedLevel);
if (_claw.values(ClawClause.INTERCHANGE_INDEXES) != null) {
if (_claw.values(ClawClause.INTERCHANGE_INDEXES).size() != 3) {
xcodeml.addError("new-order option has not enough parameters", _claw.getPragma().lineNo());
}
List<String> inductions = _doStmts.getInductionVariables();
for (String idx : _claw.values(ClawClause.INTERCHANGE_INDEXES)) {
if (!inductions.contains(idx.toLowerCase())) {
xcodeml.addError("invalid induction variable in new-order option. " + idx, _claw.getPragma().lineNo());
return false;
}
}
} else {
if (_doStmts.size() < 2) {
xcodeml.addError("Not enough nested do statements to reorder", _claw.getPragma().lineNo());
}
}
return true;
}
use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.
the class ScaCPUvectorizeGroup method generateDoStatements.
/**
* Generate new DO statement at flagged location.
*
* @param xcodeml Current translation unit.
* @param blocks List of vectorization friendly blocks.
*/
private void generateDoStatements(Configuration cfg, XcodeProgram xcodeml, List<VectorBlock> blocks) throws IllegalTransformationException {
for (VectorBlock block : blocks) {
NestedDoStatement loops = new NestedDoStatement(_claw.getDefaultLayoutReversed(cfg), xcodeml);
if (block.isSingleStatement()) {
block.getStartStmt().insertAfter(loops.getOuterStatement());
loops.getInnerStatement().body().append(block.getStartStmt(), true);
block.getStartStmt().delete();
} else {
block.getEndStmt().insertAfter(loops.getOuterStatement());
Body.shiftIn(block.getStartStmt(), block.getEndStmt(), loops.getInnerStatement().body(), true);
}
Directive.generateLoopDirectives(xcodeml, loops.getOuterStatement(), loops.getOuterStatement(), Directive.NO_COLLAPSE);
}
}
use of claw.tatsu.xcodeml.abstraction.NestedDoStatement in project claw-compiler by C2SM-RCM.
the class ScaForward method propagatePromotion.
/**
* Propagate possible promotion in assignments statements in the parent
* subroutine of the function call.
*
* @param xcodeml Current XcodeML program unit.
* @param translator Current translator to store information between
* transformation.
*/
private void propagatePromotion(XcodeProgram xcodeml, ClawTranslator translator) throws IllegalTransformationException {
// Get all the assignment statements in the function definition
FfunctionDefinition parentFctDef = _fCall.findParentFunction();
// Retrieve information of previous forward transformation in the same fct
List<String> previouslyPromoted = Utility.convertToList(translator.hasElement(parentFctDef));
List<Xnode> assignments = parentFctDef.matchAll(Xcode.F_ASSIGN_STATEMENT);
// Find promotion info that can be used.
// TODO define how default promotion is encoded in xmod file. For the
// TODO moment using the first information found in fctType.
PromotionInfo defaultInfo = Function.readPromotionInfo(_fctType, InsertionPosition.BEFORE);
for (Xnode assignment : assignments) {
Xnode lhs = assignment.child(0);
Xnode rhs = assignment.child(1);
List<Xnode> varsInRhs = rhs.matchAll(Xcode.VAR);
for (Xnode var : varsInRhs) {
// Check if the assignment statement uses a promoted variable
if (_promotedVar.contains(var.value()) && var.matchAncestor(Xcode.FUNCTION_CALL) == null && Xnode.isOfCode(lhs, Xcode.F_ARRAY_REF)) {
Xnode varInLhs = lhs.matchDescendant(Xcode.VAR);
if (varInLhs == null) {
throw new IllegalTransformationException("Unable to propagate " + "promotion. Internal error.", _claw.getPragma().lineNo());
}
// Declare the induction variable if they are not present
for (DimensionDefinition dim : defaultInfo.getDimensions()) {
if (parentFctDef.getDeclarationTable().get(dim.getIdentifier()) == null) {
xcodeml.createIdAndDecl(dim.getIdentifier(), FortranType.INTEGER, XstorageClass.F_LOCAL, parentFctDef, DeclarationPosition.LAST);
}
}
// Generate the do statements and move the assignment statement in
NestedDoStatement doStmt = new NestedDoStatement(defaultInfo.getDimensions(), xcodeml);
assignment.insertAfter(doStmt.getOuterStatement());
doStmt.getInnerStatement().body().append(assignment);
PromotionInfo promotionInfo;
if (!previouslyPromoted.contains(varInLhs.value())) {
// Perform the promotion on the variable
promotionInfo = new PromotionInfo(varInLhs.value(), defaultInfo.getDimensions());
Field.promote(promotionInfo, parentFctDef, xcodeml);
_promotions.put(promotionInfo.getIdentifier(), promotionInfo);
} else {
promotionInfo = _promotions.get(varInLhs.value());
}
_promotedVar.add(varInLhs.value());
// Adapt the reference in the assignment statement
for (String id : _promotedVar) {
_promotions.get(id).resetFlags();
Field.adaptArrayRef(_promotions.get(id), assignment, false, xcodeml);
}
// If the array is a target, check if we have to promote a pointer
if (!previouslyPromoted.contains(varInLhs.value())) {
Field.adaptPointer(xcodeml, parentFctDef, _promotions, promotionInfo);
previouslyPromoted.add(varInLhs.value());
}
break;
/*
* if one var in the rhs of the assignment statement was promoted it's enough
* and we can switch to the next assignment statement.
*/
}
}
}
translator.storeElement(parentFctDef, previouslyPromoted);
}
Aggregations