Esempio n. 1
0
void
RtedTransformation::insertVariableCreateInitForParams( SgFunctionDefinition& fndef)
{
    SgBasicBlock* body = fndef.get_body();
    ROSE_ASSERT( body);

    SgInitializedNamePtrList names = fndef.get_declaration()->get_parameterList()->get_args();

    BOOST_FOREACH( SgInitializedName* param, names)
    {
      SgType* initType = param->get_type();

      // nov2010 code:
      // reference variables don't allocate new memory
      // if we call createVariable the RTS will think it's a double
      // allocation fault

      // \pp we skip array types because they will be handled elsewhere
      // \todo not sure if this is correct here, b/c arrays would decay
      //       to pointers anyway. However, this decay is not represented
      //       in the nov2010 code, thus we skip these initializations
      //       here.
      if ( isSgReferenceType(initType) || isSgArrayType(skip_ModifierType(initType)) )
        continue;

      SgFunctionDeclaration* fndecl = fndef.get_declaration();
      std::cerr << ">>> " << fndecl->get_name() << std::endl;
      ROSE_ASSERT(isSgFunctionDefinition(param->get_scope()));

      body->prepend_statement( buildVariableCreateCallStmt(param, true) );
    }
Esempio n. 2
0
void examineFunctionDeclaration(SgFunctionDeclaration* decl, ostream &out) {
    SgSymbol* symbol = decl->get_symbol_from_symbol_table();
    SgFunctionDefinition* def = decl->get_definition();

    ExprSynAttr *attr;
    stringstream fake;

    /* We don't want to output the function withou definition */
    if (NULL == symbol || NULL == def)
        return;
    SgType *ret_type = decl->get_orig_return_type();
    examineType(ret_type, out);

    out << " " << symbol->get_name().getString();
    out << "(";

    SgInitializedNamePtrList& name_list = decl->get_args();
    SgInitializedNamePtrList::const_iterator name_iter;
    for (name_iter = name_list.begin(); 
            name_iter != name_list.end(); 
            name_iter++) {
        if (name_iter != name_list.begin())
            out << ", ";
        SgInitializedName* name = *name_iter;
        examineInitializedName(name, out);
    }
    out << ")";
    out << endl;

    SgBasicBlock* body = def->get_body();
    attr = examineScopeStatement(body,symbol->get_name().getString(), fake);
    out << attr->code.str();
    delete attr;
}
int main( int argc, char * argv[] ) 
{
        // Build the AST used by ROSE
        SgProject* project = frontend(argc,argv);
        
        generatePDF ( *project );
        
        Rose_STL_Container<SgNode*> functions = NodeQuery::querySubTree(project, V_SgFunctionDefinition);
        for (Rose_STL_Container<SgNode*>::const_iterator i = functions.begin(); i != functions.end(); ++i) {
                SgFunctionDefinition* curFunc = isSgFunctionDefinition(*i);
                ROSE_ASSERT(curFunc);
                                
                SgBasicBlock *funcBody = curFunc->get_body();
                InterestingNode funcCFGStart = (InterestingNode)funcBody->cfgForBeginning();;
                        
                // output the CFG to a file
                ofstream fileCFG;
                fileCFG.open((curFunc->get_declaration()->get_name().getString()+"_cfg.dot").c_str());
                cout << "writing to file "<<(curFunc->get_declaration()->get_name().getString()+"_cfg.dot")<<"\n";
                VirtualCFG::cfgToDot(fileCFG, curFunc->get_declaration()->get_name(), funcCFGStart);
                fileCFG.close();
        }
        
        // Unparse and compile the project (so this can be used for testing)
        return backend(project);
}
void
Unparse_Jovial::unparseFuncDefnStmt(SgStatement* stmt, SgUnparse_Info& info)
   {
     SgFunctionDefinition* funcdef = isSgFunctionDefinition(stmt);
     ROSE_ASSERT(funcdef != NULL);

     curprint("BEGIN\n");

  // unparse the body of the function
     if (funcdef->get_body())
        {
          unparseStatement(funcdef->get_body(), info);
        }

     curprint("END\n");
   }
Esempio n. 5
0
int
main ( int argc,  char * argv[] )
   {

     if (argc <= 1) {
         PrintUsage(argv[0]);
         return -1;
     }

     SgProject sageProject ( (int)argc,argv);
     SageInterface::changeAllBodiesToBlocks(&sageProject);
    CmdOptions::GetInstance()->SetOptions(argc, argv);


   int filenum = sageProject.numberOfFiles();
   for (int i = 0; i < filenum; ++i) {
     SgSourceFile* sageFile = isSgSourceFile(sageProject.get_fileList()[i]);
     ROSE_ASSERT(sageFile != NULL);
     SgGlobal *root = sageFile->get_globalScope();
     SgDeclarationStatementPtrList& declList = root->get_declarations ();
     for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) {
          SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
          if (func == 0)
             continue;
          SgFunctionDefinition *defn = func->get_definition();
          if (defn == 0)
             continue;
          SgBasicBlock *stmts = defn->get_body();  
          AstInterfaceImpl scope(stmts);
          AstInterface fa(&scope);
          StmtVarAliasCollect alias;
          alias(fa, AstNodePtrImpl(defn));
          if (GenerateDOT(argc, argv)) {
             string name = string(strrchr(sageFile->getFileName().c_str(),'/')+1) + ".dot";
             TestDUWrap_DOT op(alias);
             op(fa, defn, name);
          }
          else {
             string name = string(strrchr(sageFile->getFileName().c_str(),'/')+1) + ".outx";
#if 0   // Test harness uses stdout now rather than a temporary file [Robb P. Matzke 2013-02-25]
             TestDUWrap_Text op(alias,name);
#else
             TestDUWrap_Stdout op(alias);
#endif
             op(fa, defn);
          }
     }
   }

  return 0;
}
Esempio n. 6
0
void Jovial_to_C::translateProgramHeaderStatement(SgProgramHeaderStatement* programHeaderStatement)
{
// Get scopeStatement from SgProgramHeaderStatement
   SgScopeStatement* scopeStatement = programHeaderStatement->get_scope();
   ROSE_ASSERT(scopeStatement);
  
// Get ParameterList and DecoratorList
   SgFunctionParameterList* functionParameterList = buildFunctionParameterList(); 
   SgExprListExp* decoratorList = deepCopy(programHeaderStatement->get_decoratorList());
  
// Reuse FunctionDefinition from Fortran programHeaderStatement
   SgFunctionDefinition* functionDefinition = programHeaderStatement->get_definition();
  
// Get basicBlock from SgProgramHeaderStatement
   SgBasicBlock* basicBlock = functionDefinition->get_body();
   ROSE_ASSERT(basicBlock);

   SgSymbolTable* symbolTable = basicBlock->get_symbol_table();
   ROSE_ASSERT(symbolTable);
  
// The main function return type is int
   SgType* mainType = SgTypeInt::createType();
  
// Remove original function symbol.  Keep the new function symbol with name of "main"
   SgFunctionSymbol* functionSymbol = isSgFunctionSymbol(scopeStatement->lookup_symbol(programHeaderStatement->get_name()));
   SgSymbolTable* globalSymbolTable = isSgSymbolTable(functionSymbol->get_parent());
   globalSymbolTable->remove(functionSymbol);
   functionSymbol->set_parent(NULL);
   delete(functionSymbol);
  
// Create SgFunctionDeclaration for C main function. Name must be "main".
   SgFunctionDeclaration* cFunctionDeclaration = buildDefiningFunctionDeclaration("main",
                                                                                  mainType,
                                                                                  functionParameterList,
                                                                                  scopeStatement);
  
// Setup the C function declaration.
   removeList.push_back(cFunctionDeclaration->get_definition());
   functionDefinition->set_parent(cFunctionDeclaration);
   cFunctionDeclaration->set_definition(functionDefinition);
   programHeaderStatement->set_definition(NULL);
 
// Replace the SgProgramHeaderStatement with SgFunctionDeclaration.
   replaceStatement(programHeaderStatement,cFunctionDeclaration,true);
   cFunctionDeclaration->set_decoratorList(decoratorList);
// cFunctionDeclaration->set_startOfConstruct(functionDefinition->get_startOfConstruct());
// cFunctionDeclaration->set_endOfConstruct(functionDefinition->get_endOfConstruct());
// cFunctionDeclaration->get_file_info()->set_physical_filename(cFunctionDeclaration->get_file_info()->get_filenameString()); 
  
   programHeaderStatement->set_parent(NULL);
}  // End of Jovial_to_C::translateProgramHeaderStatement
Esempio n. 7
0
void PreAndPostOrderTraversal::preOrderVisit(SgNode* n) {

        SgFunctionDeclaration * dec = isSgFunctionDeclaration(n);
        if (dec != NULL) {
                cout << "Found function declaration " << dec->get_name().getString();
                Sg_File_Info * start = dec->get_startOfConstruct();
                Sg_File_Info * end = dec->get_endOfConstruct();
                if(start->isCompilerGenerated()) {
                        cout << ", which is compiler-generated" << endl;
                } else {
                        cout << " in file " << start->get_raw_filename() << ", " << start->get_file_id() << " from line " << 
                            start->get_line() << ", col " << start->get_col() << " to line " << 
                            end->get_line() << ", col " << end->get_col() << endl;
                }
                SgFunctionType * type = dec->get_type();
                SgType * retType = type->get_return_type();
        cout << "Return type: " << retType->unparseToString() << endl;
        SgFunctionParameterList * params = dec->get_parameterList();
        SgInitializedNamePtrList & ptrList = params->get_args();
        if(!ptrList.empty()) {
            cout << "Parameter types: ";
            for(SgInitializedNamePtrList::iterator j = ptrList.begin(); j != ptrList.end(); j++) {
                SgType * pType = (*j)->get_type();
                cout << pType->unparseToString() << " ";
            }
            cout << endl;
        }
        cout << "Linkage: " << dec->get_linkage() << endl;
               cout << endl;
        }


        SgFunctionDefinition * def = isSgFunctionDefinition(n);
        if (def != NULL) {
                cout << "Found function definition " << def->get_declaration()->get_name().getString();
                Sg_File_Info * start = def->get_startOfConstruct();
                Sg_File_Info * end = def->get_endOfConstruct();
                if(start->isCompilerGenerated()) {
                        cout << ", which is compiler-generated" << endl;
                } else {
                        cout << " in file " << start->get_raw_filename() << " from line " << start->get_line() << ", col " << start->get_col() << " to line " << end->get_line() << ", col " << end->get_col() << endl;
                SgBasicBlock * body = def->get_body();
        Sg_File_Info * bodyStart = body->get_startOfConstruct();
        Sg_File_Info * bodyEnd =   body->get_endOfConstruct();
        cout << "Function body from line " << bodyStart->get_line() << ", col " << bodyStart->get_col() << " to line " << bodyEnd->get_line() << ", col " << bodyEnd->get_col() << endl; 
 }
        cout << endl;
        }
}
Esempio n. 8
0
/*
 * Main Function
 */
