Go to the previous, next section.

Mapping Functions Over Subtrees

Many SUIF programs contain code that visits all of the nodes in an AST to perform various operations. Rather than having every programmer duplicate the code for this traversal, the SUIF library includes methods to map functions over ASTs. The tree_node and tree_node_list classes both provide these map methods.

The function to be mapped must be of type tree_map_f. For a tree node, the map method applies the function to the tree node and all of its children. The preorder parameter is used to select either preorder or postorder traversals; the default is preorder. For preorder traversals, the function is applied to the tree node before it is applied to the children. For postorder, the function is first applied to the tree_node's children and descendants and then last applied to the tree node itself.

The map method for a tree node list calls map for each node in the list. The nodes are visited in order from first to last regardless of the preorder parameter. The tree_node_list version of the map method has an extra optional parameter that allows you to only map the function over the entries in the list without recursively visiting their children.

The tree_map_f functions have two parameters: a pointer to the tree node and a void* value passed on from the map method. Additional parameters can be passed by making the void* value a pointer to a structure containing the parameters. For example, the following code counts the number of tree_for and tree_loop nodes in a procedure:

struct count_result {
    int num_fors;
    int num_loops;
};

void count_loops (tree_node *t, void *x)
{
    count_result *results = (count_result *)x;

    if (t->kind() == TREE_FOR) results->num_fors++; 
    else if (t->kind() == TREE_LOOP) results->num_loops++; 
}

/*
 *  Return the number of tree_fors and tree_loops in the procedure.
 */

void counter (tree_proc *p, int *for_count, int *loop_count)
{
    count_result results;
    results.num_fors = 0;
    results.num_loops = 0;

    p->map(count_loops, (void *)&results);

    *for_count =  results.num_fors;
    *loop_count = results.num_loops;
}

Go to the previous, next section.