Exemplo n.º 1
0
Arquivo: woodpecker.C Projeto: 8l/rose
void printCodeStatistics(SgNode* root) {
  SgProject* project=isSgProject(root);
  VariableIdMapping variableIdMapping;
  variableIdMapping.computeVariableSymbolMapping(project);
  VariableIdSet setOfUsedVars=AnalysisAbstractionLayer::usedVariablesInsideFunctions(project,&variableIdMapping);
  DeadCodeElimination dce;
  cout<<"----------------------------------------------------------------------"<<endl;
  cout<<"Statistics:"<<endl;
  cout<<"Number of empty if-statements: "<<dce.listOfEmptyIfStmts(root).size()<<endl;
  cout<<"Number of functions          : "<<SgNodeHelper::listOfFunctionDefinitions(project).size()<<endl;
  cout<<"Number of global variables   : "<<SgNodeHelper::listOfGlobalVars(project).size()<<endl;
  cout<<"Number of used variables     : "<<setOfUsedVars.size()<<endl;
  cout<<"----------------------------------------------------------------------"<<endl;
  cout<<"VariableIdMapping-size       : "<<variableIdMapping.getVariableIdSet().size()<<endl;
  cout<<"----------------------------------------------------------------------"<<endl;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
int main( int argc, char * argv[] )
   {
  // If we want this translator to take specific options (beyond those defined 
  // by ROSE) then insert command line processing for new options here.

  // To better support the stencil specification that might benifit from constant 
  // folding, I have turned this ON is hte frontend.  By default it is OFF so that
  // we can preserve source code as much as possible (original expression trees).
  // The Stencil DSL can be made to work in eithr setting, but this make sure that
  // dimension dependent processing of the stencil coeficients will be evaluated 
  // to constants.  I will turn this off (and thus use a less blunt axe) when the new
  // constant expression evaluation in ROSE is fixed to support more general types
  // than integer expresion (should be done by JP later today).
  // bool frontendConstantFolding = true;
     bool frontendConstantFolding = false;

  // Generate the ROSE AST.
     SgProject* project = frontend(argc,argv,frontendConstantFolding);
     ROSE_ASSERT(project != NULL);

     try
        {
          variableIdMapping.computeVariableSymbolMapping(project);
        }
     catch(char* str)
        {
          cout << "*Exception raised: " << str << endl;
        } 
     catch(const char* str) 
        {
          cout << "Exception raised: " << str << endl;
        } 
     catch(string str)
        {
          cout << "Exception raised: " << str << endl;
        }

  // variableIdMapping.toStream(cout);

#if 1
     printf ("variableIdMapping.getVariableIdSet().size() = %zu \n",variableIdMapping.getVariableIdSet().size());
     ROSE_ASSERT(variableIdMapping.getVariableIdSet().size() > 0);
#endif

#if 0
     printf ("Exiting as a test after calling variableIdMapping.computeVariableSymbolMapping(project) \n");
     ROSE_ASSERT(false);
#endif

#if 0
     printf ("Calling constant folding \n");
     ConstantFolding::constantFoldingOptimization(project,false);

#if 0
     printf ("Exiting as a test after calling ConstantFolding::constantFoldingOptimization() \n");
     ROSE_ASSERT(false);
#endif
#endif

  // DQ (2/8/2015): Find the associated SgFile so we can restrict processing to the current file.
     ROSE_ASSERT(project->get_fileList().empty() == false);
     SgFile* firstFile = project->get_fileList()[0];
     ROSE_ASSERT(firstFile != NULL);

#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen;
     astdotgen.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_before_transformation");
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 12000;
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_before");
#endif

  // Build the inherited attribute
     Detection_InheritedAttribute inheritedAttribute;

  // Define the traversal
     DetectionTraversal shiftCalculus_DetectionTraversal;

#if 1
     printf ("Call the Detection traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverse(project,inheritedAttribute);
     Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverseWithinFile(firstFile,inheritedAttribute);
#if 0
     printf ("Stencil Operator was transformed: %s \n",result.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the Detection traversal starting at the project (root) node of the AST \n");
#endif
#if 0
     shiftCalculus_DetectionTraversal.display();
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_2;
     astdotgen_2.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_detection");
#endif
#if 0
     printf ("Exiting after the initial traversal to detect the stencil useage. \n");
     ROSE_ASSERT(false);
#endif

  // Build the inherited attribute
     StencilEvaluation_InheritedAttribute inheritedAttribute_stencilEval;

  // Define the traversal
  // StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal(shiftCalculus_DetectionTraversal);
     StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal;

#if 1
     printf ("Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverse(project,inheritedAttribute_stencilEval);
     StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverseWithinFile(firstFile,inheritedAttribute_stencilEval);

#if 0
     printf ("Stencil Evaluation was transformed: %s \n",result_stencilEval.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result_stencilEval.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif
#if 1
     shiftCalculus_StencilEvaluationTraversal.displayStencil("After evaluation of stencil");
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_3;
     astdotgen_3.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_evaluation");
#endif

#if 1
     printf ("Call generateStencilCode to generate example code \n");
#endif

#if 0
     printf ("Exiting after the second traversal to evaluate the stencils. \n");
     ROSE_ASSERT(false);
#endif

  // Generate code from stencil data structure.
     bool generateLowlevelCode = true;
     generateStencilCode(shiftCalculus_StencilEvaluationTraversal,generateLowlevelCode);

#if 1
     printf ("DONE: Call generateStencilCode to generate example code \n");
#endif

#if 0
     printf ("Exiting after call to generateStencilCode() \n");
     ROSE_ASSERT(false);
#endif

  // AST consistency tests (optional for users, but this enforces more of our tests)
     AstTests::runAllTests(project);

#if DEBUG_USING_DOT_GRAPHS
     printf ("Write out the DOT file after the transformation \n");
  // generateDOTforMultipleFile(*project,"after_transformation");
     generateDOT(*project,"_after_transformation");
     printf ("DONE: Write out the DOT file after the transformation \n");
#endif
#if DEBUG_USING_DOT_GRAPHS && 0
  // 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 = 10000;
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_after");
#endif

  // Regenerate the source code but skip the call the to the vendor compiler.
     return backend(project);
   }
Exemplo n.º 4
0
int main( int argc, char * argv[] )
   {
  // If we want this translator to take specific options (beyond those defined 
  // by ROSE) then insert command line processing for new options here.

  // To better support the stencil specification that might benifit from constant 
  // folding, I have turned this ON is hte frontend.  By default it is OFF so that
  // we can preserve source code as much as possible (original expression trees).
  // The Stencil DSL can be made to work in eithr setting, but this make sure that
  // dimension dependent processing of the stencil coeficients will be evaluated 
  // to constants.  I will turn this off (and thus use a less blunt axe) when the new
  // constant expression evaluation in ROSE is fixed to support more general types
  // than integer expresion (should be done by JP later today).
  // bool frontendConstantFolding = true;
     bool frontendConstantFolding = false;

// Liao, support a flag to control if CUDA code should be generated
// ./shiftCalculusCompiler -rose:dslcompiler:cuda  -c input_file
    std::vector <std::string> argvList (argv, argv + argc);
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","cuda",true))
    {
      std::cout<<"Turning on CUDA code generation ..."<<std::endl;
      b_gen_cuda = true;
      // avoid invoking the built in lowering, just create AST
      //argvList.push_back("-rose:openmp:ast_only");
      //argvList.push_back("-rose:openmp:lowering");
      //OmpSupport::enable_accelerator = true;
    }
    else
      b_gen_cuda = false;
// Pei-Hung, enable loop collapsing
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","collapse",true))
    {
      std::cout<<"Turning on OpenMP loop collapsing ..."<<std::endl;
      b_enable_collapse = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_enable_collapse = false;
// Pei-Hung, code generation to fulfill polyopt 
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","polyopt",true))
    {
      std::cout<<"Generating code for PolyOpt  ..."<<std::endl;
      b_enable_polyopt = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_enable_polyopt = false;

// Pei-Hung, code generation to vectorization 
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","vectorization",true))
    {
      std::cout<<"Generating code for vectorization  ..."<<std::endl;
      b_gen_vectorization = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_gen_vectorization = false;
// If MPI code generation is turned on
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","mpi",true))
    {
      std::cout<<"Turning on MPI code generation ..."<<std::endl;
      b_gen_mpi = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_gen_mpi = false;

      
  // Generate the ROSE AST.
     //SgProject* project = frontend(argc,argv,frontendConstantFolding);
     SgProject* project = frontend(argvList,frontendConstantFolding);
     ROSE_ASSERT(project != NULL);

     try
        {
          variableIdMapping.computeVariableSymbolMapping(project);
        }
     catch(char* str)
        {
          cout << "*Exception raised: " << str << endl;
        } 
     catch(const char* str) 
        {
          cout << "Exception raised: " << str << endl;
        } 
     catch(string str)
        {
          cout << "Exception raised: " << str << endl;
        }

  // variableIdMapping.toStream(cout);

#if 1
     printf ("variableIdMapping.getVariableIdSet().size() = %zu \n",variableIdMapping.getVariableIdSet().size());
     ROSE_ASSERT(variableIdMapping.getVariableIdSet().size() > 0);
#endif

#if 0
     printf ("Exiting as a test after calling variableIdMapping.computeVariableSymbolMapping(project) \n");
     ROSE_ASSERT(false);
#endif

#if 0
     printf ("Calling constant folding \n");
     ConstantFolding::constantFoldingOptimization(project,false);

#if 0
     printf ("Exiting as a test after calling ConstantFolding::constantFoldingOptimization() \n");
     ROSE_ASSERT(false);
#endif
#endif

  // DQ (2/8/2015): Find the associated SgFile so we can restrict processing to the current file.
     ROSE_ASSERT(project->get_fileList().empty() == false);
     SgFile* firstFile = project->get_fileList()[0];
     ROSE_ASSERT(firstFile != NULL);

#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen;
     astdotgen.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_before_transformation");
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 12000;
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_before");
#endif

  // Build the inherited attribute
     Detection_InheritedAttribute inheritedAttribute;

  // Define the traversal
     DetectionTraversal shiftCalculus_DetectionTraversal;

#if 1
     printf ("Call the Detection traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverse(project,inheritedAttribute);
     Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverseWithinFile(firstFile,inheritedAttribute);
#if 0
     printf ("Stencil Operator was transformed: %s \n",result.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the Detection traversal starting at the project (root) node of the AST \n");
#endif
#if 0
     shiftCalculus_DetectionTraversal.display();
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_2;
     astdotgen_2.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_detection");
#endif
#if 0
     printf ("Exiting after the initial traversal to detect the stencil useage. \n");
     ROSE_ASSERT(false);
#endif

  // Build the inherited attribute
     StencilEvaluation_InheritedAttribute inheritedAttribute_stencilEval;

  // Define the traversal
  // StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal(shiftCalculus_DetectionTraversal);
     StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal;

#if 1
     printf ("Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverse(project,inheritedAttribute_stencilEval);
     StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverseWithinFile(firstFile,inheritedAttribute_stencilEval);

#if 0
     printf ("Stencil Evaluation was transformed: %s \n",result_stencilEval.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result_stencilEval.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif
#if 1
     shiftCalculus_StencilEvaluationTraversal.displayStencil("After evaluation of stencil");
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_3;
     astdotgen_3.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_evaluation");
#endif

#if 1
     printf ("Call generateStencilCode to generate example code \n");
#endif

#if 0
     printf ("Exiting after the second traversal to evaluate the stencils. \n");
     ROSE_ASSERT(false);
#endif

  // Generate code from stencil data structure.
     bool generateLowlevelCode = true;
     generateStencilCode(shiftCalculus_StencilEvaluationTraversal,generateLowlevelCode);

#if 1
     printf ("DONE: Call generateStencilCode to generate example code \n");
#endif

   ROSE_ASSERT (project->get_fileList().size() ==1);
   SgFile * cur_file = project->get_fileList()[0];

   // Generate MPI specific code
   if (b_gen_mpi)
   { 
     //#include "mpi.h" 
     SageInterface::insertHeader (isSgSourceFile(cur_file), "libxomp_mpi.h", false);
     SageInterface::insertHeader (isSgSourceFile(cur_file), "mpi.h", false);
     SgFunctionDeclaration* main_decl = findMain(cur_file); 
     ROSE_ASSERT (main_decl != NULL);
     SgFunctionDefinition* main_def = main_decl->get_definition();
     ROSE_ASSERT (main_def != NULL);
     SgBasicBlock* func_body = main_def->get_body();
     ROSE_ASSERT (func_body != NULL);

     // Setup MPI
     SgStatement* decl_rank = buildStatementFromString("int _xomp_rank;", func_body); 
     prependStatement(decl_rank, func_body);

     SgStatement* decl_nprocs= buildStatementFromString("int _xomp_nprocs;", func_body); 
     prependStatement(decl_nprocs, func_body);

     // xomp_init_mpi (&argc, &argv, &_xomp_rank, &_xomp_nprocs);
     SgExprListExp * para_list = buildExprListExp (buildAddressOfOp (buildVarRefExp("argc", func_body)), 
                      buildAddressOfOp (buildVarRefExp("argv", func_body)),
                      buildAddressOfOp (buildVarRefExp("_xomp_rank", func_body)),
                      buildAddressOfOp (buildVarRefExp("_xomp_nprocs", func_body))
                      );
     SgExprStatement* mpi_init_stmt = buildFunctionCallStmt ("xomp_init_mpi", buildIntType(), para_list, func_body);
//     SgStatement* last_decl = findLastDeclarationStatement (func_body);
     insertStatementAfter (decl_rank, mpi_init_stmt);

   }

   // Further generate CUDA code if requested
   if (b_gen_cuda)
   {
     // We only process one single input file at a time

     OmpSupport::enable_accelerator = true;
     cur_file->set_openmp_lowering(true);
     cur_file->set_openmp(true);
     cur_file->set_openmp_parse_only(false);
     // process OpenMP directives, including omp target
     // This will translate inserted pragmas again
     OmpSupport::processOpenMP(isSgSourceFile(cur_file));

#if 0 // use rose:output instead to control this
     // rename output file to have .cu suffice
     // change .c suffix to .cu suffix
     std::string orig_name = cur_file->get_file_info()->get_filenameString();
     std::string file_suffix = StringUtility::fileNameSuffix(orig_name);
     // We only allow C file to be compatible with nvcc CUDA compiler
     //ROSE_ASSERT (CommandlineProcessing::isCFileNameSuffix(file_suffix));
     orig_name = StringUtility::stripPathFromFileName(orig_name);
     std::string naked_name = StringUtility::stripFileSuffixFromFileName(orig_name);
     cur_file->set_unparse_output_filename("rose_"+naked_name+".cu");
#endif
   }

#if 0
     printf ("Exiting after call to generateStencilCode() \n");
     ROSE_ASSERT(false);
#endif

  // AST consistency tests (optional for users, but this enforces more of our tests)
     AstTests::runAllTests(project);

#if DEBUG_USING_DOT_GRAPHS
     printf ("Write out the DOT file after the transformation \n");
  // generateDOTforMultipleFile(*project,"after_transformation");
     generateDOT(*project,"_after_transformation");
     printf ("DONE: Write out the DOT file after the transformation \n");
#endif
#if DEBUG_USING_DOT_GRAPHS && 0
  // 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 = 10000;
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_after");
#endif

  // Regenerate the source code but skip the call the to the vendor compiler.
     return backend(project);
   }