int main(int argc, char * argv[]) {
	// Build the AST used by ROSE
	SgProject* sageProject = frontend(argc, argv);

	// For each source file in the project
	SgFilePtrList & ptr_list = sageProject->get_fileList();
	for (SgFilePtrList::iterator iter = ptr_list.begin(); iter
			!= ptr_list.end(); iter++) {
		SgFile* sageFile = (*iter);
		SgSourceFile * sfile = isSgSourceFile(sageFile);
		ROSE_ASSERT(sfile);
		SgGlobal *root = sfile->get_globalScope();
		SgDeclarationStatementPtrList& declList = root->get_declarations();

		// Insert header file
		insertHeader(sfile);

		//For each function body in the scope
		for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p
				!= declList.end(); ++p) {
			SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
			if (func == 0)
				continue;
			SgFunctionDefinition *defn = func->get_definition();
			if (defn == 0)
				continue;
			//ignore functions in system headers, Can keep them to test robustness
			if (defn->get_file_info()->get_filename()
					!= sageFile->get_file_info()->get_filename())
				continue;
			SgBasicBlock *body = defn->get_body();
			ROSE_ASSERT(body);

			vector<SgForStatement*> loops = querySubTree<SgForStatement> (defn,
					V_SgForStatement);
			if (loops.size() == 0)
				continue;

			visitLoops(loops);
		}

		// Generate source code from AST and call the vendor's compiler
		return backend(sageProject);
	}

}
Esempio n. 9
0
ScopExtractor::ScopExtractor(SgProject* project, PolyRoseOptions& polyopts)
{
  //   this->project = project;
  this->polyoptions = polyopts;
  isVerbose = ! polyopts.getQuiet();
  if (isVerbose)
    std::cout << "[PolyOpt] Using generic scop extractor" << std::endl;

  SgFilePtrList& file_list = project->get_fileList();
  SgFilePtrList::const_iterator file_iter;
  // Iterate on all files of the project.
  for (file_iter = file_list.begin(); file_iter != file_list.end(); file_iter++)
    {
      SgSourceFile* file = isSgSourceFile(*file_iter);
      if (polyoptions.getScVerboseLevel())
	cout << "[Extr] File: " << file->getFileName() << endl;
      SgNodePtrList funcDefnList =
	NodeQuery::querySubTree(file, V_SgFunctionDefinition);
      SgNodePtrList::const_iterator iter;
      // Iterate on all function defined in a file.
      for (iter = funcDefnList.begin(); iter != funcDefnList.end(); ++iter)
	{
	  SgFunctionDefinition *fun = isSgFunctionDefinition(*iter);
	  if (!fun)
	    {
	      cout << "[Extr] Warning: Expected SgFunctionDefinition in " <<
		file->getFileName() << endl;
	      continue; // with the next function definition
	    }
	  SgName name = fun->get_declaration()->get_name();
	  if (polyoptions.getScVerboseLevel())
	    cout << "[Extr] Function: " << name.getString() << endl;
	  SgBasicBlock* body = fun->get_body();

	  // Ensure the function is a candidate (no (unsafe) function
	  // calls).
	  if (assertFunctionIsCandidate(project, body))
	    {
	      // Proceed recursively, bottom up.
	      inspectBottomUpFunctionBody(project, body);
	    }
	}
    }
  if (isVerbose)
    std::cout << "[ScopExtraction] Generic: done" << std::endl;
}
Esempio n. 10
0
/**
 * Create scops for a sub-tree.
 *
 */
void
ScopExtractor::extractScops(SgNode* root)
{
  if (isVerbose)
    std::cout << "[PolyOpt] Using generic scop extractor" << std::endl;

  SgNodePtrList funcDefnList =
    NodeQuery::querySubTree(root, V_SgFunctionDefinition);
  SgNodePtrList::const_iterator iter;
  // Iterate on all functions defined in a sub-tree.
  for (iter = funcDefnList.begin(); iter != funcDefnList.end(); ++iter)
    {
      SgFunctionDefinition *fun = isSgFunctionDefinition(*iter);
      if (!fun)
	{
	  cout << "[Extr] Warning: Expected SgFunctionDefinition" << endl;
	  continue; // with the next function definition
	}
      SgName name = fun->get_declaration()->get_name();
      if (polyoptions.getScVerboseLevel())
	cout << "[Extr] Function: " << name.getString() << endl;
      SgBasicBlock* body = fun->get_body();

      // Ensure the function is a candidate (no (unsafe) function
      // calls).
      if (assertFunctionIsCandidate(NULL, body))
	{
	  // Proceed recursively, bottom up.
	  inspectBottomUpFunctionBody(NULL, body);
	}
    }

  // If no function is defined in the subtree, simply process it
  // as-is.
  if (funcDefnList.size() == 0)
    if (assertFunctionIsCandidate(NULL, root))
      // Proceed recursively, bottom up.
      inspectBottomUpFunctionBody(NULL, root);

  if (isVerbose)
    std::cout << "[ScopExtraction] Generic: done" << std::endl;
}
Esempio n. 11
0
void visitorTraversal::visit(SgNode* n)
   {
     SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(n);
     if (functionDeclaration != NULL)
        {
          SgFunctionDefinition* functionDefinition = functionDeclaration->get_definition();
          if (functionDefinition != NULL)
             {
               SgBasicBlock* functionBody = functionDefinition->get_body();
               ROSE_ASSERT(functionBody != NULL);

               ControlFlowGraph controlflow;

            // The CFG can only be called on a function definition (at present)
               makeCfg(functionDefinition,controlflow);
               string fileName = functionDeclaration->get_name().str();
               fileName += ".dot";
               ofstream dotfile(fileName.c_str());
               printCfgAsDot(dotfile, controlflow);
             }
        }
   }
Esempio n. 12
0
int
main ( int argc,  char * argv[] )
{
  //init_poet();  // initialize poet

  if (argc <= 1) {
      PrintUsage(argv[0]);
      return -1;
  }

#ifdef USE_OMEGA
  std::stringstream buffer;
  buffer << argv[argc-1] << std::endl;
  DepStats.SetFileName(buffer.str());
#endif

  vector<string> argvList(argv, argv + argc);
  CmdOptions::GetInstance()->SetOptions(argvList);

  ArrayAnnotation* array_annot = ArrayAnnotation::get_inst();
  array_annot->register_annot();

  //OperatorSideEffectAnnotation* funcAnnot=OperatorSideEffectAnnotation::get_inst();
  //funcAnnot->register_annot();
  LoopTransformInterface::set_sideEffectInfo(array_annot);

  ArrayInterface anal(*array_annot);
  LoopTransformInterface::set_arrayInfo(&anal);

  ReadAnnotation::get_inst()->read();
  if (DebugAnnot()) {
   // funcAnnot->Dump();
    array_annot->Dump();
  }

  AssumeNoAlias aliasInfo;
  LoopTransformInterface::set_aliasInfo(&aliasInfo);

  LoopTransformInterface::cmdline_configure(argvList);

  SgProject *sageProject = new SgProject ( argvList);
  FixFileInfo(sageProject);

  // DQ (11/19/2013): Added AST consistency tests.
     AstTests::runAllTests(sageProject);

  int filenum = sageProject->numberOfFiles();
  for (int i = 0; i < filenum; ++i) {

  // DQ (11/19/2013): Added AST consistency tests.
     AstTests::runAllTests(sageProject);

    SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]);
    ROSE_ASSERT(sageFile != NULL);

    std::string fname = sageFile->get_file_info()->get_raw_filename();
    fname=fname.substr(fname.find_last_of('/')+1);

    AutoTuningInterface tuning(fname);

    LoopTransformInterface::set_tuningInterface(&tuning);
    SgGlobal *root = sageFile->get_globalScope();
    ROSE_ASSERT(root != NULL);

    SgDeclarationStatementPtrList declList = root->get_declarations ();

 // DQ (11/19/2013): Added AST consistency tests.
    AstTests::runAllTests(sageProject);

    for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
    {
      SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
      if (func == 0) continue;
      SgFunctionDefinition *defn = func->get_definition();
      if (defn == 0) continue;
      SgBasicBlock *stmts = defn->get_body();  
      AstInterfaceImpl scope(stmts);

   // DQ (11/19/2013): Added AST consistency tests.
      AstTests::runAllTests(sageProject);

   // DQ (11/19/2013): Added AST consistency tests.
      AstTests::runAllTests(sageProject);

      LoopTransformInterface::TransformTraverse(scope,AstNodePtrImpl(stmts));

#if 0
   // DQ (11/19/2013): Added AST consistency tests (this fails).
      AstTests::runAllTests(sageProject);
#endif
    }
    tuning.GenOutput();

#if 0
  // DQ (11/19/2013): Added AST consistency tests (this fails).
     AstTests::runAllTests(sageProject);
#endif
  }

//   if (CmdOptions::GetInstance()->HasOption("-fd")) {
//       simpleIndexFiniteDifferencing(sageProject);
//   }
//   if (CmdOptions::GetInstance()->HasOption("-pre")) {
//       partialRedundancyElimination(sageProject);
//   }

#if 0
  // DQ (11/19/2013): Added AST consistency tests (this fails).
     AstTests::runAllTests(sageProject);
#endif

     unparseProject(sageProject);
   //backend(sageProject);

#ifdef USE_OMEGA
     DepStats.SetDepChoice(0x1 | 0x2 | 0x4);
     DepStats.PrintResults();
