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