Esempio n. 1
0
static std::string
commentAndCppInformation (SgNode* node)
   {
  // DQ (8/31/2013): Adding source position information for DOT output.
     string ss;

     SgLocatedNode* locatedNode = isSgLocatedNode(node);
     if (locatedNode != NULL)
        {
          AttachedPreprocessingInfoType* commentsAndCppDirectives = locatedNode->getAttachedPreprocessingInfo();
          size_t numberofCommentsAndCppDirectives = 0;
          if (commentsAndCppDirectives != NULL)
             {
               numberofCommentsAndCppDirectives = commentsAndCppDirectives->size();
               if (numberofCommentsAndCppDirectives >= 0)
                  {
                 // ss = string("comments = ") + StringUtility::numberToString(numberofCommentsAndCppDirectives) + "\\n";
                    ss += string("comments/directives (before) = ") + StringUtility::numberToString(numberByRelativePosition(commentsAndCppDirectives,PreprocessingInfo::before)) + "\\n";
                    ss += string("comments/directives (inside) = ") + StringUtility::numberToString(numberByRelativePosition(commentsAndCppDirectives,PreprocessingInfo::inside)) + "\\n";
                    ss += string("comments/directives (after)  = ") + StringUtility::numberToString(numberByRelativePosition(commentsAndCppDirectives,PreprocessingInfo::after)) + "\\n";
                  }
             }
        }

#if 0
       else
        {
       // DQ (9/1/2013): We could handle the source position of some other IR nodes (e.g. output name of the file for SgFile).
          SgFile* file = isSgFile(node);
          if (file != NULL)
             {
            // ROSE_ASSERT(file->get_file_info() != NULL);
            // ss += generateFileLineColumnString(file->get_file_info());
               AttachedPreprocessingInfoType* commentsAndCppDirectives = file->getAttachedPreprocessingInfo();
               size_t numberofCommentsAndCppDirectives = 0;
               if (commentsAndCppDirectives != NULL)
                  {
                    numberofCommentsAndCppDirectives = commentsAndCppDirectives->size();
                    if (numberofCommentsAndCppDirectives > 0)
                       {
                         ss = string("comments = ") + StringUtility::numberToString(numberofCommentsAndCppDirectives) + "\\n";
                       }
                  }
             }
        }
#endif

     return ss;
   }
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++;
  }