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