ROSE 编译器框架/转换跟踪
外观
一个跟踪转换的实验性功能
转换跟踪或 IR 映射信息
- 每个 AST 节点都分配了一个唯一的整数 ID,基于 AST 的先序遍历。
- 一个转换生成的节点(受影响节点)与一个或多个输入节点相连。
- 存储在 std::map<AST_NODE_ID, std::set<AST_NODE_ID> > 中,从受影响节点映射到其输入节点集。
这是一个很少使用的功能。为了避免内存/计算开销,我们将信息存储在独立的内存中,而不是直接扩展 AST 节点的成员。
跟踪基于 AST 节点的唯一 ID。为了禁用已删除 AST 节点的内存重用,建议使用以下配置 ROSE:
- --enable-memory-pool-no-reuse 启用特殊的内存池模型:不重用已删除的内存(默认情况下重用内存)
源代码和 API 函数定义在 https://github.com/rose-compiler/rose-develop/tree/master/src/midend/programTransformation/transformationTracking
来自
//! Assign Ids and save current File Info. void registerAstSubtreeIds (SgNode* root); // get unique ID AST_NODE_ID getId (SgNode* ); // check if a node has been assigned a unique ID bool hasId (SgNode* n); //Obtain the SgNode from an ID SgNode* getNode (AST_NODE_ID id); // the input AST node IDs for a transformation generated node. extern std::map<AST_NODE_ID, std::set<AST_NODE_ID> > inputIDs; // This should be called after the transformation is completed and all IDs are assigned. void addInputNode(SgNode* affected_node, SgNode* inputnode);
来自 transformationTracking.cpp:内部两个映射/表存储 ID 和内存地址
// the following data structures are for internal use only std::map <SgNode*, unsigned int > AstToIdTable; // reverse lookup , oops, if they are one-to-one mapping, how a single node obtains multiple IDs? std::map <unsigned int, SgNode*> IdToAstTable;
// Assign portable and unique IDs for all located nodes in AST TransformationTracking::registerAstSubtreeIds (project); // Dump AST dotgraph with unique IDs , for debugging purpose // Test unique ID assignment and dot graph generation TransformationTracking::registerAstSubtreeIds (sageProject); generateWholeGraphOfAST("wholeAST-v1"); AstDOTGeneration astdotgen; astdotgen.generate(sageProject,AstDOTGeneration::TOPDOWNBOTTOMUP, "v1"); // record the input node of an affected node after some transformation // patch up IDs for the changed subtree TransformationTracking::registerAstSubtreeIds (orig_scope); std::vector <SgVariableDeclaration*>::iterator iter; for (iter = newly_inserted_copied_decls.begin(); iter!= newly_inserted_copied_decls.end(); iter++) { //TransformationTracking::addInputNode (affected_node, input_node) TransformationTracking::addInputNode (*iter, decl); } // retrieve stored mapping information std::map<AST_NODE_ID, std::set<AST_NODE_ID> >::iterator iter; for (iter = TransformationTracking::inputIDs.begin(); iter != TransformationTracking::inputIDs.end(); iter++) { std::set<AST_NODE_ID> ids = (*iter).second; if (ids.size()>0) { string src_comment = "Transformation generated based on "; cout<<"Found a node with IR mapping info"<<endl; SgNode* affected_node = TransformationTracking::getNode((*iter).first); cout<<isSgLocatedNode(affected_node)->unparseToString()<<endl; cout<<"-- with input nodes ----------"<<endl; std::set<AST_NODE_ID>::iterator iditer; for(iditer = ids.begin(); iditer != ids.end(); iditer ++) { SgNode* input_node = TransformationTracking::getNode((*iditer)); SgLocatedNode* lnode = isSgLocatedNode(input_node); cout<<lnode->unparseToString()<<endl; cout<<"//Transformation generated based on line #"<< lnode->get_file_info()->get_line() <<endl; src_comment += " line # " + StringUtility::numberToString(lnode->get_file_info()->get_line()); } src_comment +="\n"; SgStatement* enclosing_stmt = getEnclosingStatement(affected_node); attachComment (enclosing_stmt, src_comment); } // end if ids.size() >0 } // end for inputIDs