#endif

  return 0;
}
Esempio n. 13
0
void RewriteFSM::visitSgFunctionDeclaration(SgFunctionDeclaration *FD)
{
  SgFunctionDefinition *fdef = FD->get_definition();
  if (!fdef) {
    return;
  }

  if (debugHooks) {
    std::cout << "Func decl: " << FD << " " << FD->get_name() << std::endl;
  }

  std::string modName = FD->get_name().getString();
  HtdInfoAttribute *htd = getHtdInfoAttribute(fdef);

  bool isStreamingStencil = false;
  size_t pos = 0;
  if ((pos = modName.find(StencilStreamPrefix)) != std::string::npos
      && pos == 0) {
    isStreamingStencil = true;
  }

#define hostEntryPrefix  "__HTC_HOST_ENTRY_"
  bool isHostEntry = false;
  if ((pos = modName.find(hostEntryPrefix)) != std::string::npos
      && pos == 0) {
    isHostEntry = true;
  }

  // Emit a default, unnamed thread group.
  std::string modWidth = boost::to_upper_copy(modName) + "_HTID_W";
  if (isStreamingStencil) {
    // The streaming version of a stencil must have width 0.
    htd->appendDefine(modWidth, "0");
  } else if (isHostEntry) {
    htd->appendDefine(modWidth, "1");
  } else if (htd->moduleWidth != -1) {
    htd->appendDefine(modWidth, boost::lexical_cast<std::string>(htd->moduleWidth));
  } else {
    DefaultModuleWidthAttribute *dwAttr = 
        getDefaultModuleWidthAttribute(SageInterface::getGlobalScope(fdef));
    if (dwAttr) {
      htd->appendDefine(modWidth, boost::lexical_cast<std::string>(dwAttr->width));
    } else { 
      htd->appendDefine(modWidth, "5");
    }
  }
  htd->appendModule(modName, "", modWidth);

  // For streaming stencils, ProcessStencils inserts a canned sequence,
  // so we bypass generating a normal FSM.
  if (isStreamingStencil) {
    return;
  }

  //
  // Create new case body blocks for each state.
  // The first executable statement starts the first state, and each
  // label starts a new state.
  //
  std::map<SgLabelStatement *, int> labelToState;
  std::map<int, std::string> stateToName;
  SgBasicBlock *funcBody = isSgBasicBlock(fdef->get_body());
  SgStatementPtrList &stmts = funcBody->get_statements();

  std::vector<SgStatement *>::iterator SI, SP;
  for (SI = stmts.begin(); SI != stmts.end(); ++SI) {
    if (!isSgDeclarationStatement(*SI)) {
      break;
    }
  }
  if (SI == stmts.end()) {
    return;
  }
  SP = SI;

  std::vector<SgBasicBlock *> newBlocks;
  SgBasicBlock *newbb = SageBuilder::buildBasicBlock();
  newBlocks.push_back(newbb);
  stateToName[1] = "__START";
  bool prevIsLabel = false;
  for (; SI != stmts.end(); ++SI) {
    SgStatement *stmt = *SI;
    SgLabelStatement *labstmt = isSgLabelStatement(stmt);
    if (labstmt) {
      if (!prevIsLabel) {
        newbb = SageBuilder::buildBasicBlock();
        newBlocks.push_back(newbb);
      }
      int snum = newBlocks.size();
      labelToState[labstmt] = snum;
      stateToName[snum] += "__" + labstmt->get_label().getString();
      prevIsLabel = true;
#if 1
      // TODO: these labels can carry preproc infos-- but the unparser
      // doesn't output them if the label is not actually output.
      AttachedPreprocessingInfoType *comments =
          labstmt->getAttachedPreprocessingInfo();
      if (comments && comments->size() > 0) {
        std::cerr << "DEVWARN: losing Preprocinfo on label" << std::endl;
        SageInterface::dumpPreprocInfo(labstmt);
      }
#endif
      stmt->unsetOutputInCodeGeneration();
      SageInterface::appendStatement(stmt, newbb);
    } else {
      prevIsLabel = false;
      SageInterface::appendStatement(stmt, newbb);
    }
  }
  stmts.erase(SP, stmts.end());

  // Add module name to each state name and create enum decl.
  SgEnumDeclaration *enumDecl = SageBuilder::buildEnumDeclaration("states",
    fdef);
  for (int i = 1; i <= newBlocks.size(); i++) {
    stateToName[i] = modName + stateToName[i];
    boost::to_upper(stateToName[i]);
    SgName nm(stateToName[i]);
    SgInitializedName *enumerator = SageBuilder::buildInitializedName(nm,
        SageBuilder::buildIntType(),
        SageBuilder::buildAssignInitializer(SageBuilder::buildIntVal(i)));
    enumerator->set_scope(funcBody);
    enumDecl->append_enumerator(enumerator);

    // Add the instruction to the htd info.
    htd->appendInst(nm.getString());
  }
  SageInterface::prependStatement(enumDecl, funcBody);
  if (!debugHooks) {
    enumDecl->unsetOutputInCodeGeneration();
  }

  SgGlobal *GS = SageInterface::getGlobalScope(FD);
  SgVariableDeclaration *declHtValid = 
      HtDeclMgr::buildHtlVarDecl("PR_htValid", GS);
  SgVariableDeclaration *declHtInst = 
      HtDeclMgr::buildHtlVarDecl("PR_htInst", GS);
  SgFunctionDeclaration *declHtContinue = 
      HtDeclMgr::buildHtlFuncDecl("HtContinue", GS);
  SgFunctionDeclaration *declHtAssert =
     HtDeclMgr::buildHtlFuncDecl("HtAssert", GS);

  //
  // Create the finite state machine switch statement "switch (PR_htInst)",
  // and insert guard "if (PR_htValid)".
  //
  SgBasicBlock *newSwitchBody = SageBuilder::buildBasicBlock();

  SgExpression *htInstExpr = SageBuilder::buildVarRefExp(declHtInst);
  SgSwitchStatement *newSwitch = 
      SageBuilder::buildSwitchStatement(htInstExpr, newSwitchBody);

  SgExpression *htValidExpr = SageBuilder::buildVarRefExp(declHtValid);
  SgIfStmt *newIfStmt = SageBuilder::buildIfStmt(htValidExpr,
      SageBuilder::buildBasicBlock(newSwitch), 0);
  SageInterface::appendStatement(newIfStmt, funcBody);

  int casenum = 1;
  foreach (SgBasicBlock *newCaseBody, newBlocks) {
    SgExpression *caseExpr = 
        SageBuilder::buildEnumVal_nfi(casenum, enumDecl, stateToName[casenum]);
    SgCaseOptionStmt *newCase = 
        SageBuilder::buildCaseOptionStmt(caseExpr, newCaseBody);
    SageInterface::appendStatement(newCase, newSwitchBody);
    casenum++;
  }
Esempio n. 14
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
   {
#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     SgGlobal* globalScope = TransformationSupport::getGlobalScope(funcall);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

     SgExpression* funname = funcall->get_function();
     SgExpression* funname2 = isSgFunctionRefExp(funname);
     SgDotExp* dotexp = isSgDotExp(funname);
     SgArrowExp* arrowexp = isSgArrowExp(funname);
     SgExpression* thisptr = 0;
     if (dotexp || arrowexp)
        {
          funname2 = isSgBinaryOp(funname)->get_rhs_operand();
          if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
              SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
              ROSE_ASSERT (isSgInitializer(ai->get_operand()));
#if 1
              printf ("ai = %p ai->isTransformation() = %s \n",ai,ai->isTransformation() ? "true" : "false");
#endif
              SgInitializedName* in = isSgInitializedName(ai->get_parent());
              ROSE_ASSERT (in);
              removeRedundantCopyInConstruction(in);
              lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
          } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
          } else {
            assert (false);
          }
        }

     if (!funname2)
        {
       // std::cout << "Inline failed: not a call to a named function" << std::endl;
          return false; // Probably a call through a fun ptr
        }

     SgFunctionSymbol* funsym = 0;
     if (isSgFunctionRefExp(funname2))
          funsym = isSgFunctionRefExp(funname2)->get_symbol();
       else
          if (isSgMemberFunctionRefExp(funname2))
               funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
            else
               assert (false);

     assert (funsym);
     if (isSgMemberFunctionSymbol(funsym) &&
         isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
        {
       // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
          return false;
        }

     SgFunctionDeclaration* fundecl = funsym->get_declaration();
     fundecl = fundecl ? isSgFunctionDeclaration(fundecl->get_definingDeclaration()) : NULL;

     SgFunctionDefinition* fundef = fundecl ? fundecl->get_definition() : NULL;
     if (!fundef)
        {
       // std::cout << "Inline failed: no definition is visible" << std::endl;
          return false; // No definition of the function is visible
        }
     if (!allowRecursion)
        {
          SgNode* my_fundef = funcall;
          while (my_fundef && !isSgFunctionDefinition(my_fundef))
             {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
               my_fundef = my_fundef->get_parent();
               ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
             }
       // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
          assert (isSgFunctionDefinition(my_fundef));
          if (isSgFunctionDefinition(my_fundef) == fundef)
             {
               std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
               return false;
             }
        }

     SgVariableDeclaration* thisdecl = 0;
     SgName thisname("this__");
     thisname << ++gensym_counter;
     SgInitializedName* thisinitname = 0;
     if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
        {
          assert (thisptr != NULL);
          SgType* thisptrtype = thisptr->get_type();
          const SgSpecialFunctionModifier& specialMod = 
            funsym->get_declaration()->get_specialFunctionModifier();
          if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
          }
          SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
       // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
          thisptrtype = new SgModifierType(thisptrtype);
          isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
       // }
       // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
          SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
          assignInitializer->set_endOfConstruct(SgNULL_FILE);
#if 1
          printf ("before new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
#if 1
          printf ("(after new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl->set_endOfConstruct(SgNULL_FILE);
          thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
          thisdecl->set_definingDeclaration(thisdecl);

          thisinitname = (thisdecl->get_variables()).back();
          //thisinitname = lastElementOfContainer(thisdecl->get_variables());
          // thisinitname->set_endOfConstruct(SgNULL_FILE);
          assignInitializer->set_parent(thisinitname);
          markAsTransformation(assignInitializer);

       // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

       // DQ (6/23/2006): New test
          ROSE_ASSERT(assignInitializer->get_parent() != NULL);
        }

     // Get the list of actual argument expressions from the function call, which we'll later use to initialize new local
     // variables in the inlined code.  We need to detach the actual arguments from the AST here since we'll be reattaching
     // them below (otherwise we would violate the invariant that the AST is a tree).
     SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);
     SgExpressionPtrList funargs = funcall->get_args()->get_expressions();
     funcall->get_args()->get_expressions().clear();
     BOOST_FOREACH (SgExpression *actual, funargs)
         actual->set_parent(NULL);

     // Make a copy of the to-be-inlined function so we're not modifying and (re)inserting the original.
     SgBasicBlock* funbody_raw = fundef->get_body();
     SgInitializedNamePtrList& params = fundecl->get_args();
     std::vector<SgInitializedName*> inits;
     SgTreeCopy tc;
     SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
     ROSE_ASSERT (function_copy);
     SgBasicBlock* funbody_copy = function_copy->get_body();

     renameLabels(funbody_copy, targetFunction);
     ASSERT_require(funbody_raw->get_symbol_table()->size() == funbody_copy->get_symbol_table()->size());

     // We don't need to keep the copied SgFunctionDefinition now that the labels in it have been moved to the target function
     // (having it in the memory pool confuses the AST tests), but we must not delete the formal argument list or the body
     // because we need them below.
     if (function_copy->get_declaration()) {
         ASSERT_require(function_copy->get_declaration()->get_parent() == function_copy);
         function_copy->get_declaration()->set_parent(NULL);
         function_copy->set_declaration(NULL);
     }
     if (function_copy->get_body()) {
         ASSERT_require(function_copy->get_body()->get_parent() == function_copy);
         function_copy->get_body()->set_parent(NULL);
         function_copy->set_body(NULL);
     }
     delete function_copy;
     function_copy = NULL;
#if 0
     SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
     pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaBegin->set_parent(pragmaBeginDecl);
     pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
     funbody_copy->prepend_statement(pragmaBeginDecl);
     pragmaBeginDecl->set_parent(funbody_copy);
#endif

     // In the to-be-inserted function body, create new local variables with distinct non-conflicting names, one per formal
     // argument and having the same type as the formal argument. Initialize those new local variables with the actual
     // arguments.  Also, build a paramMap that maps each formal argument (SgInitializedName) to its corresponding new local
     // variable (SgVariableSymbol).
     ReplaceParameterUseVisitor::paramMapType paramMap;
     SgInitializedNamePtrList::iterator formalIter = params.begin();
     SgExpressionPtrList::iterator actualIter = funargs.begin();
     for (size_t argNumber=0;
          formalIter != params.end() && actualIter != funargs.end();
          ++argNumber, ++formalIter, ++actualIter) {
         SgInitializedName *formalArg = *formalIter;
         SgExpression *actualArg = *actualIter;

         // Build the new local variable.
         // FIXME[Robb P. Matzke 2014-12-12]: we need a better way to generate a non-conflicting local variable name
         SgAssignInitializer* initializer = new SgAssignInitializer(SgNULL_FILE, actualArg, formalArg->get_type());
         ASSERT_not_null(initializer);
         initializer->set_endOfConstruct(SgNULL_FILE);
#if 1
         printf ("initializer = %p initializer->isTransformation() = %s \n",initializer,initializer->isTransformation() ? "true" : "false");
#endif
         SgName shadow_name(formalArg->get_name());
         shadow_name << "__" << ++gensym_counter;
         SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE, shadow_name, formalArg->get_type(), initializer);
         vardecl->set_definingDeclaration(vardecl);
         vardecl->set_endOfConstruct(SgNULL_FILE);
         vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
         vardecl->set_parent(funbody_copy);

         // Insert the new local variable into the (near) beginning of the to-be-inserted function body.  We insert them in the
         // order their corresponding actuals/formals appear, although the C++ standard does not require this order of
         // evaluation.
         SgInitializedName* init = vardecl->get_variables().back();
         inits.push_back(init);
         initializer->set_parent(init);
         init->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + argNumber, vardecl);
         SgVariableSymbol* sym = new SgVariableSymbol(init);
         paramMap[formalArg] = sym;
         funbody_copy->insert_symbol(shadow_name, sym);
         sym->set_parent(funbody_copy->get_symbol_table());
     }

     // Similarly for "this". We create a local variable in the to-be-inserted function body that will be initialized with the
     // caller's "this".
     if (thisdecl) {
         thisdecl->set_parent(funbody_copy);
         thisinitname->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
         SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
         funbody_copy->insert_symbol(thisname, thisSym);
         thisSym->set_parent(funbody_copy->get_symbol_table());
         ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
     }
     ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

     SgName end_of_inline_name = "rose_inline_end__";
     end_of_inline_name << ++gensym_counter;
     SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
     end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
     printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

  // Need to set the parent of funbody_copy to avoid error.
     funbody_copy->set_parent(funbody_raw->get_parent());

     printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

     printf ("funbody_raw->get_statements().size()  = %" PRIuPTR " \n",funbody_raw->get_statements().size());
     printf ("funbody_copy->get_statements().size() = %" PRIuPTR " \n",funbody_copy->get_statements().size());

     printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
     printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

     printf ("Output the symbol table for funbody_raw \n");
     funbody_raw->get_symbol_table()->print("debugging copy problem");

  // printf ("Output the symbol table for funbody_copy \n");
  // funbody_copy->get_symbol_table()->print("debugging copy problem");

     SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
     ROSE_ASSERT(project_copy != NULL);

     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
     generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

     funbody_copy->append_statement(end_of_inline_label);
     end_of_inline_label->set_scope(targetFunction);
     SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
     end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
     targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);

     // To ensure that there is some statement after the label
     SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
     dummyStatement->set_endOfConstruct(SgNULL_FILE);
     funbody_copy->append_statement(dummyStatement);
     dummyStatement->set_parent(funbody_copy);
