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;
}
예제 #2
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;
   }
예제 #3
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

  // 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;
   }
예제 #4
0
파일: tilek.cpp 프로젝트: 8l/rose
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;
}
예제 #5
0
파일: code-generation.cpp 프로젝트: 8l/rose
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;
   }
예제 #7
0
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;
}
예제 #8
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();     
}
예제 #9
0
파일: testParser10.C 프로젝트: 8l/rose
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();
   }
예제 #10
0
파일: upctr.C 프로젝트: mbdriscoll/upctr
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;
}
예제 #11
0
파일: main.C 프로젝트: 8l/rose
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;
}
예제 #12
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();
   }
예제 #13
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

  // 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);
   }
예제 #14
0
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;
}
예제 #15
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;
}
예제 #16
0
파일: woodpecker.C 프로젝트: 8l/rose
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;
}
예제 #17
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();
    }
  }

}
예제 #18
0
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
예제 #19
0
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;
}