跳轉到內容

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

華夏公益教科書