#if 0
     SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
     pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaEnd->set_parent(pragmaEndDecl);
     pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
     funbody_copy->append_statement(pragmaEndDecl);
     pragmaEndDecl->set_parent(funbody_copy);
#endif

     ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
     replaceExpressionWithStatement(funcall, &previsitor);

     // Make sure the AST is consistent. To save time, we'll just fix things that we know can go wrong. For instance, the
     // SgAsmExpression.p_lvalue data member is required to be true for certain operators and is set to false in other
     // situations. Since we've introduced new expressions into the AST we need to adjust their p_lvalue according to the
     // operators where they were inserted.
     markLhsValues(targetFunction);
#ifdef NDEBUG
     AstTests::runAllTests(SageInterface::getProject());
#endif

#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

  // DQ (4/7/2015): This fixes something I was required to fix over the weekend and which is fixed more directly, I think.
  // Mark the things we insert as being transformations so they get inserted into the output by backend()
     markAsTransformation(funbody_copy);

     return true;
   }
Esempio n. 15
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
{
    SgExpression* funname = funcall->get_function();
    SgExpression* funname2 = isSgFunctionRefExp(funname);
    SgDotExp* dotexp = isSgDotExp(funname);
    SgArrowExp* arrowexp = isSgArrowExp(funname);
    SgExpression* thisptr = 0;
    if (dotexp || arrowexp)
    {
        funname2 = isSgBinaryOp(funname)->get_rhs_operand();
        if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
                SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
                ROSE_ASSERT (isSgInitializer(ai->get_operand()));
                SgInitializedName* in = isSgInitializedName(ai->get_parent());
                ROSE_ASSERT (in);
                removeRedundantCopyInConstruction(in);
                lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
        } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
        } else {
            assert (false);
        }
    }

    if (!funname2)
    {
        // std::cout << "Inline failed: not a call to a named function" << std::endl;
        return false; // Probably a call through a fun ptr
    }

    SgFunctionSymbol* funsym = 0;
    if (isSgFunctionRefExp(funname2))
        funsym = isSgFunctionRefExp(funname2)->get_symbol();
    else if (isSgMemberFunctionRefExp(funname2))
        funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
    else
        assert (false);

    assert (funsym);
    if (isSgMemberFunctionSymbol(funsym) && isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
    {
        // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
        return false;
    }

    SgFunctionDeclaration* fundecl = funsym->get_declaration();
    SgFunctionDefinition* fundef = fundecl->get_definition();
    if (!fundef)
    {
        // std::cout << "Inline failed: no definition is visible" << std::endl;
        return false; // No definition of the function is visible
    }
    if (!allowRecursion)
    {
        SgNode* my_fundef = funcall;
        while (my_fundef && !isSgFunctionDefinition(my_fundef))
        {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
            my_fundef = my_fundef->get_parent();
            ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        }
        // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        assert (isSgFunctionDefinition(my_fundef));
        if (isSgFunctionDefinition(my_fundef) == fundef)
        {
            std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
            return false;
        }
    }

    SgVariableDeclaration* thisdecl = 0;
    SgName thisname("this__");
    thisname << ++gensym_counter;
    SgInitializedName* thisinitname = 0;
    if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
    {
        assert (thisptr != NULL);
        SgType* thisptrtype = thisptr->get_type();
        const SgSpecialFunctionModifier& specialMod =
            funsym->get_declaration()->get_specialFunctionModifier();
        if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
        }
        SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
        // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
        thisptrtype = new SgModifierType(thisptrtype);
        isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
        // }
        // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
        SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
        assignInitializer->set_endOfConstruct(SgNULL_FILE);
        // thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, new SgAssignInitializer(SgNULL_FILE, thisptr));
        thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
        thisdecl->set_endOfConstruct(SgNULL_FILE);
        thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
        thisdecl->set_definingDeclaration(thisdecl);

        thisinitname = (thisdecl->get_variables()).back();
        //thisinitname = lastElementOfContainer(thisdecl->get_variables());
        // thisinitname->set_endOfConstruct(SgNULL_FILE);
        assignInitializer->set_parent(thisinitname);

        // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

        // DQ (6/23/2006): New test
        ROSE_ASSERT(assignInitializer->get_parent() != NULL);
    }

    std::cout << "Trying to inline function " << fundecl->get_name().str() << std::endl;
    SgBasicBlock* funbody_raw = fundef->get_body();
    SgInitializedNamePtrList& params = fundecl->get_args();
    SgInitializedNamePtrList::iterator i;
    SgExpressionPtrList& funargs = funcall->get_args()->get_expressions();
    SgExpressionPtrList::iterator j;
    //int ctr; // unused variable, Liao
    std::vector<SgInitializedName*> inits;
    SgTreeCopy tc;
    SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
    ROSE_ASSERT (function_copy);
    SgBasicBlock* funbody_copy = function_copy->get_body();


    SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);

    renameLabels(funbody_copy, targetFunction);
    std::cout << "Original symbol count: " << funbody_raw->get_symbol_table()->size() << std::endl;
    std::cout << "Copied symbol count: " << funbody_copy->get_symbol_table()->size() << std::endl;
    // std::cout << "Original symbol count f: " << fundef->get_symbol_table()->size() << std::endl;
    // std::cout << "Copied symbol count f: " << function_copy->get_symbol_table()->size() << std::endl;
    // We don't need to keep the copied function definition now that the
    // labels in it have been moved to the target function.  Having it in the
    // memory pool confuses the AST tests.
    function_copy->set_declaration(NULL);
    function_copy->set_body(NULL);
    delete function_copy;
    function_copy = NULL;
