The SUIF Programs and Passes Guide
The SUIF compiler infrastructure is designed to be modular so as to facilitate
research in compilers. Users can easily create new passes or combine different
passes together to build a complete compiler. The current SUIF system consists
of a number of predefined standalone programs for generating and manipulating
the SUIF representations. In particular, the user can use the suifdriver,
one of the standalone programs, to run one or more compiler passes that
translate a SUIF representation to another. The system currently includes
a set of passes that are mostly simple transforms to dismantle high-level
constructs and utilities for checking and cleaning up the representation.
Table of contents
Setup and Hints
Before executing any of these programs , the user MUST set up some environment
variables. This can be done in the csh or tcsh shells with:
source $(NCIHOME)/suif_setup.csh
In sh or bash shells use:
. $(NCIHOME)/suif_setup.sh
You can usually find out what a standalone program in $NCIHOME/bin
does by simply invoking the program without any arguments. It will
usually print out a usage description if it expects any arguments.
Example:
> suif2c
Usage: suif2c [-o outputfile] [-keep] [-v] [-ftn] [-arch ARCH] file.suif
Create a C file from a suif file with SUIF and BASIC nodes.
The default output filename will be file.out.c
The architecture will be read from the Linux variable
or the command line -arch flag, or the output of 'uname'
You can usually find out what a shared library in $NCIHOME/solib
does by simply importing it into the suifdriver and invoking
list_modules. Example:
> suifdriver -e "import usefulpasses; list_modules"
Module: exec:
Description: Usage:
exec ...
executes a shell command in
Module: validate_suif:
Description: validates the FileSetBlock
Module: gc_symbol_table:
Description: Remove unreferenced Types and Symbols from external symbol table.
Module: count_suif_object:
Description: Count number of suif IR objects
...
Standalone Programs
These are a collection of self-contained programs found in the "bin"
subdirectory.
Front Ends
-
c2suif [ -D<define> ] [-I <include> ] [ -o <outputfile>]
[ -keep ] <file.c>
C to SUIF front end based on the EDG front end, outputs the SUIF representation
in <outputfile>. If the <outputfile> is not specified, it is written
to <file.suif>. The resulting <outputfile> will only contain nodes
from basicnodes and suifnodes.
-
f2suif [-o <outputfile>] [-v]
[-pipeline <pass>] [-require <module>]
[-D<define>] [-U<undefs>] [-I<include>] [-arch <ARCH>]
<file.f>
Create a suif file from the input Fortran file.
When -require is used, the named modules will be loaded
before dismantling
When -pipeline is used, the named pass will be executed
before other dismantlers.
The architecture will be read from the Linux variable
or the command line -arch flag, or the output of 'uname'.
-
cpp2suif [-o <outputfile>] [-keep] [-v]
[-D<define>] [-U<undefs>] [-I<include>] [-arch <ARCH>]
file.cpp
Create a suif file from the input c file.
Uses a native C preprocessor, the edg frontend
the edgsuif converter, and some dismantlers to
build a the edgsuif converter, and some dismantlers to
create a suif file (with only SUIF and BASIC nodes)
from the input c file.
The architecture will be read from the Linux variable
or the command line -arch flag, or the output of 'uname'.
Back Ends
-
suif2c [ -o <outputfile> ] [ -arch <arch> ] <file.suif>
SUIF to C backend. Generates a C file output from the input file <file.suif>
. If <outputfile> is not specified, <file.out.c> will be used. If
<arch> is not specified, the name from the system program `uname` will
be used. Currently supported architectures are:
Linux,
OSF1,
and SunOS.
-
suif2a [-o <outputfile>] [-keep] [-v] [-target_lib <target>] file.suif
This assumes that the alpha code generator has already been built.
Generate an object file, and the default file name is file.o.
Currently, valid targets are: 'alpha'
SUIF Pass Drivers and Tools
-
suifdriver
suifdriver -i
suifdriver -f < cmd-file >
suifdriver -e "< module arg ... >; < module arg ... >;
..."
The high-level driver to run SUIF passes on SUIF representations. The
user supplies a sequence of commands to the suifdriver either interactively
(the -i option), in a file (the -f option), or on the command line (the
-e option).
-
pass_driver [-v] [--help] <pass_list> <input_files>
Invokes the suifdriver to apply a series of passes to the input
files. The pass_list is a ':' separated list of pass specs. Pass_spec
files are normally found in $NCIHOME/pass_spec_db.
-
sbrowser
for navigating a program represented in the SUIF2 format.
Format Translators
-
suif1to2 [ -o <outputfile> ] <file.spd>
SUIF1 to SUIF2 converter. Generates a SUIF2 file <outputfile> from
the inputfile <file.spd> . If the <outputfile> is not specified,
the outputfile will be named <file.suif> . To run this, the suif1 environment
must be set up in addition to the suif2 environment. For the csh and tcsh
shells, you will need to execute:
setenv SUIFHOME < your_suifhome_here >
setenv MACHINE < your_suif1_machine_type_here >
# e.g. i586-linux
eval `$SUIFHOME/setup_suif`
source $NCIHOME/nci_setup.csh
For the sh and bash shells, you will need to execute:
SUIFHOME= < your_suifhome_here >
export SUIFHOME
MACHINE= < your_suif1_machine_type_here >
# e.g. i586-Linux
export MACHINE
eval `$SUIFHOME/setup_suif -sh`
. $NCIHOME/nci_setup.sh
suif2to1 [ -o <outputfile> ] <file.suif>
SUIF2 to SUIF1 converter. Generates a SUIF1 file <outputfile> from
the input file <file.suif> . If the <outputfile> is not specified,
the outputfile will be named <file.suif1>. To use this script, the
SUIF1 environment must be set up as with suif1to2.
Tools for developing passes
-
texec [-v] [-t <time_out>] program [arg list....]
A tool to run a program within a given time limit.
-t <timeout> Timeout value in seconds(default is infinity)
-s <timeout> Timeout value in seconds
-m <timeout> Timeout value in minutes
-h <timeout> Timeout value in hours
-v Print execution time
-
smgn [options] <grammar> <source> <macro file 1> <macro file 2>
...
Suif macro generator.
Applies a set of macro files to a source file described by a grammar.
Options are: -p print result of parsing source
-d debug macro expansion
-D<name>=<value> define a name for macro expansion
-I<directory> add directory for includes
-
edgdisp <file.cil>
a utility to print the intermediate file generated by the edg
front end.
Instances of standalone compiler passes
-
print_driver <sfile>
a simple script that prints a suif file.
-
link_suif [-o <outputfile>] [-keep] [-v]
[-arch <ARCH>] file1.suif file2.suif ...
Link the global symbol tables of the input suif files into
a single output suif file set
The default output filename will be a.suif
-
create_suif_hello_world
Generates a simple program that prints hello world
without any front ends.
Contributed software
-
deadcode_driver
Applies deadcode elimination to a SUIF program
-
ecr_driver
Applies pointer alias analysis to a SUIF program
Programs Invoked Internally
- pgcpp1 C and C++ front ends called by c2suif and cpp2suif.
- pgf77 Fortran front end called by f2suif.
- suifint Translates C and C++ front end outputs to SUIF.
These are libraries found in the "solib" subdirectory. These libraries
can be imported into the suifdriver. A module defined in a library can
define a set of IR nodes, or it can define a set of passes. In the suifdriver
is a SUIF environment (SuifEnv) to which the user can import new libraries
and load new SUIF files. The commands, when invoked, typically apply to
the current IR file that is loaded into the Suif environment.
Modules with Intermediate Representation Nodes
- basicnodes - basic representation
- suifnodes - SUIF program representation
- cfenodes - nodes capturing higher level C program semantics, used
in the front end
Modules with Compiler Passes
-
built-in modules in suifdriver
-
import <lib1> <lib2> ...
Dynamically import, register, and initialize the specified set of libraries.
-
require <lib1> <lib2> ...
Dynamically import, register, and initialize the specified set of
libraries if they have not been imported already.
-
load <sfile>
Load a SUIF program in memory.
-
save <sfile>
Save the currently loaded SUIF representation to a file.
-
print [-style <stylename>] [-o <file>]
Print an ASCII format of the currently load SUIF representation to
<file> if specified, and standard I/O otherwise. It will use the default
style unless it is overwritten by the style option. Examples of styles
are the basic "print", which prints all the class of all the objects in
the representation, or "print_suif", which exploits the SUIF nodes semantics.
The style must be have been imported before its use.
-
execute
execute -f <cmd-file>
execute -e "<module arg ... >; <module arg ...>; ..."
Read in a sequence of modules names and their arguments from the command
line directly (the -e option) or from a file (the -f option).
Example: execute -e "import basicnodes suifnodes; load file.s2; print"
-
pipeline
pipeline -f <cmd-file>
vSimilar to the above, except that the modules which necessarily are
pipelineable passes, are applied to the same section or procedure in the
program before moving onto the next.
Example: pipeline -e "dismantle_c_for_statements; dismantle_cfor_to_fors".
-
list_modules
list_modules
list all of the modules accessable from the current suif environment
-
list_interfaces
list_interfaces
list all of the interfaces that are supported by some module in the
current suif environment
-
s2c - Translate SUIF to C.
-
s2c -D ARCH= <system> <outputfile>
-D ARCH= <system> specifies the target machine. (e.g. SunOs,
OSF). The default is set to unknown, which should work except for
the case when the target architecture is OSF.
-
suifprinter - Pretty-print the SUIF representation. Loading the
suifprinter module will automatically change the default printing style
used by "print".
-
transforms - a suite of simple passes that transform the program
representation. They are mainly passes to build higher level constructs
from simpler objects, to dismantle high-level constructs, and to clean
up the representation.
- add_explicit_loop_labels
Add continues and break labels as explicit LabelLocationStatement if they are not there yet
- add_statement_lists_to_procs
Put StatementLists inside of procedures that just have bare statements as their body
-
avoid_external_collisions
Rename the local variables from Symbols that conflict with Symbols
in the ExternalSymbolTable.
-
avoid_file_scope_collisions
Rename the local variables from Symbols that conflict with Symbols
in the external_symbol_table, the file_set_symbol_table, or any other FileBlock's
symbol_table. This is needed after linking files to rename statically file
scoped symbols so they do not conflict.
-
avoid_label_collisions
Remove the names on local labels that conflict and rename them to something
unique.
-
build_field_access_expressions
Build FieldAccessExpressions in code converted from SUIF1 that contains
"field" annotations.
-
build_multi_dim_arrays
Convert ArrayReferenceExpressions and ArrayTypes to MultiDimArrayReferenceExpressions
and MultiDimArrayTypes.
-
build_repeat_value_blocks
Build RepeatValueBlocks from repeated ExpressionValueBlocks owned by
MultiValueBlocks.
-
compact_multi_way_branch_statements
Convert multi-way branches to IfStatements with dense multi-way branches.
-
dismantle_c_for_statements
Convert CForStatements to Branches and Jumps.
- dismantle_call_arguments
Replace expressions in call arguments with temporary variables whose values are set to the results of the expressions
-
dismantle_call_expressions
Convert all CallExpressions to CallStatements.
-
dismantle_cfors_to_fors
Convert CFor loops that have SUIF FOR semantics to For loops. This
may be followed by dismantle_c_for_statements to dismantle the rest of
the CFor loops to Branches and Jumps.
-
dismantle_do_while_statements
Convert DoWhileStatements to Branches and Jumps.
- dismantle_empty_scope_statements
Eliminate empty scope statements
-
dismantle_field_access_expressions
Convert FieldAccessExpressions to to address arithmetic.
-
dismantle_for_statements
Convert ForStatements to Branches and Jumps.
-
dismantle_if_statements
Convert IfStatements to Branches and Jumps.
-
dismantle_ifs_and_loops
Dismantle IfStatements, DoWhileStatements, WhileStatements.
- dismantle_load_expressions
Force all load results into a temporary scalar variable
-
dismantle_multi_dim_arrays
Dismantle multi dimensional arrays.
- dismantle_multi_entry_scope_statements
Dismantle scoped statements that have jumps going inside of them.
-
dismantle_multi_way_branch_statements
Convert MultiWayBranchStatements to IfStatements.
-
dismantle_non_const_bound_arrays
Dismantle arrays with a non-constant bound.
-
dismantle_scope_statements
Remove ScopeStatements and move any scope local variables to the procedure
scope.
- dismantle_stmts_with_jumps_inside
Dismantle structural statements that have jumps going inside of them.
- dismantle_structured_returns
Change procedures that return structures to pass the result back as an extra argument
-
dismantle_while_statements
Convert WhileStatements to Branches and Jumps.
- fixup_explicit_loop_labels
Fix up all the explicit labels in the different kinds of loops
-
flatten_statement_lists
Flatten statement lists of statement lists.
-
fold_statements
Fold constant expressions and simplify statements with constant expressions.
- guard_all_fors
Make all For statements execute at least once by guarding all the Fors with a test if necessary.
- if_conditions_to_binary_exprs
Convert if conditions that are not BinaryExpressions by explicitly comparing them with 0
-
insert_procedure_end_labels
Insert a unique label at the end of each procedure.
-
insert_struct_padding
Add empty fields for any portion of a structure that has a hole.
-
insert_struct_final_padding
Add empty fields at the end of structures that need padding.
- mark_guarded_fors
Mark a ForStatement as guarded if lb TEST UB is true. This works only when they are constants.
-
name_all_symbols
Set the name on all VariableSymbols and LabelSymbols that are anonymous.
- normalize_procedure_returns
Ensure all returned results match the type of the procedure
- remove_explicit_loop_labels
Remove continues and break labels as explicit LabelLocationStatement that have the same labels as continues/breaks of loops.
-
rename_colliding_symbols
Name the symbols, and rename colliding symbols; necessary before running
s2c.
- require_procedure_returns
Add return statements to procedures if necessary
- set_address_taken
Set addr_taken to true iff the symbol is part of an SymbolAddressExpression
-
usefulpasses - This is a set of useful passes to help programmers
in developing their passes.
-
check_types
Validate a number of SUIF invariants on Types that should hold for
any valid SUIF2 file
-
count_suif_object
Count and print number of SuifObject instances.
-
find_unowned
Print out unowned objects, for debugging
-
gc_symbol_table
Garbage-collect all unreferenced SymbolTableObject in symbol tables.
-
time
Print out the current time; can use this to determine the time taken
before and after a pass.
-
recycle_trash
Garbage-collect the IR nodes that have been placed in the Trash.
Nodes whose reference edges are removed are first placed in the Trash,
and this single pass can be used to remove them efficiently. See
trash-utils.h.
-
validate_suif
Check for unowned nodes and ensure that the symbols in the symbol_table_objects
are in the lookup_table in the symbol table and vice versa.
-
convertsuif1to2 - convert a program in SUIF1 to SUIF2
-
convertsuif1to2 < suif1file >
Convert the given SUIF1 file into a SUIF 2 representation and make
that the current IR in the SUIF environment.
-
convertsuif2to1 - convert a program in SUIF2 to SUIF1
-
convertsuif2to1 < suif1file >
Convert the currently loaded SUIF2 program into SUIF1 format and place
it in the specified SUIF1 file.