void RtedTransformation::insertVariableCreateInitForParams( SgFunctionDefinition& fndef) { SgBasicBlock* body = fndef.get_body(); ROSE_ASSERT( body); SgInitializedNamePtrList names = fndef.get_declaration()->get_parameterList()->get_args(); BOOST_FOREACH( SgInitializedName* param, names) { SgType* initType = param->get_type(); // nov2010 code: // reference variables don't allocate new memory // if we call createVariable the RTS will think it's a double // allocation fault // \pp we skip array types because they will be handled elsewhere // \todo not sure if this is correct here, b/c arrays would decay // to pointers anyway. However, this decay is not represented // in the nov2010 code, thus we skip these initializations // here. if ( isSgReferenceType(initType) || isSgArrayType(skip_ModifierType(initType)) ) continue; SgFunctionDeclaration* fndecl = fndef.get_declaration(); std::cerr << ">>> " << fndecl->get_name() << std::endl; ROSE_ASSERT(isSgFunctionDefinition(param->get_scope())); body->prepend_statement( buildVariableCreateCallStmt(param, true) ); }
void examineFunctionDeclaration(SgFunctionDeclaration* decl, ostream &out) { SgSymbol* symbol = decl->get_symbol_from_symbol_table(); SgFunctionDefinition* def = decl->get_definition(); ExprSynAttr *attr; stringstream fake; /* We don't want to output the function withou definition */ if (NULL == symbol || NULL == def) return; SgType *ret_type = decl->get_orig_return_type(); examineType(ret_type, out); out << " " << symbol->get_name().getString(); out << "("; SgInitializedNamePtrList& name_list = decl->get_args(); SgInitializedNamePtrList::const_iterator name_iter; for (name_iter = name_list.begin(); name_iter != name_list.end(); name_iter++) { if (name_iter != name_list.begin()) out << ", "; SgInitializedName* name = *name_iter; examineInitializedName(name, out); } out << ")"; out << endl; SgBasicBlock* body = def->get_body(); attr = examineScopeStatement(body,symbol->get_name().getString(), fake); out << attr->code.str(); delete attr; }
int main( int argc, char * argv[] ) { // Build the AST used by ROSE SgProject* project = frontend(argc,argv); generatePDF ( *project ); Rose_STL_Container<SgNode*> functions = NodeQuery::querySubTree(project, V_SgFunctionDefinition); for (Rose_STL_Container<SgNode*>::const_iterator i = functions.begin(); i != functions.end(); ++i) { SgFunctionDefinition* curFunc = isSgFunctionDefinition(*i); ROSE_ASSERT(curFunc); SgBasicBlock *funcBody = curFunc->get_body(); InterestingNode funcCFGStart = (InterestingNode)funcBody->cfgForBeginning();; // output the CFG to a file ofstream fileCFG; fileCFG.open((curFunc->get_declaration()->get_name().getString()+"_cfg.dot").c_str()); cout << "writing to file "<<(curFunc->get_declaration()->get_name().getString()+"_cfg.dot")<<"\n"; VirtualCFG::cfgToDot(fileCFG, curFunc->get_declaration()->get_name(), funcCFGStart); fileCFG.close(); } // Unparse and compile the project (so this can be used for testing) return backend(project); }
void Unparse_Jovial::unparseFuncDefnStmt(SgStatement* stmt, SgUnparse_Info& info) { SgFunctionDefinition* funcdef = isSgFunctionDefinition(stmt); ROSE_ASSERT(funcdef != NULL); curprint("BEGIN\n"); // unparse the body of the function if (funcdef->get_body()) { unparseStatement(funcdef->get_body(), info); } curprint("END\n"); }
int main ( int argc, char * argv[] ) { if (argc <= 1) { PrintUsage(argv[0]); return -1; } SgProject sageProject ( (int)argc,argv); SageInterface::changeAllBodiesToBlocks(&sageProject); CmdOptions::GetInstance()->SetOptions(argc, argv); int filenum = sageProject.numberOfFiles(); for (int i = 0; i < filenum; ++i) { SgSourceFile* sageFile = isSgSourceFile(sageProject.get_fileList()[i]); ROSE_ASSERT(sageFile != NULL); SgGlobal *root = sageFile->get_globalScope(); SgDeclarationStatementPtrList& declList = root->get_declarations (); for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) { SgFunctionDeclaration *func = isSgFunctionDeclaration(*p); if (func == 0) continue; SgFunctionDefinition *defn = func->get_definition(); if (defn == 0) continue; SgBasicBlock *stmts = defn->get_body(); AstInterfaceImpl scope(stmts); AstInterface fa(&scope); StmtVarAliasCollect alias; alias(fa, AstNodePtrImpl(defn)); if (GenerateDOT(argc, argv)) { string name = string(strrchr(sageFile->getFileName().c_str(),'/')+1) + ".dot"; TestDUWrap_DOT op(alias); op(fa, defn, name); } else { string name = string(strrchr(sageFile->getFileName().c_str(),'/')+1) + ".outx"; #if 0 // Test harness uses stdout now rather than a temporary file [Robb P. Matzke 2013-02-25] TestDUWrap_Text op(alias,name); #else TestDUWrap_Stdout op(alias); #endif op(fa, defn); } } } return 0; }
void Jovial_to_C::translateProgramHeaderStatement(SgProgramHeaderStatement* programHeaderStatement) { // Get scopeStatement from SgProgramHeaderStatement SgScopeStatement* scopeStatement = programHeaderStatement->get_scope(); ROSE_ASSERT(scopeStatement); // Get ParameterList and DecoratorList SgFunctionParameterList* functionParameterList = buildFunctionParameterList(); SgExprListExp* decoratorList = deepCopy(programHeaderStatement->get_decoratorList()); // Reuse FunctionDefinition from Fortran programHeaderStatement SgFunctionDefinition* functionDefinition = programHeaderStatement->get_definition(); // Get basicBlock from SgProgramHeaderStatement SgBasicBlock* basicBlock = functionDefinition->get_body(); ROSE_ASSERT(basicBlock); SgSymbolTable* symbolTable = basicBlock->get_symbol_table(); ROSE_ASSERT(symbolTable); // The main function return type is int SgType* mainType = SgTypeInt::createType(); // Remove original function symbol. Keep the new function symbol with name of "main" SgFunctionSymbol* functionSymbol = isSgFunctionSymbol(scopeStatement->lookup_symbol(programHeaderStatement->get_name())); SgSymbolTable* globalSymbolTable = isSgSymbolTable(functionSymbol->get_parent()); globalSymbolTable->remove(functionSymbol); functionSymbol->set_parent(NULL); delete(functionSymbol); // Create SgFunctionDeclaration for C main function. Name must be "main". SgFunctionDeclaration* cFunctionDeclaration = buildDefiningFunctionDeclaration("main", mainType, functionParameterList, scopeStatement); // Setup the C function declaration. removeList.push_back(cFunctionDeclaration->get_definition()); functionDefinition->set_parent(cFunctionDeclaration); cFunctionDeclaration->set_definition(functionDefinition); programHeaderStatement->set_definition(NULL); // Replace the SgProgramHeaderStatement with SgFunctionDeclaration. replaceStatement(programHeaderStatement,cFunctionDeclaration,true); cFunctionDeclaration->set_decoratorList(decoratorList); // cFunctionDeclaration->set_startOfConstruct(functionDefinition->get_startOfConstruct()); // cFunctionDeclaration->set_endOfConstruct(functionDefinition->get_endOfConstruct()); // cFunctionDeclaration->get_file_info()->set_physical_filename(cFunctionDeclaration->get_file_info()->get_filenameString()); programHeaderStatement->set_parent(NULL); } // End of Jovial_to_C::translateProgramHeaderStatement
void PreAndPostOrderTraversal::preOrderVisit(SgNode* n) { SgFunctionDeclaration * dec = isSgFunctionDeclaration(n); if (dec != NULL) { cout << "Found function declaration " << dec->get_name().getString(); Sg_File_Info * start = dec->get_startOfConstruct(); Sg_File_Info * end = dec->get_endOfConstruct(); if(start->isCompilerGenerated()) { cout << ", which is compiler-generated" << endl; } else { cout << " in file " << start->get_raw_filename() << ", " << start->get_file_id() << " from line " << start->get_line() << ", col " << start->get_col() << " to line " << end->get_line() << ", col " << end->get_col() << endl; } SgFunctionType * type = dec->get_type(); SgType * retType = type->get_return_type(); cout << "Return type: " << retType->unparseToString() << endl; SgFunctionParameterList * params = dec->get_parameterList(); SgInitializedNamePtrList & ptrList = params->get_args(); if(!ptrList.empty()) { cout << "Parameter types: "; for(SgInitializedNamePtrList::iterator j = ptrList.begin(); j != ptrList.end(); j++) { SgType * pType = (*j)->get_type(); cout << pType->unparseToString() << " "; } cout << endl; } cout << "Linkage: " << dec->get_linkage() << endl; cout << endl; } SgFunctionDefinition * def = isSgFunctionDefinition(n); if (def != NULL) { cout << "Found function definition " << def->get_declaration()->get_name().getString(); Sg_File_Info * start = def->get_startOfConstruct(); Sg_File_Info * end = def->get_endOfConstruct(); if(start->isCompilerGenerated()) { cout << ", which is compiler-generated" << endl; } else { cout << " in file " << start->get_raw_filename() << " from line " << start->get_line() << ", col " << start->get_col() << " to line " << end->get_line() << ", col " << end->get_col() << endl; SgBasicBlock * body = def->get_body(); Sg_File_Info * bodyStart = body->get_startOfConstruct(); Sg_File_Info * bodyEnd = body->get_endOfConstruct(); cout << "Function body from line " << bodyStart->get_line() << ", col " << bodyStart->get_col() << " to line " << bodyEnd->get_line() << ", col " << bodyEnd->get_col() << endl; } cout << endl; } }
/* * Main Function */ int main(int argc, char * argv[]) { // Build the AST used by ROSE SgProject* sageProject = frontend(argc, argv); // For each source file in the project SgFilePtrList & ptr_list = sageProject->get_fileList(); for (SgFilePtrList::iterator iter = ptr_list.begin(); iter != ptr_list.end(); iter++) { SgFile* sageFile = (*iter); SgSourceFile * sfile = isSgSourceFile(sageFile); ROSE_ASSERT(sfile); SgGlobal *root = sfile->get_globalScope(); SgDeclarationStatementPtrList& declList = root->get_declarations(); // Insert header file insertHeader(sfile); //For each function body in the scope for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) { SgFunctionDeclaration *func = isSgFunctionDeclaration(*p); if (func == 0) continue; SgFunctionDefinition *defn = func->get_definition(); if (defn == 0) continue; //ignore functions in system headers, Can keep them to test robustness if (defn->get_file_info()->get_filename() != sageFile->get_file_info()->get_filename()) continue; SgBasicBlock *body = defn->get_body(); ROSE_ASSERT(body); vector<SgForStatement*> loops = querySubTree<SgForStatement> (defn, V_SgForStatement); if (loops.size() == 0) continue; visitLoops(loops); } // Generate source code from AST and call the vendor's compiler return backend(sageProject); } }
ScopExtractor::ScopExtractor(SgProject* project, PolyRoseOptions& polyopts) { // this->project = project; this->polyoptions = polyopts; isVerbose = ! polyopts.getQuiet(); if (isVerbose) std::cout << "[PolyOpt] Using generic scop extractor" << std::endl; SgFilePtrList& file_list = project->get_fileList(); SgFilePtrList::const_iterator file_iter; // Iterate on all files of the project. for (file_iter = file_list.begin(); file_iter != file_list.end(); file_iter++) { SgSourceFile* file = isSgSourceFile(*file_iter); if (polyoptions.getScVerboseLevel()) cout << "[Extr] File: " << file->getFileName() << endl; SgNodePtrList funcDefnList = NodeQuery::querySubTree(file, V_SgFunctionDefinition); SgNodePtrList::const_iterator iter; // Iterate on all function defined in a file. for (iter = funcDefnList.begin(); iter != funcDefnList.end(); ++iter) { SgFunctionDefinition *fun = isSgFunctionDefinition(*iter); if (!fun) { cout << "[Extr] Warning: Expected SgFunctionDefinition in " << file->getFileName() << endl; continue; // with the next function definition } SgName name = fun->get_declaration()->get_name(); if (polyoptions.getScVerboseLevel()) cout << "[Extr] Function: " << name.getString() << endl; SgBasicBlock* body = fun->get_body(); // Ensure the function is a candidate (no (unsafe) function // calls). if (assertFunctionIsCandidate(project, body)) { // Proceed recursively, bottom up. inspectBottomUpFunctionBody(project, body); } } } if (isVerbose) std::cout << "[ScopExtraction] Generic: done" << std::endl; }
/** * Create scops for a sub-tree. * */ void ScopExtractor::extractScops(SgNode* root) { if (isVerbose) std::cout << "[PolyOpt] Using generic scop extractor" << std::endl; SgNodePtrList funcDefnList = NodeQuery::querySubTree(root, V_SgFunctionDefinition); SgNodePtrList::const_iterator iter; // Iterate on all functions defined in a sub-tree. for (iter = funcDefnList.begin(); iter != funcDefnList.end(); ++iter) { SgFunctionDefinition *fun = isSgFunctionDefinition(*iter); if (!fun) { cout << "[Extr] Warning: Expected SgFunctionDefinition" << endl; continue; // with the next function definition } SgName name = fun->get_declaration()->get_name(); if (polyoptions.getScVerboseLevel()) cout << "[Extr] Function: " << name.getString() << endl; SgBasicBlock* body = fun->get_body(); // Ensure the function is a candidate (no (unsafe) function // calls). if (assertFunctionIsCandidate(NULL, body)) { // Proceed recursively, bottom up. inspectBottomUpFunctionBody(NULL, body); } } // If no function is defined in the subtree, simply process it // as-is. if (funcDefnList.size() == 0) if (assertFunctionIsCandidate(NULL, root)) // Proceed recursively, bottom up. inspectBottomUpFunctionBody(NULL, root); if (isVerbose) std::cout << "[ScopExtraction] Generic: done" << std::endl; }
void visitorTraversal::visit(SgNode* n) { SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(n); if (functionDeclaration != NULL) { SgFunctionDefinition* functionDefinition = functionDeclaration->get_definition(); if (functionDefinition != NULL) { SgBasicBlock* functionBody = functionDefinition->get_body(); ROSE_ASSERT(functionBody != NULL); ControlFlowGraph controlflow; // The CFG can only be called on a function definition (at present) makeCfg(functionDefinition,controlflow); string fileName = functionDeclaration->get_name().str(); fileName += ".dot"; ofstream dotfile(fileName.c_str()); printCfgAsDot(dotfile, controlflow); } } }
int main ( int argc, char * argv[] ) { //init_poet(); // initialize poet if (argc <= 1) { PrintUsage(argv[0]); return -1; } #ifdef USE_OMEGA std::stringstream buffer; buffer << argv[argc-1] << std::endl; DepStats.SetFileName(buffer.str()); #endif vector<string> argvList(argv, argv + argc); CmdOptions::GetInstance()->SetOptions(argvList); ArrayAnnotation* array_annot = ArrayAnnotation::get_inst(); array_annot->register_annot(); //OperatorSideEffectAnnotation* funcAnnot=OperatorSideEffectAnnotation::get_inst(); //funcAnnot->register_annot(); LoopTransformInterface::set_sideEffectInfo(array_annot); ArrayInterface anal(*array_annot); LoopTransformInterface::set_arrayInfo(&anal); ReadAnnotation::get_inst()->read(); if (DebugAnnot()) { // funcAnnot->Dump(); array_annot->Dump(); } AssumeNoAlias aliasInfo; LoopTransformInterface::set_aliasInfo(&aliasInfo); LoopTransformInterface::cmdline_configure(argvList); SgProject *sageProject = new SgProject ( argvList); FixFileInfo(sageProject); // DQ (11/19/2013): Added AST consistency tests. AstTests::runAllTests(sageProject); int filenum = sageProject->numberOfFiles(); for (int i = 0; i < filenum; ++i) { // DQ (11/19/2013): Added AST consistency tests. AstTests::runAllTests(sageProject); SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); ROSE_ASSERT(sageFile != NULL); std::string fname = sageFile->get_file_info()->get_raw_filename(); fname=fname.substr(fname.find_last_of('/')+1); AutoTuningInterface tuning(fname); LoopTransformInterface::set_tuningInterface(&tuning); SgGlobal *root = sageFile->get_globalScope(); ROSE_ASSERT(root != NULL); SgDeclarationStatementPtrList declList = root->get_declarations (); // DQ (11/19/2013): Added AST consistency tests. AstTests::runAllTests(sageProject); for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) { SgFunctionDeclaration *func = isSgFunctionDeclaration(*p); if (func == 0) continue; SgFunctionDefinition *defn = func->get_definition(); if (defn == 0) continue; SgBasicBlock *stmts = defn->get_body(); AstInterfaceImpl scope(stmts); // DQ (11/19/2013): Added AST consistency tests. AstTests::runAllTests(sageProject); // DQ (11/19/2013): Added AST consistency tests. AstTests::runAllTests(sageProject); LoopTransformInterface::TransformTraverse(scope,AstNodePtrImpl(stmts)); #if 0 // DQ (11/19/2013): Added AST consistency tests (this fails). AstTests::runAllTests(sageProject); #endif } tuning.GenOutput(); #if 0 // DQ (11/19/2013): Added AST consistency tests (this fails). AstTests::runAllTests(sageProject); #endif } // if (CmdOptions::GetInstance()->HasOption("-fd")) { // simpleIndexFiniteDifferencing(sageProject); // } // if (CmdOptions::GetInstance()->HasOption("-pre")) { // partialRedundancyElimination(sageProject); // } #if 0 // DQ (11/19/2013): Added AST consistency tests (this fails). AstTests::runAllTests(sageProject); #endif unparseProject(sageProject); //backend(sageProject); #ifdef USE_OMEGA DepStats.SetDepChoice(0x1 | 0x2 | 0x4); DepStats.PrintResults(); #endif return 0; }
void RewriteFSM::visitSgFunctionDeclaration(SgFunctionDeclaration *FD) { SgFunctionDefinition *fdef = FD->get_definition(); if (!fdef) { return; } if (debugHooks) { std::cout << "Func decl: " << FD << " " << FD->get_name() << std::endl; } std::string modName = FD->get_name().getString(); HtdInfoAttribute *htd = getHtdInfoAttribute(fdef); bool isStreamingStencil = false; size_t pos = 0; if ((pos = modName.find(StencilStreamPrefix)) != std::string::npos && pos == 0) { isStreamingStencil = true; } #define hostEntryPrefix "__HTC_HOST_ENTRY_" bool isHostEntry = false; if ((pos = modName.find(hostEntryPrefix)) != std::string::npos && pos == 0) { isHostEntry = true; } // Emit a default, unnamed thread group. std::string modWidth = boost::to_upper_copy(modName) + "_HTID_W"; if (isStreamingStencil) { // The streaming version of a stencil must have width 0. htd->appendDefine(modWidth, "0"); } else if (isHostEntry) { htd->appendDefine(modWidth, "1"); } else if (htd->moduleWidth != -1) { htd->appendDefine(modWidth, boost::lexical_cast<std::string>(htd->moduleWidth)); } else { DefaultModuleWidthAttribute *dwAttr = getDefaultModuleWidthAttribute(SageInterface::getGlobalScope(fdef)); if (dwAttr) { htd->appendDefine(modWidth, boost::lexical_cast<std::string>(dwAttr->width)); } else { htd->appendDefine(modWidth, "5"); } } htd->appendModule(modName, "", modWidth); // For streaming stencils, ProcessStencils inserts a canned sequence, // so we bypass generating a normal FSM. if (isStreamingStencil) { return; } // // Create new case body blocks for each state. // The first executable statement starts the first state, and each // label starts a new state. // std::map<SgLabelStatement *, int> labelToState; std::map<int, std::string> stateToName; SgBasicBlock *funcBody = isSgBasicBlock(fdef->get_body()); SgStatementPtrList &stmts = funcBody->get_statements(); std::vector<SgStatement *>::iterator SI, SP; for (SI = stmts.begin(); SI != stmts.end(); ++SI) { if (!isSgDeclarationStatement(*SI)) { break; } } if (SI == stmts.end()) { return; } SP = SI; std::vector<SgBasicBlock *> newBlocks; SgBasicBlock *newbb = SageBuilder::buildBasicBlock(); newBlocks.push_back(newbb); stateToName[1] = "__START"; bool prevIsLabel = false; for (; SI != stmts.end(); ++SI) { SgStatement *stmt = *SI; SgLabelStatement *labstmt = isSgLabelStatement(stmt); if (labstmt) { if (!prevIsLabel) { newbb = SageBuilder::buildBasicBlock(); newBlocks.push_back(newbb); } int snum = newBlocks.size(); labelToState[labstmt] = snum; stateToName[snum] += "__" + labstmt->get_label().getString(); prevIsLabel = true; #if 1 // TODO: these labels can carry preproc infos-- but the unparser // doesn't output them if the label is not actually output. AttachedPreprocessingInfoType *comments = labstmt->getAttachedPreprocessingInfo(); if (comments && comments->size() > 0) { std::cerr << "DEVWARN: losing Preprocinfo on label" << std::endl; SageInterface::dumpPreprocInfo(labstmt); } #endif stmt->unsetOutputInCodeGeneration(); SageInterface::appendStatement(stmt, newbb); } else { prevIsLabel = false; SageInterface::appendStatement(stmt, newbb); } } stmts.erase(SP, stmts.end()); // Add module name to each state name and create enum decl. SgEnumDeclaration *enumDecl = SageBuilder::buildEnumDeclaration("states", fdef); for (int i = 1; i <= newBlocks.size(); i++) { stateToName[i] = modName + stateToName[i]; boost::to_upper(stateToName[i]); SgName nm(stateToName[i]); SgInitializedName *enumerator = SageBuilder::buildInitializedName(nm, SageBuilder::buildIntType(), SageBuilder::buildAssignInitializer(SageBuilder::buildIntVal(i))); enumerator->set_scope(funcBody); enumDecl->append_enumerator(enumerator); // Add the instruction to the htd info. htd->appendInst(nm.getString()); } SageInterface::prependStatement(enumDecl, funcBody); if (!debugHooks) { enumDecl->unsetOutputInCodeGeneration(); } SgGlobal *GS = SageInterface::getGlobalScope(FD); SgVariableDeclaration *declHtValid = HtDeclMgr::buildHtlVarDecl("PR_htValid", GS); SgVariableDeclaration *declHtInst = HtDeclMgr::buildHtlVarDecl("PR_htInst", GS); SgFunctionDeclaration *declHtContinue = HtDeclMgr::buildHtlFuncDecl("HtContinue", GS); SgFunctionDeclaration *declHtAssert = HtDeclMgr::buildHtlFuncDecl("HtAssert", GS); // // Create the finite state machine switch statement "switch (PR_htInst)", // and insert guard "if (PR_htValid)". // SgBasicBlock *newSwitchBody = SageBuilder::buildBasicBlock(); SgExpression *htInstExpr = SageBuilder::buildVarRefExp(declHtInst); SgSwitchStatement *newSwitch = SageBuilder::buildSwitchStatement(htInstExpr, newSwitchBody); SgExpression *htValidExpr = SageBuilder::buildVarRefExp(declHtValid); SgIfStmt *newIfStmt = SageBuilder::buildIfStmt(htValidExpr, SageBuilder::buildBasicBlock(newSwitch), 0); SageInterface::appendStatement(newIfStmt, funcBody); int casenum = 1; foreach (SgBasicBlock *newCaseBody, newBlocks) { SgExpression *caseExpr = SageBuilder::buildEnumVal_nfi(casenum, enumDecl, stateToName[casenum]); SgCaseOptionStmt *newCase = SageBuilder::buildCaseOptionStmt(caseExpr, newCaseBody); SageInterface::appendStatement(newCase, newSwitchBody); casenum++; }
// Main inliner code. Accepts a function call as a parameter, and inlines // only that single function call. Returns true if it succeeded, and false // otherwise. The function call must be to a named function, static member // function, or non-virtual non-static member function, and the function // must be known (not through a function pointer or member function // pointer). Also, the body of the function must already be visible. // Recursive procedures are handled properly (when allowRecursion is set), by // inlining one copy of the procedure into itself. Any other restrictions on // what can be inlined are bugs in the inliner code. bool doInline(SgFunctionCallExp* funcall, bool allowRecursion) { #if 0 // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag. ROSE_ASSERT(funcall != NULL); ROSE_ASSERT(funcall->get_parent() != NULL); SgGlobal* globalScope = TransformationSupport::getGlobalScope(funcall); ROSE_ASSERT(globalScope != NULL); // checkTransformedFlagsVisitor(funcall->get_parent()); checkTransformedFlagsVisitor(globalScope); #endif SgExpression* funname = funcall->get_function(); SgExpression* funname2 = isSgFunctionRefExp(funname); SgDotExp* dotexp = isSgDotExp(funname); SgArrowExp* arrowexp = isSgArrowExp(funname); SgExpression* thisptr = 0; if (dotexp || arrowexp) { funname2 = isSgBinaryOp(funname)->get_rhs_operand(); if (dotexp) { SgExpression* lhs = dotexp->get_lhs_operand(); // FIXME -- patch this into p_lvalue bool is_lvalue = lhs->get_lvalue(); if (isSgInitializer(lhs)) is_lvalue = false; if (!is_lvalue) { SgAssignInitializer* ai = SageInterface::splitExpression(lhs); ROSE_ASSERT (isSgInitializer(ai->get_operand())); #if 1 printf ("ai = %p ai->isTransformation() = %s \n",ai,ai->isTransformation() ? "true" : "false"); #endif SgInitializedName* in = isSgInitializedName(ai->get_parent()); ROSE_ASSERT (in); removeRedundantCopyInConstruction(in); lhs = dotexp->get_lhs_operand(); // Should be a var ref now } thisptr = new SgAddressOfOp(SgNULL_FILE, lhs); } else if (arrowexp) { thisptr = arrowexp->get_lhs_operand(); } else { assert (false); } } if (!funname2) { // std::cout << "Inline failed: not a call to a named function" << std::endl; return false; // Probably a call through a fun ptr } SgFunctionSymbol* funsym = 0; if (isSgFunctionRefExp(funname2)) funsym = isSgFunctionRefExp(funname2)->get_symbol(); else if (isSgMemberFunctionRefExp(funname2)) funsym = isSgMemberFunctionRefExp(funname2)->get_symbol(); else assert (false); assert (funsym); if (isSgMemberFunctionSymbol(funsym) && isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual()) { // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl; return false; } SgFunctionDeclaration* fundecl = funsym->get_declaration(); fundecl = fundecl ? isSgFunctionDeclaration(fundecl->get_definingDeclaration()) : NULL; SgFunctionDefinition* fundef = fundecl ? fundecl->get_definition() : NULL; if (!fundef) { // std::cout << "Inline failed: no definition is visible" << std::endl; return false; // No definition of the function is visible } if (!allowRecursion) { SgNode* my_fundef = funcall; while (my_fundef && !isSgFunctionDefinition(my_fundef)) { // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str()); my_fundef = my_fundef->get_parent(); ROSE_ASSERT(my_fundef != NULL); // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str()); } // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str()); assert (isSgFunctionDefinition(my_fundef)); if (isSgFunctionDefinition(my_fundef) == fundef) { std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl; return false; } } SgVariableDeclaration* thisdecl = 0; SgName thisname("this__"); thisname << ++gensym_counter; SgInitializedName* thisinitname = 0; if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic()) { assert (thisptr != NULL); SgType* thisptrtype = thisptr->get_type(); const SgSpecialFunctionModifier& specialMod = funsym->get_declaration()->get_specialFunctionModifier(); if (specialMod.isConstructor()) { SgFunctionType* ft = funsym->get_declaration()->get_type(); ROSE_ASSERT (ft); SgMemberFunctionType* mft = isSgMemberFunctionType(ft); ROSE_ASSERT (mft); SgType* ct = mft->get_class_type(); thisptrtype = new SgPointerType(ct); } SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier(); // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME thisptrtype = new SgModifierType(thisptrtype); isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv; // } // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl; SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr); assignInitializer->set_endOfConstruct(SgNULL_FILE); #if 1 printf ("before new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false"); #endif thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer); #if 1 printf ("(after new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false"); #endif thisdecl->set_endOfConstruct(SgNULL_FILE); thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE); thisdecl->set_definingDeclaration(thisdecl); thisinitname = (thisdecl->get_variables()).back(); //thisinitname = lastElementOfContainer(thisdecl->get_variables()); // thisinitname->set_endOfConstruct(SgNULL_FILE); assignInitializer->set_parent(thisinitname); markAsTransformation(assignInitializer); // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl); // DQ (6/23/2006): New test ROSE_ASSERT(assignInitializer->get_parent() != NULL); } // Get the list of actual argument expressions from the function call, which we'll later use to initialize new local // variables in the inlined code. We need to detach the actual arguments from the AST here since we'll be reattaching // them below (otherwise we would violate the invariant that the AST is a tree). SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall); SgExpressionPtrList funargs = funcall->get_args()->get_expressions(); funcall->get_args()->get_expressions().clear(); BOOST_FOREACH (SgExpression *actual, funargs) actual->set_parent(NULL); // Make a copy of the to-be-inlined function so we're not modifying and (re)inserting the original. SgBasicBlock* funbody_raw = fundef->get_body(); SgInitializedNamePtrList& params = fundecl->get_args(); std::vector<SgInitializedName*> inits; SgTreeCopy tc; SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc)); ROSE_ASSERT (function_copy); SgBasicBlock* funbody_copy = function_copy->get_body(); renameLabels(funbody_copy, targetFunction); ASSERT_require(funbody_raw->get_symbol_table()->size() == funbody_copy->get_symbol_table()->size()); // We don't need to keep the copied SgFunctionDefinition now that the labels in it have been moved to the target function // (having it in the memory pool confuses the AST tests), but we must not delete the formal argument list or the body // because we need them below. if (function_copy->get_declaration()) { ASSERT_require(function_copy->get_declaration()->get_parent() == function_copy); function_copy->get_declaration()->set_parent(NULL); function_copy->set_declaration(NULL); } if (function_copy->get_body()) { ASSERT_require(function_copy->get_body()->get_parent() == function_copy); function_copy->get_body()->set_parent(NULL); function_copy->set_body(NULL); } delete function_copy; function_copy = NULL; #if 0 SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE); SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin); pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE); pragmaBegin->set_parent(pragmaBeginDecl); pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl); funbody_copy->prepend_statement(pragmaBeginDecl); pragmaBeginDecl->set_parent(funbody_copy); #endif // In the to-be-inserted function body, create new local variables with distinct non-conflicting names, one per formal // argument and having the same type as the formal argument. Initialize those new local variables with the actual // arguments. Also, build a paramMap that maps each formal argument (SgInitializedName) to its corresponding new local // variable (SgVariableSymbol). ReplaceParameterUseVisitor::paramMapType paramMap; SgInitializedNamePtrList::iterator formalIter = params.begin(); SgExpressionPtrList::iterator actualIter = funargs.begin(); for (size_t argNumber=0; formalIter != params.end() && actualIter != funargs.end(); ++argNumber, ++formalIter, ++actualIter) { SgInitializedName *formalArg = *formalIter; SgExpression *actualArg = *actualIter; // Build the new local variable. // FIXME[Robb P. Matzke 2014-12-12]: we need a better way to generate a non-conflicting local variable name SgAssignInitializer* initializer = new SgAssignInitializer(SgNULL_FILE, actualArg, formalArg->get_type()); ASSERT_not_null(initializer); initializer->set_endOfConstruct(SgNULL_FILE); #if 1 printf ("initializer = %p initializer->isTransformation() = %s \n",initializer,initializer->isTransformation() ? "true" : "false"); #endif SgName shadow_name(formalArg->get_name()); shadow_name << "__" << ++gensym_counter; SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE, shadow_name, formalArg->get_type(), initializer); vardecl->set_definingDeclaration(vardecl); vardecl->set_endOfConstruct(SgNULL_FILE); vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE); vardecl->set_parent(funbody_copy); // Insert the new local variable into the (near) beginning of the to-be-inserted function body. We insert them in the // order their corresponding actuals/formals appear, although the C++ standard does not require this order of // evaluation. SgInitializedName* init = vardecl->get_variables().back(); inits.push_back(init); initializer->set_parent(init); init->set_scope(funbody_copy); funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + argNumber, vardecl); SgVariableSymbol* sym = new SgVariableSymbol(init); paramMap[formalArg] = sym; funbody_copy->insert_symbol(shadow_name, sym); sym->set_parent(funbody_copy->get_symbol_table()); } // Similarly for "this". We create a local variable in the to-be-inserted function body that will be initialized with the // caller's "this". if (thisdecl) { thisdecl->set_parent(funbody_copy); thisinitname->set_scope(funbody_copy); funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl); SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname); funbody_copy->insert_symbol(thisname, thisSym); thisSym->set_parent(funbody_copy->get_symbol_table()); ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder); } ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder); SgName end_of_inline_name = "rose_inline_end__"; end_of_inline_name << ++gensym_counter; SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name); end_of_inline_label->set_endOfConstruct(SgNULL_FILE); #if 0 printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n"); // Need to set the parent of funbody_copy to avoid error. funbody_copy->set_parent(funbody_raw->get_parent()); printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy); printf ("funbody_raw->get_statements().size() = %" PRIuPTR " \n",funbody_raw->get_statements().size()); printf ("funbody_copy->get_statements().size() = %" PRIuPTR " \n",funbody_copy->get_statements().size()); printf ("funbody_raw->get_symbol_table()->size() = %d \n",(int)funbody_raw->get_symbol_table()->size()); printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size()); printf ("Output the symbol table for funbody_raw \n"); funbody_raw->get_symbol_table()->print("debugging copy problem"); // printf ("Output the symbol table for funbody_copy \n"); // funbody_copy->get_symbol_table()->print("debugging copy problem"); SgProject* project_copy = TransformationSupport::getProject(funbody_raw); ROSE_ASSERT(project_copy != NULL); const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000; generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH); #endif funbody_copy->append_statement(end_of_inline_label); end_of_inline_label->set_scope(targetFunction); SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label); end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table()); targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym); // To ensure that there is some statement after the label SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression()); dummyStatement->set_endOfConstruct(SgNULL_FILE); funbody_copy->append_statement(dummyStatement); dummyStatement->set_parent(funbody_copy); #if 0 SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE); SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd); pragmaEndDecl->set_endOfConstruct(SgNULL_FILE); pragmaEnd->set_parent(pragmaEndDecl); pragmaEndDecl->set_definingDeclaration(pragmaEndDecl); funbody_copy->append_statement(pragmaEndDecl); pragmaEndDecl->set_parent(funbody_copy); #endif ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy); replaceExpressionWithStatement(funcall, &previsitor); // Make sure the AST is consistent. To save time, we'll just fix things that we know can go wrong. For instance, the // SgAsmExpression.p_lvalue data member is required to be true for certain operators and is set to false in other // situations. Since we've introduced new expressions into the AST we need to adjust their p_lvalue according to the // operators where they were inserted. markLhsValues(targetFunction); #ifdef NDEBUG AstTests::runAllTests(SageInterface::getProject()); #endif #if 0 // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag. ROSE_ASSERT(funcall != NULL); ROSE_ASSERT(funcall->get_parent() != NULL); ROSE_ASSERT(globalScope != NULL); // checkTransformedFlagsVisitor(funcall->get_parent()); checkTransformedFlagsVisitor(globalScope); #endif // DQ (4/7/2015): This fixes something I was required to fix over the weekend and which is fixed more directly, I think. // Mark the things we insert as being transformations so they get inserted into the output by backend() markAsTransformation(funbody_copy); return true; }
// Main inliner code. Accepts a function call as a parameter, and inlines // only that single function call. Returns true if it succeeded, and false // otherwise. The function call must be to a named function, static member // function, or non-virtual non-static member function, and the function // must be known (not through a function pointer or member function // pointer). Also, the body of the function must already be visible. // Recursive procedures are handled properly (when allowRecursion is set), by // inlining one copy of the procedure into itself. Any other restrictions on // what can be inlined are bugs in the inliner code. bool doInline(SgFunctionCallExp* funcall, bool allowRecursion) { SgExpression* funname = funcall->get_function(); SgExpression* funname2 = isSgFunctionRefExp(funname); SgDotExp* dotexp = isSgDotExp(funname); SgArrowExp* arrowexp = isSgArrowExp(funname); SgExpression* thisptr = 0; if (dotexp || arrowexp) { funname2 = isSgBinaryOp(funname)->get_rhs_operand(); if (dotexp) { SgExpression* lhs = dotexp->get_lhs_operand(); // FIXME -- patch this into p_lvalue bool is_lvalue = lhs->get_lvalue(); if (isSgInitializer(lhs)) is_lvalue = false; if (!is_lvalue) { SgAssignInitializer* ai = SageInterface::splitExpression(lhs); ROSE_ASSERT (isSgInitializer(ai->get_operand())); SgInitializedName* in = isSgInitializedName(ai->get_parent()); ROSE_ASSERT (in); removeRedundantCopyInConstruction(in); lhs = dotexp->get_lhs_operand(); // Should be a var ref now } thisptr = new SgAddressOfOp(SgNULL_FILE, lhs); } else if (arrowexp) { thisptr = arrowexp->get_lhs_operand(); } else { assert (false); } } if (!funname2) { // std::cout << "Inline failed: not a call to a named function" << std::endl; return false; // Probably a call through a fun ptr } SgFunctionSymbol* funsym = 0; if (isSgFunctionRefExp(funname2)) funsym = isSgFunctionRefExp(funname2)->get_symbol(); else if (isSgMemberFunctionRefExp(funname2)) funsym = isSgMemberFunctionRefExp(funname2)->get_symbol(); else assert (false); assert (funsym); if (isSgMemberFunctionSymbol(funsym) && isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual()) { // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl; return false; } SgFunctionDeclaration* fundecl = funsym->get_declaration(); SgFunctionDefinition* fundef = fundecl->get_definition(); if (!fundef) { // std::cout << "Inline failed: no definition is visible" << std::endl; return false; // No definition of the function is visible } if (!allowRecursion) { SgNode* my_fundef = funcall; while (my_fundef && !isSgFunctionDefinition(my_fundef)) { // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str()); my_fundef = my_fundef->get_parent(); ROSE_ASSERT(my_fundef != NULL); // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str()); } // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str()); assert (isSgFunctionDefinition(my_fundef)); if (isSgFunctionDefinition(my_fundef) == fundef) { std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl; return false; } } SgVariableDeclaration* thisdecl = 0; SgName thisname("this__"); thisname << ++gensym_counter; SgInitializedName* thisinitname = 0; if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic()) { assert (thisptr != NULL); SgType* thisptrtype = thisptr->get_type(); const SgSpecialFunctionModifier& specialMod = funsym->get_declaration()->get_specialFunctionModifier(); if (specialMod.isConstructor()) { SgFunctionType* ft = funsym->get_declaration()->get_type(); ROSE_ASSERT (ft); SgMemberFunctionType* mft = isSgMemberFunctionType(ft); ROSE_ASSERT (mft); SgType* ct = mft->get_class_type(); thisptrtype = new SgPointerType(ct); } SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier(); // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME thisptrtype = new SgModifierType(thisptrtype); isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv; // } // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl; SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr); assignInitializer->set_endOfConstruct(SgNULL_FILE); // thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, new SgAssignInitializer(SgNULL_FILE, thisptr)); thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer); thisdecl->set_endOfConstruct(SgNULL_FILE); thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE); thisdecl->set_definingDeclaration(thisdecl); thisinitname = (thisdecl->get_variables()).back(); //thisinitname = lastElementOfContainer(thisdecl->get_variables()); // thisinitname->set_endOfConstruct(SgNULL_FILE); assignInitializer->set_parent(thisinitname); // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl); // DQ (6/23/2006): New test ROSE_ASSERT(assignInitializer->get_parent() != NULL); } std::cout << "Trying to inline function " << fundecl->get_name().str() << std::endl; SgBasicBlock* funbody_raw = fundef->get_body(); SgInitializedNamePtrList& params = fundecl->get_args(); SgInitializedNamePtrList::iterator i; SgExpressionPtrList& funargs = funcall->get_args()->get_expressions(); SgExpressionPtrList::iterator j; //int ctr; // unused variable, Liao std::vector<SgInitializedName*> inits; SgTreeCopy tc; SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc)); ROSE_ASSERT (function_copy); SgBasicBlock* funbody_copy = function_copy->get_body(); SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall); renameLabels(funbody_copy, targetFunction); std::cout << "Original symbol count: " << funbody_raw->get_symbol_table()->size() << std::endl; std::cout << "Copied symbol count: " << funbody_copy->get_symbol_table()->size() << std::endl; // std::cout << "Original symbol count f: " << fundef->get_symbol_table()->size() << std::endl; // std::cout << "Copied symbol count f: " << function_copy->get_symbol_table()->size() << std::endl; // We don't need to keep the copied function definition now that the // labels in it have been moved to the target function. Having it in the // memory pool confuses the AST tests. function_copy->set_declaration(NULL); function_copy->set_body(NULL); delete function_copy; function_copy = NULL; #if 0 SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE); SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin); pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE); pragmaBegin->set_parent(pragmaBeginDecl); pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl); funbody_copy->prepend_statement(pragmaBeginDecl); pragmaBeginDecl->set_parent(funbody_copy); #endif ReplaceParameterUseVisitor::paramMapType paramMap; for (i = params.begin(), j = funargs.begin(); i != params.end() && j != funargs.end(); ++i, ++j) { SgAssignInitializer* ai = new SgAssignInitializer(SgNULL_FILE, *j, (*i)->get_type()); ROSE_ASSERT(ai != NULL); ai->set_endOfConstruct(SgNULL_FILE); SgName shadow_name((*i)->get_name()); shadow_name << "__" << ++gensym_counter; SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE,shadow_name,(*i)->get_type(),ai); vardecl->set_definingDeclaration(vardecl); vardecl->set_endOfConstruct(SgNULL_FILE); vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE); printf ("Built new SgVariableDeclaration #2 = %p = %s initializer = %p \n",vardecl,shadow_name.str(),(*(vardecl->get_variables().begin()))->get_initializer()); vardecl->set_parent(funbody_copy); SgInitializedName* init = (vardecl->get_variables()).back(); // init->set_endOfConstruct(SgNULL_FILE); inits.push_back(init); ai->set_parent(init); init->set_scope(funbody_copy); funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + (i - params.begin()), vardecl); SgVariableSymbol* sym = new SgVariableSymbol(init); paramMap[*i] = sym; funbody_copy->insert_symbol(shadow_name, sym); sym->set_parent(funbody_copy->get_symbol_table()); } if (thisdecl) { thisdecl->set_parent(funbody_copy); thisinitname->set_scope(funbody_copy); funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl); SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname); funbody_copy->insert_symbol(thisname, thisSym); thisSym->set_parent(funbody_copy->get_symbol_table()); ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder); } ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder); SgName end_of_inline_name = "rose_inline_end__"; end_of_inline_name << ++gensym_counter; SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name); end_of_inline_label->set_endOfConstruct(SgNULL_FILE); #if 0 printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n"); // Need to set the parent of funbody_copy to avoid error. funbody_copy->set_parent(funbody_raw->get_parent()); printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy); printf ("funbody_raw->get_statements().size() = %zu \n",funbody_raw->get_statements().size()); printf ("funbody_copy->get_statements().size() = %zu \n",funbody_copy->get_statements().size()); printf ("funbody_raw->get_symbol_table()->size() = %d \n",(int)funbody_raw->get_symbol_table()->size()); printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size()); printf ("Output the symbol table for funbody_raw \n"); funbody_raw->get_symbol_table()->print("debugging copy problem"); // printf ("Output the symbol table for funbody_copy \n"); // funbody_copy->get_symbol_table()->print("debugging copy problem"); SgProject* project_copy = TransformationSupport::getProject(funbody_raw); ROSE_ASSERT(project_copy != NULL); const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000; generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH); #endif // printf ("Exiting as a test after testing the symbol table \n"); // ROSE_ASSERT(false); funbody_copy->append_statement(end_of_inline_label); end_of_inline_label->set_scope(targetFunction); SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label); end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table()); targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym); // To ensure that there is some statement after the label SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression()); dummyStatement->set_endOfConstruct(SgNULL_FILE); funbody_copy->append_statement(dummyStatement); dummyStatement->set_parent(funbody_copy); #if 0 SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE); SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd); pragmaEndDecl->set_endOfConstruct(SgNULL_FILE); pragmaEnd->set_parent(pragmaEndDecl); pragmaEndDecl->set_definingDeclaration(pragmaEndDecl); funbody_copy->append_statement(pragmaEndDecl); pragmaEndDecl->set_parent(funbody_copy); #endif // std::cout << "funbody_copy is " << funbody_copy->unparseToString() << std::endl; ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy); // std::cout << "funbody_copy 2 is " << funbody_copy->unparseToString() << std::endl; replaceExpressionWithStatement(funcall, &previsitor); // std::cout << "Inline succeeded " << funcall->get_parent()->unparseToString() << std::endl; return true; }
void InsertFortranContainsStatement::visit ( SgNode* node ) { // DQ (10/3/2008): This bug in OFP is now fixed so no fixup is required. printf ("Error: fixup of contains statement no longer required. \n"); ROSE_ASSERT(false); // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST. ROSE_ASSERT(node != NULL); #if 0 Sg_File_Info* fileInfo = node->get_file_info(); printf ("node = %s fileInfo = %p \n",node->class_name().c_str(),fileInfo); if (fileInfo != NULL) { bool isCompilerGenerated = fileInfo->isCompilerGenerated(); std::string filename = fileInfo->get_filenameString(); int line_number = fileInfo->get_line(); int column_number = fileInfo->get_line(); printf ("--- isCompilerGenerated = %s position = %d:%d filename = %s \n",isCompilerGenerated ? "true" : "false",line_number,column_number,filename.c_str()); } #endif SgFunctionDefinition* functionDefinition = isSgFunctionDefinition(node); // This is for handling where CONTAINS is required in a function if (functionDefinition != NULL) { SgBasicBlock* block = functionDefinition->get_body(); SgStatementPtrList & statementList = block->get_statements(); SgStatementPtrList::iterator i = statementList.begin(); bool firstFunctionDeclaration = false; bool functionDeclarationSeen = false; while (i != statementList.end() && firstFunctionDeclaration == false) { SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); // DQ (1/20/2008): Note that entry statements should not cause introduction of a contains statement! if (isSgEntryStatement(functionDeclaration) != NULL) functionDeclaration = NULL; if (functionDeclaration != NULL) { firstFunctionDeclaration = functionDeclarationSeen == false; functionDeclarationSeen = true; if (firstFunctionDeclaration == true) { // Insert a CONTAINS statement. // printf ("Building a contains statement (in function) \n"); SgContainsStatement* containsStatement = new SgContainsStatement(); SageInterface::setSourcePosition(containsStatement); containsStatement->set_definingDeclaration(containsStatement); block->get_statements().insert(i,containsStatement); containsStatement->set_parent(block); ROSE_ASSERT(containsStatement->get_parent() != NULL); } } i++; } } #if 0 // OFP now has better support for the CONTAINS statement so this code is not longer required. // The use of CONTAINS in modules appears to be handled by OFP, so no fixup is required. SgClassDefinition* classDefinition = isSgClassDefinition(node); // This is for handling where CONTAINS is required in a module if (classDefinition != NULL) { SgDeclarationStatementPtrList & statementList = classDefinition->get_members(); SgDeclarationStatementPtrList::iterator i = statementList.begin(); bool firstFunctionDeclaration = false; bool functionDeclarationSeen = false; while (i != statementList.end() && firstFunctionDeclaration == false) { printf ("InsertFortranContainsStatement: *i in statementList in module = %p = %s \n",*i,(*i)->class_name().c_str()); SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); if (functionDeclaration != NULL) { firstFunctionDeclaration = functionDeclarationSeen == false; functionDeclarationSeen = true; if (firstFunctionDeclaration == true) { // Insert a CONTAINS statement. // printf ("Building a contains statement (in module) \n"); SgContainsStatement* containsStatement = new SgContainsStatement(); SageInterface::setSourcePosition(containsStatement); containsStatement->set_definingDeclaration(containsStatement); // This insert function does not set the parent (unlike for SgBasicBlock) classDefinition->get_members().insert(i,containsStatement); containsStatement->set_parent(classDefinition); ROSE_ASSERT(containsStatement->get_parent() != NULL); } } i++; } } #endif }
void CudaOutliner::functionParameterHandling(ASTtools::VarSymSet_t& syms, // regular (shared) parameters MintHostSymToDevInitMap_t hostToDevVars, const ASTtools::VarSymSet_t& pdSyms, // those must use pointer dereference const ASTtools::VarSymSet_t& pSyms, // private variables, handles dead variables (neither livein nor liveout) std::set<SgInitializedName*> & readOnlyVars, std::set<SgInitializedName*> & liveOutVars, SgFunctionDeclaration* func) // the outlined function { //ASTtools::VarSymSet_t syms; //std::copy(syms1.begin(), syms1.end(), std::inserter(syms,syms.begin())); VarSymRemap_t sym_remap; // variable remapping for regular(shared) variables VarSymRemap_t private_remap; // variable remapping for private/firstprivate/reduction variables ROSE_ASSERT (func); SgFunctionParameterList* params = func->get_parameterList (); ROSE_ASSERT (params); SgFunctionDefinition* def = func->get_definition (); ROSE_ASSERT (def); SgBasicBlock* body = def->get_body (); ROSE_ASSERT (body); // Place in which to put new outlined variable symbols. SgScopeStatement* args_scope = isSgScopeStatement (body); ROSE_ASSERT (args_scope); // For each variable symbol, create an equivalent function parameter. // Also create unpacking and repacking statements. int counter=0; // SgInitializedName* parameter1=NULL; // the wrapper parameter SgVariableDeclaration* local_var_decl = NULL; // handle OpenMP private variables/ or those which are neither live-in or live-out handlePrivateVariables(pSyms, body, private_remap); // -------------------------------------------------- // for each parameters passed to the outlined function // They include parameters for regular shared variables and // also the shared copies for firstprivate and reduction variables for (ASTtools::VarSymSet_t::reverse_iterator i = syms.rbegin ();i != syms.rend (); ++i) { // Basic information about the variable to be passed into the outlined function // Variable symbol name const SgInitializedName* i_name = (*i)->get_declaration (); ROSE_ASSERT (i_name); string name_str = i_name->get_name ().str (); SgName p_sg_name ( name_str); //SgType* i_type = i_name->get_type (); bool readOnly = false; if (readOnlyVars.find(const_cast<SgInitializedName*> (i_name)) != readOnlyVars.end()) readOnly = true; // step 1. Create parameters and insert it into the parameter list. // ---------------------------------------- SgInitializedName* p_init_name = NULL; SgVariableSymbol* host_sym= const_cast<SgVariableSymbol*> (*i); if(hostToDevVars.find(host_sym) != hostToDevVars.end() ){ //these are vector variables SgInitializedName* dev_name = hostToDevVars[host_sym]; p_init_name = createInitName (dev_name->get_name(), dev_name->get_type(), func, def); ROSE_ASSERT (p_init_name); prependArg(func->get_parameterList (),p_init_name); } else{ //scalar values p_init_name = createOneFunctionParameter(i_name, readOnly, func); } // step 2. Create unpacking/unwrapping statements, also record variables to be replaced // ---------------------------------------- // bool isPointerDeref = false; if (Outliner::enable_classic) { // classic methods use parameters directly, no unpacking is needed if (!readOnly) //read only variable should not have local variable declaration, using parameter directly // taking advantage of the same parameter names for readOnly variables // Let postprocessing to patch up symbols for them { // non-readonly variables need to be mapped to their parameters with different names (p__) // remapVarSyms() will use pointer dereferencing for all of them by default in C, // this is enough to mimic the classic outlining work //handleSharedVariables(*i, p_init_name, args_scope, sym_remap); //handleSharedVariables(*i, body, sym_remap); //Didem: I comment out this part because it uses pointer deferencing for all non-readonly variables. //recordSymRemap(*i,p_init_name, args_scope, sym_remap); } } else { local_var_decl = NULL; //createUnpackDecl (p_init_name, counter, isPointerDeref, i_name , NULL, body); ROSE_ASSERT (local_var_decl); prependStatement (local_var_decl,body); // regular and shared variables used the first local declaration recordSymRemap (*i, local_var_decl, args_scope, sym_remap); // transfer the value for firstprivate variables. } // step 3. Create and insert companion re-pack statement in the end of the function body // If necessary // ---------------------------------------- SgInitializedName* local_var_init = NULL; if (local_var_decl != NULL ) local_var_init = local_var_decl->get_decl_item (SgName (name_str.c_str ())); if (!SageInterface::is_Fortran_language() && !Outliner::enable_classic) ROSE_ASSERT(local_var_init!=NULL); SgExprStatement* pack_stmt = createPackStmt (local_var_init); if (pack_stmt) appendStatement (pack_stmt,body); counter ++; } //end for // variable substitution SgBasicBlock* func_body = func->get_definition()->get_body(); remapVarSyms (sym_remap, pdSyms, private_remap , func_body); }
void process() { int i; for (i = 0; i < fdefList.size(); i++) { SgFunctionDefinition* fndef = fdefList.at(i); if (fndef == NULL) { return; } std::string functionName = fndef->get_declaration()->get_name().getString(); SgFunctionDeclaration *f = fndef->get_declaration(); if (!debugHooks) { SgNode *body = fndef->get_body(); // Move any preprocessing info before the function to a new // null statement preceding the function. AttachedPreprocessingInfoType save_buf; SageInterface::cutPreprocessingInfo(f, PreprocessingInfo::before, save_buf) ; if (save_buf.size()) { SgVariableDeclaration *dummy = SageBuilder::buildVariableDeclaration( "___htc_dummy_decl_for_preproc_info", SageBuilder::buildIntType(), 0, f->get_scope()); SageInterface::setExtern(dummy); SageInterface::insertStatementBefore(f, dummy); SageInterface::pastePreprocessingInfo( dummy, PreprocessingInfo::before, save_buf); } SageInterface::addTextForUnparser( f, "\n#if 0", AstUnparseAttribute::e_before); std::string CapFnName = Capitalize(functionName); std::string before_body = "\n#endif\n"; std::string macro_name = "HTC_KEEP_MODULE_" + Upper(functionName); before_body += "#ifdef " + macro_name + "\n"; before_body += "#include \"Ht.h\"\n"; before_body += "#include \"Pers" + CapFnName + ".h\"\n"; before_body += "#ifndef __htc_GW_write_addr\n"; before_body += "#define __htc_GW_write_addr(v,a) v.write_addr(a)\n"; before_body += "#endif\n"; before_body += "#ifndef __htc_GW_write_addr2\n"; before_body += "#define __htc_GW_write_addr2(v,a,b) v.write_addr(a,b)\n"; before_body += "#endif\n"; before_body += "void CPers" + CapFnName + "::Pers" + CapFnName + "()\n"; SageInterface::addTextForUnparser(body, before_body, AstUnparseAttribute::e_before); std::string after_body = "\n#endif /* " + macro_name + " */\n"; SageInterface::addTextForUnparser(body, after_body, AstUnparseAttribute::e_after); // Write the _src.cpp file generate_src_cpp_file(fndef, CapFnName, macro_name); } } for (i = 0; i < fdeclList.size(); i++) { SgFunctionDeclaration *fdecl = fdeclList.at(i); if (!debugHooks && fdecl && fdecl->get_definingDeclaration() != fdecl) { // Move any preprocessing info before the function to a new // null statement preceding the function. AttachedPreprocessingInfoType save_buf; SageInterface::cutPreprocessingInfo(fdecl, PreprocessingInfo::before, save_buf) ; if (save_buf.size()) { SgVariableDeclaration *dummy2 = SageBuilder::buildVariableDeclaration( "___htc_dummy_decl2_for_preproc_info", SageBuilder::buildIntType(), 0, fdecl->get_scope()); SageInterface::setExtern(dummy2); SageInterface::insertStatementBefore(fdecl, dummy2); SageInterface::pastePreprocessingInfo( dummy2, PreprocessingInfo::before, save_buf); } SageInterface::addTextForUnparser(fdecl, "\n/* ", AstUnparseAttribute::e_before); SageInterface::addTextForUnparser(fdecl, " */", AstUnparseAttribute::e_after); // comment out function prototypes // fdecl->setCompilerGenerated(); // fdecl->unsetOutputInCodeGeneration(); } } }
int main (int argc, char *argv[]) { /* indicate whether include files need to be added */ bool loopTransformApplied = false ; /* more bools at top of file... */ bool withPAPI = false ; bool showStats = false ; bool enablePostProcessing = false ; /***********************************************/ /* Process command line options */ /***********************************************/ Rose_STL_Container<string> cmdLineArgs = CommandlineProcessing::generateArgListFromArgcArgv(argc,argv) ; if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "(s|stats)", true) ) { showStats = true ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "(p|papi)", true) ) { withPAPI = true ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "(l|loops)", true) ) { emitSeqSeg = false ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "noiter", true) ) { countIters = false ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "fast", true) ) { fullLoopStat = false ; emitSeqSeg = false ; countIters = false ; withPAPI = false ; enablePostProcessing = true ; } dumpFunc = (showStats ? "ET_LogStats" : "ET_Dump") ; /***********************************************/ /* Invoke ROSE */ /***********************************************/ /* build AST */ SgProject* project = frontend(argc, argv); ROSE_ASSERT(project); if (project->get_fileList().empty() == false) { /* make sure AST is well formed */ AstTests::runAllTests(project); /* set up some needed typedefs for runtime support */ SgGlobal *globalScope = SageInterface::getFirstGlobalScope(project) ; ETtype = buildTypedefDeclaration("ET_Idx_t", buildShortType(), globalScope)->get_type() ; /* insert probes into each function in this file */ Rose_STL_Container<SgNode*> funcDefs = NodeQuery::querySubTree(project, V_SgFunctionDefinition) ; for (Rose_STL_Container<SgNode*>::iterator f_itr = funcDefs.begin(); f_itr != funcDefs.end(); ++f_itr) { SgFunctionDefinition *funcDef = isSgFunctionDefinition(*f_itr) ; ROSE_ASSERT(funcDef); #ifdef ET_DEBUG printf("--- %s ---\n", funcDef->get_qualified_name().str()) ; #endif SgBasicBlock *funcBody = funcDef->get_body() ; if (funcBody == NULL) continue ; /* should be impossible to get here... */ SgFunctionDeclaration *funcDecl = funcDef->get_declaration() ; ROSE_ASSERT(funcDecl); /* don't transform header file code */ if (strstr(funcDecl->get_name().str(), "operator")) continue ; #ifdef ET_DEBUG printf("--- %s ---\n", funcDecl->get_name().str()) ; #endif int loopCount = 0 ; /* used to create local variable names */ int segCount = 0 ; TransformFunction(funcDecl, funcBody, funcBody, &loopCount, &segCount) ; if (loopCount != 0) { loopTransformApplied = true ; } } SgFunctionDeclaration *mainFunc = SageInterface::findMain(project) ; if (countIters == false && (loopTransformApplied || mainFunc != NULL)) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_NO_COUNT_ITERS 1\n")) ; } /* files containing at least one loop require run-time support */ if (loopTransformApplied) { SageInterface::attachArbitraryText(globalScope, std::string("#include \"ETrt.h\"\n")) ; } /* fold run-time support code into file containing main() */ if (mainFunc != NULL) { SgFunctionDefinition *mainFuncDef = mainFunc->get_definition() ; /* include ETrt.c just before main() in this file */ if (!fullLoopStat) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_SIMPLE_LOOP_STATS 1\n") ); } if (enablePostProcessing) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_POST_PROCESS_SEQ_TO_LOOP 1\n") ); } if (withPAPI) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_PAPI 1\n\n") ); } SageInterface::attachArbitraryText(globalScope, std::string("#include \"ETrt.c\"\n") ); if (withPAPI) { /* Insert PAPI initialization code at top of main */ SgBasicBlock *mainBody = mainFuncDef->get_body() ; Rose_STL_Container<SgNode*> blockStmts = NodeQuery::querySubTree(mainBody, V_SgStatement, AstQueryNamespace::ChildrenOnly) ; for (Rose_STL_Container<SgNode*>::iterator s_itr = blockStmts.begin(); s_itr != blockStmts.end(); ++s_itr) { SgStatement *stmt = isSgStatement(*s_itr) ; ROSE_ASSERT(stmt); /* skip variable declarations */ if (isSgDeclarationStatement(stmt)) continue ; SgExprStatement *initCall = buildFunctionCallStmt( SgName("ET_Init"), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; stmt->get_scope()->insert_statement(stmt, initCall) ; break ; } } /* insert finalization code at end of main() */ Rose_STL_Container<SgNode*> retStmts = NodeQuery::querySubTree(mainFunc, V_SgReturnStmt) ; if (retStmts.size() > 0) { for (Rose_STL_Container<SgNode*>::iterator r_itr = retStmts.begin(); r_itr != retStmts.end(); ++r_itr) { SgReturnStmt *ret = isSgReturnStmt(*r_itr) ; ROSE_ASSERT(ret); SgExprStatement *sanityCall = buildFunctionCallStmt( SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; ret->get_scope()->insert_statement(ret, sanityCall) ; SgExprStatement *logStatCall = buildFunctionCallStmt( SgName(dumpFunc), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; ret->get_scope()->insert_statement(ret, logStatCall) ; } } else { SgExprStatement *sanityCall = buildFunctionCallStmt( SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; mainFuncDef->get_body()->append_statement(sanityCall) ; SgExprStatement *logStatCall = buildFunctionCallStmt( SgName(dumpFunc), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; mainFuncDef->get_body()->append_statement(logStatCall) ; } } } /* make sure AST is well formed */ AstTests::runAllTests(project); // generateDOT (*project); return backend(project); }
int main( int argc, char *argv[] ) { if( argc < 2 ) { cout << "./amos: no input files " << endl; cout << " " << endl; cout << "Hi, this is Amos! " << endl; cout << "It's my pleasure to serve you. " << endl; cout << " " << endl; cout << "Please type option '--help' to see guide " << endl; cout << " " << endl; return 0; } cout << "*************************************************************" << endl; cout << "** **" << endl; cout << "** Welcome to use OpenMP task validation system! **" << endl; cout << "** **" << endl; cout << "** editor: Amos Wang **" << endl; cout << "*************************************************************\n" << endl; vector<string> argvList( argv, argv+argc ); vector<string> argvList0( argv, argv+argc ); // keep original argv and argc command_processing( argvList ); if( !parse_OmpTask( argvList ) ) { cout << "\nAmos says: I am sorry that I could not find any OpenMP task !" << endl << endl; return 0; } // for time counter long t_start; long t_end; double time_program = 0.0; t_start = usecs(); // for time counter transform_Task2Loop( argvList ); SgProject *project = frontend(argvList); ROSE_ASSERT( project != NULL ); #if 1 VariantVector vv( V_SgForStatement ); Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv); for( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgForStatement* cur_loop = isSgForStatement(*iter); ROSE_ASSERT(cur_loop); SageInterface::normalizeForLoopInitDeclaration(cur_loop); } #endif //initialize_analysis( project, false ); initialize_analysis( project, false ); //For each source file in the project SgFilePtrList &ptr_list = project->get_fileList(); cout << "\n**** Amos' validation system running ****\n" << endl; for( SgFilePtrList::iterator iter = ptr_list.begin(); iter != ptr_list.end(); iter++ ) { cout << "temp source code: " << (*iter)->get_file_info()->get_filename() << endl << endl; SgFile *sageFile = (*iter); SgSourceFile *sfile = isSgSourceFile(sageFile); ROSE_ASSERT(sfile); SgGlobal *root = sfile->get_globalScope(); SgDeclarationStatementPtrList& declList = root->get_declarations (); //cout << "Check point 2" << endl; //For each function body in the scope for( SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p ) { SgFunctionDeclaration *func = isSgFunctionDeclaration(*p); if ( func == 0 ) continue; SgFunctionDefinition *defn = func->get_definition(); if ( defn == 0 ) continue; //ignore functions in system headers, Can keep them to test robustness if ( defn->get_file_info()->get_filename() != sageFile->get_file_info()->get_filename() ) continue; SgBasicBlock *body = defn->get_body(); // For each loop Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree( defn, V_SgForStatement ); if( loops.size() == 0 ) continue; // X. Replace operators with their equivalent counterparts defined // in "inline" annotations AstInterfaceImpl faImpl_1( body ); CPPAstInterface fa_body( &faImpl_1 ); OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body) ); // Pass annotations to arrayInterface and use them to collect // alias info. function info etc. ArrayAnnotation* annot = ArrayAnnotation::get_inst(); ArrayInterface array_interface( *annot ); array_interface.initialize( fa_body, AstNodePtrImpl(defn) ); array_interface.observe( fa_body ); // X. Loop normalization for all loops within body NormalizeForLoop(fa_body, AstNodePtrImpl(body)); //cout << "Check point 3" << endl; for ( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgNode* current_loop = *iter; SgInitializedName* invarname = getLoopInvariant( current_loop ); if( invarname != NULL ) { if( invarname->get_name().getString().compare("__Amos_Wang__") == 0 ) { //cout << "It's __Amos_Wang__." << endl; //replace "for(__Amos_Wang__ = 0;__Amos_Wang__ <= 1 - 1;__Amos_Wang__ += 1)" //to "#pragma omp task" std::string strtemp = current_loop->unparseToString(); strtemp.replace( 0, 64, "#pragma omp task" ); cout << "task position at: " << current_loop->get_file_info()->get_line() << ", " << current_loop->get_file_info()->get_col() << endl; cout << "context: " << strtemp.c_str() << endl; TaskValidation( current_loop ); cout << "TaskValidation done...\n" << endl; } else continue; } }// end for loops }//end loop for each function body cout << "--------------------------------------------" << endl; }//end loop for each source file release_analysis(); //generateDOT( *project ); backend( project ); //generate final file with correct directive amos_filter( argvList0 ); // for time counter t_end = usecs(); time_program = ((double)(t_end - t_start))/1000000; cout << "analysis time: " << time_program << " sec" << endl; // cout << endl << "***** Thank you for using Amos' compiler ! *****\n" << endl; return 0; }
int main (int argc, char *argv[]) { vector<string> argvList(argv, argv+argc); //Processing debugging and annotation options // autopar_command_processing(argvList); argvList = commandline_processing (argvList); // enable parsing user-defined pragma if enable_diff is true // -rose:openmp:parse_only if (enable_diff) argvList.push_back("-rose:openmp:parse_only"); SgProject *project = frontend (argvList); ROSE_ASSERT (project != NULL); // register midend signal handling function if (KEEP_GOING_CAUGHT_MIDEND_SIGNAL) { std::cout << "[WARN] " << "Configured to keep going after catching a " << "signal in AutoPar" << std::endl; Rose::KeepGoing::setMidendErrorCode (project, 100); goto label_end; } // create a block to avoid jump crosses initialization of candidateFuncDefs etc. { std::vector<SgFunctionDefinition* > candidateFuncDefs; findCandidateFunctionDefinitions (project, candidateFuncDefs); normalizeLoops (candidateFuncDefs); //Prepare liveness analysis etc. //Too much output for analysis debugging info. //initialize_analysis (project,enable_debug); initialize_analysis (project, false); // This is a bit redundant with findCandidateFunctionDefinitions () // But we do need the per file control to decide if omp.h is needed for each file // // For each source file in the project SgFilePtrList & ptr_list = project->get_fileList(); for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end(); iter++) { SgFile* sageFile = (*iter); SgSourceFile * sfile = isSgSourceFile(sageFile); ROSE_ASSERT(sfile); SgGlobal *root = sfile->get_globalScope(); Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file //For each function body in the scope //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) { // cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl; SgFunctionDefinition *defn = isSgFunctionDefinition(*p); ROSE_ASSERT (defn != NULL); SgFunctionDeclaration *func = defn->get_declaration(); ROSE_ASSERT (func != NULL); //ignore functions in system headers, Can keep them to test robustness if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename()) { continue; } SgBasicBlock *body = defn->get_body(); // For each loop Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); if (loops.size()==0) { if (enable_debug) cout<<"\t skipped since no for loops are found in this function"<<endl; continue; } #if 0 // Moved to be executed before running liveness analysis. // normalize C99 style for (int i= x, ...) to C89 style: int i; (i=x, ...) // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgForStatement* cur_loop = isSgForStatement(*iter); ROSE_ASSERT(cur_loop); SageInterface::normalizeForLoopInitDeclaration(cur_loop); } #endif // X. Replace operators with their equivalent counterparts defined // in "inline" annotations AstInterfaceImpl faImpl_1(body); CPPAstInterface fa_body(&faImpl_1); OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body)); // Pass annotations to arrayInterface and use them to collect // alias info. function info etc. ArrayAnnotation* annot = ArrayAnnotation::get_inst(); ArrayInterface array_interface(*annot); array_interface.initialize(fa_body, AstNodePtrImpl(defn)); array_interface.observe(fa_body); //FR(06/07/2011): aliasinfo was not set which caused segfault LoopTransformInterface::set_aliasInfo(&array_interface); for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgNode* current_loop = *iter; if (enable_debug) { SgForStatement * fl = isSgForStatement(current_loop); cout<<"\t\t Considering loop at "<< fl->get_file_info()->get_line()<<endl; } //X. Parallelize loop one by one // getLoopInvariant() will actually check if the loop has canonical forms // which can be handled by dependence analysis SgInitializedName* invarname = getLoopInvariant(current_loop); if (invarname != NULL) { bool ret = ParallelizeOutermostLoop(current_loop, &array_interface, annot); if (ret) // if at least one loop is parallelized, we set hasOpenMP to be true for the entire file. hasOpenMP = true; } else // cannot grab loop index from a non-conforming loop, skip parallelization { if (enable_debug) cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl; // We should not reset it to false. The last loop may not be parallelizable. But a previous one may be. //hasOpenMP = false; } }// end for loops } // end for-loop for declarations // insert omp.h if needed if (hasOpenMP && !enable_diff) { SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root); if (enable_patch) generatePatchFile(sfile); } // compare user-defined and compiler-generated OmpAttributes if (enable_diff) diffUserDefinedAndCompilerGeneratedOpenMP(sfile); } //end for-loop of files #if 1 // undo loop normalization std::map <SgForStatement* , bool >::iterator iter = trans_records.forLoopInitNormalizationTable.begin(); for (; iter!= trans_records.forLoopInitNormalizationTable.end(); iter ++) { SgForStatement* for_loop = (*iter).first; unnormalizeForLoopInitDeclaration (for_loop); } #endif // Qing's loop normalization is not robust enough to pass all tests //AstTests::runAllTests(project); // clean up resources for analyses release_analysis(); } label_end: // Report errors if (keep_going) { std::vector<std::string> orig_rose_cmdline(argv, argv+argc); Rose::KeepGoing::generate_reports (project, orig_rose_cmdline); } //project->unparse(); return backend (project); }
int main ( int argc, char * argv[] ) { // Initialize and check compatibility. See rose::initialize ROSE_INITIALIZE; if (argc <= 1) { PrintUsage(argv[0]); return -1; } vector<string> argvList(argv, argv + argc); CmdOptions::GetInstance()->SetOptions(argvList); AssumeNoAlias aliasInfo; LoopTransformInterface::cmdline_configure(argvList); LoopTransformInterface::set_aliasInfo(&aliasInfo); #ifdef USE_OMEGA DepStats.SetFileName(buffer.str()); #endif OperatorSideEffectAnnotation *funcInfo = OperatorSideEffectAnnotation::get_inst(); funcInfo->register_annot(); ReadAnnotation::get_inst()->read(); if (DebugAnnot()) funcInfo->Dump(); LoopTransformInterface::set_sideEffectInfo(funcInfo); SgProject *project = new SgProject ( argvList); int filenum = project->numberOfFiles(); for (int i = 0; i < filenum; ++i) { // SgFile &sageFile = sageProject->get_file(i); // SgGlobal *root = sageFile.get_root(); SgSourceFile* file = isSgSourceFile(project->get_fileList()[i]); SgGlobal *root = file->get_globalScope(); SgDeclarationStatementPtrList& declList = root->get_declarations (); for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) { SgFunctionDeclaration *func = isSgFunctionDeclaration(*p); if (func == 0) continue; SgFunctionDefinition *defn = func->get_definition(); if (defn == 0) continue; SgBasicBlock *stmts = defn->get_body(); AstInterfaceImpl faImpl = AstInterfaceImpl(stmts); LoopTransformInterface::TransformTraverse(faImpl, AstNodePtrImpl(stmts)); // JJW 10-29-2007 Adjust for iterator invalidation and possible changes to declList p = std::find(declList.begin(), declList.end(), func); assert (p != declList.end()); } } if (CmdOptions::GetInstance()->HasOption("-fd")) { simpleIndexFiniteDifferencing(project); } if (CmdOptions::GetInstance()->HasOption("-pre")) { PRE::partialRedundancyElimination(project); } #ifdef USE_OMEGA DepStats.SetDepChoice(0x1 | 0x2 | 0x4); DepStats.PrintResults(); #endif //Qing's loop transformations are not robust enough to pass all tests. //AstTests::runAllTests(sageProject); unparseProject(project); if (GenerateObj()) return project->compileOutput(); return 0; }
int main (int argc, char *argv[]) { vector<string> argvList(argv, argv+argc); //Processing debugging and annotation options autopar_command_processing(argvList); // enable parsing user-defined pragma if enable_diff is true // -rose:openmp:parse_only if (enable_diff) argvList.push_back("-rose:openmp:parse_only"); SgProject *project = frontend (argvList); ROSE_ASSERT (project != NULL); #if 1 // This has to happen before analyses are called. // For each loop VariantVector vv (V_SgForStatement); Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv); // normalize C99 style for (int i= x, ...) to C89 style: int i; (i=x, ...) // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgForStatement* cur_loop = isSgForStatement(*iter); ROSE_ASSERT(cur_loop); SageInterface::normalizeForLoopInitDeclaration(cur_loop); } #endif //Prepare liveness analysis etc. initialize_analysis (project,false); // For each source file in the project SgFilePtrList & ptr_list = project->get_fileList(); for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end(); iter++) { SgFile* sageFile = (*iter); SgSourceFile * sfile = isSgSourceFile(sageFile); ROSE_ASSERT(sfile); SgGlobal *root = sfile->get_globalScope(); SgDeclarationStatementPtrList& declList = root->get_declarations (); bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file //For each function body in the scope for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) { SgFunctionDeclaration *func = isSgFunctionDeclaration(*p); if (func == 0) continue; SgFunctionDefinition *defn = func->get_definition(); if (defn == 0) continue; //ignore functions in system headers, Can keep them to test robustness if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename()) continue; SgBasicBlock *body = defn->get_body(); // For each loop Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); if (loops.size()==0) continue; #if 0 // Moved to be executed before running liveness analysis. // normalize C99 style for (int i= x, ...) to C89 style: int i; (i=x, ...) // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgForStatement* cur_loop = isSgForStatement(*iter); ROSE_ASSERT(cur_loop); SageInterface::normalizeForLoopInitDeclaration(cur_loop); } #endif // X. Replace operators with their equivalent counterparts defined // in "inline" annotations AstInterfaceImpl faImpl_1(body); CPPAstInterface fa_body(&faImpl_1); OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body)); // Pass annotations to arrayInterface and use them to collect // alias info. function info etc. ArrayAnnotation* annot = ArrayAnnotation::get_inst(); ArrayInterface array_interface(*annot); array_interface.initialize(fa_body, AstNodePtrImpl(defn)); array_interface.observe(fa_body); //FR(06/07/2011): aliasinfo was not set which caused segfault LoopTransformInterface::set_aliasInfo(&array_interface); // X. Loop normalization for all loops within body NormalizeForLoop(fa_body, AstNodePtrImpl(body)); for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgNode* current_loop = *iter; //X. Parallelize loop one by one // getLoopInvariant() will actually check if the loop has canonical forms // which can be handled by dependence analysis SgInitializedName* invarname = getLoopInvariant(current_loop); if (invarname != NULL) { hasOpenMP = ParallelizeOutermostLoop(current_loop, &array_interface, annot); } else // cannot grab loop index from a non-conforming loop, skip parallelization { if (enable_debug) cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl; hasOpenMP = false; } }// end for loops } // end for-loop for declarations // insert omp.h if needed if (hasOpenMP && !enable_diff) { SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root); if (enable_patch) generatePatchFile(sfile); } // compare user-defined and compiler-generated OmpAttributes if (enable_diff) diffUserDefinedAndCompilerGeneratedOpenMP(sfile); } //end for-loop of files // Qing's loop normalization is not robust enough to pass all tests //AstTests::runAllTests(project); release_analysis(); //project->unparse(); return backend (project); }