#if 0
    SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
    pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaBegin->set_parent(pragmaBeginDecl);
    pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
    funbody_copy->prepend_statement(pragmaBeginDecl);
    pragmaBeginDecl->set_parent(funbody_copy);
#endif
    ReplaceParameterUseVisitor::paramMapType paramMap;
    for (i = params.begin(), j = funargs.begin(); i != params.end() && j != funargs.end(); ++i, ++j)
    {
        SgAssignInitializer* ai = new SgAssignInitializer(SgNULL_FILE, *j, (*i)->get_type());
        ROSE_ASSERT(ai != NULL);
        ai->set_endOfConstruct(SgNULL_FILE);
        SgName shadow_name((*i)->get_name());
        shadow_name << "__" << ++gensym_counter;
        SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE,shadow_name,(*i)->get_type(),ai);
        vardecl->set_definingDeclaration(vardecl);
        vardecl->set_endOfConstruct(SgNULL_FILE);
        vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);

        printf ("Built new SgVariableDeclaration #2 = %p = %s initializer = %p \n",vardecl,shadow_name.str(),(*(vardecl->get_variables().begin()))->get_initializer());

        vardecl->set_parent(funbody_copy);
        SgInitializedName* init = (vardecl->get_variables()).back();
        // init->set_endOfConstruct(SgNULL_FILE);
        inits.push_back(init);
        ai->set_parent(init);
        init->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + (i - params.begin()), vardecl);
        SgVariableSymbol* sym = new SgVariableSymbol(init);
        paramMap[*i] = sym;
        funbody_copy->insert_symbol(shadow_name, sym);
        sym->set_parent(funbody_copy->get_symbol_table());
    }

    if (thisdecl)
    {
        thisdecl->set_parent(funbody_copy);
        thisinitname->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
        SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
        funbody_copy->insert_symbol(thisname, thisSym);
        thisSym->set_parent(funbody_copy->get_symbol_table());
        ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
    }
    ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

    SgName end_of_inline_name = "rose_inline_end__";
    end_of_inline_name << ++gensym_counter;
    SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
    end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
    printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

    // Need to set the parent of funbody_copy to avoid error.
    funbody_copy->set_parent(funbody_raw->get_parent());

    printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

    printf ("funbody_raw->get_statements().size()  = %zu \n",funbody_raw->get_statements().size());
    printf ("funbody_copy->get_statements().size() = %zu \n",funbody_copy->get_statements().size());

    printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
    printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

    printf ("Output the symbol table for funbody_raw \n");
    funbody_raw->get_symbol_table()->print("debugging copy problem");

    // printf ("Output the symbol table for funbody_copy \n");
    // funbody_copy->get_symbol_table()->print("debugging copy problem");

    SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
    ROSE_ASSERT(project_copy != NULL);

    const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
    generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

    // printf ("Exiting as a test after testing the symbol table \n");
    // ROSE_ASSERT(false);

    funbody_copy->append_statement(end_of_inline_label);
    end_of_inline_label->set_scope(targetFunction);
    SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
    end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
    targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);
    // To ensure that there is some statement after the label
    SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
    dummyStatement->set_endOfConstruct(SgNULL_FILE);
    funbody_copy->append_statement(dummyStatement);
    dummyStatement->set_parent(funbody_copy);
#if 0
    SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
    pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaEnd->set_parent(pragmaEndDecl);
    pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
    funbody_copy->append_statement(pragmaEndDecl);
    pragmaEndDecl->set_parent(funbody_copy);
#endif
    // std::cout << "funbody_copy is " << funbody_copy->unparseToString() << std::endl;

    ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
    // std::cout << "funbody_copy 2 is " << funbody_copy->unparseToString() << std::endl;
    replaceExpressionWithStatement(funcall, &previsitor);
    // std::cout << "Inline succeeded " << funcall->get_parent()->unparseToString() << std::endl;
    return true;
}
void
InsertFortranContainsStatement::visit ( SgNode* node )
   {
  // DQ (10/3/2008): This bug in OFP is now fixed so no fixup is required.
     printf ("Error: fixup of contains statement no longer required. \n");
     ROSE_ASSERT(false);

  // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST.
     ROSE_ASSERT(node != NULL);
#if 0
     Sg_File_Info* fileInfo = node->get_file_info();

     printf ("node = %s fileInfo = %p \n",node->class_name().c_str(),fileInfo);
     if (fileInfo != NULL)
        {
          bool isCompilerGenerated = fileInfo->isCompilerGenerated();
          std::string filename = fileInfo->get_filenameString();
          int line_number = fileInfo->get_line();
          int column_number = fileInfo->get_line();

          printf ("--- isCompilerGenerated = %s position = %d:%d filename = %s \n",isCompilerGenerated ? "true" : "false",line_number,column_number,filename.c_str());
        }
#endif

     SgFunctionDefinition* functionDefinition = isSgFunctionDefinition(node);

  // This is for handling where CONTAINS is required in a function
     if (functionDefinition != NULL)
        {
          SgBasicBlock* block = functionDefinition->get_body();
          SgStatementPtrList & statementList = block->get_statements();
          SgStatementPtrList::iterator i = statementList.begin();

          bool firstFunctionDeclaration = false;
          bool functionDeclarationSeen  = false;

          while (i != statementList.end() && firstFunctionDeclaration == false)
             {
               SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);

            // DQ (1/20/2008): Note that entry statements should not cause introduction of a contains statement!
               if (isSgEntryStatement(functionDeclaration) != NULL)
                    functionDeclaration = NULL;

               if (functionDeclaration != NULL)
                  {
                    firstFunctionDeclaration = functionDeclarationSeen == false;
                    functionDeclarationSeen  = true;

                    if (firstFunctionDeclaration == true)
                       {
                      // Insert a CONTAINS statement.
                      // printf ("Building a contains statement (in function) \n");
                         SgContainsStatement* containsStatement = new SgContainsStatement();
                         SageInterface::setSourcePosition(containsStatement);
                         containsStatement->set_definingDeclaration(containsStatement);

                         block->get_statements().insert(i,containsStatement);
                         containsStatement->set_parent(block);
                         ROSE_ASSERT(containsStatement->get_parent() != NULL);
                       }
                  }

               i++;
             }
        }

#if 0
  // OFP now has better support for the CONTAINS statement so this code is not longer required.

  // The use of CONTAINS in modules appears to be handled by OFP, so no fixup is required.
     SgClassDefinition* classDefinition = isSgClassDefinition(node);

  // This is for handling where CONTAINS is required in a module
     if (classDefinition != NULL)
        {
          SgDeclarationStatementPtrList & statementList = classDefinition->get_members();
          SgDeclarationStatementPtrList::iterator i = statementList.begin();

          bool firstFunctionDeclaration = false;
          bool functionDeclarationSeen  = false;

          while (i != statementList.end() && firstFunctionDeclaration == false)
             {
               printf ("InsertFortranContainsStatement: *i in statementList in module = %p = %s \n",*i,(*i)->class_name().c_str());

               SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
               if (functionDeclaration != NULL)
                  {
                    firstFunctionDeclaration = functionDeclarationSeen == false;
                    functionDeclarationSeen  = true;

                    if (firstFunctionDeclaration == true)
                       {
                      // Insert a CONTAINS statement.
                      // printf ("Building a contains statement (in module) \n");
                         SgContainsStatement* containsStatement = new SgContainsStatement();
                         SageInterface::setSourcePosition(containsStatement);
                         containsStatement->set_definingDeclaration(containsStatement);

                      // This insert function does not set the parent (unlike for SgBasicBlock)
                         classDefinition->get_members().insert(i,containsStatement);
                         containsStatement->set_parent(classDefinition);
                         ROSE_ASSERT(containsStatement->get_parent() != NULL);
                       }
                  }

               i++;
             }
        }
#endif
   }
