//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()
/* * Add calls to register and unregister expressions/arrays with the memory * management wrapper. */ bool RegisterPointers::addRegUnregCalls() { string msg; if(definedInSystemHeader) { msg = "\t\t\tVariable " + NAME(varSymbol) + " is in system headers"; WARNING(TOOL, msg); return false; } if(compilerGenerated) { msg = "\t\t\tVariable " + NAME(varSymbol) + " is compiler-generated"; WARNING(TOOL, msg); return false; } if(addrUsedInIO) { msg = "\t\t\tVariable " + NAME(varSymbol) + " has its address taken in " + "a function known to not require registering/unregistering"; WARNING(TOOL, msg); return false; } //Add register/unregister calls SgStatement* prevStmt = NULL; SgExprStatement* funcCall = NULL; SgType* type = NULL; SgExpression* expr = NULL; if(isGlobal) { type = varName->get_type(); SgName name = varName->get_name(); int numVals = 1; if(isSgPointerType(type)) return false; //If its a pointer, it points to a static array, dynamic array, or scalar //which has its address taken (all of which have already been registered) SgFunctionDeclaration* main = findMain(getScope(varName)); ROSE_ASSERT(main); expr = buildVarRefExp(name, varName->get_scope()); if(isSgArrayType(type)) numVals = getArrayElementCount(isSgArrayType(type)); else expr = buildAddressOfOp(expr); funcCall = MMCallBuilder::buildRegisterPointerCall(expr, buildUnsignedIntVal(numVals), main->get_definition()); insertStatement(getFirstStatement(main->get_definition()), funcCall);//, false, true); funcCall = MMCallBuilder::buildUnregisterPointerCall(expr, main->get_definition()); instrumentEndOfFunction(main, funcCall); } else if(expression) //Address-of expressions { prevStmt = getEnclosingStatement(expression); funcCall = MMCallBuilder::buildRegisterPointerCall(expression, buildUnsignedIntVal(1), getScope(expression)); insertStatement(prevStmt, funcCall); funcCall = MMCallBuilder::buildUnregisterPointerCall(expression, getScope(expression)); instrumentEndOfFunction(getEnclosingFunctionDeclaration(prevStmt), funcCall); } else //Array types { SgVarRefExp* varRef = buildVarRefExp(varName, getScope(varName)); int numVals = getArrayElementCount(isSgArrayType(varName->get_type())); funcCall = MMCallBuilder::buildRegisterPointerCall(varRef, buildUnsignedIntVal(numVals), varName->get_scope()); insertStatement(varName->get_declaration(), funcCall, false, true); varRef = buildVarRefExp(varName, getScope(varName)); funcCall = MMCallBuilder::buildUnregisterPointerCall(varRef, varName->get_scope()); instrumentEndOfFunction(getEnclosingFunctionDeclaration(varName), funcCall); } return true; }