예제 #1
0
void visitorTraversal::analyzePath(vector<VertexID>& pth) {
    std::vector<VertexID> pathR = pth;
    std::vector<SgGraphNode*> path;
    for (unsigned int j = 0; j < pathR.size(); j++) {
        SgGraphNode* R = (*orig)[pathR[j]].sg;
        path.push_back(R);
    }
    for (unsigned int k = 0; k < path.size(); k++) {
        if (isSgFunctionRefExp(path[k]->get_SgNode())) {
            SgFunctionRefExp* sfrd = isSgFunctionRefExp(path[k]->get_SgNode());
            SgFunctionDeclaration* fd = sfrd->getAssociatedFunctionDeclaration();
            fd = isSgFunctionDeclaration(fd->get_definingDeclaration());
            assert(fd!=NULL);
            SgFunctionDefinition* fdd = fd->get_definition();
            SgName sname = fdd->get_mangled_name();
            string sn = sname.getString();
            if (find(defstr.begin(), defstr.end(), sn) == defstr.end()) {
                defstr.push_back(sn);
                defs.push_back(fdd);
                std::cout << "found new sn: " << sn << std::endl;
            }
            else {
                std::cout << "found old sn: " << sn << std::endl;
            }
        }
    }
#pragma omp atomic
    paths++;
}
void
FortranProgramDeclarationsAndDefinitions::visit (SgNode * node)
{
  using boost::filesystem::path;
  using boost::filesystem::system_complete;
  using boost::iequals;
  using boost::starts_with;
  using boost::lexical_cast;
  using std::string;

  if (isSgSourceFile (node))
  {
    path p = system_complete (path (isSgSourceFile (node)->getFileName ()));

    currentSourceFile = p.filename ();

    Debug::getInstance ()->debugMessage ("Source file '" + currentSourceFile
        + "' detected", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__ );
  }
  else if (Globals::getInstance ()->isInputFile (currentSourceFile))
  {
    /*
     * ======================================================
     * Only process this portion of the AST if we recognise
     * this source file as one passed on the command line. In
     * Fortran, .rmod files are sometimes generated whose
     * traversal should be avoided
     * ======================================================
     */

    switch (node->variantT ())
    {
      case V_SgModuleStatement:
      {
        SgModuleStatement * moduleStatement = isSgModuleStatement (node);

        currentModuleName = moduleStatement->get_name ().getString ();

        fileNameToModuleNames[currentSourceFile].push_back (currentModuleName);

        moduleNameToFileName[currentModuleName] = currentSourceFile;

        Debug::getInstance ()->debugMessage ("Module '" + currentModuleName
            + "' in file '" + currentSourceFile + "'", Debug::OUTER_LOOP_LEVEL,
            __FILE__, __LINE__ );

        break;
      }

      case V_SgProcedureHeaderStatement:
      {
        /*
         * ======================================================
         * We need to store all subroutine definitions since we
         * later have to copy and modify the user kernel subroutine
         * ======================================================
         */
        SgProcedureHeaderStatement * procedureHeaderStatement =
            isSgProcedureHeaderStatement (node);

        string const subroutineName =
            procedureHeaderStatement->get_name ().getString ();

        subroutinesInSourceCode[subroutineName] = procedureHeaderStatement;

        ROSE_ASSERT (currentModuleName.size() > 0);

        moduleNameToSubroutines[currentModuleName].push_back (subroutineName);

        subroutineToFileName[subroutineName] = currentSourceFile;

        Debug::getInstance ()->debugMessage (
            "Found procedure header statement '"
                + procedureHeaderStatement->get_name ().getString ()
                + "' in file '" + currentSourceFile + "', and module '"
                + currentModuleName + "'", Debug::FUNCTION_LEVEL, __FILE__,
            __LINE__);

        break;
      }

      case V_SgFunctionCallExp:
      {
        /*
         * ======================================================
         * Function call found in the AST. Get its actual arguments
         * and the callee name
         * ======================================================
         */
        SgFunctionCallExp * functionCallExp = isSgFunctionCallExp (node);

        SgExprListExp * actualArguments = functionCallExp->get_args ();

        string const
            calleeName =
                functionCallExp->getAssociatedFunctionSymbol ()->get_name ().getString ();

        Debug::getInstance ()->debugMessage ("Found function call '"
            + calleeName + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

        if ( iequals (calleeName, OP2::OP_DECL_SET) ||
             iequals (calleeName, OP2::OP_DECL_SET_HDF5) )
        {
          /*
           * ======================================================
           * An OP_SET variable declared through an OP_DECL_SET call
           * ======================================================
           */
          bool isHDF5Format = false;
          
          if ( iequals (calleeName, OP2::OP_DECL_SET_HDF5) ) isHDF5Format = true;
          
          FortranOpSetDefinition * opSetDeclaration =
              new FortranOpSetDefinition (actualArguments, isHDF5Format);

          OpSetDefinitions[opSetDeclaration->getVariableName ()]
              = opSetDeclaration;
        }        
        else if ( iequals (calleeName, OP2::OP_DECL_MAP) ||
                  iequals (calleeName, OP2::OP_DECL_MAP_HDF5) )
        {
          /*
           * ======================================================
           * An OP_MAP variable declared through an OP_DECL_MAP call
           * ======================================================
           */

          bool isHDF5Format = false;
          
          if ( iequals (calleeName, OP2::OP_DECL_MAP_HDF5) )
          {
            isHDF5Format = true;

            Debug::getInstance ()->debugMessage ("This is the HDF5 version: '"
              + calleeName + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);
          }
          
          FortranOpMapDefinition * opMapDeclaration =
              new FortranOpMapDefinition (actualArguments, isHDF5Format);

          OpMapDefinitions[opMapDeclaration->getVariableName ()]
              = opMapDeclaration;
        }
        else if ( iequals (calleeName, OP2::OP_DECL_DAT) ||
                  iequals (calleeName, OP2::OP_DECL_DAT_HDF5) )
        {
          /*
           * ======================================================
           * An OP_DAT variable declared through an OP_DECL_DAT call
           * ======================================================
           */
          bool isHDF5Format = false;
          
          if ( iequals (calleeName, OP2::OP_DECL_DAT_HDF5) ) isHDF5Format = true;

          FortranOpDatDefinition * opDatDeclaration =
              new FortranOpDatDefinition (actualArguments, isHDF5Format);

          OpDatDefinitions[opDatDeclaration->getVariableName ()]
              = opDatDeclaration;
        }
        else if (iequals (calleeName, OP2::OP_DECL_CONST))
        {
          /*
           * ======================================================
           * A constant declared through an OP_DECL_CONST call
           * ======================================================
           */

          FortranOpConstDefinition * opConstDeclaration =
              new FortranOpConstDefinition (actualArguments, functionCallExp);

          OpConstDefinitions[opConstDeclaration->getVariableName ()]
              = opConstDeclaration;
        }
        else if (starts_with (calleeName, OP2::OP_PAR_LOOP))
        {
          /*
           * ======================================================
           * The first argument to an 'OP_PAR_LOOP' call should be
           * a reference to the kernel function. Cast it and proceed,
           * otherwise throw an exception
           * ======================================================
           */

          SgExprListExp * actualArguments = functionCallExp->get_args ();

          SgFunctionRefExp * functionRefExpression = isSgFunctionRefExp (
              actualArguments->get_expressions ().front ());

          ROSE_ASSERT (functionRefExpression != NULL);

          string const
              userSubroutineName =
                  functionRefExpression->getAssociatedFunctionDeclaration ()->get_name ().getString ();

          Debug::getInstance ()->debugMessage ("Found '" + calleeName
              + "' with (host) user subroutine '" + userSubroutineName + "'",
              Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

          if (parallelLoops.find (userSubroutineName) == parallelLoops.end ())
          {
            int numberOfOpArgs = getLoopSuffixNumber ( calleeName );

            /*
             * ======================================================
             * If this kernel has not been previously encountered then
             * build a new parallel loop representation
             * ======================================================
             */

            FortranParallelLoop * parallelLoop = new FortranParallelLoop (
                functionCallExp);

            parallelLoop->addFileName (currentSourceFile);

            parallelLoops[userSubroutineName] = parallelLoop;

            Debug::getInstance ()->debugMessage ("Parallel loop with '"
                + lexical_cast <string> (numberOfOpArgs)  + "' arguments",
                Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);
                        
            analyseParallelLoopArguments (parallelLoop, actualArguments,
              numberOfOpArgs);

            parallelLoop->checkArguments ();
            
            parallelLoop->setIncrementalID (IDCounter);
            IDCounter++;
          }
          else
          {
            Debug::getInstance ()->debugMessage ("Parallel loop for '"
                + userSubroutineName + "' already created",
                Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

            ParallelLoop * parallelLoop = parallelLoops[userSubroutineName];

            parallelLoop->addFunctionCallExpression (functionCallExp);

            parallelLoop->addFileName (currentSourceFile);
          }
        }

        break;
      }

      default:
      {
        break;
      }
    }
  }
}