Go to the first, previous, next, last section, table of contents.
This is a complete example of a SUIF pass that will modify programs.
Assume that this pass must add a special local variable to each procedure in the input program. This variable needs to hold a special value while the procedure is active. The lower 6 bits of this value should hold an unique identifier number of the procedure, the next 9 bits hold the initial value of the first parameter and the highest bit should be one. If any of those numbers overflow, the value should be zero. Note that overflowing of the unique identifier can be calculated at compile time but the first parameter needs to be checked at runtime. Assume each procedure has at least one parameter and that the first parameter is an integer.
#include <stdlib.h> #include <suif1.h> #include <builder.h> int UID; void do_proc(tree_proc * tp) { block::set_proc(tp); sym_node_list * snl = tp->proc_syms()->params(); assert(snl->count() > 0); assert((*snl)[0]->is_var()); var_sym * first_param = (var_sym *)(*snl)[0]; block fp_var(first_param); type_node * type = block::parse_type("int32"); block num_var(block::new_sym(type, "proc_id")); block setid; if(UID <= 0x3F) { block count(UID); setid.set(block::IF((fp_var <= block(0x1FF)), (num_var = block(0x8000) + fp_var << block(6) + count), (num_var = 0x0000))); } else setid.set(num_var = block(0x0000)); tree_node * tn = setid.make_tree_node(); tp->body()->push(tn); UID++; } main(int argc, char * argv[]) { start_suif(argc, argv); UID = 0; suif_proc_iter(argc, argv, do_proc, TRUE, TRUE, TRUE); }
The above C++ program is a SUIF pass that will accomplish this task. For all the procedures in the input program, the call to `do_proc' will incorporate the above mentioned local variable to the SUIF procedure. The following steps are carried-out by `do_proc'.
set_proc
function
should be called before any use of builder functions.
IF
conditional will create a runtime check of the parameter. If
it is within bounds, the `num_var' will be set to the correct
value. Otherwise, `num_var' is set to zero at runtime.
Here is the Makefile for the above pass.
TARGET = ex LIBS = -lbuilder -lsuif -luseful -lm SRCS = main.cc OBJS = main.o all: ex install-bin: install-prog include $(SUIFHOME)/Makefile.std
csh> gmake g++ -c -g -Wall -I/hawg/suif/hawg/include main.cc g++ -c -g -Wall -I/hawg/suif/hawg/include suif_init.cc g++ -o ex -g -Wall -I/hawg/suif/hawg/include main.o suif_init.o \ -L/hawg/suif/hawg/MIPSEL/lib \ -lbuilder -lsuif -luseful -lm prog_ver.cc
The SUIF pass can be tested by applying it to a few input programs. First, the input file is compiled down to SUIF. Then the pass that was created is applied to the input SUIF file and a resulting SUIF file is generated. Finally, the resulting SUIF file is converted back to C.
t0(int i) { } t2(int k) { } t3(int l) { } ... t15(int j) { } ... t63(int y) { } t64(int x) { } t65(int z) { }
csh> scc -.sf- test.c csh> ex test.sf- test.sfx csh> s2c test.sfx > test.sfx.c
extern int t0(int i) { unsigned short proc_id0; if (i <= 511) proc_id0 = 32768 + i << 6 + 0; else proc_id0 = 0; return 0; } ... extern int t15(int j) { unsigned short proc_id0; if (j <= 511) proc_id0 = 32768 + j << 6 + 15; else proc_id0 = 0; return 0; } ... extern int t64(int x) { unsigned short proc_id0; proc_id0 = 0; return 0; }
Go to the first, previous, next, last section, table of contents.