Esempio n. 17
0
void CudaOutliner::functionParameterHandling(ASTtools::VarSymSet_t& syms, // regular (shared) parameters
					     MintHostSymToDevInitMap_t hostToDevVars,		                      
					     const ASTtools::VarSymSet_t& pdSyms, // those must use pointer dereference
					     const ASTtools::VarSymSet_t& pSyms, 
					     // private variables, handles dead variables (neither livein nor liveout) 
					     std::set<SgInitializedName*> & readOnlyVars,
					     std::set<SgInitializedName*> & liveOutVars,
					     SgFunctionDeclaration* func) // the outlined function
{

  //ASTtools::VarSymSet_t syms;
  //std::copy(syms1.begin(), syms1.end(), std::inserter(syms,syms.begin()));

  VarSymRemap_t sym_remap;     // variable remapping for regular(shared) variables
  VarSymRemap_t private_remap; // variable remapping for private/firstprivate/reduction variables
  ROSE_ASSERT (func);
  SgFunctionParameterList* params = func->get_parameterList ();
  ROSE_ASSERT (params);
  SgFunctionDefinition* def = func->get_definition ();
  ROSE_ASSERT (def);
  SgBasicBlock* body = def->get_body ();
  ROSE_ASSERT (body);

  // Place in which to put new outlined variable symbols.
  SgScopeStatement* args_scope = isSgScopeStatement (body);
  ROSE_ASSERT (args_scope);

  // For each variable symbol, create an equivalent function parameter. 
  // Also create unpacking and repacking statements.
  int counter=0;
//  SgInitializedName* parameter1=NULL; // the wrapper parameter
  SgVariableDeclaration*  local_var_decl  =  NULL;

  // handle OpenMP private variables/ or those which are neither live-in or live-out
  handlePrivateVariables(pSyms, body, private_remap);

  // --------------------------------------------------
  // for each parameters passed to the outlined function
  // They include parameters for regular shared variables and 
  // also the shared copies for firstprivate and reduction variables

  for (ASTtools::VarSymSet_t::reverse_iterator i = syms.rbegin ();i != syms.rend (); ++i)
  {
    // Basic information about the variable to be passed into the outlined function
    // Variable symbol name
    const SgInitializedName* i_name = (*i)->get_declaration ();
    ROSE_ASSERT (i_name);
    string name_str = i_name->get_name ().str ();

    SgName p_sg_name ( name_str);
    //SgType* i_type = i_name->get_type ();
    bool readOnly = false;
    if (readOnlyVars.find(const_cast<SgInitializedName*> (i_name)) != readOnlyVars.end())
      readOnly = true;

    // step 1. Create parameters and insert it into the parameter list.
    // ----------------------------------------
    SgInitializedName* p_init_name = NULL;
    SgVariableSymbol* host_sym= const_cast<SgVariableSymbol*> (*i);
    
    if(hostToDevVars.find(host_sym) != hostToDevVars.end() ){
      //these are vector variables
      SgInitializedName* dev_name = hostToDevVars[host_sym];
      p_init_name = createInitName (dev_name->get_name(), dev_name->get_type(), func, def);

      ROSE_ASSERT (p_init_name);
      prependArg(func->get_parameterList (),p_init_name);
    }
    else{
      //scalar values
      p_init_name = createOneFunctionParameter(i_name, readOnly, func); 
    }
    // step 2. Create unpacking/unwrapping statements, also record variables to be replaced
    // ----------------------------------------
   // bool isPointerDeref = false; 

    if (Outliner::enable_classic) 
      {  // classic methods use parameters directly, no unpacking is needed
	if (!readOnly) 
	  //read only variable should not have local variable declaration, using parameter directly
	  // taking advantage of the same parameter names for readOnly variables
	  // Let postprocessing to patch up symbols for them
	  {
	    // non-readonly variables need to be mapped to their parameters with different names (p__)
	    // remapVarSyms() will use pointer dereferencing for all of them by default in C, 
	    // this is enough to mimic the classic outlining work 
	    //handleSharedVariables(*i, p_init_name, args_scope, sym_remap);
	    //handleSharedVariables(*i, body, sym_remap);

	    //Didem: I comment out this part because it uses pointer deferencing for all non-readonly variables.
	    //recordSymRemap(*i,p_init_name, args_scope, sym_remap); 
	  }
      }
    else 
      { 
	local_var_decl  = NULL; //createUnpackDecl (p_init_name, counter, isPointerDeref, i_name , NULL, body);
	ROSE_ASSERT (local_var_decl);
	prependStatement (local_var_decl,body);
	// regular and shared variables used the first local declaration
        recordSymRemap (*i, local_var_decl, args_scope, sym_remap);
	// transfer the value for firstprivate variables. 
      }


    // step 3. Create and insert companion re-pack statement in the end of the function body
    // If necessary
    // ----------------------------------------
    SgInitializedName* local_var_init = NULL;
    if (local_var_decl != NULL )
      local_var_init = local_var_decl->get_decl_item (SgName (name_str.c_str ()));

    if (!SageInterface::is_Fortran_language() && !Outliner::enable_classic)  
      ROSE_ASSERT(local_var_init!=NULL);  


    SgExprStatement* pack_stmt = createPackStmt (local_var_init);
    if (pack_stmt)
      appendStatement (pack_stmt,body);
    
    counter ++;
  } //end for

  // variable substitution
  SgBasicBlock* func_body = func->get_definition()->get_body();
  remapVarSyms (sym_remap, pdSyms, private_remap , func_body);
}
Esempio n. 18
0
    void process() {
        int i;

        for (i = 0; i < fdefList.size(); i++) {
            SgFunctionDefinition* fndef = fdefList.at(i);       

            if (fndef == NULL) {
                return;
            }

            std::string functionName = 
                fndef->get_declaration()->get_name().getString();

            SgFunctionDeclaration *f = fndef->get_declaration();

            if (!debugHooks) {
                SgNode *body = fndef->get_body();

                // Move any preprocessing info before the function to a new
                // null statement preceding the function.
                AttachedPreprocessingInfoType save_buf;
                SageInterface::cutPreprocessingInfo(f, 
                                                    PreprocessingInfo::before, 
                                                    save_buf) ;
                if (save_buf.size()) {
                    SgVariableDeclaration *dummy = 
                        SageBuilder::buildVariableDeclaration(
                            "___htc_dummy_decl_for_preproc_info", 
                            SageBuilder::buildIntType(), 0, f->get_scope());
                    SageInterface::setExtern(dummy);

                    SageInterface::insertStatementBefore(f, dummy);
                    SageInterface::pastePreprocessingInfo(
                        dummy, 
                        PreprocessingInfo::before, 
                        save_buf); 
                }

                SageInterface::addTextForUnparser(
                    f, 
                    "\n#if 0",     
                    AstUnparseAttribute::e_before);

                std::string CapFnName = Capitalize(functionName);
                std::string before_body = "\n#endif\n";
                std::string macro_name = "HTC_KEEP_MODULE_" + Upper(functionName);
                before_body += 
                    "#ifdef " +
                    macro_name +
                    "\n";
                before_body += "#include \"Ht.h\"\n";
                before_body += "#include \"Pers" +
                    CapFnName +
                    ".h\"\n";
                before_body += "#ifndef __htc_GW_write_addr\n";
                before_body += "#define __htc_GW_write_addr(v,a) v.write_addr(a)\n";
                before_body += "#endif\n";
                before_body += "#ifndef __htc_GW_write_addr2\n";
                before_body += "#define __htc_GW_write_addr2(v,a,b) v.write_addr(a,b)\n";
                before_body += "#endif\n";
                before_body += "void CPers" +
                    CapFnName +
                    "::Pers" +
                    CapFnName +
                    "()\n";
                SageInterface::addTextForUnparser(body, before_body,
                                                  AstUnparseAttribute::e_before);
                std::string after_body =
                    "\n#endif /* " +
                    macro_name +
                    " */\n";
                SageInterface::addTextForUnparser(body, after_body,
                                                  AstUnparseAttribute::e_after);
                
                // Write the _src.cpp file
                generate_src_cpp_file(fndef, CapFnName, macro_name);            
            }
        }
        for (i = 0; i < fdeclList.size(); i++) {

            SgFunctionDeclaration *fdecl = fdeclList.at(i);

            if (!debugHooks && 
                fdecl && 
                fdecl->get_definingDeclaration() != fdecl) {

                // Move any preprocessing info before the function to a new
                // null statement preceding the function.
                AttachedPreprocessingInfoType save_buf;
                SageInterface::cutPreprocessingInfo(fdecl, 
                                                    PreprocessingInfo::before, 
                                                    save_buf) ;
                if (save_buf.size()) {
                    SgVariableDeclaration *dummy2 = 
                        SageBuilder::buildVariableDeclaration(
                            "___htc_dummy_decl2_for_preproc_info", 
                            SageBuilder::buildIntType(), 
                            0, 
                            fdecl->get_scope());
                    SageInterface::setExtern(dummy2);

                    SageInterface::insertStatementBefore(fdecl, dummy2);
                    SageInterface::pastePreprocessingInfo(
                        dummy2, 
                        PreprocessingInfo::before, 
                        save_buf); 

                }

                SageInterface::addTextForUnparser(fdecl, "\n/* ",
                                                  AstUnparseAttribute::e_before);
                SageInterface::addTextForUnparser(fdecl, " */",
                                                  AstUnparseAttribute::e_after);
                // comment out function prototypes
                //            fdecl->setCompilerGenerated();
                //            fdecl->unsetOutputInCodeGeneration();
            }
        }

    }
