Go to the previous, next section.

Source Operands

Even though the base instruction class does not contain any source operand fields, it does provide several methods to access the source operands in derived classes. First, the num_srcs method returns the number of source operands in a particular instruction. Once you know the number of sources, you can access them by number. This is frequently useful when you need to visit all of the source operands without concern for how they are used in the instruction. The src_op and set_src_op methods provide this access. The operands are numbered beginning from zero (like arrays in C). Specifying an operand number that does not exist will cause an error. Do not use these methods to access a particular operand field in an instruction; the operand numbering used here is implementation-defined and subject to change.

The src_map method provides an alternate way to visit all of the source operands. It applies a function that you specify to all of the source operands. This can be used to implement recursive descents of expression trees by making the mapped function call src_map if the operand is an instruction. This is similar to what the instr_map method in the tree_instr class does. See section Instruction Nodes. The mapped function must match the src_map_f type which has three parameters: a pointer to the instruction, a pointer to a copy of the operand, and a void* value used to pass any other information needed by the function. If the function returns TRUE, the copy of the operand will be assigned to the actual operand field within the instruction. If it returns FALSE, the source operand field is not modified.

The SUIF library requires that instruction pointers in operands be consistent. That is, a source operand may only point to an instruction if the destination of that instruction points back to where the result value is used. Because of this, you cannot simply overwrite a source operand that contains an instruction pointer. Doing so would leave the other instruction with an inconsistent destination operand. Instead, you must first use the source operand's remove method. This clears the instruction pointers in both the source and destination operands. If the source instruction was part of an expression tree (i.e. it didn't have its own parent tree_instr node), remove also clears its parent pointer by calling the parent's remove_instr method (see section Instruction Nodes). If the source operand is not an instruction, the remove method does nothing so it is always safe to use it. The instruction class also has a remove method which does the same thing.

As an example, the following code clears all of the source operands in an instruction:

for (int n = 0; n < i->num_srcs(); n++) {
    i->src_op(n).remove();
    i->set_src_op(n, operand());
}

Go to the previous, next section.