跳转到内容

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

华夏公益教科书