Esempio n. 19
0
File: traceCPU.C Progetto: 8l/rose
int main (int argc, char *argv[])
{
   /* indicate whether include files need to be added */
   bool loopTransformApplied = false ;

   /* more bools at top of file... */
   bool withPAPI = false ;
   bool showStats = false ;
   bool enablePostProcessing = false ;

   /***********************************************/
   /* Process command line options                */
   /***********************************************/

   Rose_STL_Container<string> cmdLineArgs =
     CommandlineProcessing::generateArgListFromArgcArgv(argc,argv) ;

   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(s|stats)", true) )
   {
     showStats = true ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(p|papi)", true) )
   {
     withPAPI = true ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(l|loops)", true) )
   {
     emitSeqSeg = false ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "noiter", true) )
   {
     countIters = false ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "fast", true) )
   {
     fullLoopStat = false ;
     emitSeqSeg   = false ;
     countIters   = false ;
     withPAPI     = false ;
     enablePostProcessing = true ;
   }

   dumpFunc = (showStats ? "ET_LogStats" : "ET_Dump") ;

   /***********************************************/
   /*               Invoke ROSE                   */
   /***********************************************/

   /* build AST */
   SgProject* project = frontend(argc, argv);
   ROSE_ASSERT(project);

   if (project->get_fileList().empty() == false) {

     /* make sure AST is well formed */
     AstTests::runAllTests(project);

     /* set up some needed typedefs for runtime support */

     SgGlobal *globalScope = SageInterface::getFirstGlobalScope(project) ;
     ETtype = buildTypedefDeclaration("ET_Idx_t", buildShortType(), globalScope)->get_type() ;

     /* insert probes into each function in this file */

     Rose_STL_Container<SgNode*> funcDefs =
         NodeQuery::querySubTree(project, V_SgFunctionDefinition) ;

     for (Rose_STL_Container<SgNode*>::iterator f_itr = funcDefs.begin();
                f_itr != funcDefs.end(); ++f_itr)
     {
        SgFunctionDefinition *funcDef = isSgFunctionDefinition(*f_itr) ;
        ROSE_ASSERT(funcDef);

#ifdef ET_DEBUG 
        printf("--- %s ---\n", funcDef->get_qualified_name().str()) ;
#endif

        SgBasicBlock *funcBody = funcDef->get_body() ;
        if (funcBody == NULL)
           continue ;  /* should be impossible to get here... */

        SgFunctionDeclaration *funcDecl = funcDef->get_declaration() ;
        ROSE_ASSERT(funcDecl);

        /* don't transform header file code  */
        if (strstr(funcDecl->get_name().str(), "operator"))
           continue ;

#ifdef ET_DEBUG
        printf("--- %s ---\n", funcDecl->get_name().str()) ;
#endif

        int loopCount = 0 ;  /* used to create local variable names */
        int segCount = 0 ;

        TransformFunction(funcDecl, funcBody, funcBody, &loopCount, &segCount) ;

        if (loopCount != 0)
        {
           loopTransformApplied = true ;
        }
     }

     SgFunctionDeclaration *mainFunc = SageInterface::findMain(project) ;
     if (countIters == false && (loopTransformApplied || mainFunc != NULL)) {
        SageInterface::attachArbitraryText(globalScope,
           std::string("#define ET_NO_COUNT_ITERS 1\n")) ;
     }

     /* files containing at least one loop require run-time support */

     if (loopTransformApplied)
     {
        SageInterface::attachArbitraryText(globalScope,
           std::string("#include \"ETrt.h\"\n")) ;
     }

     /* fold run-time support code into file containing main() */

     if (mainFunc != NULL)
     {

        SgFunctionDefinition *mainFuncDef = mainFunc->get_definition() ;

        /* include ETrt.c just before main() in this file */
        if (!fullLoopStat) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_SIMPLE_LOOP_STATS 1\n") );
        }
        if (enablePostProcessing) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_POST_PROCESS_SEQ_TO_LOOP 1\n") );
        }
        if (withPAPI) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_PAPI 1\n\n") );
        }
        SageInterface::attachArbitraryText(globalScope,
           std::string("#include \"ETrt.c\"\n") );

        if (withPAPI) {
           /* Insert PAPI initialization code at top of main */
           SgBasicBlock *mainBody = mainFuncDef->get_body() ;

           Rose_STL_Container<SgNode*> blockStmts =
               NodeQuery::querySubTree(mainBody, V_SgStatement,
                                       AstQueryNamespace::ChildrenOnly) ;

           for (Rose_STL_Container<SgNode*>::iterator s_itr = blockStmts.begin();
                   s_itr != blockStmts.end(); ++s_itr)
           {
              SgStatement *stmt = isSgStatement(*s_itr) ;
              ROSE_ASSERT(stmt);

              /* skip variable declarations */
              if (isSgDeclarationStatement(stmt))
                 continue ;

              SgExprStatement *initCall = buildFunctionCallStmt(
                 SgName("ET_Init"), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              stmt->get_scope()->insert_statement(stmt, initCall) ;

              break ;
           }
        }

        /* insert finalization code at end of main() */
        Rose_STL_Container<SgNode*> retStmts =
            NodeQuery::querySubTree(mainFunc, V_SgReturnStmt) ;

        if (retStmts.size() > 0)
        {
           for (Rose_STL_Container<SgNode*>::iterator r_itr = retStmts.begin();
                   r_itr != retStmts.end(); ++r_itr)
           {
              SgReturnStmt *ret = isSgReturnStmt(*r_itr) ;
              ROSE_ASSERT(ret);

              SgExprStatement *sanityCall = buildFunctionCallStmt(
                 SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              ret->get_scope()->insert_statement(ret, sanityCall) ;

              SgExprStatement *logStatCall = buildFunctionCallStmt(
                 SgName(dumpFunc), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              ret->get_scope()->insert_statement(ret, logStatCall) ;
           }
        }
        else
        {
           SgExprStatement *sanityCall = buildFunctionCallStmt(
              SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(),
              mainFuncDef->get_body()) ;
           mainFuncDef->get_body()->append_statement(sanityCall) ;

           SgExprStatement *logStatCall = buildFunctionCallStmt(
              SgName(dumpFunc), buildVoidType(), buildExprListExp(),
              mainFuncDef->get_body()) ;
           mainFuncDef->get_body()->append_statement(logStatCall) ;
        }
     }
   }

   /* make sure AST is well formed */
   AstTests::runAllTests(project);

   // generateDOT (*project);

   return backend(project);
}
Esempio n. 20
0
int main( int argc, char *argv[] )
{
	if( argc < 2 ) {
		cout << "./amos: no input files                               " << endl;
		cout << "                                                     " << endl;
		cout << "Hi, this is Amos!                                    " << endl;
		cout << "It's my pleasure to serve you.                       " << endl;
		cout << "                                                     " << endl;
		cout << "Please type option '--help' to see guide             " << endl;
		cout << "                                                     " << endl;

		return 0;
	}

	cout << "*************************************************************" << endl;
	cout << "**                                                         **" << endl;
	cout << "**      Welcome to use OpenMP task validation system!      **" << endl;
	cout << "**                                                         **" << endl;
	cout << "**                                      editor: Amos Wang  **" << endl;
	cout << "*************************************************************\n" << endl;

	vector<string> argvList( argv, argv+argc );
	vector<string> argvList0( argv, argv+argc ); // keep original argv and argc

	command_processing( argvList );

	if( !parse_OmpTask( argvList ) ) {

		cout << "\nAmos says: I am sorry that I could not find any OpenMP task !" << endl << endl;
		return 0;
	}

	// for time counter
	long t_start;
	long t_end;
	double time_program = 0.0;

	t_start = usecs(); 
	// for time counter

	transform_Task2Loop( argvList );

	SgProject *project = frontend(argvList);
	ROSE_ASSERT( project != NULL );

#if 1
	VariantVector vv( V_SgForStatement );
	Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv);
	for( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) {
		SgForStatement* cur_loop = isSgForStatement(*iter);
		ROSE_ASSERT(cur_loop);
		SageInterface::normalizeForLoopInitDeclaration(cur_loop);
	}
#endif

	//initialize_analysis( project, false );
	initialize_analysis( project, false );

	//For each source file in the project
	SgFilePtrList &ptr_list = project->get_fileList();

	cout << "\n**** Amos' validation system running ****\n" << endl;

	for( SgFilePtrList::iterator iter = ptr_list.begin(); iter != ptr_list.end(); iter++ ) {

		cout << "temp source code: " << (*iter)->get_file_info()->get_filename() << endl << endl;
		SgFile *sageFile = (*iter);
		SgSourceFile *sfile = isSgSourceFile(sageFile);
		ROSE_ASSERT(sfile);
		SgGlobal *root = sfile->get_globalScope();
		SgDeclarationStatementPtrList& declList = root->get_declarations ();

		//cout << "Check point 2" << endl;
		//For each function body in the scope
		for( SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p ) 
		{
			SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
			if ( func == 0 )  continue;

			SgFunctionDefinition *defn = func->get_definition();
			if ( defn == 0 )  continue;

			//ignore functions in system headers, Can keep them to test robustness
			if ( defn->get_file_info()->get_filename() != sageFile->get_file_info()->get_filename() )
				continue;

			SgBasicBlock *body = defn->get_body();

			// For each loop
			Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree( defn, V_SgForStatement ); 

			if( loops.size() == 0 ) continue;

			// X. Replace operators with their equivalent counterparts defined 
			// in "inline" annotations
			AstInterfaceImpl faImpl_1( body );
			CPPAstInterface fa_body( &faImpl_1 );
			OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body) );

			// Pass annotations to arrayInterface and use them to collect 
			// alias info. function info etc.  
			ArrayAnnotation* annot = ArrayAnnotation::get_inst(); 
			ArrayInterface array_interface( *annot );
			array_interface.initialize( fa_body, AstNodePtrImpl(defn) );
			array_interface.observe( fa_body );

			// X. Loop normalization for all loops within body
			NormalizeForLoop(fa_body, AstNodePtrImpl(body));

			//cout << "Check point 3" << endl;
			for ( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) {

				SgNode* current_loop = *iter;
				SgInitializedName* invarname = getLoopInvariant( current_loop );

				if( invarname != NULL ) {

					if( invarname->get_name().getString().compare("__Amos_Wang__") == 0 ) {

						//cout << "It's __Amos_Wang__." << endl;
						//replace "for(__Amos_Wang__ = 0;__Amos_Wang__ <= 1 - 1;__Amos_Wang__ += 1)" 
						//to "#pragma omp task"
						std::string strtemp = current_loop->unparseToString();
						strtemp.replace( 0, 64, "#pragma omp task" );

						cout << "task position at: " << current_loop->get_file_info()->get_line()
							<< ", " << current_loop->get_file_info()->get_col() << endl;

						cout << "context: " << strtemp.c_str() << endl; 

						TaskValidation( current_loop );

						cout << "TaskValidation done...\n" << endl;
					}
					else continue;

				}

			}// end for loops

		}//end loop for each function body
		cout << "--------------------------------------------" << endl;

	}//end loop for each source file

	release_analysis();

	//generateDOT( *project );
	backend( project );

	//generate final file with correct directive
	amos_filter( argvList0 );

	// for time counter
	t_end = usecs();
	time_program = ((double)(t_end - t_start))/1000000;
	cout << "analysis time: " << time_program << " sec" << endl;
	//

	cout << endl << "***** Thank you for using Amos' compiler ! *****\n" << endl;

	return 0;
}
Esempio n. 21
0
int
main (int argc, char *argv[])
{
  vector<string> argvList(argv, argv+argc);
  //Processing debugging and annotation options
  //  autopar_command_processing(argvList);
  argvList = commandline_processing (argvList);
  // enable parsing user-defined pragma if enable_diff is true
  // -rose:openmp:parse_only
  if (enable_diff)
    argvList.push_back("-rose:openmp:parse_only");
  SgProject *project = frontend (argvList);
  ROSE_ASSERT (project != NULL);

  // register midend signal handling function
  if (KEEP_GOING_CAUGHT_MIDEND_SIGNAL)
  {
    std::cout
      << "[WARN] "
      << "Configured to keep going after catching a "
      << "signal in AutoPar"
      << std::endl;
    Rose::KeepGoing::setMidendErrorCode (project, 100);
    goto label_end;
  }   

  // create a block to avoid jump crosses initialization of candidateFuncDefs etc.
  {                             
    std::vector<SgFunctionDefinition* > candidateFuncDefs; 
    findCandidateFunctionDefinitions (project, candidateFuncDefs);
    normalizeLoops (candidateFuncDefs);

    //Prepare liveness analysis etc.
    //Too much output for analysis debugging info.
    //initialize_analysis (project,enable_debug);   
    initialize_analysis (project, false);   

    // This is a bit redundant with findCandidateFunctionDefinitions ()
    // But we do need the per file control to decide if omp.h is needed for each file
    //
    // For each source file in the project
    SgFilePtrList & ptr_list = project->get_fileList();
    for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end();
        iter++)
    {
      SgFile* sageFile = (*iter);
      SgSourceFile * sfile = isSgSourceFile(sageFile);
      ROSE_ASSERT(sfile);
      SgGlobal *root = sfile->get_globalScope();

      Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); 
      bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file

      //For each function body in the scope
      //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
      for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) 
      {

        //      cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl;

        SgFunctionDefinition *defn = isSgFunctionDefinition(*p);
        ROSE_ASSERT (defn != NULL);

        SgFunctionDeclaration *func = defn->get_declaration();
        ROSE_ASSERT (func != NULL);

        //ignore functions in system headers, Can keep them to test robustness
        if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename())
        {
          continue;
        }

        SgBasicBlock *body = defn->get_body();  
        // For each loop 
        Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); 
        if (loops.size()==0) 
        {
          if (enable_debug)
            cout<<"\t skipped since no for loops are found in this function"<<endl;
          continue;
        }

