Instruction nodes, implemented by the tree_instr
class, are the
leaves of the abstract syntax trees. Each instruction node contains a
single instruction or expression tree which can be accessed using the
instr
method. The set_instr
method attaches an
instruction to a tree_instr
, and the remove_instr
method
detaches an instruction. Note that remove_instr
does not free
the storage for the instruction, and unlike the remove
method in
the instruction
class (see section Source Operands), it does not
remove the instruction from its expression tree. Conversely, removing
an instruction from an expression tree with the remove
method
will automatically call remove_instr
if necessary.
The SUIF library automatically maintains back-pointers from instructions
to their parent tree_instr
nodes. As a result, the
set_instr
and remove_instr
methods must always be used to
attach and detach instructions to tree_instr
nodes. Never use
the instruction in a tree_instr
elsewhere without first calling
remove_instr
, and never use set_instr
with a
tree_instr
that already contains an instruction.
Unlike other tree nodes, instruction nodes are considered temporary objects. They are destroyed and created automatically by the SUIF library when switching between expression trees and flat lists, and their annotations and ID numbers are not written to the output files. Consequently, annotations should generally not be attached to them but should instead be placed directly on the instructions.
The destructor for the tree_instr
class also deletes the
instruction or expression tree contained in the node. This is the
desired behavior for most cases. However, if you only want to delete
the tree_instr
node, simply call remove_instr
first and
save a pointer to the instruction.
Often in SUIF one needs to perform some operation on all the
instructions in a procedure. The map
methods in the
tree_node
and tree_node_list
classes (see section Mapping Functions Over Subtrees) make it easy to visit all of the instruction nodes. Once an
instruction node is reached, its instr_map
method may be used to
apply a function to every instruction in the associated expression tree.
Given a function of type instr_map_f
, instr_map
will
traverse the expression tree and apply the function to every
instruction. The preorder
parameter is used to select either
preorder or postorder traversals; the default is preorder. The
instr_map_f
function takes two arguments: the instruction pointer
and a void*
value that you provide to instr_map
.