SynthesizedAttribute visitorTraversal::evaluateSynthesizedAttribute ( SgNode* n, SynthesizedAttributesList childAttributes ) { // Fold up the list of child attributes using logical or, i.e. the local // result will be true iff one of the child attributes is true. SynthesizedAttribute localResult = std::accumulate(childAttributes.begin(), childAttributes.end(), false, std::logical_or<bool>()); if (isSgForStatement(n) != NULL) { printf ("Found a for loop ... \n"); localResult = true; } return localResult; }
virtual void visit(SgNode * n) { switch (n->variantT()) { case V_SgFunctionDeclaration: { SgFunctionDeclaration * func_decl = isSgFunctionDeclaration(n); ROSE_ASSERT(func_decl != NULL); std::string func_name = func_decl->get_name().getString(); // std::cout << "Found SgFunctionDeclaration: " << func_name << std::endl; if (func_name == "caller") p_caller = func_decl; if (func_name == "kernel") p_kernel = func_decl; break; } case V_SgForStatement: { SgForStatement * for_stmt = isSgForStatement(n); ROSE_ASSERT(for_stmt != NULL); // std::cout << "Found SgForStatement." << std::endl; p_for_stmts.push_back(for_stmt); break; } case V_SgFunctionCallExp: { SgFunctionCallExp * func_call = isSgFunctionCallExp(n); ROSE_ASSERT(func_call != NULL); SgFunctionRefExp * func_ref = isSgFunctionRefExp(func_call->get_function()); ROSE_ASSERT(func_ref != NULL); // std::cout << "Found SgFunctionCallExp: " << func_ref->getAssociatedFunctionDeclaration ()->get_name().getString() << std::endl; if (func_ref->getAssociatedFunctionDeclaration()->get_name().getString() == "kernel") p_kernel_call_site = func_call; break; } case V_SgSourceFile: // fix the file suffix, Liao 12/29/2010 { SgSourceFile * sfile = isSgSourceFile (n); ROSE_ASSERT (sfile != NULL); sfile->set_Cuda_only(true); } default:{} } }
/* recommenderTraversal::visit */ void recommenderTraversal::visit(SgNode *node) { Sg_File_Info *info = NULL; SgFunctionDefinition *function = NULL; SgForStatement *c_loop = NULL; SgNode *grandparent = NULL; SgNode *parent = NULL; int node_found = 0; info = node->get_file_info(); /* Find code fragment for bottlenecks type 'loop' in C */ if ((isSgForStatement(node)) && (info->get_line() == fragment->line) && (PERFEXPERT_HOTSPOT_LOOP == fragment->type)) { /* Found a C loop on the exact line number */ OUTPUT_VERBOSE((8, " [loop] %s (line %d)", _GREEN((char *)"found"), info->get_line())); /* Extract the loop fragment */ if (PERFEXPERT_SUCCESS != output_fragment(node, info, fragment)) { OUTPUT(("%s", _ERROR((char *)"extracting fragment"))); rc = PERFEXPERT_ERROR; return; } /* Save the fragment path and filename */ PERFEXPERT_ALLOC(char, fragment->fragment_file, (strlen(globals.workdir) + strlen(FRAGMENTS_DIR) + strlen(fragment->file) + 15)); sprintf(fragment->fragment_file, "%s/%s/%s_%d", globals.workdir, FRAGMENTS_DIR, fragment->file, fragment->line); /* What is the loop detph and who is parent node */ if (2 <= fragment->depth) { parent = node->get_parent(); /* It is a basic block. Who is this basic block's parent? */ if (NULL != isSgBasicBlock(parent)) { parent = parent->get_parent(); } /* Is it a for/do/while? */ if (isSgForStatement(parent)) { info = parent->get_file_info(); fragment->outer_loop_line = info->get_line(); /* The parent is a loop */ OUTPUT_VERBOSE((8, " [parent loop] %s (line %d)", _GREEN((char *)"found"), fragment->outer_loop_line)); /* Extract the parent loop fragment */ if (PERFEXPERT_SUCCESS != output_fragment(parent, info, fragment)) { OUTPUT(("%s", _ERROR((char *)"extracting fragment"))); rc = PERFEXPERT_ERROR; return; } /* Save the fragment path and filename */ PERFEXPERT_ALLOC(char, fragment->outer_loop_fragment_file, (strlen(globals.workdir) + strlen(FRAGMENTS_DIR) + strlen(fragment->file) + 15)); sprintf(fragment->outer_loop_fragment_file, "%s/%s/%s_%d", globals.workdir, FRAGMENTS_DIR, fragment->file, fragment->outer_loop_line); /* What is the loop detph and who is the grandparent node */ if (3 <= fragment->depth) { grandparent = parent->get_parent(); /* It is a basic block. Who is this basic block's parent? */ if (NULL != isSgBasicBlock(grandparent)) { grandparent = grandparent->get_parent(); } /* Is it a for/do/while? */ if (isSgForStatement(grandparent)) { info = grandparent->get_file_info(); fragment->outer_outer_loop_line = info->get_line(); /* The grandparent is a loop */ OUTPUT_VERBOSE((8, " [grandparent loop] %s (line %d)", _GREEN((char *)"found"), fragment->outer_outer_loop_line)); /* Extract the parent loop fragment */ if (PERFEXPERT_SUCCESS != output_fragment(grandparent, info, fragment)) { OUTPUT(("%s", _ERROR((char *)"extracting fragment"))); rc = PERFEXPERT_ERROR; return; } /* Save the fragment path and filename */ PERFEXPERT_ALLOC(char, fragment->outer_outer_loop_fragment_file, (strlen(globals.workdir) + strlen(FRAGMENTS_DIR) + strlen(fragment->file) + 15)); sprintf(fragment->outer_outer_loop_fragment_file, "%s/%s/%s_%d", globals.workdir, FRAGMENTS_DIR, fragment->file, fragment->outer_outer_loop_line); } } }
//A generic function to check if a loop has a tag statement prepended to it, asking for instrumentation //If so, the loop will be instrumented and the tag statement will be returned. // This function supports both C/C++ for loops and Fortran Do loops SgStatement* instrumentLoopForCounting(SgStatement* loop) { //get scope of the loop assert (loop != NULL); SgForStatement* forloop = isSgForStatement(loop); SgFortranDo* doloop = isSgFortranDo(loop); SgScopeStatement* scope = NULL; if (forloop) scope = forloop->get_scope(); else if (doloop) scope = doloop->get_scope(); else { cerr<<"Error in instrumentLoopForCounting(): Unrecognized loop type:"<< loop->class_name()<<endl; assert(false); } ROSE_ASSERT(scope != NULL); // Only for a do-loop which immediately follows chiterations = .. SgVariableSymbol * chiterations_sym = lookupVariableSymbolInParentScopes(SgName("chiterations"), isSgScopeStatement(loop)); if (chiterations_sym==NULL) return NULL; SgStatement* prev_stmt = getPreviousStatement(loop,false); // backwards search, skipping pragma declaration etc. while (prev_stmt!=NULL && !isAssignmentStmtOf (prev_stmt, chiterations_sym->get_declaration())) prev_stmt = getPreviousStatement(prev_stmt,false); if (prev_stmt == NULL) return NULL; // To support nested loops, we need to use unique chiterations variable for each loop // otherwise the value stored in inner loop will overwrite the iteration count for the outerloop. loop_id ++; // increment loop ID // insert size_t chiterations_id ; // Find the enclosing function declaration, including its derived instances like //isSgProcedureHeaderStatement, isSgProgramHeaderStatement, and isSgMemberFunctionDeclaration. SgFunctionDeclaration* func_decl = getEnclosingFunctionDeclaration (loop); ROSE_ASSERT (func_decl !=NULL); SgFunctionDefinition* func_def = func_decl->get_definition(); ROSE_ASSERT (func_def !=NULL); SgBasicBlock* func_body = func_def->get_body(); // insert a new variable declaration std::string new_iter_var_name = std::string("chiterations_") + StringUtility::numberToString(loop_id); SgVariableDeclaration* new_iter_var_decl = buildVariableDeclaration(new_iter_var_name, chiterations_sym->get_type(), NULL, func_body); SgStatement* last_decl = findLastDeclarationStatement(func_body); if (last_decl!=NULL) insertStatementAfter (last_decl, new_iter_var_decl, false); else prependStatement(new_iter_var_decl, func_body); // rewrite the assignment stmt's left hand variable to be the new symbol SgExpression* lhs = NULL; bool rt = isAssignmentStatement (prev_stmt, &lhs); ROSE_ASSERT (rt == true); ROSE_ASSERT (lhs != NULL); SgVarRefExp* var_ref = isSgVarRefExp (lhs); ROSE_ASSERT (var_ref != NULL); var_ref->set_symbol(getFirstVarSym (new_iter_var_decl)); SgStatement* loop_body = NULL; if (forloop) loop_body = forloop->get_loop_body(); else if (doloop) loop_body = doloop->get_body(); assert (loop_body != NULL); // count FP operations for each loop CountFPOperations (loop_body); //chflops=chflops+chiterations*n FPCounters* current_result = getFPCounters (loop_body); if (current_result->getTotalCount() >0) { SgExprStatement* stmt = buildCounterAccumulationStmt("chflops", new_iter_var_name , buildIntVal(current_result->getTotalCount()),scope); insertStatementAfter (loop, stmt); attachComment(stmt," aitool generated FLOPS counting statement ..."); } // Obtain per-iteration load/store bytes calculation expressions // excluding scalar types to match the manual version //CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars = true, bool includeIntType = true); std::pair <SgExpression*, SgExpression*> load_store_count_pair = CountLoadStoreBytes (loop_body, false, true); // chstores=chstores+chiterations*8 if (load_store_count_pair.second!= NULL) { SgExprStatement* store_byte_stmt = buildCounterAccumulationStmt("chstores", new_iter_var_name, load_store_count_pair.second, scope); insertStatementAfter (loop, store_byte_stmt); attachComment(store_byte_stmt," aitool generated Stores counting statement ..."); } // handle loads stmt 2nd so it can be inserted as the first after the loop // build chloads=chloads+chiterations*2*8 if (load_store_count_pair.first != NULL) { SgExprStatement* load_byte_stmt = buildCounterAccumulationStmt("chloads", new_iter_var_name, load_store_count_pair.first, scope); insertStatementAfter (loop, load_byte_stmt); attachComment(load_byte_stmt," aitool generated Loads counting statement ..."); } return prev_stmt; } // end instrumentLoopForCounting()
// Count the load and store bytes for the // I think we can only return expressions to calculate the value, not the actual values, // since sizeof(type) is machine dependent // Consider both scalar and array accesses by default. Consider both floating point and integer types by default. // return a pair of expressions: // load_byte_exp, and // store_byte_exp // Algorithm: // 1. Call side effect analysis to find read/write variables, some reference may trigger both read and write accesses // Accesses to the same array/scalar variable are grouped into one read (or write) access // e.g. array[i][j], array[i][j+1], array[i][j-1], etc are counted a single access // 2. Group accesses based on the types (same type? increment the same counter to shorten expression length) // 4. Iterate on the results to generate expression like 2*sizeof(float) + 5* sizeof(double) // As an approximate, we use simple analysis here assuming no function calls. std::pair <SgExpression*, SgExpression*> CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars /* = true */, bool includeIntType /* = true */) { std::pair <SgExpression*, SgExpression*> result; assert (input != NULL); // the input is essentially the loop body, a scope statement SgScopeStatement* scope = isSgScopeStatement(input); // We need to record the associated loop info. //SgStatement* loop= NULL; SgForStatement* forloop = isSgForStatement(scope->get_scope()); SgFortranDo* doloop = isSgFortranDo(scope->get_scope()); if (forloop) { //loop = forloop; } else if (doloop) { //loop = doloop; } else { cerr<<"Error in CountLoadStoreBytes (): input is not loop body type:"<< input->class_name()<<endl; assert(false); } //Plan A: use and extend Qing's side effect analysis std::set<SgInitializedName*> readVars; std::set<SgInitializedName*> writeVars; bool success = SageInterface::collectReadWriteVariables (isSgStatement(input), readVars, writeVars); if (success!= true) { cout<<"Warning: CountLoadStoreBytes(): failed to collect load/store, mostly due to existence of function calls inside of loop body @ "<<input->get_file_info()->get_line()<<endl; } std::set<SgInitializedName*>::iterator it; if (debug) cout<<"debug: found read variables (SgInitializedName) count = "<<readVars.size()<<endl; for (it=readVars.begin(); it!=readVars.end(); it++) { SgInitializedName* iname = (*it); if (debug) cout<<scalar_or_array (iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl; } if (!includeScalars ) readVars = filterVariables (readVars); if (debug) cout<<"debug: found write variables (SgInitializedName) count = "<<writeVars.size()<<endl; for (it=writeVars.begin(); it!=writeVars.end(); it++) { SgInitializedName* iname = (*it); if (debug) cout<<scalar_or_array(iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl; } if (!includeScalars ) writeVars = filterVariables (writeVars); result.first = calculateBytes (readVars, scope, true); result.second = calculateBytes (writeVars, scope, false); return result; }
//! Return an expression like 8*sizeof(int)+ 3*sizeof(float) + 5*sizeof(double) for a list of variables accessed (either read or write) // For array variable, we should only count a single element access, not the entire array size // Algorithm: // Iterate on each variable in the set // group them into buckets based on types, using a map<SgType*, int> to store this // Iterate the list of buckets to generate count*sizeof(type) + .. expression SgExpression* calculateBytes (std::set<SgInitializedName*>& name_set, SgScopeStatement* scope, bool isRead) { SgExpression* result = NULL; if (name_set.size()==0) return result; // the input is essentially the loop body, a scope statement ROSE_ASSERT (scope != NULL); // We need to record the associated loop info. SgStatement* loop= NULL; SgForStatement* forloop = isSgForStatement(scope->get_scope()); SgFortranDo* doloop = isSgFortranDo(scope->get_scope()); if (forloop) loop = forloop; else if (doloop) loop = doloop; else { cerr<<"Error in CountLoadStoreBytes (): input is not loop body type:"<< scope->class_name()<<endl; assert(false); } std::map<SgType* , int> type_based_counters; // get all processed variables by inner loops std::set<SgInitializedName*> processed_var_set; getVariablesProcessedByInnerLoops (scope, isRead, processed_var_set); // fill in the type-based counters std::set<SgInitializedName*>::iterator set_iter; for (set_iter = name_set.begin(); set_iter != name_set.end(); set_iter++) { SgInitializedName* init_name = *set_iter; // skip visited variable when processing inner loops // some global variables may be visited by another function // But we should count it when processing the current function! // // We group all references to a same variable into one reference for now // if a variable is considered when processing inner loops, the variable // will be skipped when processing outer loops. if (isRead) { // if inner loops already processed it, skip it if (processed_var_set.find(init_name) != processed_var_set.end()) continue; else LoopLoadVariables[loop].insert(init_name); } else { if (processed_var_set.find(init_name) != processed_var_set.end()) continue; else LoopStoreVariables[loop].insert(init_name); } // It is tricky here, TODO consider pointer, typedefs, reference, modifier types SgType* stripped_type = (*set_iter)->get_type()->stripTypedefsAndModifiers(); SgType* base_type = NULL; if (isScalarType(stripped_type)) base_type = stripped_type; else if (isSgArrayType(stripped_type)) { // we may have multi-dimensional arrays like int a[][][]; base_type = stripped_type; do { base_type = isSgArrayType(base_type)->get_base_type(); } while (isSgArrayType (base_type)); } else { cerr<<"Error in calculateBytes(). Unhandled stripped type:"<<stripped_type->class_name()<<endl; assert (false); } type_based_counters[base_type] ++; } // end for // use the type-based counters for byte calculation std::map<SgType* , int>::iterator citer; //It is possible now to have zero after filtering out redundant variables //assert (type_based_counters.size()>0); for (citer = type_based_counters.begin(); citer !=type_based_counters.end(); citer ++) { SgType* t = (*citer).first; // at this point, we should not have array types any more ROSE_ASSERT (isSgArrayType (t) == false); int count = (*citer).second; assert (t != NULL); assert (count>0); SgExpression* sizeof_exp = NULL; if (is_Fortran_language()) { #if 0 // this does not work. cannot find func symbol for sizeof() // In Fortran sizeof() is a function call, not SgSizeOfOp. // type name is a variable in the AST, // Too much trouble to build assert (scope !=NULL); // This does not work //SgFunctionSymbol* func_sym = lookupFunctionSymbolInParentScopes(SgName("sizeof"), scope); SgGlobal* gscope = getGlobalScope (scope); assert (gscope !=NULL); SgFunctionSymbol* func_sym = gscope->lookup_function_symbol(SgName("sizeof")); assert (func_sym!=NULL); SgVarRefExp* type_var = buildVarRefExp( t->unparseToString(), scope ); assert (type_var !=NULL); sizeof_exp = buildFunctionCallExp (func_sym, buildExprListExp(type_var)); #else // sizeof is not an operator in Fortran, there is no unparsing support for this // sizeof_exp = buildSizeOfOp(t); // Directly obtain an integer size value sizeof_exp = buildIntVal(getSizeOf(t)); #endif } else if (is_C_language() || is_C99_language() || is_Cxx_language()) { sizeof_exp = buildSizeOfOp(t); } else { cerr<<"Error in calculateBytes(). Unsupported programming language other than C/Cxx and Fortran. "<<endl; assert (false); } SgExpression* mop = buildMultiplyOp(buildIntVal(count), sizeof_exp); if (result == NULL) result = mop; else result = buildAddOp(result, mop); } return result; }
EdgeConditionKind CFGEdge::condition() const { #if 0 SgAsmNode* srcNode = src.getNode(); unsigned int srcIndex = src.getIndex(); SgAsmNode* tgtNode = tgt.getNode(); unsigned int tgtIndex = tgt.getIndex(); if (isSgAsmMov(srcNode) ) { SgAsmMov* ifs = isSgAsmMov(srcNode); #if 0 if (ifs->get_true_body() == tgtNode) { return eckTrue; } else if (ifs->get_false_body() == tgtNode) { return eckFalse; } else ROSE_ASSERT (!"Bad successor in if statement"); #endif } #if 0 else if (isSgWhileStmt(srcNode) && srcIndex == 1) { if (srcNode == tgtNode) { // False case for while test return eckFalse; } else { return eckTrue; } } else if (isSgDoWhileStmt(srcNode) && srcIndex == 2) { // tgtIndex values are 0 for true branch and 3 for false branch if (tgtIndex == 0) { return eckTrue; } else { return eckFalse; } } else if (isSgForStatement(srcNode) && srcIndex == 2) { if (srcNode == tgtNode) { // False case for test return eckFalse; } else { return eckTrue; } } else if (isSgSwitchStatement(srcNode) && isSgCaseOptionStmt(tgtNode)) { return eckCaseLabel; } else if (isSgSwitchStatement(srcNode) && isSgDefaultOptionStmt(tgtNode)){ return eckDefault; } else if (isSgConditionalExp(srcNode) && srcIndex == 1) { SgConditionalExp* ce = isSgConditionalExp(srcNode); if (ce->get_true_exp() == tgtNode) { return eckTrue; } else if (ce->get_false_exp() == tgtNode) { return eckFalse; } else ROSE_ASSERT (!"Bad successor in conditional expression"); } else if (isSgAndOp(srcNode) && srcIndex == 1) { if (srcNode == tgtNode) { // Short-circuited false case return eckFalse; } else { return eckTrue; } } else if (isSgOrOp(srcNode) && srcIndex == 1) { if (srcNode == tgtNode) { // Short-circuited true case return eckTrue; } else { return eckFalse; } } #endif else { // No key return eckUnconditional; } #else // DQ (11/28/2009): This function was already commented out, but must return a value for use in MSVC. return eckFalse; #endif }
POETCode* POETAstInterface::Ast2POET(const Ast& n) { static SgTemplateInstantiationFunctionDecl* tmp=0; SgNode* input = (SgNode*) n; if (input == 0) return EMPTY; POETCode* res = POETAstInterface::find_Ast2POET(input); if (res != 0) return res; { SgProject* sageProject=isSgProject(input); if (sageProject != 0) { int filenum = sageProject->numberOfFiles(); for (int i = 0; i < filenum; ++i) { SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); SgGlobal *root = sageFile->get_globalScope(); SgDeclarationStatementPtrList declList = root->get_declarations (); POETCode* curfile = ROSE_2_POET_list(declList, 0, tmp); curfile = new POETCode_ext(sageFile, curfile); POETAstInterface::set_Ast2POET(sageFile, curfile); res=LIST(curfile, res); } POETAstInterface::set_Ast2POET(sageProject,res); return res; } } { SgBasicBlock* block = isSgBasicBlock(input); if (block != 0) { res=ROSE_2_POET_list(block->get_statements(), res, tmp); POETAstInterface::set_Ast2POET(block, res); return res; } } { SgExprListExp* block = isSgExprListExp(input); if (block != 0) { res=ROSE_2_POET_list(block->get_expressions(), 0, tmp); POETAstInterface::set_Ast2POET(block, res); return res; } } { SgForStatement *f = isSgForStatement(input); if (f != 0) { POETCode* init = ROSE_2_POET_list(f->get_for_init_stmt()->get_init_stmt(),0, tmp); POETCode* ctrl = new POETCode_ext(f, TUPLE3(init,Ast2POET(f->get_test_expr()), Ast2POET(f->get_increment()))); res = CODE_ACC("Nest", PAIR(ctrl,Ast2POET(f->get_loop_body()))); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgVarRefExp * v = isSgVarRefExp(input); if (v != 0) { res = STRING(v->get_symbol()->get_name().str()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgMemberFunctionRefExp * v = isSgMemberFunctionRefExp(input); if (v != 0) { res = STRING(v->get_symbol()->get_name().str()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgIntVal * v = isSgIntVal(input); if (v != 0) { res = ICONST(v->get_value()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgInitializedName* var = isSgInitializedName(input); if (var != 0) { POETCode* name = STRING(var->get_name().str()); POETCode* init = Ast2POET(var->get_initializer()); res = new POETCode_ext(var, PAIR(name,init)); POETAstInterface::set_Ast2POET(input, res); return res; } } /* { std::string fname; AstInterface::AstList params; AstNodeType returnType; AstNodePtr body; if (AstInterface :: IsFunctionDefinition( input, &fname, ¶ms, (AstInterface::AstList*)0, &body, (AstInterface::AstTypeList*)0, &returnType)) { if (body != AST_NULL) std::cerr << "body not empty:" << fname << "\n"; POETCode* c = TUPLE4(STRING(fname), ROSE_2_POET_list(0,params,0), STRING(AstInterface::GetTypeName(returnType)), Ast2POET(body.get_ptr())); res = new POETCode_ext(input, c); POETAstInterface::set_Ast2POET(input,res); return res; } } */ AstInterface::AstList c = AstInterface::GetChildrenList(input); switch (input->variantT()) { case V_SgCastExp: case V_SgAssignInitializer: res = Ast2POET(c[0]); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgDotExp: { POETCode* v1 = Ast2POET(c[1]); if (dynamic_cast<POETString*>(v1)->get_content() == "operator()") return Ast2POET(c[0]); res = CODE_ACC("Bop",TUPLE3(STRING("."), Ast2POET(c[0]), v1)); return res; } case V_SgLessThanOp: res = CODE_ACC("Bop",TUPLE3(STRING("<"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgSubtractOp: res = CODE_ACC("Bop",TUPLE3(STRING("-"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgAddOp: res = CODE_ACC("Bop",TUPLE3(STRING("+"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgMultiplyOp: res = CODE_ACC("Bop",TUPLE3(STRING("*"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgDivideOp: res = CODE_ACC("Bop",TUPLE3(STRING("/"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgAssignOp: res = CODE_ACC("Assign",PAIR(Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgFunctionCallExp: res = CODE_ACC("FunctionCall",PAIR(Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; } POETCode * c2 = 0; if (tmp == 0) tmp=isSgTemplateInstantiationFunctionDecl(input); switch (c.size()) { case 0: break; case 1: c2 = Ast2POET(c[0]); break; case 2: c2 = PAIR(Ast2POET(c[0]),Ast2POET(c[1])); break; case 3: c2 = TUPLE3(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2])); break; case 4: c2 = TUPLE4(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2]),Ast2POET(c[3])); break; default: //std::cerr << "too many children: " << c.size() << ":" << input->unparseToString() << "\n"; c2 = EMPTY; } if (tmp == input) tmp = 0; res = new POETCode_ext(input, c2); POETAstInterface::set_Ast2POET(input,res); return res; }
/** Visits AST nodes in post-order. This is function-evaluation order. */ bool FunctionEvaluationOrderTraversal::evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList) { SgFunctionCallExp* functionCall = isSgFunctionCallExp(astNode); if (functionCall == NULL) return false; //dummy return value FunctionCallInfo functionCallInfo(functionCall); // Can't lift function call arguments from the following: // 1. For loop test and increment // 2. While loop test // 3. Do-While loop test // 4. Either arms of ternary op // 5. RHS of any short circuit expression // An alternative is to use comma operators and use assignemnt op as done by the original author. // for(;foo(bar());) ==> T i; for(;i=bar();foo(i);) // But using assignement op is not always safe and it requires us to always have a default constructor // There is also an issue when the return type is a reference and we'll have to use & op to get a pointer // but if & op is overloaded we may not get the pointer. // Taking all these in view, I am simpling not lifting such expressions. if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_TEST || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION) { // ***** FOR UNSAFE TRANSFORMATION ******* //Temporary variables should be declared before the stmt ROSE_ASSERT(isSgStatement(parentAttribute.currentScope)); functionCallInfo.tempVarDeclarationLocation = isSgStatement(parentAttribute.currentScope); functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; nonNormalizableFunctionCalls.push_back(functionCallInfo); return false; } // In future, if the function call is assured to be side effect free, then we can lift it from short circuit and conditional expressions if(parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS){ if(!IsFunctionCallSideEffectFree(functionCall)) { // ***** FOR UNSAFE TRANSFORMATION ******* //Temporary variables should be declared before the stmt ROSE_ASSERT(parentAttribute.lastStatement); functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; nonNormalizableFunctionCalls.push_back(functionCallInfo); return false; } } //Handle for loops (being inside the body of a for loop doesn't need special handling) if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INIT) { SgForStatement* forLoop = isSgForStatement(parentAttribute.currentScope); ROSE_ASSERT(forLoop != NULL); //Temporary variables should be declared before the loop functionCallInfo.tempVarDeclarationLocation = forLoop; functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; } else if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE) { //Assume we're in a basic block. Then just insert right before the current statement ROSE_ASSERT(parentAttribute.scopeStatus = FunctionCallInheritedAttribute::IN_SAFE_PLACE); functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; } else { //Unhandled condition?! ROSE_ASSERT(false); } normalizableFunctionCalls.push_back(functionCallInfo); return false; //dummy return value }
/** Visits AST nodes in pre-order */ FunctionCallInheritedAttribute FunctionEvaluationOrderTraversal::evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute) { FunctionCallInheritedAttribute result = parentAttribute; SgForStatement* parentForLoop = isSgForStatement(parentAttribute.currentScope); SgWhileStmt* parentWhileLoop = isSgWhileStmt(parentAttribute.currentScope); SgDoWhileStmt* parentDoWhileLoop = isSgDoWhileStmt(parentAttribute.currentScope); SgConditionalExp* parentSgConditionalExp = astNode->get_parent() ? isSgConditionalExp(astNode->get_parent()) : NULL; SgAndOp* parentAndOp = astNode->get_parent() ?isSgAndOp(astNode->get_parent()) : NULL; SgOrOp* parentOrOp = astNode->get_parent() ? isSgOrOp(astNode->get_parent()) : NULL; if (isSgForStatement(astNode)) result.currentScope = isSgForStatement(astNode); else if (isSgWhileStmt(astNode)) result.currentScope = isSgWhileStmt(astNode); else if (isSgDoWhileStmt(astNode)) result.currentScope = isSgDoWhileStmt(astNode); //else if (isSgConditionalExp(astNode)) // result.currentScope = isSgConditionalExp(astNode); //else if (isSgAndOp(astNode)) // result.currentScope = isSgAndOp(astNode); //else if (isSgOrOp(astNode)) // result.currentScope = isSgOrOp(astNode); else if (isSgForInitStatement(astNode)) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INIT; ROSE_ASSERT(isSgForStatement(result.currentScope)); } else if (parentForLoop != NULL && parentForLoop->get_test() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_TEST; } else if (parentForLoop != NULL && parentForLoop->get_increment() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT; } else if (parentWhileLoop != NULL && parentWhileLoop->get_condition() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION; } else if (parentDoWhileLoop != NULL && parentDoWhileLoop->get_condition() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION; } else if( parentSgConditionalExp != NULL && parentSgConditionalExp->get_true_exp() == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM; } else if(parentSgConditionalExp != NULL && parentSgConditionalExp->get_false_exp() == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM; } else if( parentOrOp != NULL && parentOrOp->get_rhs_operand () == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; } else if( parentAndOp != NULL && parentAndOp->get_rhs_operand () == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; } //We can't insert variables before an expression statement that appears inside if(), switch, throw, etc. if (isSgExprStatement(astNode) && !isSgBasicBlock(astNode->get_parent())) { //We can't insert a variable declaration at these locations. Use the parent statement } else if (isSgStatement(astNode)) { result.lastStatement = isSgStatement(astNode); } return result; }
SgFunctionDeclaration * CudaOutliner::generateFunction ( SgBasicBlock* s, const string& func_name_str, ASTtools::VarSymSet_t& syms, MintHostSymToDevInitMap_t hostToDevVars, const ASTtools::VarSymSet_t& pdSyms, const ASTtools::VarSymSet_t& psyms, SgScopeStatement* scope) { //Create a function named 'func_name_str', with a parameter list from 'syms' //pdSyms specifies symbols which must use pointer dereferencing if replaced during outlining, //only used when -rose:outline:temp_variable is used //psyms are the symbols for OpenMP private variables, or dead variables (not live-in, not live-out) ROSE_ASSERT ( s && scope); ROSE_ASSERT(isSgGlobal(scope)); // step 1: perform necessary liveness and side effect analysis, if requested. // --------------------------------------------------------- std::set< SgInitializedName *> liveIns, liveOuts; // Collect read-only variables of the outlining target std::set<SgInitializedName*> readOnlyVars; if (Outliner::temp_variable||Outliner::enable_classic) { SgStatement* firstStmt = (s->get_statements())[0]; if (isSgForStatement(firstStmt)&& Outliner::enable_liveness) { LivenessAnalysis * liv = SageInterface::call_liveness_analysis (SageInterface::getProject()); SageInterface::getLiveVariables(liv, isSgForStatement(firstStmt), liveIns, liveOuts); } SageInterface::collectReadOnlyVariables(s,readOnlyVars); if (0)//Outliner::enable_debug) { cout<<" INFO:Mint: CudaOutliner::generateFunction()---Found "<<readOnlyVars.size()<<" read only variables..:"; for (std::set<SgInitializedName*>::const_iterator iter = readOnlyVars.begin(); iter!=readOnlyVars.end(); iter++) cout<<" "<<(*iter)->get_name().getString()<<" "; cout<<endl; cout<<"CudaOutliner::generateFunction() -----Found "<<liveOuts.size()<<" live out variables..:"; for (std::set<SgInitializedName*>::const_iterator iter = liveOuts.begin(); iter!=liveOuts.end(); iter++) cout<<" "<<(*iter)->get_name().getString()<<" "; cout<<endl; } } //step 2. Create function skeleton, 'func'. // ----------------------------------------- SgName func_name (func_name_str); SgFunctionParameterList *parameterList = buildFunctionParameterList(); SgType* func_Type = SgTypeVoid::createType (); SgFunctionDeclaration* func = createFuncSkeleton (func_name, func_Type ,parameterList, scope); //adds __global__ keyword func->get_functionModifier().setCudaKernel(); ROSE_ASSERT (func); // Liao, 4/15/2009 , enforce C-bindings for C++ outlined code // enable C code to call this outlined function // Only apply to C++ , pure C has trouble in recognizing extern "C" // Another way is to attach the function with preprocessing info: // #if __cplusplus // extern "C" // #endif // We don't choose it since the language linkage information is not explicit in AST if ( SageInterface::is_Cxx_language() || is_mixed_C_and_Cxx_language() \ || is_mixed_Fortran_and_Cxx_language() || is_mixed_Fortran_and_C_and_Cxx_language() ) { // Make function 'extern "C"' func->get_declarationModifier().get_storageModifier().setExtern(); func->set_linkage ("C"); } //step 3. Create the function body // ----------------------------------------- // Generate the function body by deep-copying 's'. SgBasicBlock* func_body = func->get_definition()->get_body(); ROSE_ASSERT (func_body != NULL); // This does a copy of the statements in "s" to the function body of the outlined function. ROSE_ASSERT(func_body->get_statements().empty() == true); // This calls AST copy on each statement in the SgBasicBlock, but not on the block, so the // symbol table is setup by AST copy mechanism and it is setup properly SageInterface::moveStatementsBetweenBlocks (s, func_body); if (Outliner::useNewFile) ASTtools::setSourcePositionAtRootAndAllChildrenAsTransformation(func_body); //step 4: variable handling, including: // ----------------------------------------- // create parameters of the outlined functions // add statements to unwrap the parameters if wrapping is requested // add repacking statements if necessary // replace variables to access to parameters, directly or indirectly // do not wrap parameters Outliner::enable_classic = true; functionParameterHandling(syms, hostToDevVars, pdSyms, psyms, readOnlyVars, liveOuts, func); ROSE_ASSERT (func != NULL); // Retest this... // Copied the similar fix from the rose outliner // Liao 2/6/2013. It is essential to rebuild function type after the parameter list is finalized. // The original function type was build using empty parameter list. SgType* stale_func_type = func->get_type(); func->set_type(buildFunctionType(func->get_type()->get_return_type(), buildFunctionParameterTypeList(func->get_parameterList()))); SgFunctionDeclaration* non_def_func = isSgFunctionDeclaration(func->get_firstNondefiningDeclaration ()) ; ROSE_ASSERT (non_def_func != NULL); ROSE_ASSERT (stale_func_type == non_def_func->get_type()); non_def_func->set_type(func->get_type()); ROSE_ASSERT(func->get_definition()->get_body()->get_parent() == func->get_definition()); ROSE_ASSERT(scope->lookup_function_symbol(func->get_name())); return func; }
bool ClastToSage::insertPragmas(SgNode* root) { // 1- Collect the list of outer-parallel loop iterators specified // by pluto, as given by the .pragmas file. Grammar is: 1 line per // iterator, "ITER \SPACE PRAGMA STRING \ENDLNE" std::ifstream plutofile; plutofile.open(".pragmas"); std::vector<std::string> ompLoopIterators; if (plutofile) { std::string iter; char junk[256]; while (plutofile >> iter) { ompLoopIterators.push_back(iter); plutofile.getline(junk, 256); } plutofile.close(); } // 2- Collect the list of inner-parallel loop iterators specified // by pluto, as given by the .vectorize file. Grammar is: 1 line per // iterator, "ITER\ENDLINE" plutofile.open(".vectorize"); std::vector<std::string> simdLoopIterators; if (plutofile) { std::string iter; char junk[256]; while (plutofile >> iter) { simdLoopIterators.push_back(iter); plutofile.getline(junk, 256); } plutofile.close(); } // 3- Collect all for loops. std::vector<SgNode*> forLoops = NodeQuery::querySubTree(root, V_SgForStatement); std::set<std::string>::const_iterator i; std::set<std::string> allIterators; allIterators.insert(ompLoopIterators.begin(), ompLoopIterators.end()); allIterators.insert(simdLoopIterators.begin(), simdLoopIterators.end()); // 4- Iterate on all dimensions to parallelize. for (i = allIterators.begin(); i != allIterators.end(); ++i) { SgName iterName(*i); SgSymbol* iterSymb = isSgScopeStatement(root)->lookup_symbol(iterName); if (iterSymb == NULL) { // The loop iterator symbol does not exist. Typical case // where the tile size exceeds the iteration domain size: // there is only one parallel iteration, thus no loop, // thus no iterator. Safely proceed to the next loop iterator. continue; } std::vector<SgNode*>::const_iterator j; for (j = forLoops.begin(); j != forLoops.end(); ++j) { SgForStatement* fornode = isSgForStatement(*j); ROSE_ASSERT(fornode); // Get the loop iterator. SgVariableSymbol* forSymb = SageTools::getLoopIteratorSymbol(fornode); ROSE_ASSERT(forSymb); if (forSymb == iterSymb) { std::string pragmaClause; if (std::find(simdLoopIterators.begin(), simdLoopIterators.end(),*i) != simdLoopIterators.end()) { // This is a SIMDizable loop. // For a vectorizable and parallelizable dimension, // vectorization has precedence. pragmaClause = "#pragma ivdep\n#pragma vector always"; } else if (std::find(ompLoopIterators.begin(), ompLoopIterators.end(), *i) != ompLoopIterators.end()) { // This is an OpenMP parallelizable loop. // Collect all loop iterator names in the enclosed loops std::vector<SgNode*> innerLoops = NodeQuery::querySubTree(fornode->get_loop_body(), V_SgForStatement); // Create the pragma clause. pragmaClause = "#pragma omp parallel for"; bool first = true; std::vector<SgNode*>::const_iterator k; std::set<SgVariableSymbol*> loopSymbols; for (k = innerLoops.begin(); k != innerLoops.end(); ++k) loopSymbols.insert(SageTools::getLoopIteratorSymbol (isSgForStatement(*k))); if (loopSymbols.size() > 0) pragmaClause = pragmaClause + " private("; std::set<SgVariableSymbol*>::const_iterator l; for (l = loopSymbols.begin(); l != loopSymbols.end(); ++l) { std::string iterName = (*l)->get_name().getString(); if (first) { pragmaClause = pragmaClause + iterName; first = false; } else pragmaClause = pragmaClause + ", " + iterName; } if (loopSymbols.size() > 0) pragmaClause = pragmaClause + ")"; } else { // Should never occur. ROSE_ASSERT(0); } // Annotate the for node with the pragma clause. SageInterface::attachArbitraryText(fornode, pragmaClause, PreprocessingInfo::before); // Put loop lower bound and upper bound outside the loop // (OpenMp does not like complex loop bounds). /// LNP: FIXME: do it if it becomes needed. } } } return true; }
MySynthesizedAttribute MyTraversal::evaluateRewriteSynthesizedAttribute ( SgNode* astNode, MyInheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList ) { MySynthesizedAttribute returnAttribute; switch(astNode->variantT()) { case V_SgForStatement: { SgForStatement *forStat = isSgForStatement(astNode); cout << " found V_SgForStatement " << printPosition(astNode) << "" << endl; for(size_t i=0; i<mAllFors.size(); i++) { if((mAllFors[i]->blocked)&&(astNode == mAllFors[i]->forStmt)) { ostringstream newFor; newFor << "for("; newFor << (*(forStat->get_init_stmt().begin()))->unparseToString(); newFor << forStat->get_test_expr()->unparseToString() << ";" ; newFor << mAllFors[i]->varName << "+=" << mAllFors[i]->blockSize << ")\n" ; newFor << forStat->get_loop_body()->unparseToString(); cout << " is blocked loop..." << endl; returnAttribute.replace( astNode, newFor.str() ); } } } break; case V_SgVarRefExp: { cout << " found V_SgVarRefExp " << printPosition(astNode) << astNode->unparseToString() << endl; forBlockVector fors = inheritedAttribute.getForScopes(); // replace variable occurrences in the loop kernel if(inheritedAttribute.getLoopKernel()) { for(size_t i=0;i<fors.size(); i++) { if( ( strcmp( astNode->unparseToString().c_str(), fors[i]->varName.c_str() )==0 ) && ( isSgVarRefExp(astNode)->get_type() == fors[i]->varType ) ) { string blockedVarName("blocked_"); blockedVarName += fors[i]->varName; AstRestructure::unparserReplace( isSgVarRefExp(astNode), blockedVarName ); cout << " replacing with '"<<blockedVarName<<"' " << endl; } } } } break; default: break; } // node type bool synth = false; for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin(); i!= synthesizedAttributeList.end(); i++ ) { if( (*i).getVarRefFound() ) synth = true; } if( synth ) { returnAttribute.setVarRefFound( true ); if(isSgStatement( astNode )) { cout << " new statement " << printPosition(astNode) << " : '" << astNode->unparseToString() << "' " << endl; returnAttribute.setVarRefFound( false ); //if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!? returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope ); //} } } if(isSgScopeStatement(astNode)) { // dont replace variable in higher scopes... if(mReplaceVariable > 0) { mReplaceVariable--; cerr << "end of scope " << mReplaceVariable << endl; } } //if(astNode == mpLoopBody) { // FIXME why doesnt replace basic block work? if( (astNode->get_parent() == mpLoopBody)&&(inheritedAttribute.getLoopKernel()) ) { // we're back at the loop kernel block, now replace and insert new loops... insertTransformedLoopBody( astNode, returnAttribute, inheritedAttribute.getForScopes() ); } return returnAttribute; }
// Functions required by the tree traversal mechanism MyInheritedAttribute MyTraversal::evaluateRewriteInheritedAttribute ( SgNode* astNode, MyInheritedAttribute inheritedAttribute ) { MyInheritedAttribute returnAttribute = inheritedAttribute; switch(astNode->variantT()) { case V_SgForStatement: { cout << " found V_SgForStatement " << printPosition(astNode) << "" << endl; SgForStatement *forStat = isSgForStatement(astNode); forBlockInfo *inf = new forBlockInfo; inf->forStmt = forStat; SgInitializedName *varin = isSgInitializedName( forStat->get_traversalSuccessorContainer()[0] //for init ->get_traversalSuccessorContainer()[0] // var decl ->get_traversalSuccessorContainer()[0] // initialized name ); assert( varin ); inf->varName = varin->get_name().str(); inf->varType = varin->get_type(); inf->blocked = false; inf->blockSize = 0; returnAttribute.addForStatement( inf ); mAllFors.push_back( inf ); list<SgNode*> forList = NodeQuery::querySubTree( astNode, forStatementNodeQuery ); if( (forList.size()==1) && // only the current loop? (returnAttribute.getForScopes().size()>1) ) { cerr << " it is the innermost for loop " << endl; mpLoopBody = forStat->get_loop_body(); } } break; default: break; } if(astNode == mpLoopBody) { bool loopsValid = true; // do some basic checks for validity forBlockVector fors = returnAttribute.getForScopes(); for(size_t i=0;i<fors.size(); i++) { SgExpression *testExpr = fors[i]->forStmt->get_test_expr(); SgExpression *incExpr = fors[i]->forStmt->get_increment_expr(); if(isSgPlusPlusOp(incExpr) ==NULL) loopsValid = false; if(isSgLessThanOp(testExpr) ==NULL) loopsValid = false; else { if(! isSgVarRefExp(isSgLessThanOp(testExpr)->get_lhs_operand()) ) loopsValid = false; } } // this is the basic block of the innermost loop // only do trafos, if more than two nested loop nests, and we found the inner one if(loopsValid) { returnAttribute.setLoopKernel( true ); } else { cout << " loop nest not valid, skipping transformation..." << endl; } } if(isSgScopeStatement(astNode)) { // dont replace variable in higher scopes... if(mReplaceVariable > 0) { mReplaceVariable++; cerr << "nested scope found, #" << mReplaceVariable << endl; } } return returnAttribute; }
void getSgScopeStatement(SgScopeStatement* scopeStat) { VariantT var = scopeStat->variantT(); std::string scopeStatStr = ""; switch (var) { case V_SgBasicBlock: { getSgBasicBlock(isSgBasicBlock(scopeStat)); break; } case V_SgCatchOptionStmt: { std::cout << "SgCatchOptionStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgDoWhileStmt: { std::cout << "SgDoWhileStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgForStatement: { // std::cout << "SgForStatement is not yet implemented" << std::endl; #ifdef FORLOOPONCETHROUGH forOnceThrough(isSgForStatement(scopeStat)); #else std::cout << "SgForStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); #endif break; } case V_SgGlobal: { std::cout << "SgGlobal is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgIfStmt: { getSgIfStmt(isSgIfStmt(scopeStat)); break; } case V_SgSwitchStatement: { std::cout << "SgSwitchStatement is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgWhileStmt: { std::cout << "SgWhileStmt is not yet implemented" << std::endl; ROSE_ASSERT(false); break; } case V_SgForAllStatement: { std::cout << "SgForAllStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgAssociateStatement: { std::cout << "SgAssociateStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgBlockDataStatement: { std::cout << "SgBlockDataStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgNamespaceDefinitionStatement: { std::cout << "SgNamespaceDefinitionStatement is not yet implemented" << std::endl; ; ROSE_ASSERT(false); break; } case V_SgClassDefinition: { std::cout << "SgClassDefinition should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgFunctionDefinition: { getSgFunctionDefinition(isSgFunctionDefinition(scopeStat)); break; } case V_SgCAFWithTeamStatement: { std::cout << "SgCAFWithTeamStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgFortranDo: { std::cout << "SgFortranDo should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgFortranNonblockedDo: { std::cout << "SgFortranNonblockedDo should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgJavaForEachStatement: { std::cout << "SgJavaForEachStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgJavaLabelStatement: { std::cout << "SgJavaLabelStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } case V_SgUpcForAllStatement: { std::cout << "SgUpcForAllStatement should not be found here! " << std::endl; ROSE_ASSERT(false); break; } default: { std::cout << " Unknown node type!: " << scopeStat->class_name() << std::endl; ROSE_ASSERT(false); } } return; }