use of claw.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class ScaCPUvectorizeGroup method flagDoStatementLocation.
/**
* Go through all assignments and flag all location where a do statement should
* be inserted after variables promotion.
*
* @param assignStatements List of assignments.
* @return Set of vector blocks as flag to do statement insertion location.
*/
private Set<VectorBlock> flagDoStatementLocation(List<AssignStatement> assignStatements) {
Set<VectorBlock> blocks = flagIfStatementWithPromotion();
/*
* Iterate a second time over assign statements to flag places where to insert
* the do statements
*/
for (AssignStatement assign : assignStatements) {
Xnode lhs = assign.getLhs();
String lhsName = assign.getLhsName();
boolean wrapInDoStatement = true;
// Check if assignment is dependant of an if statement.
if (assign.isChildOf(Xcode.F_IF_STATEMENT)) {
// Gather all potential ancestor if statements
List<Xnode> ifStatements = assign.matchAllAncestor(Xcode.F_IF_STATEMENT, Xcode.F_FUNCTION_DEFINITION);
Xnode flaggedIfStmt = null;
Set<String> assignVars = assign.getVarNames();
assignVars.retainAll(_arrayFieldsInOut);
for (Xnode ifStmt : ifStatements) {
if (Condition.dependsOn(ifStmt.matchDirectDescendant(Xcode.CONDITION), assignVars)) {
// Have to put the do statement around the if as the assignment
// is conditional as well.
flaggedIfStmt = ifStmt;
}
}
if (flaggedIfStmt != null) {
wrapInDoStatement = false;
boolean addFlaggedIf = true;
// Get rid of previously flagged location in this if body.
Iterator<VectorBlock> iter = blocks.iterator();
while (iter.hasNext()) {
Xnode crt = iter.next().getStartStmt();
if (assign.isNestedIn(crt) || flaggedIfStmt.isNestedIn(crt)) {
addFlaggedIf = false;
}
if (crt.isNestedIn(flaggedIfStmt)) {
iter.remove();
}
}
if (addFlaggedIf) {
blocks.add(new VectorBlock(flaggedIfStmt));
}
}
}
for (VectorBlock block : blocks) {
if (assign.isNestedIn(block.getStartStmt())) {
wrapInDoStatement = false;
break;
}
}
if (((Xnode.isOfCode(lhs, Xcode.F_ARRAY_REF) || Xnode.isOfCode(lhs, Xcode.VAR)) && _arrayFieldsInOut.contains(lhsName) && wrapInDoStatement) || ((Xnode.isOfCode(lhs, Xcode.VAR) || Xnode.isOfCode(lhs, Xcode.F_ARRAY_REF) && _scalarFields.contains(lhsName)) && (shouldBePromoted(assign) && wrapInDoStatement))) {
blocks.add(new VectorBlock(assign));
}
}
return blocks;
}
use of claw.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class Serialization method createBaseSerFctCall.
/**
* Create the skeletion of a function call for serialization functions.
*
* @param xcodeml Current XcodeML translation unit.
* @param callType Type of call for the
* @return Newly create functionCall node.
*/
private static FunctionCall createBaseSerFctCall(XcodeProgram xcodeml, SerializationCall callType) {
FfunctionType serType = xcodeml.createSubroutineType();
Xnode savepointArg = xcodeml.createVar(FortranType.STRUCT, SER_PPSER_SAVEPOINT, Xscope.GLOBAL);
String serFctName;
switch(callType) {
case SER_READ:
case SER_READ_PERTURB:
serFctName = SER_FS_READ_FIELD;
break;
case SER_ADD_METAINFO:
serFctName = SER_FS_ADD_SP_METAINFO;
break;
case SER_WRITE:
default:
serFctName = SER_FS_WRITE_FIELD;
}
FunctionCall serCall = xcodeml.createFctCall(serType, serFctName);
if (callType == SerializationCall.SER_WRITE) {
Xnode serializerArg = xcodeml.createVar(FortranType.STRUCT, SER_PPSER_SERIALIZER, Xscope.GLOBAL);
serCall.addArguments(serializerArg);
} else if (callType == SerializationCall.SER_READ || callType == SerializationCall.SER_READ_PERTURB) {
Xnode serializerArg = xcodeml.createVar(FortranType.STRUCT, SER_PPSER_SERIALIZER_REF, Xscope.GLOBAL);
serCall.addArguments(serializerArg);
}
serCall.addArguments(savepointArg);
return serCall;
}
use of claw.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class Serialization method createAddMetaInfoCall.
/**
* Create a fs_add_savepoint_metainfo call to the serialization library.
*
* @param xcodeml Current XcodeML translation unit.
* @param key Metadata key.
* @param value Metadata value.
* @return exprStmt node created with the specific function call inside.
*/
private static Xnode createAddMetaInfoCall(XcodeProgram xcodeml, String key, String value) {
FunctionCall serCall = createBaseSerFctCall(xcodeml, SerializationCall.SER_ADD_METAINFO);
// Create the char constant type
Xnode metadataName = xcodeml.createCharConstant(key);
serCall.addArguments(metadataName);
if (value.contains("%")) {
String[] values = value.split("%");
serCall.addArguments(xcodeml.createNode(Xcode.F_MEMBER_REF).setAttribute(Xattr.MEMBER, values[1]).append(xcodeml.createNode(Xcode.VAR_REF).append(xcodeml.createNode(Xcode.VAR).setValue(values[0]))));
} else {
serCall.addArguments(xcodeml.createNode(Xcode.VAR).setValue(value));
}
return xcodeml.createNode(Xcode.EXPR_STATEMENT).insert(serCall);
}
use of claw.tatsu.xcodeml.xnode.common.Xnode 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.tatsu.xcodeml.xnode.common.Xnode in project claw-compiler by C2SM-RCM.
the class ExpandNotation method transform.
/**
* Transform an assignment using array notation to a do statement.
*
* @param xcodeml The XcodeML on which the transformations are applied.
* @param translator The translator used to applied the transformations.
* @param other Only for dependent transformation. The other transformation
* part of the transformation.
* @throws Exception If the transformation cannot be applied.
*/
@Override
public void transform(XcodeProgram xcodeml, Translator translator, Transformation other) throws Exception {
final ClawTranslator ct = (ClawTranslator) translator;
final Configuration cfg = ct.cfg();
// 1. Find the function/module declaration TODO handle module/program ?
FfunctionDefinition fctDef = _clawStart.getPragma().findParentFunction();
Xnode from = _clawStart.getPragma();
Xnode to = _clawEnd != null ? _clawEnd.getPragma() : null;
List<String> readArrays = XnodeUtil.getReadArraysInRegion(from, to);
List<String> writtenArrays = XnodeUtil.getWrittenArraysInRegion(from, to);
Set<String> presents = new HashSet<>(readArrays);
presents.addAll(writtenArrays);
Xblock doStmtsBlock = null;
Xblock dataRegionBlock = null;
if (xcodeml.context().isTarget(Target.GPU)) {
Xblock crtBlock;
for (int i = 0; i < _groupedAssignStmts.size(); ++i) {
crtBlock = generateDoStmtNotation(xcodeml, ct, fctDef, _groupIterationRanges.get(i), _groupedAssignStmts.get(i), from);
if (doStmtsBlock == null) {
doStmtsBlock = new Xblock(crtBlock.getStart());
} else {
doStmtsBlock.setEnd(crtBlock.getEnd());
}
}
if (doStmtsBlock == null) {
throw new IllegalTransformationException("Problem occurred during expand transformation", _clawStart.getPragma().lineNo());
}
Xblock parallelRegionBlock;
Xblock updateRegionBlock = null;
if (_clawStart.hasClause(ClawClause.PARALLEL)) {
List<String> privates = Collections.emptyList();
String clauses = _clawStart.hasClause(ClawClause.ACC) ? _clawStart.value(ClawClause.ACC) : "";
parallelRegionBlock = Directive.generateParallelLoopClause(xcodeml, privates, doStmtsBlock.getStart(), doStmtsBlock.getEnd(), clauses, _groupedAssignStmts.size());
if (_clawStart.hasClause(ClawClause.UPDATE) && cfg.getBooleanParameter(Configuration.SCA_FORWARD_UPDATE_ENABLED)) {
updateRegionBlock = generateUpdateClause(cfg, xcodeml, parallelRegionBlock, readArrays, writtenArrays);
}
if (updateRegionBlock == null) {
updateRegionBlock = parallelRegionBlock;
}
List<String> presentLst = new ArrayList<>(presents);
dataRegionBlock = Directive.generateDataRegionClause(xcodeml, presentLst, Collections.emptyList(), updateRegionBlock);
}
} else {
doStmtsBlock = new Xblock(_clawStart.getPragma());
if (_clawEnd != null) {
doStmtsBlock.setEnd(_clawEnd.getPragma());
} else {
doStmtsBlock.setEnd(_clawStart.getPragma().nextSibling());
}
}
if (_clawStart.hasClause(ClawClause.SAVEPOINT) && cfg.getBooleanParameter(Configuration.SCA_SERIALIZATION_ENABLED)) {
if (dataRegionBlock == null) {
dataRegionBlock = doStmtsBlock;
}
generateSavepoint(cfg, xcodeml, dataRegionBlock, readArrays, writtenArrays);
}
removePragma();
transformed();
}
Aggregations