int main (int argc, char* argv[]) { // Main Function for default example ROSE Preprocessor // This is an example of a preprocessor that can be built with ROSE // Build the project object (AST) which we will fill up with multiple files and use as a // handle for all processing of the AST(s) associated with one or more source files. SgProject* sageProject = frontend(argc,argv); simpleIndexFiniteDifferencing(sageProject); FixSgProject(*sageProject); // partialRedundancyElimination(sageProject); // AstPDFGeneration().generateInputFiles(sageProject); // Generate the final C++ source code from the potentially modified SAGE AST sageProject->unparse(); // What remains is to run the specified compiler (typically the C++ compiler) using // the generated output file (unparsed and transformed application code) to generate // an object file. // int finalCombinedExitStatus = sageProject->compileOutput(); // return exit code from complilation of generated (unparsed) code return 0; }
int main ( int argc, char * argv[] ) { // Main Function for default example ROSE Preprocessor // This is an example of a preprocessor that can be built with ROSE // This example tests the ROSE infrastructure ios::sync_with_stdio(); // Syncs C++ and C I/O subsystems! // Declare usage (if incorrect number of inputs): if (argc == 1) { // Print usage and exit with exit status == 1 Rose::usage (1); } // Build the project object which we will fill up with multiple files and use as a // handle for all processing of the AST(s) associated with one or more source files. SgProject sageProject (argc,argv); // Warnings from EDG processing are OK but not errors // ROSE_ASSERT (EDG_FrontEndErrorCode <= 3); // cout << "EDG/SAGE Processing DONE! (manipulate AST with ROSE ...) " << endl; // DQ (10/17/2004): Added internal testing of AST AstTests::runAllTests(&sageProject); SIDL_TreeTraversal treeTraversal(chooseConstructor(&sageProject)); MethodSearchVisitor treeVisitor(&sageProject); treeVisitor.traverseInputFiles(&sageProject, preorder); // Ignore the return value since we don't need it treeTraversal.traverseInputFiles(&sageProject); AstDOTGeneration dotgen; dotgen.generateInputFiles(&sageProject, AstDOTGeneration::PREORDER); cout << "ROSE Processing DONE! (no need to call unparse or backend C++ compiler ...) " << endl; #if 0 // DQ (10/17/2004): This seems to be a problem, some sort of infinit loop is generated in the unparser! // the test code has been transfrered to another location for internal testing. for now this should // be commented out. It is not required for Babel Processing. This is now fixed! // Generate the final C++ source code from the potentially modified SAGE AST // sageProject.set_verbose(true); sageProject.unparse(); #endif // Later we want to call babel to process the generated SIDL file and generate the imple files which // we will process as part of the next phase of work to completely automate the process. int finalCombinedExitStatus = 0; printf ("Program Compiled Normally (exit status = %d)! \n\n\n\n",finalCombinedExitStatus); // either of these will work similarly // exit (finalCombinedExitStatus); return finalCombinedExitStatus; }
int main (int argc, char* argv[]) { // Main Function for default example ROSE Preprocessor // This is an example of a preprocessor that can be built with ROSE // Build the project object (AST) which we will fill up with multiple files and use as a // handle for all processing of the AST(s) associated with one or more source files. vector<string> argvList(argv, argv + argc); VectorCmdOptions::GetInstance()->SetOptions(argvList); SgProject* sageProject = frontend(argvList); // FixSgProject(sageProject); // AstTests::runAllTests(const_cast<SgProject*>(project)); AstTests::runAllTests(sageProject); PRE::partialRedundancyElimination(sageProject); // AstPDFGeneration().generateInputFiles(sageProject); AstTests::runAllTests(sageProject); // AstPDFGeneration().generateInputFiles(sageProject); // Generate the final C++ source code from the potentially modified SAGE AST sageProject->unparse(); // What remains is to run the specified compiler (typically the C++ compiler) using // the generated output file (unparsed and transformed application code) to generate // an object file. // int finalCombinedExitStatus = sageProject.compileOutput(); // return exit code from complilation of generated (unparsed) code return 0; }
int main(int argc, char ** argv) { std::vector<std::string> args(argv, argv + argc); #if defined(TILEK_ACCELERATOR) # if defined(TILEK_TARGET_OPENCL) args.push_back("-DSKIP_OPENCL_SPECIFIC_DEFINITION"); # endif #endif SgProject * project = new SgProject(args); assert(project->numberOfFiles() == 1); SgSourceFile * source_file = isSgSourceFile(project->get_fileList()[0]); assert(source_file != NULL); std::string filename = source_file->get_sourceFileNameWithoutPath(); std::string basename = filename.substr(0, filename.find_last_of('.')); KLT::DLX::Compiler< ::DLX::TileK::language_t, ::KLT::TileK::Generator> compiler(project, KLT_PATH, TILEK_PATH, basename); // MFB::api_t * api = compiler.getDriver().getAPI(); // dump_api(api); compiler.compile(project); project->unparse(); return 0; }
int main ( int argc, char* argv[] ) { SgProject * project = frontend ( argc , argv ) ; Rose_STL_Container<SgNode*> pragma_decls = NodeQuery::querySubTree(project, V_SgPragmaDeclaration); Rose_STL_Container<SgNode*>::iterator it; for (it = pragma_decls.begin(); it != pragma_decls.end(); it++) { SgPragmaDeclaration * pragma_decl = isSgPragmaDeclaration(*it); try { PolyhedricAnnotation::parse(pragma_decl); } catch (Exception::ExceptionBase & e) { e.print(std::cerr); continue; } PolyhedricAnnotation::PragmaPolyhedralProgram & polyhedral_program = PolyhedricAnnotation::getPolyhedralProgram<SgPragmaDeclaration, SgExprStatement, RoseVariable>(pragma_decl); Scheduling::PragmaSchedule schedule(polyhedral_program, 0); CodeGeneration::generateAndReplace(schedule); } project->unparse(); return 0; }
int main( int argc, char * argv[] ) { // This test code demonstrates the differences between an ordinary // SgTopDownBottomUpProcessing traversal and a traversal using the // AST Rewrite Mechanism. // DQ (4/6/2017): This will not fail if we skip calling ROSE_INITIALIZE (but // any warning message using the message looging feature in ROSE will fail). ROSE_INITIALIZE; ios::sync_with_stdio(); // Syncs C++ and C I/O subsystems! if (argc == 1) { // Print usage and exit with exit status == 1 rose::usage (1); } // Build the project object which we will fill up with multiple files and use as a // handle for all processing of the AST(s) associated with one or more source files. int EDG_FrontEndErrorCode = 0; SgProject* sageProject = new SgProject(argc,argv,EDG_FrontEndErrorCode); // Warnings from EDG processing are OK but not errors ROSE_ASSERT (EDG_FrontEndErrorCode <= 3); cout << "EDG/SAGE Processing DONE! (manipulate with ROSE ...) " << endl; // Output the source code file (as represented by the SAGE AST) as a PDF file (with bookmarks) AstPDFGeneration pdftest; pdftest.generateInputFiles(sageProject); // Build the inherited attribute MyInheritedAttribute inheritedAttribute; // The traversal uses the AST rewrite mechanism which requires the SgProject object to retrive the // command line for compilation of the intermeditate files (from strings to AST fragments) before // patching them into the application's AST. MyTraversal myTraversal(*sageProject); // Call the traversal starting at the sageProject node of the AST myTraversal.traverseInputFiles(sageProject,inheritedAttribute); // Generate the final C++ source code from the potentially modified SAGE AST sageProject->unparse(); cout << "Generation of final source code (unparsing) DONE! (compile ...) " << endl; // What remains is to run the specified compiler (typically the C++ compiler) using // the generated output file (unparsed and transformed application code) to generate // an object file. int finalCombinedExitStatus = sageProject->compileOutput(); printf ("Program Compiled Normally (exit status = %d)! \n\n\n\n",finalCombinedExitStatus); return finalCombinedExitStatus; }
int main(int argc, char *argv[]){ SgProject* sgproject = frontend(argc, argv); // SgProject *sgproject_copy = static_cast<SgProject*>(sgproject->copy(SgTREE_COPY)); // This copy of the sgproject fails due to the copy function of the SgFile fails (aborts) SgFile &file = sgproject->get_file(0); // SgFile *file_copy = static_cast<SgFile*>(file.copy(SgTREE_COPY)); // Calling the copy function of SgFile fails: // Before aborting the execution, the following error message is displayed: // "This is the default constructor, use SgFile (argc,argv) instead" SgGlobal *root = file.get_root(); SgGlobal *root_copy = static_cast<SgGlobal*>(root->copy(SgTREE_COPY)); // Copying the SgGlobal object is OK // removing the return statement...from the copy! list<SgNode*> returnstmt_list = NodeQuery::querySubTree(root_copy, V_SgReturnStmt); SgStatement* stmt = isSgStatement(*returnstmt_list.begin()); LowLevelRewrite::remove(stmt); sgproject->unparse(); // should output unmodified sgproject and it does. The deep copy // mechanism works for the SgGlobal object. // moving the output file to a new file, so that we can unparse the sgproject again without // overwriting the results char *outputfile = file.get_unparse_output_filename(); string move = "mv " + string(outputfile) + " orig_" + string(outputfile); system(move.c_str()); // want to output modified sgproject file.set_root(root_copy); //sgproject->set_file(file); sgproject->unparse(); // or use: file.unparse();? // Unparsing the sgproject after adding the root_copy to the file-object (I want // to unparse the modified copy...), gives me an error message: // /home/hauge2/ROSE/src/backend/unparser/unparse_stmt.C:1047: void Unparser::unparseFuncDefnStmt(SgStatement*, SgUnparse_Info&): Assertion `funcdefn_stmt->get_declaration() != __null' failed. return 0; }
int main(int argc, char *argv[]) { SgProject *project = frontend(argc, argv); SlicingInfo si=SlicingInfo(); si.traverse(project, preorder); SystemDependenceGraph * sdg=new SystemDependenceGraph(); sdg->parseProject(project); CreateSliceSet sliceSet(sdg,si.getSlicingTargets()); CreateSlice cs(sliceSet.computeSliceSet()); cs.traverse(project); project->unparse(); }
int main( int argc, char * argv[] ) { CommandlineProcessing::addCppSourceFileSuffix("docs") CommandlineProcessing::addCppSourceFileSuffix("h"); // Build the AST used by ROSE SgProject* sageProject = frontend(argc,argv); Doxygen::annotate(sageProject); OrganizeAllComments oac; oac.traverse(sageProject, preorder); // Generate source code from AST and call the vendor's compiler sageProject->unparse(); }
int main(int argc, char* argv[]) { /* Processing cmd line args */ vector<string> argvList(argv, argv+argc); UpcLibrary::processOptions(argvList); /* Parse the input file */ SgProject* proj = frontend(argc, argv); /* collect all upc_forall stmts */ vector<SgUpcForAllStatement*> forall_stmts = SageInterface::querySubTree<SgUpcForAllStatement>(proj); /* translate upc_forall stmts to normal c */ foreach (SgUpcForAllStatement* forall_stmt, forall_stmts) SageInterface::replaceStatement(forall_stmt, translate_from_upc(forall_stmt)); /* collect all for_stmts */ vector<SgForStatement*> for_stmts = SageInterface::querySubTree<SgForStatement>(proj); /* Normalize C99-style for (int i=x, ...) to C89-style: int i; for(i=x, ...) */ foreach (SgForStatement* for_stmt, for_stmts) SageInterface::normalizeForLoopInitDeclaration(for_stmt); /* Filter out the inner loops in each nest */ vector<SgForStatement*> nests; foreach (SgForStatement* for_stmt, for_stmts) if (isOuterLoop(for_stmt)) nests.push_back(for_stmt); /* optimize each nest */ foreach (SgForStatement* nest, nests) optimize(nest); /* replace upc affinity expressions */ foreach (SgForStatement* for_stmt, for_stmts) SageInterface::replaceStatement(for_stmt, translate_to_upc(for_stmt)); proj->unparse(); return 0; }
int main(int argc, char * argv[]) { //this adds -rose:openmp:ast_only -linearize args MintOptions::setInternalCommandLineArgs(argc, argv); vector<string> argvList(argv, argv + argc); MintOptions::GetInstance()->SetMintOptions(argvList); //isCFileNameSuffix (); //call the front end with -rose:openmp:ast_only and //then call the lowering explicitly SgProject *project = frontend (argc, argv); //currently we only handle single input file SgSourceFile* file = isSgSourceFile(project->get_fileList()[0]); MintTools::setOutputFileName(isSgFile(file)); //insert cuda header files. is there any? MintCudaMidend::insertHeaders(project); //Now we have the AST and search for Mint pragmas MintCudaMidend::lowerMinttoCuda(file); if(MintOptions::GetInstance()->linearize()){ cout << " INFO:Mint: flattening the array accesses" << endl; MintArrayInterface::linearizeArrays(file); } cout << " INFO:Mint: calling ROSE backend" << endl; project->unparse(); //return backend(project); cout << endl <<" INFO:Mint: Good Job. Translation is done!" << endl << endl; return 0; }
int main( int argc, char * argv[] ) { vector<string> argvList(argv, argv + argc); CommandlineProcessing::addCppSourceFileSuffix("docs"); CommandlineProcessing::addCppSourceFileSuffix("h"); Doxygen::parseCommandLine(argvList); // Build the AST used by ROSE SgProject* sageProject = frontend(argvList); Doxygen::annotate(sageProject); Doxygen::correctAllComments(sageProject); // Generate source code from AST Doxygen::unparse(sageProject); sageProject->unparse(); }
int main (int argc, char* argv[]) { // Main Function for default example ROSE Preprocessor // This is an example of a preprocessor that can be built with ROSE // Build the project object (AST) which we will fill up with multiple files and use as a // handle for all processing of the AST(s) associated with one or more source files. SgProject* sageProject = frontend(argc,argv); // DQ (7/20/2004): Added internal consistancy tests on AST AstTests::runAllTests(sageProject); // This is not needed here // FixSgProject(sageProject); bool changed = true; int count = 0; /* Inline one call at a time until all have been inlined. Loops on recursive code. */ while (changed) { changed = false; calls_to_inline.clear(); FindCallsVisitor().traverseInputFiles(sageProject, preorder); for (std::vector<SgFunctionCallExp*>::iterator i = calls_to_inline.begin(); i != calls_to_inline.end(); ++i) { // cout << (*i)->unparseToString() << endl; // generateAstGraph(sageProject, 400000); if (doInline(*i)) { changed = true; // AstTests::runAllTests(sageProject); break; } } ++count; #if 0 sageProject.unparse(); #endif // To prevent infinite loops if (count == 10) { break; } } #if 1 // Rename each variable declaration renameVariables(sageProject); #if 1 // Fold up blocks flattenBlocks(sageProject); // Clean up inliner-generated code cleanupInlinedCode(sageProject); #endif // Change members to public changeAllMembersToPublic(sageProject); // AstPDFGeneration().generateInputFiles(sageProject); // AstDOTGeneration().generateInputFiles(sageProject); #endif AstTests::runAllTests(sageProject); #if 0 // Output an optional graph of the AST (just the tree, when active) printf ("Generating a dot file... (ROSE Release Note: turn off output of dot files before committing code) \n"); generateDOT (*sageProject ); // generateAstGraph(project, 2000); #endif #if 1 // Output an optional graph of the AST (the whole graph, of bounded complexity, when active) const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 8000; generateAstGraph(sageProject,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH); #endif return backend(sageProject); }
int main(int argc, char* argv[]) { try { if(argc==1) { cout << "Error: wrong command line options."<<endl; exit(1); } // Command line option handling. namespace po = boost::program_options; po::options_description desc ("analyterix V0.2\n" "Written by Markus Schordan\n" "Supported options"); desc.add_options() ("help,h", "produce this help message.") ("rose-help", "show help for compiler frontend options.") ("version,v", "display the version.") ("stats", "display code statistics.") ("fi-constanalysis", "perform flow-insensitive constant analysis.") ("csv-fi-constanalysis",po::value< string >(), "generate csv-file [arg] with const-analysis data.") ("rd-analysis", "perform reaching definitions analysis.") ("rose-rd-analysis", "perform rose reaching definitions analysis.") ("lv-analysis", "perform live variables analysis.") ("ud-analysis", "use-def analysis.") ("at-analysis", "address-taken analysis.") ("icfg-dot", "generates the ICFG as dot file.") ("interval-analysis", "perform interval analysis.") ("trace", "show operations as performed by selected solver.") ("print-varidmapping", "prints variableIdMapping") ("print-varidmapping-array", "prints variableIdMapping with array element varids.") ("prefix",po::value< string >(), "set prefix for all generated files.") ; // ("int-option",po::value< int >(),"option info") po::store(po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(), args); po::notify(args); if (args.count("help")) { cout << "analyterix <filename> [OPTIONS]"<<endl; cout << desc << "\n"; return 0; } if (args.count("version")) { cout << "analyterix version 0.1\n"; cout << "Written by Markus Schordan 2014\n"; return 0; } if (args.count("rose-help")) { argv[1] = strdup("--help"); } if (args.count("prefix")) { option_prefix=args["prefix"].as<string>().c_str(); } if (args.count("trace")) { option_trace=true; } if(args.count("stats")) { option_stats=true; } if(args.count("rd-analysis")) { option_rd_analysis=true; } if(args.count("lv-analysis")) { option_lv_analysis=true; } if(args.count("interval-analysis")) { option_interval_analysis=true; } if(args.count("ud-analysis")) { option_rd_analysis=true; // required option_ud_analysis=true; } if(args.count("rose-rd-analysis")) { option_rose_rd_analysis=true; } if(args.count("fi-constanalysis")) { option_fi_constanalysis=true; } if (args.count("csv-fi-constanalysis")) { csvConstResultFileName=args["csv-fi-constanalysis"].as<string>().c_str(); option_fi_constanalysis=true; } if(args.count("at-analysis")) { option_at_analysis=true; } // clean up string-options in argv for (int i=1; i<argc; ++i) { if (string(argv[i]) == "--prefix" || string(argv[i]) == "--csv-const-result" ) { // do not confuse ROSE frontend argv[i] = strdup(""); assert(i+1<argc); argv[i+1] = strdup(""); } } cout << "INIT: Parsing and creating AST."<<endl; boolOptions.registerOption("semantic-fold",false); // temporary boolOptions.registerOption("post-semantic-fold",false); // temporary SgProject* root = frontend(argc,argv); // AstTests::runAllTests(root); if(option_stats) { SPRAY::ProgramStatistics::printBasicCodeInfo(root); } cout<<"STATUS: computing variableid mapping"<<endl; VariableIdMapping variableIdMapping; if (args.count("print-varidmapping-array")) { variableIdMapping.setModeVariableIdForEachArrayElement(true); } variableIdMapping.computeVariableSymbolMapping(root); cout<<"VariableIdMapping size: "<<variableIdMapping.getVariableIdSet().size()<<endl; Labeler* labeler=new Labeler(root); //cout<<"Labelling:\n"<<labeler->toString()<<endl; #if 0 IOLabeler* iolabeler=new IOLabeler(root,&variableIdMapping); //cout<<"IOLabelling:\n"<<iolabeler->toString()<<endl; #endif if (args.count("print-varidmapping")||args.count("print-varidmapping-array")) { variableIdMapping.toStream(cout); } runAnalyses(root, labeler, &variableIdMapping); cout << "INFO: generating annotated source code."<<endl; root->unparse(0,0); if(option_rose_rd_analysis) { Experimental::RoseRDAnalysis::generateRoseRDDotFiles(labeler,root); } cout<< "STATUS: finished."<<endl; // main function try-catch } catch(char* str) { cerr << "*Exception raised: " << str << endl; return 1; } catch(const char* str) { cerr << "Exception raised: " << str << endl; return 1; } catch(string str) { cerr << "Exception raised: " << str << endl; return 1; } return 0; }
int main(int argc,char ** argv) { SgProject *project = frontend(argc, argv); VisPromelaAST * debugPromelaAst=new VisPromelaAST(project); cout <<"reverting mpi"<<endl; revertMPIDefinitions(project); announceStep(1,0,"Identify modelchecking targets"); //! step1: Identify modelchecking targets PromelaMarker initialMarker; initialMarker.traverse(project, preorder); debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.inital_marking.dot"); // since the next step is creating a slice, we must identify all statements which are modelchekcing targets so that we have a valid slice SlicingInfo si=SlicingInfo(); // it might be better to use the AST-Attributes as a method for containing this information, but right now the pragma is sufficient si.setSliceTargetString(string("SPIN_TARGET")); si.traverse(project, preorder); announceStep(2,0,"Create abstractions using sdg and other means"); // create the sdg SystemDependenceGraph * sdg=new SystemDependenceGraph(); sdg->parseProject(project); //TODO: at this point one would implement abstractions, because they alter the code in such a way, that slicing might be able to remove additional statements, which otherwihse would not be removed announceStep(3,0,"Slice program to reduce state-space and\n\t eliminate dead code from abstractions"); //! Step2: Slice program to reduce towards abstraction and goal // create the set of nodes, that are in the slice, in terms of the sdg CreateSliceSet sliceSet(sdg,si.getSlicingTargets()); // using the set of statements that are within the slice construct an unnamed CreateSlice-class and slice the project CreateSlice(sliceSet.computeSliceSet()).traverse(project); // since now the ast is substantially different from the previouse version the sdg is not valid anymore delete(sdg); //DEVEL: output the sliced statement-graph debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.sliced.dot"); //DEVEL: run-ast-consistancy-test to enshure a valid ast AstTests::runAllTests(project); announceStep(4,1,"Perform sanity-check for non-transformable code like scanf and parameterinput argc and argv"); //TODO: implement the sanitiy-checks announceStep(4,2,"Identify Process and Thread functions and mark them as PROMELA-Procs"); // find process functions,like main and thread-functions. // For this version of the transformation only main is valid, // but later on threadfunctions might also work. Therefore the // a vector is used to store the main function vector<SgFunctionDefinition*> procFuncVec=findProcessFunctions(project); // mark those function declarations,definitions and main-basic block to enshure proper promela-output for (int i=0;i<procFuncVec.size();i++) { cout <<"\t*marking function for promela-output: "<<procFuncVec[i]->get_declaration()->get_name().getString()<<endl; // mark the function body for transformation markForPromelaTransformation(procFuncVec[i]); // force the first SgBasicBlock to be converted to promela!!!!! markForPromelaTransformation(procFuncVec[i]->get_body () ); //CI (04/16/2007): This is currently not necessary if (isSgFile(procFuncVec[i]->get_parent()->get_parent()->get_parent())) { cout <<"marking file"<<endl; markForPromelaTransformation(procFuncVec[i]->get_parent()->get_parent()->get_parent()); } } announceStep(4,3,"Identify functions using global variables and add them to the inlining list"); vector<SgVariableDeclaration *> globalVarDeclVec; vector<SgFunctionDefinition *> functionsToInline; std::map<SgNode*,bool> functionToInlineMap; //TODO: search in each functions for uses of a global variable, if the function contains a use, mark it and continue with the next function list<SgNode*> sgGlobalList=NodeQuery::querySubTree(project,V_SgGlobal); for (list<SgNode*>::iterator sgGlobalIt=sgGlobalList.begin();sgGlobalIt!=sgGlobalList.end();sgGlobalIt++) { // iterate over this scope without recursing and find all variabledeclarations ... SgDeclarationStatementPtrList globalDeclList=isSgGlobal(*sgGlobalIt)->get_declarations (); for (SgDeclarationStatementPtrList::iterator it=globalDeclList.begin();it!=globalDeclList.end();it++) { if (isSgVariableDeclaration(*it)) { cout <<"\t\t*found VarDecl:"<<(*it)->unparseToString()<<endl; //TODO: check if its from a header and if it is used.. globalVarDeclVec.push_back(isSgVariableDeclaration(*it)); } } } // remove MPI-Symbols form the globals vector<SgVariableDeclaration *> globalVarDeclVecTmp; for (int i=0;i<globalVarDeclVec.size();i++) { // if the current declaration is an mpi declaration, remove it from the global list (it is from a header, and will be directly supported in spin if (isNodeMPI(globalVarDeclVec[i])) { cout<<"\t\t* found an MPI-Var-Decl, ignoring"<<endl; } else { globalVarDeclVecTmp.push_back(globalVarDeclVec[i]); } } globalVarDeclVec=globalVarDeclVecTmp; // now that we have a list of all global declarations, find their uses list<SgNode*> functionList=NodeQuery::querySubTree(project,V_SgFunctionDefinition); for (list<SgNode*>::iterator fIt=functionList.begin();fIt!=functionList.end();fIt++) { //check if the function is main, .. kind of silly to inline main... if (isSgFunctionDefinition(*fIt)->get_declaration()->get_name().getString()=="main") continue; // search the function for globals list<SgNode*> sgVarRefList=NodeQuery::querySubTree(*fIt,V_SgVarRefExp); for (list<SgNode*>::iterator it=sgVarRefList.begin();sgVarRefList.end()!=it;it++) { // // get the declaration and then if the declaration is of global scope -> it is a global if (isSgFunctionParameterList(isSgVarRefExp(*it)->get_symbol () ->get_declaration ()->get_declaration())) continue; if (isSgVarRefExp(*it)->get_symbol () ->get_declaration ()->get_declaration()==NULL) // is an initialized name form the function.parameter.list continue; SgNode * tmp=(*it); while(!isSgStatement(tmp) && !isSgGlobal(tmp)) tmp=tmp->get_parent(); // cout <<"\t\tParentStmt: "<<tmp->unparseToString()<<endl; // cout <<"\t\tdebug:"<<(*it)->unparseToString()<<endl; // cout <<"\t\tclass:"<<isSgVarRefExp(*it)->get_symbol () ->get_declaration ()->get_declaration()->class_name()<<endl; SgVariableDeclaration *decl=isSgVariableDeclaration(isSgVarRefExp(*it)->get_symbol () ->get_declaration ()->get_declaration()); assert(decl!=NULL); // cout <<"\t\t*decl: "<<decl->unparseToString()<<endl; if (isSgGlobal(decl->get_parent())) // is a global scope -> global { // we have a global, add the function to the list and break functionsToInline.push_back(isSgFunctionDefinition(*fIt)); functionToInlineMap[isSgFunctionDefinition(*fIt)]=true; cout <<"\t\t*Found use of Global <"<<decl->get_definition()->get_vardefn ()->get_name ().getString()<<"> in "<<isSgFunctionDefinition(*fIt)->get_declaration()->get_name().getString()<<", -> added to inline list"<<endl; break; } } } debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step4_3.dot"); announceStep(4,4,"Identify function called by proc-functions that contain modelchecking critical code"); // a function that contains modelchecking code is marked as a promela-target after PropagatePromelaTargetTraversal -> propagate promela-targets PropagatePromelaTargetTraversal().traverse(project); for (list<SgNode*>::iterator fIt=functionList.begin();fIt!=functionList.end();fIt++) { // if the definition has a promela and is not main //check if the function is main, .. kind of silly to inline main... if (isSgFunctionDefinition(*fIt)->get_declaration()->get_name().getString()=="main") continue; // add it to the list of inline targets.. if (!functionToInlineMap.count(isSgFunctionDefinition(*fIt)) || !functionToInlineMap[isSgFunctionDefinition(*fIt)]) { functionsToInline.push_back(isSgFunctionDefinition(*fIt)); functionToInlineMap[isSgFunctionDefinition(*fIt)]=true; cout <<"\t\t*"<<isSgFunctionDefinition(*fIt)->get_declaration()->get_name().getString()<<" contains a modelchecking target, -> added to inline list"<<endl; } else { cout <<"\t\t*"<<isSgFunctionDefinition(*fIt)->get_declaration()->get_name().getString()<<" contains a modelchecking target, but is already marked for inlining"<<endl; } } debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step4_4.dot"); announceStep(4,5,"Inlining identifyed functions"); bool doneSomeInlineing=false; if (functionsToInline.size()) { // for all thread functions for (int procNr=0;procNr<procFuncVec.size();procNr++) { list<SgNode*> callSiteList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgFunctionCallExp); for (list<SgNode*>::iterator callSite=callSiteList.begin();callSite!=callSiteList.end();callSite++) { SgFunctionDefinition * def; // get the definition for that function if (isSgFunctionRefExp(isSgFunctionCallExp((*callSite))->get_function())) { // straight function call def=isSgFunctionRefExp(isSgFunctionCallExp((*callSite))->get_function())->get_symbol()->get_declaration()->get_definition(); } else { cerr <<"ERROR: could not identify function-definition"<<endl; assert(false); } if (functionToInlineMap[def]) { cout <<"\t\t*need to inline function >"<<def->get_declaration()->get_name().getString()<<"<"<<endl; bool inliningOK=false; inliningOK=doInline(isSgFunctionCallExp(*callSite)); assert(inliningOK==true); doneSomeInlineing|=true; } } } if (doneSomeInlineing) { cout <<"\t\t*Inlineing done->performing ast-consistancy-check"<<endl; // now we can remove the definion and declaration of the iline functions for (int fNr=0;fNr<functionsToInline.size();fNr++) { cout <<"\t\t* removing function declaration and definition of "<<functionsToInline[fNr]->get_declaration()->get_name().getString()<<endl; LowLevelRewrite::remove(isSgStatement(functionsToInline[fNr])); LowLevelRewrite::remove(isSgStatement(functionsToInline[fNr]->get_declaration())); } // AstTests::runAllTests(project); } } debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step4_5.dot"); //this one failes.. AstTests::runAllTests(project); announceStep(4,6,"transform for loops to whjile loops"); for (int procNr=0;procNr<procFuncVec.size();procNr++) { changeForLoops(procFuncVec[procNr]); } announceStep(4,6,"MPI-Specific: Moving globals into main"); for(int i=0;i<globalVarDeclVec.size();i++) { bool used=false; // do a nast search if or not the globals are used (->rules aout includesd stuff) SgInitializedName * gIniName=globalVarDeclVec[globalVarDeclVec.size()-1-i]->get_definition()->get_vardefn (); list<SgNode*> varRefExpList=NodeQuery::querySubTree(procFuncVec[0],V_SgVarRefExp); for (list<SgNode*>::iterator it=varRefExpList.begin();it!=varRefExpList.end();it++) { // check if the initialized name is in the list... SgVarRefExp * exp=isSgVarRefExp(*it); SgInitializedName * iniName=exp->get_symbol ()->get_declaration () ; if (gIniName==iniName) { used=true; break; } } // and if not used->skip if (!used) continue; LowLevelRewrite::remove(isSgStatement(globalVarDeclVec[globalVarDeclVec.size()-1-i])); // is allwayzs main // add them in reverse order in case they depend on each other assert(procFuncVec.size()>0); assert(procFuncVec[0]->get_body ()); procFuncVec[0]->get_body ()->prepend_statement (globalVarDeclVec[globalVarDeclVec.size()-1-i]); // and remove it from the old localtion } announceStep(4,7,"Replacing do-while and for-loops which contain model-targets with while-loops"); //CI (4/19/2007): TODO for (int procNr=0;procNr<procFuncVec.size();procNr++) { list<SgNode*> loopsToReplace; list<SgNode*> tmpList; tmpList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgForStatement); loopsToReplace.insert(loopsToReplace.end(),tmpList.begin(),tmpList.end()); tmpList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgDoWhileStmt); loopsToReplace.insert(loopsToReplace.end(),tmpList.begin(),tmpList.end()); for (list<SgNode*>::iterator it=loopsToReplace.begin();it!=loopsToReplace.end();it++) { if (!toConvert(*it)) continue; //else if (isSgForStatement(*it)) forToWhileTransformation(isSgForStatement(*it)); if (isSgDoWhileStmt(*it)) doWhileToWhileTransformation(isSgDoWhileStmt(*it)); } } // since the inline does not preserve ast-attributes, we need to regenerate them prom the "copied" pragmas announceStep(4,8,"Re-Identify modelchecking targets"); PromelaMarker().traverse(project, preorder); debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step4_8.dot"); // from this point on, only work on the function of procFuncVec is necessary,since all necessary data has been inlined announceStep(4,9,"Identify sideffecting-conditionals and move them out of the control-statement, if the statement is transformed to promela"); // first update the modelchecking information PropagatePromelaTargetTraversal().traverse(project); list<SgNode*> conditinalControlStmts; for (int procNr=0;procNr<procFuncVec.size();procNr++) { list<SgNode*> tmpList; // IF tmpList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgIfStmt); conditinalControlStmts.insert(conditinalControlStmts.end(),tmpList.begin(),tmpList.end()); // WHILE tmpList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgWhileStmt); conditinalControlStmts.insert(conditinalControlStmts.end(),tmpList.begin(),tmpList.end()); // SWITCH tmpList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgSwitchStatement); conditinalControlStmts.insert(conditinalControlStmts.end(),tmpList.begin(),tmpList.end()); //make loop userfriendly: for (list<SgNode*>::iterator it=conditinalControlStmts.begin();it!=conditinalControlStmts.end();it++) { bool isWhile=false; // if the statement is not suppoesed to be unparsed to promela -> skip if (!toConvert(*it)) continue; SgStatement * conditional=NULL; if (isSgIfStmt(*it)) { conditional=isSgIfStmt(*it)->get_conditional (); } else if (isSgWhileStmt(*it)) { conditional=isSgWhileStmt(*it)->get_condition (); isWhile=true; } else if (isSgSwitchStatement(*it)) { conditional=isSgSwitchStatement(*it)->get_item_selector (); } // now that we have the SgStatement if (isSideEffektingStmt(conditional)) { cout <<"\t\t*need to move >"<<conditional->unparseToString()<<"< outside the control-structure"<<endl; if (isWhile) { // if the loop contains a continue, substitute those with the end-labl and a goto there, list<SgNode*> continueStmtList= NodeQuery::querySubTree(*it,V_SgContinueStmt); for (list<SgNode*>::iterator continueIt=continueStmtList.begin(); continueIt!=continueStmtList.end(); continueIt++) { // traverse from this one up to the next loop-parent SgNode * tmp=*continueIt; while(!isSgWhileStmt(tmp) && !isSgDoWhileStmt(tmp)&& !isSgForStatement(tmp)) tmp=tmp->get_parent(); // if the continue belongs to this while-loop if (tmp==*it) removeContinues(isSgWhileStmt(*it)); } } // generate a VariableDeclaration SgVariableDeclaration * tempVarDecl=new SgVariableDeclaration( Sg_File_Info::generateDefaultFileInfoForTransformationNode(), SgName("spinBoolTmp"), new SgTypeBool()); // get the expression form the statement assert(isSgExprStatement(conditional)!=NULL); SgExpression * condExpr=isSgExprStatement(conditional)->get_expression (); // generate a initial assignment using the existing stmt SgInitializer * initializer=new SgAssignInitializer( Sg_File_Info::generateDefaultFileInfoForTransformationNode(),condExpr); // attach initializer tempVarDecl->get_definition()->get_vardefn()->set_initializer (initializer); // create a sgvarRefExpr SgVarRefExp * ref=new SgVarRefExp (Sg_File_Info::generateDefaultFileInfoForTransformationNode(), new SgVariableSymbol (tempVarDecl->get_definition()->get_vardefn ())); // replace the original statement with a SgVarRefExpr isSgExprStatement(conditional)->set_expression(ref); ref->set_parent(conditional); // get the parent scope and set it for the variable SgNode * tmp=*it; while(!isSgScopeStatement(tmp)) tmp=tmp->get_parent(); tempVarDecl->get_definition()->get_vardefn()->set_scope(isSgScopeStatement(tmp)->get_scope()); // and prepend the declaration before the conditional LowLevelRewrite::insert(isSgStatement(*it),tempVarDecl,true); // and append it to the while-body, which will work together with the inliner.. if (isWhile) { ref=new SgVarRefExp (Sg_File_Info::generateDefaultFileInfoForTransformationNode(), new SgVariableSymbol (tempVarDecl->get_definition()->get_vardefn ())); // copy the other expression SgExpression *rhs=isSgExpression(SgTreeCopy().copyAst(condExpr)); SgAssignOp * assgnExpr=new SgAssignOp(Sg_File_Info::generateDefaultFileInfoForTransformationNode(),ref,rhs); //append at the end of the loop, too isSgWhileStmt(*it)->get_body ()->append_statement ( new SgExprStatement (Sg_File_Info::generateDefaultFileInfoForTransformationNode(),assgnExpr) ); // assgnExpr->set_parent(isSgWhileStmt(*it)->get_body ()); } } // else do nothing } } // * 3.3: find all variables in the function,give them a unique name and move them to the bgeinning of the function, this is allowed because this is for C only!!!. This would not work for classes which must be constructed announceStep(4,8,"find all variables assign unique name and transform them to \n\tmatch promelas 2-scope-convention"); string procName; vector<SgClassType *>classTypeList; // first rename all variables to have unique names... for (int procNr=0;procNr<procFuncVec.size();procNr++) { flattenScopes(isSgFunctionDefinition(procFuncVec[procNr])); } // output a marked ast debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.reduced.dot"); announceStep(4,9,"final propagation of promela-targets"); project->unparse(); PropagatePromelaTargetTraversal().traverse(project); debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.transformations.dot"); cout <<"-------------------------------------------------------------------------------"<<endl <<"\tFrom here on the C-Ast will be modified into a Promela/C-AST"<<endl <<"-------------------------------------------------------------------------------"<<endl; announceStep(6,1,"using the initial promela targets mark the ast"); // using the sdg traverse the project to unparse to promela // the important step is to identify staements which can not be transformed to // promela because of PROMELA restrictions and therfore must be kept in C // since we have done slicing this is only done for functioncalls and such stuff // find the model-intersting nodes` sdg=new SystemDependenceGraph(); sdg->parseProject(project); vector<SpinPStructContainer*> pStructContainerArray; for (int procNr=0;procNr<procFuncVec.size();procNr++) { // list<SgNode*> stmtList=NodeQuery::querySubTree(project,V_SgStatement); list<SgNode*> stmtList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgStatement); list<SgNode*> markedNodes; // find all nodes which have beem tagged for promela-transformation for (list<SgNode*>::iterator stmtIt=stmtList.begin();stmtIt!=stmtList.end();stmtIt++) { if (toConvert(*stmtIt)) { markedNodes.push_back(*stmtIt); } } // once these statements have been identified, track their dependencys cout <<"processing stmt's"<<endl; for (list<SgNode*>::iterator it=markedNodes.begin();it!=markedNodes.end();it++) { cout <<"*stmt marked: "<<(*it)->unparseToString()<<endl; if (isSgFunctionDefinition(*it)) continue; cout <<" control dependencys:"<<endl; DependenceNode* currDepNode=sdg->getNode(*it); set <SimpleDirectedGraphNode *> preds=currDepNode->getPredecessors(); // cout <<(*it)->unparseToString()<<" has "<<preds.size()<<" predecessors"<<endl; // process all predecessors... for (set < SimpleDirectedGraphNode * >::iterator i = preds.begin();i != preds.end(); i++) { DependenceNode *pred = dynamic_cast < DependenceNode * >(*i); // ok this node is what dependency? set < DependenceGraph::EdgeType > connectingSet=sdg->edgeType(pred,currDepNode); SgNode * predNode=getStatement(pred->getSgNode()); SgNode * parentPredNode=NULL; // since controlstatements like if and while have a statement as an expression in rose and since the expression has all the control dependencys track those, but mark the parent statement,too if (isSgWhileStmt(predNode->get_parent())) parentPredNode=predNode->get_parent(); else if (isSgIfStmt(predNode->get_parent())) parentPredNode=predNode->get_parent(); // if control, add to the transformation set if (connectingSet.count(DependenceGraph::CONTROL)) { cout <<"\tcontrol dependency"<<endl; if (toConvert(predNode)) { cout <<"\t>"<<predNode->unparseToString()<<"<already marked for conversion"<<endl; } else { markedNodes.push_back(pred->getSgNode()); cout <<"\tmark >"<<predNode->unparseToString()<<"< for conversion"<<endl; markForPromelaTransformation(predNode); if (parentPredNode!=NULL) markForPromelaTransformation(parentPredNode); } } else if (connectingSet.count(DependenceGraph::DATA)) { cout <<"data dependency presen, but not resolved!"<<endl; // this will be done by checkin all controll dependeny nodes and adding those to the promela state vector... } else { cout <<"ILLIGAL DEPENDENCY FOUND. Previouse transformations should have removed those!!!"<<endl; } } } } // now the ast is in its final marked for debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step6_1.dot"); announceStep(6,2,"Creating PStruct"); for (int procNr=0;procNr<procFuncVec.size();procNr++) { /* create astruct that contains the data that is stored in the state vector...*/ SpinPStructContainer * pStruct= new SpinPStructContainer( procFuncVec[procNr]->get_declaration()->get_name().getString() ); // add the struct to the AST-for fun->it will be hidden in the promela output pass LowLevelRewrite::insert( isSgStatement(procFuncVec[procNr]->get_parent()), pStruct->getStructSubTree(), true ); // put the struct in the vector for later use pStructContainerArray.push_back(pStruct); // register class type classTypeList.push_back(new SgClassType(pStruct->getStructSubTree())); } debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step6_2.dot"); announceStep(5,0,"transform MPI-calls to SPIN-M-calls"); MPISpinReplacement MPIreplacer; for (int i=0;i<procFuncVec.size();i++) { //old: MPIreplacer.replaceIn(procFuncVec[i],pStructContainerArray[i]->getPStructVarDeclaration()); MPIreplacer.replaceIn(procFuncVec[i],pStructContainerArray[i]); } project->unparse(); debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step5.dot"); announceStep(6,3,"Identifying variables and putting them in the state-vector"); for (int procNr=0;procNr<procFuncVec.size();procNr++) { // traverse over each promela-procedure and track wich variables are use. //later add those to the state vector. the variables that need to be in // the state vector will be stored in an ast attribute attached to the // function-definition... // Create the container that will contain the variables for the "promela-export" CStateASTAttrib * c_stateAttr=new CStateASTAttrib(); // find all VariableDeclarations list<SgNode*> variableDeclarationList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgVariableDeclaration); // this set will contain a variable declarations set<SgNode*> iniNameList; set<SgInitializedName *>cStateVariables; // the list in markedNodes contains all control nodes, // now traverse again and check variables for (list<SgNode*>::iterator it= variableDeclarationList.begin(); it!=variableDeclarationList.end(); it++) { // get the paren scope... SgNode * parentScopeTmp=*it; // get parents until we find the first scope while(!isSgScopeStatement(parentScopeTmp)) { parentScopeTmp=parentScopeTmp->get_parent(); } // tmp is now the next scope if (toConvert(parentScopeTmp)) { // parent scope will be transforemd to promela -> block might be split up // in mutliple c_blocks, and since varDecls don't carry accross c-blocks->statevec SgVariableDeclaration * decl=isSgVariableDeclaration(*it); // if the variable is promela-compatible and the parent scope is the scope form the procFuncVec -> no explicit state vector needed, can be keept in promela... // if (isPromelaCompatibleVariableType(decl)) // { // ok, mark the variable as unparsable to promela... // } // else // { // add it the the state=ast-trribute cStateVariables.insert(decl->get_definition()->get_vardefn ()); cout <<"converting "<<decl->get_definition()->get_vardefn ()->get_name ().getString()<<endl; markAsPromelaStateVar(decl); c_stateAttr->add(decl->get_definition()->get_vardefn () ); cout <<"\t\t*added "<< decl->get_definition()->get_vardefn ()->get_name ().getString()<<" to the state-vector"<<endl; // remove the old variable-declaration LowLevelRewrite::remove(isSgStatement(decl)); pStructContainerArray[procNr]->addVariable(decl); // } } else { // the block is PURE c-> no promelastate will pass across its borders // therefore all variable-declaration within can be keept as is... } /*CI (4/19/2007) not all variable-uses need to be inc-block style, determine that later c_stateAttr->add(isSgInitializedName(*setIt)); setStateVecVarAttrib(*setIt,new StateVecVarASTAttrib(true));*/ // now force all nodes that contain a variable that is declared using the c_state stmt to be converted to c!!!! markStatementsWithCStateVariables(procFuncVec[procNr],cStateVariables); } // attach the c-state-attribute to the function-defintion setCStateAttrib(procFuncVec[procNr],c_stateAttr); } debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step6_3.dot"); announceStep(6,4,"inserting promela proctype variable to the proc-functions"); // * 3.4: insert the promela proctype variable to the proc-functions for (int i=0;i<procFuncVec.size();i++) { /* // create instance SgType * instanceType=classTypeList[i]; Sg_File_Info * instanceFI=Sg_File_Info::generateDefaultFileInfoForTransformationNode(); SgName instanceName=string("P")+(procFuncVec[i])->get_declaration()->get_name().getString()+"Instance"; SgStatement * instanceVarDecl=new SgVariableDeclaration(instanceFI,instanceName,instanceType); procFuncVec[i]->get_body()->prepend_statement (instanceVarDecl); */ procFuncVec[i]->get_body()->prepend_statement ( pStructContainerArray[i]->getPStructVarDeclaration() ); // fix scope pStructContainerArray[i]->getPStructVarDeclaration()->get_definition()->get_vardefn ()->set_scope(procFuncVec[i]->get_body()->get_scope()); procFuncVec[i]->get_body()->prepend_statement ( pStructContainerArray[i]->getPStructVarInstanziationDeclaration() ); pStructContainerArray[i]->getPStructVarInstanziationDeclaration()->get_definition()->get_vardefn ()->set_scope(procFuncVec[i]->get_body()->get_scope()); /* // creat ptr variable Sg_File_Info * initializerFI=Sg_File_Info::generateDefaultFileInfoForTransformationNode(); SgVarRefExp * varRef=new SgVarRefExp ( Sg_File_Info::generateDefaultFileInfoForTransformationNode(),new SgVariableSymbol (isSgVariableDeclaration(instanceVarDecl)->get_definition()->get_vardefn ())); SgAddressOfOp *aof=new SgAddressOfOp (Sg_File_Info::generateDefaultFileInfoForTransformationNode(),isSgExpression(varRef),instanceType); SgInitializer * ptrInitializer= new SgAssignInitializer(initializerFI,aof); */ /* Sg_File_Info * ptrFI=Sg_File_Info::generateDefaultFileInfoForTransformationNode(); // ptrFI->setCompilerGenerated(); // ptrFI->unsetOutputInCodeGeneration (); SgType * pointerType=new SgPointerType (instanceType); SgName ptrName=string("P")+(procFuncVec[i])->get_declaration()->get_name().getString(); SgStatement * ptrVarDecl=new SgVariableDeclaration(ptrFI,ptrName,pointerType); //SgStatement * ptrVarDecl=new SgVariableDeclaration(ptrFI,ptrName,pointerType,ptrInitializer); procFuncVec[i]->get_body()->prepend_statement (ptrVarDecl); procVariableList.push_back(isSgVariableDeclaration(ptrVarDecl));*/ // procVariableList.push_back(pStructContainerArray[i]->getPStructVarDeclaration()); } announceStep(6,5,"transform the use of variables in c_code-blocks to PROEMALs-callingconvetion"); for (int i=0;i<procFuncVec.size();i++) { refactorSgVarRefExpInCBlocks(procFuncVec[i],pStructContainerArray[i]->getPStructVarDeclaration()); } // since mpi-commands within promela will be transformned in by the promela-mpi-iunclude-> keep the in spin for the moment..., but a direct approach is also thinkable... { list<SgNode*> stmtList=NodeQuery::querySubTree(procFuncVec[0],V_SgStatement); // find all nodes which have beem tagged for promela-transformation for (list<SgNode*>::iterator stmtIt=stmtList.begin();stmtIt!=stmtList.end();stmtIt++) { if (isNodeMPI(*stmtIt) && !toConvert(*stmtIt)) { markForPromelaTransformation(*stmtIt); } } } debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.Step6_5.dot"); // *3.x finally remove return statements in all promela functions and replace them with a goto to the end of that function body announceStep(6,6,"remove all return-statements and replace with goto-statenents"); for (int i=0;i<procFuncVec.size();i++) { removeReturnStmts(procFuncVec[i]); } // 4.x mark AST for unparse, adding astattributes announceStep(6,7,"final PROMELA-attribute propagation"); MarkAST4Unparse finalMarker; finalMarker.traverse(project); // add mpi include and pp-directives if (MPIreplacer.getNrOfMPICalls()>0) { announceStep(6,8,"MPI-touchup. Add the SPIN-M #include mpi-spin.prom directive adn the active MPI_PROC"); cout <<"\t\t*found "<<MPIreplacer.getNrOfMPICalls()<<" MPI-calls"<<endl; SgGlobal * globalNode=NULL; SgNode * tmp=procFuncVec[0]; while(!isSgGlobal(tmp)) tmp=tmp->get_parent(); globalNode=isSgGlobal(tmp); if (globalNode->get_attachedPreprocessingInfoPtr ()==NULL) globalNode->set_attachedPreprocessingInfoPtr(new AttachedPreprocessingInfoType()); PreprocessingInfo * spinInclude=new PreprocessingInfo(PreprocessingInfo::CpreprocessorIncludeDeclaration,string("#include \"mpi-spin.prom\""),"user-generated",0,0,0,PreprocessingInfo::before,false,false); globalNode->addToAttachedPreprocessingInfo(spinInclude); PreprocessingInfo * activeMPI_PROC=new PreprocessingInfo(PreprocessingInfo::CpreprocessorIncludeDeclaration,string("active MPI_PROC"),"user-generated",0,0,0,PreprocessingInfo::after,false,false); globalNode->addToAttachedPreprocessingInfo(activeMPI_PROC); } cout <<"*--------------------------------*\n\tstep 7->unparse\n*--------------------------------*"<<endl; announceStep(7,0,"unparsing mixed ast"); // output the dot-grpah AstDOTGeneration dotgen; dotgen.generateInputFiles(project,AstDOTGeneration::PREORDER); // set4: assert that the promela-part is valid // Step4: unparse project to C/Promela // Unparser_Opt options; // ofstream * out=new ofstream("main.pml"); // CToProMeLaUnparser unparser(out,string("main.pml"),options,0); // SgUnparse_Info info; // cout <<" Test of unparser. Filename is "<<unparser.getFileName()<<endl; debugPromelaAst->generate(string((*(project->get_fileList ()->begin()))->getFileName())+".SPIN.1.dot"); cout <<"unparing to C"<<endl; project->unparse(); for (int i=0;i<procFuncVec.size();i++) pStructContainerArray[i]->hideShugar(); cout << "unparsing to Promela"<<endl; unparsePromelaProject(project,NULL,NULL); //unnparser. // unparser.run_unparser(); // unparseProject(project); // unparser.unparseProject(project,info); return 0; }
int main(int argc, char* argv[]) { try { if(argc==1) { cout << "Error: wrong command line options."<<endl; exit(1); } #if 0 if(argc==3) { csvAssertFileName=argv[2]; argc=2; // don't confuse ROSE command line cout<< "INIT: CSV-output file: "<<csvAssertFileName<<endl; } #endif // Command line option handling. namespace po = boost::program_options; po::options_description desc ("Woodpecker V0.1\n" "Written by Markus Schordan\n" "Supported options"); desc.add_options() ("help,h", "produce this help message.") ("rose-help", "show help for compiler frontend options.") ("version,v", "display the version.") ("stats", "display code statistics.") ("normalize", po::value< string >(), "normalize code (eliminate compound assignment operators).") ("inline",po::value< string >(), "perform inlining ([yes]|no).") ("eliminate-empty-if",po::value< string >(), "eliminate if-statements with empty branches in main function ([yes]/no).") ("eliminate-dead-code",po::value< string >(), "eliminate dead code (variables and expressions) ([yes]|no).") ("csv-const-result",po::value< string >(), "generate csv-file [arg] with const-analysis data.") ("generate-transformed-code",po::value< string >(), "generate transformed code with prefix rose_ ([yes]|no).") ("verbose",po::value< string >(), "print detailed output during analysis and transformation (yes|[no]).") ("generate-conversion-functions","generate code for conversion functions between variable names and variable addresses.") ("csv-assert",po::value< string >(), "name of csv file with reachability assert results'") ("enable-multi-const-analysis",po::value< string >(), "enable multi-const analysis.") ("transform-thread-variable", "transform code to use additional thread variable.") ; // ("int-option",po::value< int >(),"option info") po::store(po::command_line_parser(argc, argv). options(desc).allow_unregistered().run(), args); po::notify(args); if (args.count("help")) { cout << "woodpecker <filename> [OPTIONS]"<<endl; cout << desc << "\n"; return 0; } if (args.count("rose-help")) { argv[1] = strdup("--help"); } if (args.count("version")) { cout << "Woodpecker version 0.1\n"; cout << "Written by Markus Schordan 2013\n"; return 0; } if (args.count("csv-assert")) { csvAssertFileName=args["csv-assert"].as<string>().c_str(); } if (args.count("csv-const-result")) { csvConstResultFileName=args["csv-const-result"].as<string>().c_str(); } boolOptions.init(argc,argv); // temporary fake optinos boolOptions.registerOption("arith-top",false); // temporary boolOptions.registerOption("semantic-fold",false); // temporary boolOptions.registerOption("post-semantic-fold",false); // temporary // regular options boolOptions.registerOption("normalize",false); boolOptions.registerOption("inline",true); boolOptions.registerOption("eliminate-empty-if",true); boolOptions.registerOption("eliminate-dead-code",true); boolOptions.registerOption("generate-transformed-code",true); boolOptions.registerOption("enable-multi-const-analysis",false); boolOptions.registerOption("verbose",false); boolOptions.processOptions(); if(boolOptions["verbose"]) detailedOutput=1; // clean up string-options in argv for (int i=1; i<argc; ++i) { if (string(argv[i]) == "--csv-assert" || string(argv[i]) == "--csv-const-result" ) { // do not confuse ROSE frontend argv[i] = strdup(""); assert(i+1<argc); argv[i+1] = strdup(""); } } global_option_multiconstanalysis=boolOptions["enable-multi-const-analysis"]; #if 0 if(global_option_multiconstanalysis) { cout<<"INFO: Using flow-insensitive multi-const-analysis."<<endl; } else { cout<<"INFO: Using flow-insensitive unique-const-analysis."<<endl; } #endif cout << "INIT: Parsing and creating AST started."<<endl; SgProject* root = frontend(argc,argv); // AstTests::runAllTests(root); // inline all functions cout << "INIT: Parsing and creating AST finished."<<endl; if(args.count("stats")) { printCodeStatistics(root); exit(0); } VariableIdMapping variableIdMapping; variableIdMapping.computeVariableSymbolMapping(root); if(args.count("transform-thread-variable")) { Threadification* threadTransformation=new Threadification(&variableIdMapping); threadTransformation->transform(root); root->unparse(0,0); delete threadTransformation; cout<<"STATUS: generated program with introduced thread-variable."<<endl; exit(0); } SgFunctionDefinition* mainFunctionRoot=0; if(boolOptions["inline"]) { cout<<"STATUS: eliminating non-called trivial functions."<<endl; // inline functions TrivialInlining tin; tin.setDetailedOutput(detailedOutput); tin.inlineFunctions(root); DeadCodeElimination dce; // eliminate non called functions int numEliminatedFunctions=dce.eliminateNonCalledTrivialFunctions(root); cout<<"STATUS: eliminated "<<numEliminatedFunctions<<" functions."<<endl; } else { cout<<"INFO: Inlining: turned off."<<endl; } if(boolOptions["eliminate-empty-if"]) { DeadCodeElimination dce; cout<<"STATUS: Eliminating empty if-statements."<<endl; size_t num=0; size_t numTotal=num; do { num=dce.eliminateEmptyIfStmts(root); cout<<"INFO: Number of if-statements eliminated: "<<num<<endl; numTotal+=num; } while(num>0); cout<<"STATUS: Total number of empty if-statements eliminated: "<<numTotal<<endl; } if(boolOptions["normalize"]) { cout <<"STATUS: Normalization started."<<endl; RewriteSystem rewriteSystem; rewriteSystem.resetStatistics(); rewriteSystem.rewriteCompoundAssignmentsInAst(root,&variableIdMapping); cout <<"STATUS: Normalization finished."<<endl; } cout<<"STATUS: performing flow-insensitive const analysis."<<endl; VarConstSetMap varConstSetMap; VariableIdSet variablesOfInterest; FIConstAnalysis fiConstAnalysis(&variableIdMapping); fiConstAnalysis.setOptionMultiConstAnalysis(global_option_multiconstanalysis); fiConstAnalysis.setDetailedOutput(detailedOutput); fiConstAnalysis.runAnalysis(root, mainFunctionRoot); variablesOfInterest=fiConstAnalysis.determinedConstantVariables(); cout<<"INFO: variables of interest: "<<variablesOfInterest.size()<<endl; if(detailedOutput) printResult(variableIdMapping,varConstSetMap); if(csvConstResultFileName) { VariableIdSet setOfUsedVarsInFunctions=AnalysisAbstractionLayer::usedVariablesInsideFunctions(root,&variableIdMapping); VariableIdSet setOfUsedVarsGlobalInit=AnalysisAbstractionLayer::usedVariablesInGlobalVariableInitializers(root,&variableIdMapping); VariableIdSet setOfAllUsedVars = setOfUsedVarsInFunctions; setOfAllUsedVars.insert(setOfUsedVarsGlobalInit.begin(), setOfUsedVarsGlobalInit.end()); cout<<"INFO: number of used vars inside functions: "<<setOfUsedVarsInFunctions.size()<<endl; cout<<"INFO: number of used vars in global initializations: "<<setOfUsedVarsGlobalInit.size()<<endl; cout<<"INFO: number of vars inside functions or in global inititializations: "<<setOfAllUsedVars.size()<<endl; fiConstAnalysis.filterVariables(setOfAllUsedVars); fiConstAnalysis.writeCvsConstResult(variableIdMapping, string(csvConstResultFileName)); } if(args.count("generate-conversion-functions")) { string conversionFunctionsFileName="conversionFunctions.C"; ConversionFunctionsGenerator gen; set<string> varNameSet; std::list<SgVariableDeclaration*> globalVarDeclList=SgNodeHelper::listOfGlobalVars(root); for(std::list<SgVariableDeclaration*>::iterator i=globalVarDeclList.begin();i!=globalVarDeclList.end();++i) { SgInitializedNamePtrList& initNamePtrList=(*i)->get_variables(); for(SgInitializedNamePtrList::iterator j=initNamePtrList.begin();j!=initNamePtrList.end();++j) { SgInitializedName* initName=*j; if ( true || isSgArrayType(initName->get_type()) ) { // optional filter (array variables only) SgName varName=initName->get_name(); string varNameString=varName; // implicit conversion varNameSet.insert(varNameString); } } } string code=gen.generateCodeForGlobalVarAdressMaps(varNameSet); ofstream myfile; myfile.open(conversionFunctionsFileName.c_str()); myfile<<code; myfile.close(); } VariableConstInfo vci=*(fiConstAnalysis.getVariableConstInfo()); DeadCodeElimination dce; if(boolOptions["eliminate-dead-code"]) { cout<<"STATUS: performing dead code elimination."<<endl; dce.setDetailedOutput(detailedOutput); dce.setVariablesOfInterest(variablesOfInterest); dce.eliminateDeadCodePhase1(root,&variableIdMapping,vci); cout<<"STATUS: Eliminated "<<dce.numElimVars()<<" variable declarations."<<endl; cout<<"STATUS: Eliminated "<<dce.numElimAssignments()<<" variable assignments."<<endl; cout<<"STATUS: Replaced "<<dce.numElimVarUses()<<" uses of variables with constant."<<endl; cout<<"STATUS: Eliminated "<<dce.numElimVars()<<" dead variables."<<endl; cout<<"STATUS: Dead code elimination phase 1: finished."<<endl; cout<<"STATUS: Performing condition const analysis."<<endl; } else { cout<<"STATUS: Dead code elimination: turned off."<<endl; } if(csvAssertFileName) { cout<<"STATUS: performing flow-insensensitive condition-const analysis."<<endl; Labeler labeler(root); fiConstAnalysis.performConditionConstAnalysis(&labeler); cout<<"INFO: Number of true-conditions : "<<fiConstAnalysis.getTrueConditions().size()<<endl; cout<<"INFO: Number of false-conditions : "<<fiConstAnalysis.getFalseConditions().size()<<endl; cout<<"INFO: Number of non-const-conditions: "<<fiConstAnalysis.getNonConstConditions().size()<<endl; cout<<"STATUS: performing flow-insensensitive reachability analysis."<<endl; ReachabilityAnalysis ra; PropertyValueTable reachabilityResults=ra.fiReachabilityAnalysis(labeler, fiConstAnalysis); cout<<"STATUS: generating file "<<csvAssertFileName<<endl; reachabilityResults.writeFile(csvAssertFileName,true); } #if 0 rdAnalyzer->determineExtremalLabels(startFunRoot); rdAnalyzer->run(); #endif cout << "INFO: Remaining functions in program: "<<numberOfFunctions(root)<<endl; if(boolOptions["generate-transformed-code"]) { cout << "STATUS: generating transformed source code."<<endl; root->unparse(0,0); } std::list<int> fakelist; fakelist.push_back(1); std::list<int>::iterator myit=fakelist.begin(); fakelist.erase(myit); cout<< "STATUS: finished."<<endl; // main function try-catch } catch(char* str) { cerr << "*Exception raised: " << str << endl; return 1; } catch(const char* str) { cerr << "Exception raised: " << str << endl; return 1; } catch(string str) { cerr << "Exception raised: " << str << endl; return 1; } return 0; }
void example( char** argv, vector<string> domains, vector<string> maps ){ // Produce ISL AST isl_ast_node* isl_ast; { isl_ctx* ctx = isl_ctx_alloc(); isl_union_set* domain = domain_from_domains(ctx, domains ); isl_union_map* schedule = map_from_maps(ctx, maps ); isl_ast_build* build; isl_printer* p; schedule = isl_union_map_intersect_domain(schedule, domain); build = isl_ast_build_alloc(ctx); isl_ast = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); cout << "Their Printer:" << endl; p = isl_printer_to_file(ctx, stdout); p = isl_printer_set_output_format(p, ISL_FORMAT_C); p = isl_printer_print_ast_node(p, isl_ast); cout << endl; isl_printer_free(p); // isl_ast_node_free(tree); // isl_ctx_free(ctx); } { PrintNodeWalker walker; cout << "PrintNodeWalker:" << endl; cout << walker.visit( isl_ast ) << endl; } { cout << "SageTransformationWalker:" << endl; bool verbose = false; // Template file source //string template_code( "#include <iostream>\nusing namespace std;\nint main(){\n int A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;\nA = (B = (C = (D = (E = (F = (G = (H = (I = (J = (K = (L = (M = (N = (O = (P = (Q = (R = (S = (T = (U = (V = (W = (X = (Y = (Z = (a = (b = (c = (d = (e = (f = (g = (h = (i = (j = (k = (l = (m = (n = (o = (p = (q = (r = (s = (t = (u = (v = (w = (x = (y = (z = 1234)))))))))))))))))))))))))))))))))))))))))))))))))));\n }"); string template_code( "#include <iostream>\nusing namespace std;\nint main(){ }"); std::string template_file_name( "__template_file__.cpp" ); // Write out template file. ofstream template_file; template_file.open( template_file_name.c_str(), ios::trunc | ios::out ); assert( template_file.is_open() ); template_file << template_code << endl; template_file.close(); // Create arguments to frontend to parse template file vector<string> project_argv; // Apparently it is necessary to have the executable name in the arguments. project_argv.push_back( string(argv[0]) ); project_argv.push_back( template_file_name ); if( verbose ) cout << "Calling Frontend" << endl; SgProject* project = frontend( project_argv ); // Find the existing main() definition node in the tree. if( verbose ) cout << "Finding target function definition" << endl; SgFunctionDefinition* target_defn = findFunctionDeclaration( project, "main", NULL, true)->get_definition(); // Run ISL -> Sage walker over ISL tree, rendering it into Sage, if( verbose ) cout << "Calling SageTransformationWalker" << endl; SageTransformationWalker walker( isl_ast, verbose ); SgStatement* body_stmt = isSgStatement( walker.getSageRoot() ); if( body_stmt == NULL ){ cerr << "Could not convert ISL AST into SgStatement" << endl; abort(); } // Append rendered ast to the main() body if( verbose ) cout << "Inserting into main()" << endl; target_defn->append_statement( body_stmt ); // Write AST to dot file if( verbose ) cout << "Writing to dot file" << endl; generateDOT( *project ); if( verbose ) cout << "Unparsing" << endl; project->unparse(); // Print generated code cout << "Generated Code:" << endl; string line; ifstream rose_output( (string("rose_") + template_file_name).c_str() ); if( rose_output.is_open() ){ while( getline( rose_output, line ) != NULL ){ cout << line << endl; } rose_output.close(); } } }
int main(int argc, char **argv){ string msg; if(SgProject::get_verbose() > 0) printf("In Main() \n"); //Initialize the project SgProject* project = frontend(argc,argv); ROSE_ASSERT(project); MigrationOutliner MO(project); project->unparse(); return 0; /* //find for loops and pragmas Rose_STL_Container<SgNode*> pragmas = querySubTree(project, V_SgPragmaDeclaration); Rose_STL_Container<SgNode*> fors = querySubTree(project, V_SgForStatement); Rose_STL_Container<SgNode*>::const_iterator forIt; Rose_STL_Container<SgNode*>::const_iterator pragmaIt; SgForStatement* forloop; SgPragmaDeclaration* pragma; SgFunctionDeclaration* funcDecl; SgStatement* stmt; SgClassDeclaration* st; for(forIt = fors.begin(); forIt != fors.end(); forIt++){ forloop = isSgForStatement(*forIt); ROSE_ASSERT(forloop); // printf("statement %s",MO.getForloopTest(forloop)); MO.outline_ForToFunction(forloop); }//end for for(pragmaIt = pragmas.begin(); pragmaIt != pragmas.end(); pragmaIt++){ pragma = isSgPragmaDeclaration(*pragmaIt); ROSE_ASSERT(pragma); // PragmaParser pp(pragma); { printf("\n\n-------------------------Next Pragma------------------------------------------------"); //Get pragmas for function declaration // stmt = getNextStatement(pragma); // while(!isSgFunctionDeclaration(stmt) && isSgPragmaDeclaration(stmt)) // stmt = getNextStatement(stmt); // fu/ncDecl = isSgFunctionDeclaration(stmt); // MM.setPopcornScope(funcDecl); if(!funcDecl) { msg = "Statement following popcorn pragmas is not a function declaration!"; DEBUG(TOOL, msg); continue; }//end if // SgClassDeclaration* st = MM.makeStruct4Func(funcDecl); //make popcorn equivalent of func // MM.makePopcornFunc(funcDecl, st); //remove old funct // MM.removeOrigFunc(funcDecl); // MM.mainMigrateTransform(project); //insert dependencies // MM.insertStrucs4File(st,funcDecl,uniqueness); //remove pragma //removeStatement(pragma); // msg = "Annotating function: " + MM.getFunctionName(funcDecl) + " done."; DEBUG(TOOL, msg); // st = NULL; }//end if }//end for msg = "finished LOOP"; DEBUG(TOOL,msg); MM.rollCall_Popcorn(); ////////////////END POPCORN TRANSFORMER- SRC BEGIN SEPERATOR //////////////////////////////////// msg = "OUTLINE READY!"; DEBUG(TOOL,msg); project->unparse(); return 0; */ //return backend(project); }//end main
int main(int argc, char* argv[]) { try { if(argc==1) { cout << "Error: wrong command line options."<<endl; exit(1); } // Command line option handling. #ifdef USE_SAWYER_COMMANDLINE namespace po = Sawyer::CommandLine::Boost; #else namespace po = boost::program_options; #endif po::options_description desc ("analyterix V0.2\n" "Written by Markus Schordan\n" "Supported options"); desc.add_options() ("help,h", "produce this help message.") ("rose-help", "show help for compiler frontend options.") ("version,v", "display the version.") ("stats", "display code statistics.") ("fi-constanalysis", "perform flow-insensitive constant analysis.") ("csv-fi-constanalysis",po::value< string >(), "generate csv-file [arg] with const-analysis data.") ("rd-analysis", "perform reaching definitions analysis.") ("rose-rd-analysis", "perform rose reaching definitions analysis.") ("lv-analysis", "perform live variables analysis.") ("ud-analysis", "use-def analysis.") ("at-analysis", "address-taken analysis.") ("csv-at-analysis",po::value< string >(), "generate csv-file [arg] with address-taken analysis data.") ("no-topological-sort", "do not initialize the worklist with topological sorted CFG.") ("icfg-dot", "generates the ICFG as dot file.") ("optimize-icfg", "prunes conditions with empty blocks, block begin, and block end icfg nodes.") ("no-optmize-icfg", "does not optimize icfg.") ("interval-analysis", "perform interval analysis.") ("csv-deadcode-unreachable", po::value< string >(), "perform interval analysis and generate csv-file [arg] with unreachable code.") ("csv-deadcode-deadstore", po::value< string >(), "perform liveness analysis and generate csv-file [arg] with stores to dead variables.") ("trace", "show operations as performed by selected solver.") ("check-static-array-bounds", "check static array bounds (uses interval analysis).") ("print-varid-mapping", "prints variableIdMapping") ("print-varid-mapping-array", "prints variableIdMapping with array element varids.") ("print-label-mapping", "prints mapping of labels to statements") ("prefix",po::value< string >(), "set prefix for all generated files.") ("csv-stable", "do not output csv data that is not stable/portable across environments.") ; // ("int-option",po::value< int >(),"option info") po::store(po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(), args); po::notify(args); if (args.count("help")) { cout << "analyterix <filename> [OPTIONS]"<<endl; cout << desc << "\n"; return 0; } if (args.count("version")) { cout << "analyterix version 0.1\n"; cout << "Written by Markus Schordan 2014\n"; return 0; } if (args.count("rose-help")) { argv[1] = strdup("--help"); } if (args.count("prefix")) { option_prefix=args["prefix"].as<string>().c_str(); } if (args.count("optimize-icfg")) { option_optimize_icfg=true; } if (args.count("no-optimize-icfg")) { option_optimize_icfg=false; } if (args.count("trace")) { option_trace=true; } if(args.count("stats")) { option_stats=true; } if(args.count("rd-analysis")) { option_rd_analysis=true; } if(args.count("lv-analysis")) { option_lv_analysis=true; } if(args.count("interval-analysis")) { option_interval_analysis=true; } if(args.count("csv-deadcode-unreachable")) { option_interval_analysis = true; csvDeadCodeUnreachableFileName = args["csv-deadcode-unreachable"].as<string>().c_str(); } if(args.count("csv-deadcode-deadstore")) { option_lv_analysis = true; csvDeadCodeDeadStoreFileName = args["csv-deadcode-deadstore"].as<string>().c_str(); } if(args.count("check-static-array-bounds")) { option_interval_analysis=true; option_check_static_array_bounds=true; } if(args.count("ud-analysis")) { option_rd_analysis=true; // required option_ud_analysis=true; } if(args.count("rose-rd-analysis")) { option_rose_rd_analysis=true; } if(args.count("fi-constanalysis")) { option_fi_constanalysis=true; } if (args.count("csv-fi-constanalysis")) { csvConstResultFileName=args["csv-fi-constanalysis"].as<string>().c_str(); option_fi_constanalysis=true; } if(args.count("at-analysis")) { option_at_analysis=true; } if (args.count("csv-at-analysis")) { csvAddressTakenResultFileName=args["csv-at-analysis"].as<string>().c_str(); option_at_analysis=true; } if (args.count("csv-stable")) { option_csv_stable=true; } if (args.count("no-topological-sort")) { option_no_topological_sort=true; } // clean up string-options in argv for (int i=1; i<argc; ++i) { if (string(argv[i]) == "--prefix" || string(argv[i]) == "--csv-fi-constanalysis" || string(argv[i]) == "--csv-at-analysis" || string(argv[i]) == "--csv-deadcode-unreachable" || string(argv[i]) == "--csv-deadcode-deadstore" ) { // do not confuse ROSE frontend argv[i] = strdup(""); assert(i+1<argc); argv[i+1] = strdup(""); } } cout << "INIT: Parsing and creating AST."<<endl; boolOptions.registerOption("semantic-fold",false); // temporary boolOptions.registerOption("post-semantic-fold",false); // temporary SgProject* root = frontend(argc,argv); if(option_trace) { cout << "TRACE: AST node count: " << root->numberOfNodesInSubtree() << endl; } // AstTests::runAllTests(root); if(option_stats) { SPRAY::ProgramStatistics::printBasicCodeInfo(root); } cout<<"STATUS: computing variableid mapping"<<endl; ProgramAbstractionLayer* programAbstractionLayer=new ProgramAbstractionLayer(); programAbstractionLayer->initialize(root); if (args.count("print-varid-mapping-array")) { programAbstractionLayer->getVariableIdMapping()->setModeVariableIdForEachArrayElement(true); } #if 0 IOLabeler* iolabeler=new IOLabeler(root,&variableIdMapping); //cout<<"IOLabelling:\n"<<iolabeler->toString()<<endl; #endif if (args.count("print-varid-mapping")||args.count("print-varid-mapping-array")) { programAbstractionLayer->getVariableIdMapping()->toStream(cout); return 0; } if(args.count("print-label-mapping")) { cout<<(programAbstractionLayer->getLabeler()->toString()); return 0; } if(args.count("icfg-dot")) { CFAnalysis* cfAnalysis=new CFAnalysis(programAbstractionLayer->getLabeler()); Flow flow=cfAnalysis->flow(root); if(option_optimize_icfg) { cfAnalysis->optimizeFlow(flow); } InterFlow interFlow=cfAnalysis->interFlow(flow); cfAnalysis->intraInterFlow(flow,interFlow); string dotString=flow.toDot(programAbstractionLayer->getLabeler()); writeFile("icfg.dot",dotString); cout << "generating icfg-clustered.dot."<<endl; DataDependenceVisualizer ddvis(programAbstractionLayer->getLabeler(),programAbstractionLayer->getVariableIdMapping(),"none"); ddvis.generateDotFunctionClusters(root,cfAnalysis,"icfg-clustered.dot",false); delete cfAnalysis; exit(0); } runAnalyses(root, programAbstractionLayer->getLabeler(), programAbstractionLayer->getVariableIdMapping()); cout << "INFO: generating annotated source code."<<endl; root->unparse(0,0); if(option_rose_rd_analysis) { Experimental::RoseRDAnalysis::generateRoseRDDotFiles(programAbstractionLayer->getLabeler(),root); } cout<< "STATUS: finished."<<endl; // main function try-catch } catch(CodeThorn::Exception& e) { cerr << "CodeThorn::Exception raised: " << e.what() << endl; return 1; } catch(SPRAY::Exception& e) { cerr << "Spray::Exception raised: " << e.what() << endl; return 1; } catch(std::exception& e) { cerr << "std::exception raised: " << e.what() << endl; return 1; } catch(char* str) { cerr << "*Exception raised: " << str << endl; return 1; } catch(const char* str) { cerr << "Exception raised: " << str << endl; return 1; } catch(string str) { cerr << "Exception raised: " << str << endl; return 1; } return 0; }