/* Assuming * #pragma target device (mpi:master) begin * stmt-list here // it may contain variable declarations * #pragma target device (mpi:master) end * * * Essentially wrap the code block in side if (rank ==0) { } * To ensure the correctness, all variable declarations will be moved right in front of the if () stmt * If a variable declaration has assignment initializer, the initializer will be split out and put into the if-stmt's true body * */ void MPI_Code_Generator::transMPIDeviceMaster (SgOmpTargetStatement * t_stmt) { // Sanity check ROSE_ASSERT (t_stmt != NULL); SgStatement* body_stmt = t_stmt->get_body(); SgBasicBlock * body_block = isSgBasicBlock (body_stmt); SgScopeStatement* scope = t_stmt->get_scope(); ROSE_ASSERT (scope != NULL); // normalization should happen before this point to ensure BB for body statements ROSE_ASSERT (body_block!= NULL); ROSE_ASSERT (isMPIMasterBegin (t_stmt)); //insert a if (rank) .. after the end pragma SgIfStmt * ifstmt = buildIfStmt (buildEqualityOp(buildVarRefExp("_xomp_rank", scope), buildIntVal(0)), buildBasicBlock(), NULL); insertStatementAfter (t_stmt, ifstmt); SgBasicBlock * bb = isSgBasicBlock(ifstmt->get_true_body()); SgStatement* next_stmt = (body_block->get_statements())[0]; // normalize all declarations while ( next_stmt != NULL) { // save current stmt before getting next one SgStatement* cur_stmt = next_stmt; next_stmt = getNextStatement (next_stmt); //ROSE_ASSERT (next_stmt != NULL); if (SgVariableDeclaration* decl = isSgVariableDeclaration (cur_stmt)) splitVariableDeclaration (decl); } //reset from the beginning next_stmt = (body_block->get_statements())[0]; while ( next_stmt != NULL) { // save current stmt before getting next one SgStatement* cur_stmt = next_stmt; next_stmt = getNextStatement (next_stmt); //ROSE_ASSERT (next_stmt != NULL); if (!isSgVariableDeclaration(cur_stmt)) { // now remove the current stmt removeStatement (cur_stmt, false); appendStatement(cur_stmt, bb); } else // for variable declarations, prepend them to be before t_stmt { removeStatement (cur_stmt, false); insertStatementBefore(t_stmt, cur_stmt, false); } } // remove the pragma stmt after the translation removeStatement (t_stmt); }
bool TransformFunction(SgFunctionDeclaration *funcDecl, SgBasicBlock *funcBody, SgBasicBlock *scanScope, int *loopCount, int *segmentCount) { /* Wherever TransformFunction is called recursively below, the return */ /* value should most likely be propagated to the local simpleWork var */ bool simpleWork = true ; /* entire block only contains sequential work */ SgStatement *segBegin = NULL ; SgStatement *stmt ; Rose_STL_Container<SgNode*> blockStmts = NodeQuery::querySubTree(scanScope, V_SgStatement, AstQueryNamespace::ChildrenOnly) ; for (Rose_STL_Container<SgNode*>::iterator s_itr = blockStmts.begin(); s_itr != blockStmts.end(); ++s_itr) { stmt = isSgStatement(*s_itr) ; ROSE_ASSERT(stmt); // printf("%s\n", stmt->sage_class_name()) ; /* assume no work in variable declarations -- for now */ if (isSgDeclarationStatement(stmt)) continue ; if (isSgForStatement(stmt)) /* could be embedded inside a statement */ { SgForStatement *forStatement = isSgForStatement(stmt) ; SgBasicBlock *loopBody = SageInterface::ensureBasicBlockAsBodyOfFor(forStatement) ; ROSE_ASSERT(loopBody) ; if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } CreateLoopProbe(funcDecl, funcBody, stmt, loopCount) ; simpleWork = false ; TransformFunction(funcDecl, funcBody, loopBody, loopCount, segmentCount) ; } else if (isSgWhileStmt(stmt)) /* could be embedded inside a statement */ { /* At minimum, identifiers in code should be specialized for while */ SgWhileStmt *whileStatement = isSgWhileStmt(stmt) ; SgBasicBlock *loopBody = SageInterface::ensureBasicBlockAsBodyOfWhile(whileStatement) ; ROSE_ASSERT(loopBody) ; if (instrumentWhile) { if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } CreateLoopProbe(funcDecl, funcBody, stmt, loopCount) ; simpleWork = false ; } TransformFunction(funcDecl, funcBody, loopBody, loopCount, segmentCount) ; } else if (isSgDoWhileStmt(stmt)) /* could be embedded inside a statement */ { /* At minimum, identifiers in code should be specialized for while */ SgDoWhileStmt *doWhileStatement = isSgDoWhileStmt(stmt) ; SgBasicBlock *loopBody = SageInterface::ensureBasicBlockAsBodyOfDoWhile(doWhileStatement) ; ROSE_ASSERT(loopBody) ; if (instrumentDoWhile) { if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } CreateLoopProbe(funcDecl, funcBody, stmt, loopCount) ; simpleWork = false ; } TransformFunction(funcDecl, funcBody, loopBody, loopCount, segmentCount) ; } else if (isSgReturnStmt(stmt)) /* could be embedded inside a statement */ { /* Note -- we should probably put the return statement in block scope */ /* before adding the extra code */ /* We do not currently count iterations for loops that are aborted */ int level = LoopDepth(funcBody, stmt) ; if ((segBegin != NULL) && !simpleWork) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } if (level != 0) { HandleItem(funcBody, stmt, "ET_PopLoopSeqIds", buildIntVal(level), true) ; } } else if (isSgGotoStatement(stmt)) /* could be embedded inside a stmt */ { /* ASSUMPTION: We will always be jumping out of loops, not into them */ /* Note -- we should probably put the goto statement in block scope */ /* before adding the extra code */ /* We do not currently count iterations for loops that are aborted */ int gotoLevel = LoopDepth(funcBody, stmt) ; int labelLevel = LoopDepth(funcBody, isSgGotoStatement(stmt)->get_label()) ; int levelDiff = gotoLevel - labelLevel ; if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; simpleWork = false ; segBegin = NULL ; } if (levelDiff > 0) { HandleItem(funcBody, stmt, "ET_PopLoopSeqIds", buildIntVal(levelDiff), true) ; } else if (levelDiff < 0) { printf("goto jump into a loop context unexpected. Terminating.\n") ; exit(-1) ; } } else if (isSgLabelStatement(stmt) || isSgBreakStmt(stmt) || isSgContinueStmt(stmt)) /* could be embedded inside a stmt */ { /* we are currently not making an iteration adjustment for */ /* break or continue statements. See comments below */ if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; simpleWork = false ; segBegin = NULL ; } } /* // These two clauses can be used to count iterations on a per-loop basis // rather than on a per-iteration basis. Note that goto and return also // need to be modified to do the bulk counting. else if (isSgBreakStmt(stmt)) { } else if (isSgContinueStmt(stmt)) { } */ else if (isSgIfStmt(stmt)) { bool simpleWorkTrueBody = true ; bool simpleWorkFalseBody = true ; SgIfStmt *ifStatement = isSgIfStmt(stmt) ; if (ifStatement->get_true_body() != NULL) { SgBasicBlock *trueBody = SageInterface::ensureBasicBlockAsTrueBodyOfIf(ifStatement) ; ROSE_ASSERT(trueBody) ; simpleWorkTrueBody = TransformFunction(funcDecl, funcBody, trueBody, loopCount, segmentCount) ; } if (ifStatement->get_false_body() != NULL) { SgBasicBlock *falseBody = SageInterface::ensureBasicBlockAsFalseBodyOfIf(ifStatement) ; ROSE_ASSERT(falseBody) ; simpleWorkFalseBody = TransformFunction(funcDecl, funcBody, falseBody, loopCount, segmentCount) ; } if (!(simpleWorkTrueBody && simpleWorkFalseBody)) { if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } simpleWork = false ; } else { if (segBegin == NULL) { #ifndef DISABLE_SEQUENTIAL_SEGMENTS segBegin = stmt ; #endif } } } else if (isSgSwitchStatement(stmt)) { bool simpleWorkSwitch ; SgSwitchStatement *switchStatement = isSgSwitchStatement(stmt) ; // SgBasicBlock *body = isSgBasicBlock(switchStatement->get_body()) ; SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfSwitch(switchStatement) ; ROSE_ASSERT(body) ; simpleWorkSwitch = TransformFunction(funcDecl, funcBody, body, loopCount, segmentCount) ; if (!simpleWorkSwitch) { if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } simpleWork = false ; } else { if (segBegin == NULL) { #ifndef DISABLE_SEQUENTIAL_SEGMENTS segBegin = stmt ; #endif } } } else if (isSgCaseOptionStmt(stmt)) { SgCaseOptionStmt *caseStmt = isSgCaseOptionStmt(stmt) ; if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; simpleWork = false ; segBegin = NULL ; } SgBasicBlock *body = isSgBasicBlock(caseStmt->get_body()) ; TransformFunction(funcDecl, funcBody, body, loopCount, segmentCount) ; } else if (isSgDefaultOptionStmt(stmt)) { SgDefaultOptionStmt *defaultStmt = isSgDefaultOptionStmt(stmt) ; if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; simpleWork = false ; segBegin = NULL ; } SgBasicBlock *body = isSgBasicBlock(defaultStmt->get_body()) ; TransformFunction(funcDecl, funcBody, body, loopCount, segmentCount) ; } else if (isSgBasicBlock(stmt)) { bool simpleWorkBlock ; SgBasicBlock *block = isSgBasicBlock(stmt) ; simpleWorkBlock = TransformFunction(funcDecl, funcBody, block, loopCount, segmentCount) ; if (!simpleWorkBlock) { if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } simpleWork = false ; } else { if (segBegin == NULL) { #ifndef DISABLE_SEQUENTIAL_SEGMENTS segBegin = stmt ; #endif } } } else if (ContainsNonSimpleCall(stmt)) { if (segBegin != NULL) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount) ; segBegin = NULL ; } simpleWork = false ; } else { if (segBegin == NULL) { #ifndef DISABLE_SEQUENTIAL_SEGMENTS segBegin = stmt ; #endif } } } if ((segBegin != NULL) && !simpleWork) { CreateSegmentProbe(funcDecl, funcBody, segBegin, stmt, segmentCount, true) ; } return simpleWork ; }
//! Translate generated Pragma Attributes one by one void translatePragmas (std::vector <MPI_PragmaAttribute*>& Attribute_List) { std::vector<MPI_PragmaAttribute*>::iterator iter; for (iter = Attribute_List.begin(); iter!=Attribute_List.end(); iter ++) { MPI_PragmaAttribute* cur_attr = *iter; cout<<"Translating ..." << cur_attr->toString() <<endl; SgScopeStatement* scope = cur_attr->pragma_node ->get_scope(); ROSE_ASSERT (scope != NULL); // simply obtain the default value and remove the pragma if (cur_attr-> pragma_type == pragma_mpi_device_default) { mpi_device_default_choice = cur_attr->default_semantics; // no automatic handling of attached preprocessed info. for now removeStatement(cur_attr->pragma_node, false); } // find omp target device(mpi:all) begin else if (cur_attr-> pragma_type == pragma_mpi_device_all_begin) { iter ++; // additional increment once MPI_PragmaAttribute* end_attribute = *iter; ROSE_ASSERT (end_attribute->pragma_type = pragma_mpi_device_all_end); removeStatement(cur_attr->pragma_node, false); removeStatement(end_attribute ->pragma_node, false); } else if (cur_attr-> pragma_type == pragma_mpi_device_master_begin) { // TODO refactor into a function iter ++; // additional increment once MPI_PragmaAttribute* end_attribute = *iter; ROSE_ASSERT (end_attribute->pragma_type = pragma_mpi_device_master_end); //insert a if (rank) .. after the end pragma SgIfStmt * ifstmt = buildIfStmt (buildEqualityOp(buildVarRefExp("_xomp_rank", scope), buildIntVal(0)), buildBasicBlock(), NULL); insertStatementAfter (end_attribute->pragma_node, ifstmt); SgBasicBlock * bb = isSgBasicBlock(ifstmt->get_true_body()); SgStatement* next_stmt = getNextStatement(cur_attr->pragma_node); // the next stmt is BB, skip it by starting the search from it ROSE_ASSERT (next_stmt != NULL); // normalize all declarations while ( next_stmt != end_attribute ->pragma_node) { // save current stmt before getting next one SgStatement* cur_stmt = next_stmt; next_stmt = getNextStatement (next_stmt); ROSE_ASSERT (next_stmt != NULL); if (SgVariableDeclaration* decl = isSgVariableDeclaration (cur_stmt)) splitVariableDeclaration (decl); } // move all non-declaration statements in between into the block next_stmt = getNextStatement(cur_attr->pragma_node); //reset from the beginning while ( next_stmt != end_attribute ->pragma_node) { // save current stmt before getting next one SgStatement* cur_stmt = next_stmt; next_stmt = getNextStatement (next_stmt); ROSE_ASSERT (next_stmt != NULL); if (!isSgVariableDeclaration(cur_stmt)) { // now remove the current stmt removeStatement (cur_stmt, false); appendStatement(cur_stmt, bb); } } // remove pragmas removeStatement(cur_attr->pragma_node, false); removeStatement(end_attribute ->pragma_node, false); } } // end for } // end translatePragmas ()
ExprSynAttr *examineStatement(SgStatement *stmt, ostream &out) { SgExpression *expr; SgExprStatement *expr_stmt; ExprSynAttr *expr_attr = NULL; ExprSynAttr *attr1 = NULL; stringstream fake; int i; if (NULL == stmt) return NULL; //out << "/* " << stmt->unparseToString() << " */" << endl; switch(stmt->variantT()) { case V_SgExprStatement: { expr_stmt = isSgExprStatement(stmt); expr_attr = examineExpr(expr_stmt->get_expression(), fake); //out << ";"; if (NULL != expr_attr) { expr_attr->output_comments(out); } break; } case V_SgVariableDeclaration: { SgVariableDeclaration *vardecl = isSgVariableDeclaration(stmt); expr_attr = examineVariableDeclaration(vardecl, out); break; } case V_SgBreakStmt: { out << "break;"; expr_attr->code << "break;"; break; } case V_SgContinueStmt: { out << "continue;"; expr_attr->code << "continue;"; break; } case V_SgReturnStmt: { SgReturnStmt *retstmt = isSgReturnStmt(stmt); expr_attr = new ExprSynAttr(); out << "return "; expr = retstmt->get_expression(); if (expr) { attr1 = examineExpr(expr, out); expr_attr->union_tmp_decls(attr1); expr_attr->code << attr1->code.str(); } out << ";"; expr_attr->code << "return "; if (attr1) { expr_attr->result_var = attr1->result_var; expr_attr->code << expr_attr->result_var; } expr_attr->code << ";"; break; } case V_SgForStatement: { stringstream head; head << "for ("; SgForStatement *forstmt = isSgForStatement(stmt); SgStatementPtrList &init_stmt_list = forstmt->get_init_stmt(); SgStatementPtrList::const_iterator init_stmt_iter; for (init_stmt_iter = init_stmt_list.begin(); init_stmt_iter != init_stmt_list.end(); init_stmt_iter++) { stmt = *init_stmt_iter; if (init_stmt_iter != init_stmt_list.begin()) head << ", "; expr_stmt = isSgExprStatement(stmt); if (expr_stmt) examineExpr(expr_stmt->get_expression(), head); } head << "; "; expr_stmt = isSgExprStatement(forstmt->get_test()); if (expr_stmt) examineExpr(expr_stmt->get_expression(), head); head << "; "; expr = forstmt->get_increment(); examineExpr(expr, head); head << ")" << endl; /* Loop body */ stmt = forstmt->get_loop_body(); expr_attr = examineStatement(stmt, fake); attr1 = new ExprSynAttr(); attr1->code << head.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "{" << endl; } expr_attr->output_tmp_decls(attr1->code); attr1->code << expr_attr->code.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "}" << endl; } delete expr_attr; expr_attr = attr1; attr1 = NULL; out << head.str(); out << fake.str(); break; } case V_SgBasicBlock: { SgScopeStatement *scope = isSgScopeStatement(stmt); expr_attr = examineScopeStatement(scope, "scope", out); break; } case V_SgIfStmt: { stringstream head; SgIfStmt *ifstmt = isSgIfStmt(stmt); head << "if ("; stmt = ifstmt->get_conditional(); expr_stmt = isSgExprStatement(stmt); if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); if (attr1 != NULL) delete attr1; } head << ")" << endl; out << head.str(); /* True body */ stmt = ifstmt->get_true_body(); expr_attr = examineStatement(stmt, fake); attr1 = new ExprSynAttr(); attr1->code << head.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "{" << endl; } expr_attr->output_tmp_decls(attr1->code); attr1->code << expr_attr->code.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "}" << endl; } delete expr_attr; expr_attr = attr1; attr1 = NULL; out << head.str(); out << fake.str(); /* False body */ stmt = ifstmt->get_false_body(); if (stmt) { out << endl << "else" << endl; expr_attr->code << endl << "else" << endl; attr1 = examineStatement(stmt, out); if (!isSgScopeStatement(stmt)) { expr_attr->code << "{" << endl; } attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } } break; } case V_SgWhileStmt: { stringstream head; SgWhileStmt *whilestmt = isSgWhileStmt(stmt); expr_stmt = isSgExprStatement(whilestmt->get_condition()); head << "while ("; if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); if (NULL != attr1) delete attr1; } out << head.str() << ")" << endl; head << ")" << endl; if (!isSgScopeStatement(stmt)) { head << "{" << endl; } expr_attr = new ExprSynAttr(); expr_attr->code << head.str(); /* Loop Body */ stmt = whilestmt->get_body(); attr1 = examineStatement(stmt, out); attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } delete attr1; break; } case V_SgDoWhileStmt: { stringstream head; SgDoWhileStmt *dowhilestmt = isSgDoWhileStmt(stmt); expr_stmt = isSgExprStatement(dowhilestmt->get_condition()); stmt = dowhilestmt->get_body(); out << "do"; head << "do" << endl; if (!isSgScopeStatement(stmt)) { head << "{" << endl; } expr_attr = new ExprSynAttr(); expr_attr->code << head.str(); attr1 = examineStatement(stmt, out); attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } expr_attr->code << " while ("; delete attr1; out << " while ("; head.str(""); if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); delete attr1; out << head.str(); expr_attr->code << head.str(); } out << ");" << endl; expr_attr->code << ");" << endl; break; } } return expr_attr; }