use of claw.shenron.transformation.Transformation in project claw-compiler by C2SM-RCM.
the class ExpandNotation method analyze.
@Override
public boolean analyze(XcodeProgram xcodeml, Translator translator) {
if (_clawEnd != null) {
// Block transformation
// TODO Analyse dependency between assignments. cf array9 example.
// Find assignments with vector notation
List<Xnode> foundAssignments = XnodeUtil.getArrayAssignInBlock(_clawStart.getPragma(), _clawEnd.getPragma());
if (foundAssignments.isEmpty()) {
xcodeml.addError("No vector notation assignments found in the expand block.", _clawStart.getPragma().lineNo());
return false;
}
/*
* Using a structure of list of list of assignments to group together the expand
* notation that share an identical iteration range.
*/
// 1st group always exists
_groupedAssignStmts.add(new ArrayList<>());
int crtGroup = 0;
Xnode refArrayRef = foundAssignments.get(0).matchSeq(Xcode.F_ARRAY_REF);
List<Xnode> refRanges = XnodeUtil.getIdxRangesFromArrayRef(refArrayRef);
// First vector notation is automatically in the 1st group as 1st element
_groupedAssignStmts.get(crtGroup).add(foundAssignments.get(0));
_groupIterationRanges.add(refRanges);
for (int i = 1; i < foundAssignments.size(); ++i) {
Xnode arrayRef = foundAssignments.get(i).matchSeq(Xcode.F_ARRAY_REF);
List<Xnode> ranges = XnodeUtil.getIdxRangesFromArrayRef(arrayRef);
// ranges are not identical so
if (!Range.compare(refRanges, ranges)) {
refRanges = ranges;
++crtGroup;
_groupedAssignStmts.add(new ArrayList<>());
_groupIterationRanges.add(refRanges);
}
_groupedAssignStmts.get(crtGroup).add(foundAssignments.get(i));
}
return true;
} else {
// single transformation
// pragma must be followed by an assign statement
Xnode stmt = _clawStart.getPragma().matchSibling(Xcode.F_ASSIGN_STATEMENT);
if (stmt == null) {
xcodeml.addError("Directive not followed by an assign statement", _clawStart.getPragma().lineNo());
return false;
}
// Check if we are dealing with an vector notation
if (!Xnode.isOfCode(stmt.child(0), Xcode.F_ARRAY_REF)) {
xcodeml.addError("Assign statement is not an array notation", _clawStart.getPragma().lineNo());
return false;
}
List<Xnode> ranges = stmt.firstChild().children().stream().filter(x -> x.is(Xcode.INDEX_RANGE)).collect(Collectors.toList());
if (ranges.isEmpty()) {
xcodeml.addError("Assign statement is not an array notation", _clawStart.getPragma().lineNo());
return false;
}
_groupedAssignStmts.add(Collections.singletonList(stmt));
_groupIterationRanges.add(ranges);
return true;
}
}
use of claw.shenron.transformation.Transformation in project claw-compiler by C2SM-RCM.
the class ExpandNotation method generateDoStmtNotation.
/**
* Generate the corresponding do statements for the array notations. A do
* statement is generated per dimension of the arrays. Iteration index range are
* computed with array dimensions.
*
* @param xcodeml The XcodeML on which the transformations are applied.
* @param translator The translator used to applied the transformations.
* @param fctDef The function definition in which the array notation is
* nested.
* @param ranges The list of iteration ranges to be applied to the created
* do statements.
* @param statements The list of assign statements (array notation) that will be
* included in the nested do statements.
* @param doStmtGrip Grip for the code insertion. Do statements will be inserted
* after the grip element.
* @return Block surrounding the do statements generated.
*/
private Xblock generateDoStmtNotation(XcodeProgram xcodeml, ClawTranslator translator, FfunctionDefinition fctDef, List<Xnode> ranges, List<Xnode> statements, Xnode doStmtGrip) throws IllegalTransformationException {
String[] inductionVars = new String[ranges.size()];
Xnode[] doStmts = new Xnode[ranges.size()];
Xnode var = statements.get(0).matchSeq(Xcode.F_ARRAY_REF, Xcode.VAR_REF, Xcode.VAR);
if (var == null) {
var = statements.get(0).matchSeq(Xcode.F_ARRAY_REF, Xcode.VAR_REF, Xcode.F_MEMBER_REF);
}
// 1. Create do statements with induction variables
for (int i = 0; i < ranges.size(); ++i) {
// 1.1 Create induction variables
if (_clawStart.hasClause(ClawClause.INDUCTION)) {
// Use user names
inductionVars[i] = _clawStart.values(ClawClause.INDUCTION).get(i);
} else {
// generate new names
inductionVars[i] = "claw_induction_" + translator.getNextTransformationCounter();
}
// 2.2 inject a new entry in the symbol table
if (!fctDef.getSymbolTable().contains(inductionVars[i])) {
Xid inductionVarId = xcodeml.createId(FortranType.INTEGER, XstorageClass.F_LOCAL, inductionVars[i]);
fctDef.getSymbolTable().add(inductionVarId, false);
}
// 2.3 inject a new entry in the declaration table
if (!fctDef.getDeclarationTable().contains(inductionVars[i])) {
Xnode inductionVarDecl = xcodeml.createVarDecl(FortranType.INTEGER, inductionVars[i]);
fctDef.getDeclarationTable().add(inductionVarDecl);
}
// 2.4 create do statements
Xnode inductionVar = xcodeml.createVar(FortranType.INTEGER, inductionVars[i], Xscope.LOCAL);
Xnode range;
if (ranges.get(i).getBooleanAttribute(Xattr.IS_ASSUMED_SHAPE)) {
// Allocatable array
// dimension argument of size starts at one
range = xcodeml.createRangeForAssumedShapeArray(var, 1, i + 1);
} else {
range = ranges.get(i).cloneNode();
}
doStmts[i] = xcodeml.createDoStmt(inductionVar, range);
statements.get(0).copyEnhancedInfo(doStmts[i]);
if (i == 0) {
// most outer loop goes after the pragma
doStmtGrip.insertAfter(doStmts[i]);
} else {
// others loop go in the previous one
doStmts[i - 1].body().append(doStmts[i]);
}
}
for (Xnode stmt : statements) {
// 3. Adapt array reference with induction variables
List<Xnode> allArrayRef = stmt.matchAll(Xcode.F_ARRAY_REF);
for (Xnode arrayRef : allArrayRef) {
for (int i = 0; i < arrayRef.children().size() - 1; ++i) {
Xnode el = arrayRef.child(i + 1);
if (Xnode.isOfCode(el, Xcode.INDEX_RANGE) && i < doStmts.length) {
String induction = doStmts[i].matchSeq(Xcode.VAR).value();
Xnode inductionVar = xcodeml.createVar(FortranType.INTEGER, induction, Xscope.LOCAL);
Xnode arrayIdx = xcodeml.createNode(Xcode.ARRAY_INDEX);
arrayIdx.append(inductionVar);
el.insertAfter(arrayIdx);
el.delete();
}
}
}
stmt.matchAll(Xcode.FUNCTION_CALL).stream().map(FunctionCall::new).filter(x -> x.isIntrinsicCall(Xintrinsic.SUM)).forEach(FunctionCall::adaptIntrinsicSumCall);
stmt.matchAll(Xcode.FUNCTION_CALL).stream().map(FunctionCall::new).filter(x -> x.isIntrinsicCall(Xintrinsic.SPREAD)).forEach(FunctionCall::adaptIntrinsicSpreadCall);
// 4. Move assignment statement inside the most inner loop
doStmts[ranges.size() - 1].body().append(stmt, true);
stmt.delete();
}
// Add any additional transformation defined in the directive clauses
translator.generateAdditionalTransformation(_clawStart, xcodeml, doStmts[0]);
return new Xblock(doStmts[0]);
}
use of claw.shenron.transformation.Transformation in project claw-compiler by C2SM-RCM.
the class ClawTranslator method reorderTransformations.
/**
*/
private void reorderTransformations() {
if (getGroups().containsKey(ScaForward.class)) {
TransformationGroup tg = getGroups().get(ScaForward.class);
if (tg.count() <= 1) {
return;
}
DirectedGraph<Transformation> dg = new DirectedGraph<>();
Map<String, List<Transformation>> fctMap = new HashMap<>();
for (Transformation t : tg.getTransformations()) {
ScaForward p = (ScaForward) t;
dg.addNode(p);
if (fctMap.containsKey(p.getCallingFctName())) {
List<Transformation> tList = fctMap.get(p.getCallingFctName());
tList.add(p);
} else {
List<Transformation> tList = new ArrayList<>();
tList.add(p);
fctMap.put(p.getCallingFctName(), tList);
}
}
for (Transformation t : tg.getTransformations()) {
ScaForward p = (ScaForward) t;
if (p.getCalledFctName() != null && fctMap.containsKey(p.getCalledFctName())) {
List<Transformation> tList = fctMap.get(p.getCalledFctName());
for (Transformation end : tList) {
dg.addEdge(p, end);
}
}
}
List<Transformation> ordered = TopologicalSort.sort(TopologicalSort.reverseGraph(dg));
tg.setTransformations(ordered);
}
}
Aggregations