#if 0 // Moved to be executed before running liveness analysis.
        // normalize C99 style for (int i= x, ...) to C89 style: int i;  (i=x, ...)
        // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug
        for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin();
            iter!= loops.end(); iter++ )
        {
          SgForStatement* cur_loop = isSgForStatement(*iter);
          ROSE_ASSERT(cur_loop);
          SageInterface::normalizeForLoopInitDeclaration(cur_loop);
        }
#endif
        // X. Replace operators with their equivalent counterparts defined 
        // in "inline" annotations
        AstInterfaceImpl faImpl_1(body);
        CPPAstInterface fa_body(&faImpl_1);
        OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body));

        // Pass annotations to arrayInterface and use them to collect 
        // alias info. function info etc.  
        ArrayAnnotation* annot = ArrayAnnotation::get_inst(); 
        ArrayInterface array_interface(*annot);
        array_interface.initialize(fa_body, AstNodePtrImpl(defn));
        array_interface.observe(fa_body);

        //FR(06/07/2011): aliasinfo was not set which caused segfault
        LoopTransformInterface::set_aliasInfo(&array_interface);

        for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); 
            iter!= loops.end(); iter++ ) 
        {
          SgNode* current_loop = *iter;

          if (enable_debug)
          {
            SgForStatement * fl = isSgForStatement(current_loop);
            cout<<"\t\t Considering loop at "<< fl->get_file_info()->get_line()<<endl;
          }
          //X. Parallelize loop one by one
          // getLoopInvariant() will actually check if the loop has canonical forms 
          // which can be handled by dependence analysis
          SgInitializedName* invarname = getLoopInvariant(current_loop);
          if (invarname != NULL)
          {
            bool ret = ParallelizeOutermostLoop(current_loop, &array_interface, annot);
            if (ret) // if at least one loop is parallelized, we set hasOpenMP to be true for the entire file.
              hasOpenMP = true;  
          }
          else // cannot grab loop index from a non-conforming loop, skip parallelization
          {
            if (enable_debug)
              cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl;
            // We should not reset it to false. The last loop may not be parallelizable. But a previous one may be.  
            //hasOpenMP = false;
          }
        }// end for loops
      } // end for-loop for declarations

      // insert omp.h if needed
      if (hasOpenMP && !enable_diff)
      {
        SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root);
        if (enable_patch)
          generatePatchFile(sfile); 
      }
      // compare user-defined and compiler-generated OmpAttributes
      if (enable_diff)
        diffUserDefinedAndCompilerGeneratedOpenMP(sfile); 
    } //end for-loop of files

#if 1
    // undo loop normalization
    std::map <SgForStatement* , bool >::iterator iter = trans_records.forLoopInitNormalizationTable.begin();
    for (; iter!= trans_records.forLoopInitNormalizationTable.end(); iter ++) 
    {
      SgForStatement* for_loop = (*iter).first; 
      unnormalizeForLoopInitDeclaration (for_loop);
    }
#endif
    // Qing's loop normalization is not robust enough to pass all tests
    //AstTests::runAllTests(project);


    // clean up resources for analyses
    release_analysis();
  }

label_end: 
  // Report errors
  if (keep_going)
  {
    std::vector<std::string> orig_rose_cmdline(argv, argv+argc);
    Rose::KeepGoing::generate_reports (project, orig_rose_cmdline);
  }

  //project->unparse();
  return backend (project);
}
Esempio n. 22
0
int
main ( int argc,  char * argv[] )
{
  // Initialize and check compatibility. See rose::initialize
  ROSE_INITIALIZE;

  if (argc <= 1) {
      PrintUsage(argv[0]);
      return -1;
  }
  vector<string> argvList(argv, argv + argc);
  CmdOptions::GetInstance()->SetOptions(argvList);
  AssumeNoAlias aliasInfo;
  LoopTransformInterface::cmdline_configure(argvList);
  LoopTransformInterface::set_aliasInfo(&aliasInfo);

#ifdef USE_OMEGA
  DepStats.SetFileName(buffer.str());
#endif

  OperatorSideEffectAnnotation *funcInfo = 
         OperatorSideEffectAnnotation::get_inst();
  funcInfo->register_annot();
  ReadAnnotation::get_inst()->read();
  if (DebugAnnot())
     funcInfo->Dump();
  LoopTransformInterface::set_sideEffectInfo(funcInfo);
  SgProject *project = new SgProject ( argvList);

   int filenum = project->numberOfFiles();
   for (int i = 0; i < filenum; ++i) {
  // SgFile &sageFile = sageProject->get_file(i);
  // SgGlobal *root = sageFile.get_root();
     SgSourceFile* file = isSgSourceFile(project->get_fileList()[i]);
     SgGlobal *root = file->get_globalScope();
     SgDeclarationStatementPtrList& declList = root->get_declarations ();
     for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) {
          SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
          if (func == 0)
             continue;
          SgFunctionDefinition *defn = func->get_definition();
          if (defn == 0)
             continue;
          SgBasicBlock *stmts = defn->get_body();  
          AstInterfaceImpl faImpl = AstInterfaceImpl(stmts);
          LoopTransformInterface::TransformTraverse(faImpl, AstNodePtrImpl(stmts));

       // JJW 10-29-2007 Adjust for iterator invalidation and possible changes to declList
          p = std::find(declList.begin(), declList.end(), func);
          assert (p != declList.end());
     }
   }

   if (CmdOptions::GetInstance()->HasOption("-fd")) {
       simpleIndexFiniteDifferencing(project);
   }

   if (CmdOptions::GetInstance()->HasOption("-pre")) {
       PRE::partialRedundancyElimination(project);
   }
#ifdef USE_OMEGA
     DepStats.SetDepChoice(0x1 | 0x2 | 0x4);
     DepStats.PrintResults();
#endif
  //Qing's loop transformations are not robust enough to pass all tests.
   //AstTests::runAllTests(sageProject);
   unparseProject(project);
   if (GenerateObj())
      return project->compileOutput();
   return 0;
}
Esempio n. 23
0
int
main (int argc, char *argv[])
{
  vector<string> argvList(argv, argv+argc);
  //Processing debugging and annotation options
  autopar_command_processing(argvList);
  // enable parsing user-defined pragma if enable_diff is true
  // -rose:openmp:parse_only
  if (enable_diff)
    argvList.push_back("-rose:openmp:parse_only");
  SgProject *project = frontend (argvList);
  ROSE_ASSERT (project != NULL);

#if 1 // This has to happen before analyses are called.
       // For each loop 
       VariantVector vv (V_SgForStatement); 
        Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv); 

      // normalize C99 style for (int i= x, ...) to C89 style: int i;  (i=x, ...)
       // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug
         for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin();
                     iter!= loops.end(); iter++ )
         {
           SgForStatement* cur_loop = isSgForStatement(*iter);
           ROSE_ASSERT(cur_loop);
           SageInterface::normalizeForLoopInitDeclaration(cur_loop);
         }

#endif
  //Prepare liveness analysis etc.
  initialize_analysis (project,false);   
  // For each source file in the project
    SgFilePtrList & ptr_list = project->get_fileList();
    for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end();
        iter++)
   {
     SgFile* sageFile = (*iter);
     SgSourceFile * sfile = isSgSourceFile(sageFile);
     ROSE_ASSERT(sfile);
     SgGlobal *root = sfile->get_globalScope();
     SgDeclarationStatementPtrList& declList = root->get_declarations ();
     bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file

    //For each function body in the scope
     for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
     {
        SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
        if (func == 0)  continue;
        SgFunctionDefinition *defn = func->get_definition();
        if (defn == 0)  continue;
         //ignore functions in system headers, Can keep them to test robustness
        if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename())
          continue;
        SgBasicBlock *body = defn->get_body();  
       // For each loop 
        Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); 
        if (loops.size()==0) continue;

#if 0 // Moved to be executed before running liveness analysis.
      // normalize C99 style for (int i= x, ...) to C89 style: int i;  (i=x, ...)
       // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug
         for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin();
                     iter!= loops.end(); iter++ )
         {
           SgForStatement* cur_loop = isSgForStatement(*iter);
           ROSE_ASSERT(cur_loop);
           SageInterface::normalizeForLoopInitDeclaration(cur_loop);
         }
#endif
        // X. Replace operators with their equivalent counterparts defined 
        // in "inline" annotations
        AstInterfaceImpl faImpl_1(body);
        CPPAstInterface fa_body(&faImpl_1);
        OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body));
         
	 // Pass annotations to arrayInterface and use them to collect 
         // alias info. function info etc.  
         ArrayAnnotation* annot = ArrayAnnotation::get_inst(); 
         ArrayInterface array_interface(*annot);
         array_interface.initialize(fa_body, AstNodePtrImpl(defn));
         array_interface.observe(fa_body);
	
	//FR(06/07/2011): aliasinfo was not set which caused segfault
	LoopTransformInterface::set_aliasInfo(&array_interface);
       
        // X. Loop normalization for all loops within body
        NormalizeForLoop(fa_body, AstNodePtrImpl(body));

	for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); 
	    iter!= loops.end(); iter++ ) 
	{
	  SgNode* current_loop = *iter;
	  //X. Parallelize loop one by one
          // getLoopInvariant() will actually check if the loop has canonical forms 
          // which can be handled by dependence analysis
          SgInitializedName* invarname = getLoopInvariant(current_loop);
          if (invarname != NULL)
          {
             hasOpenMP = ParallelizeOutermostLoop(current_loop, &array_interface, annot);
          }
           else // cannot grab loop index from a non-conforming loop, skip parallelization
           {
            if (enable_debug)
              cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl;
             hasOpenMP = false;
           }
	}// end for loops
      } // end for-loop for declarations
     // insert omp.h if needed
     if (hasOpenMP && !enable_diff)
     {
       SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root);
       if (enable_patch)
         generatePatchFile(sfile); 
     }
     // compare user-defined and compiler-generated OmpAttributes
     if (enable_diff)
       diffUserDefinedAndCompilerGeneratedOpenMP(sfile); 
   } //end for-loop of files

  // Qing's loop normalization is not robust enough to pass all tests
  //AstTests::runAllTests(project);
  
  release_analysis();
  //project->unparse();
  return backend (project);
}