ROSE Compiler Framework/transformation tracking

An experimental feature to keep track of transformation

Design
The transformation tracking or IR mapping information
 * each AST node is assigned a unique integer ID, based on a preorder traversal of the AST.
 * a transformation generated node (affected node) is connected with one or more input nodes.
 * stored in std::map > , map from an affected node to its input node sets

This is a rarely used feature. To avoid memory/computation overhead, we store information in separated memory, not directly extending AST node's members.

The tracking is based on unique IDs of AST nodes. To disable memory reuse of deleted AST nodes, it is recommended to configure ROSE with
 * --enable-memory-pool-no-reuse                           Enable special memory pool model: no reuse of deleted memory (default is to reuse memory)

APIs
The source code and API functions are defined in https://github.com/rose-compiler/rose-develop/tree/master/src/midend/programTransformation/transformationTracking

From

//! 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 > inputIDs;

// This should be called after the transformation is completed and all IDs are assigned. void addInputNode(SgNode* affected_node, SgNode* inputnode);

from transformationTracking.cpp:  internal  two maps/tables store IDs and memory addresses // the following data structures are for internal use only std::map  AstToIdTable; // reverse lookup, oops, if they are one-to-one mapping, how a single node obtains multiple IDs? std::map  IdToAstTable;

example use
// 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 ::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 >::iterator iter; for (iter = TransformationTracking::inputIDs.begin; iter != TransformationTracking::inputIDs.end; iter++) {     std::set ids = (*iter).second; if (ids.size>0) {       string src_comment = "Transformation generated based on "; cout<<"Found a node with IR mapping info"<unparseToString<::iterator iditer; for(iditer = ids.begin; iditer != ids.end; iditer ++) {          SgNode* input_node = TransformationTracking::getNode((*iditer)); SgLocatedNode* lnode = isSgLocatedNode(input_node); cout<unparseToString<get_file_info->get_line <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