Go to the previous, next section.

Procedure Symbols

Procedure symbols are represented by objects of the proc_sym class. SUIF does not support nested procedures, so these symbols may only be entered in global and file symbol tables. The fields in a procedure symbol hold information about the procedure, including a pointer to the body if it is in memory. The proc_sym class also provides methods to read procedure bodies from input files, write them to the output files, and flush them from memory.

Each procedure symbol contains a field to record the source language for the procedure. The src_lang and set_src_lang methods access this field, which holds a value from src_lang_type enumeration: src_unknown, src_c, src_fortran, or src_verilog. Other values may be added in the future.

A procedure symbol also has a field that specifies the type of the procedure. The type and set_type methods retrieve and change this field. The type must be a function type. See section Function Types.

The body of a procedure is represented by its abstract syntax tree. See section Abstract Syntax Trees. The procedure symbol contains a pointer to the root node of this tree. The block and set_block methods access this pointer. If the body is not in memory, the block pointer will be NULL; the is_in_memory method is provided to check this condition.

The proc_sym class contains the methods to read procedure bodies from binary SUIF files and to write them out again. The details of SUIF I/O are thus hidden from users; only entire procedures can be read and written. If one of the input files contains the body for a procedure, a pointer to the file set entry (see section File Set Entries) is recorded in the procedure symbol. The file method retrieves this pointer for a particular proc_sym. The same procedure can be read in and flushed from memory many times, but once it has been written out it can no longer be read or written again. The procedure symbol contains a flag to indicate if it has been written out yet. The is_written method returns the value of this flag. The is_readable method checks if the procedure body exists in one of the input files and if it has not yet been written out. If this method returns TRUE, the read_proc method can be used to read the body of the procedure. By default, read_proc also converts the procedure to expression tree form (see section Expression Trees) but it does not convert to Fortran form (see section Features for Compiling Fortran). The exp_trees and use_fortran_form parameters to read_proc can be used to override these defaults.

After a procedure body has been read in and possibly modified, it can be written to the output file using the procedure symbol's write_proc method. You must specify the file set entry to which the procedure should be written. In most cases, the input and output file set entry will be the same, and you will just use the file method to determine the output file set entry. As mentioned above, once a procedure has been written out it cannot be rewritten or read in again. Obviously, it should not be changed after that point because the changes could not be saved. Besides avoiding changes directly to the procedure, however, you must also be careful to avoid certain changes to the global symbol tables. The symbols and types within the procedure are written out using their ID numbers. See section Numbering Types and Symbols. Thus, you must not do anything to the global symbol tables that would cause the ID numbers for those symbols and types to change. For example, moving a symbol from a file symbol table to the global symbol table would require that its ID number change. The best solution to this is to not write out the procedures until you are certain that such changes to the symbol tables will not be needed.

When a procedure body is no longer needed, typically after it has been written out, call the flush_proc method for the procedure symbol to deallocate the storage used by the procedure. In some cases, you may want to flush the procedure before it is written. For example, interprocedural analysis requires that all procedures be read in and analyzed together. To save space, the procedures can be summarized for the purpose of the particular analysis and then flushed. After the analysis is complete, they can be re-read and the results can be attached to the code.

Go to the previous, next section.