SQUEEZE -- A Code Compressor for the DEC Alpha


0. Table of Contents


1. Squeeze man page

Invocation

squeeze {option}*

Options

The following options are available. Please note, that each option should appear at most once. Otherwise, the latest occurence will overwrite all previous ones.

-r [number-of-rounds] (default 2)
Specifies how many rounds the optimizer should run the "easy optimization" at most. The c-compiler shipped with the latest version of OSF/1 (Digital UNIX V4.0) creates binaries that squeeze cannot handle unless rounds > 0. By "easy optimizations" we mean non-inlining optimization. Currently, squeeze does "easy optimization" first, then inlining, and finally "easy optimizations" again.
-i [input-file] (default a.out)
Specifies the name of the file that should be optimized.
-o [output-file] (default b.out)
Specifies the name of the file being generated.
-O [disable-optimize-options] (default none disabled)
Disables certain optimizations. If you want to disbable more than one optimization concatenate the corresponding options with an arbitary delimiter, eg. '+'. The complete list of optimizations is changing rapidly. An uptodate overview can be obtained by running the following command in the master source directory. `grep DISABLED_OPT *.c'

Preparing Binaries For Processing with SQUEEZE

In order to optimize binaries with squeeze they have to be linked using the flags listed below. Unfortunately, this does not quite work for the gnu compiler due to a silly problem (this may have been fixed by now). the problem is that gcc and g++ pass the -r flag (from -W,-r) too late to the linker.

Here is a workaround. Run "gcc -v" : this tells you which spec file gcc is using. Patch the spec file as follows:

compileroption
cc -Wl,-r -Wl,-d -Wl,-z -non_shared
f77-Wl,-r -Wl,-d -Wl,-z -non_shared
gcc -Wl,-r -Wl,-d -Wl,-z -static
g++-Wl,-r -Wl,-d -Wl,-z -static

Example Invocations

squeeze
Runs squeeze on binary a.out producing an (optimized) binary b.out. No profiling information is used.
squeeze -i a.rr -o my.exe
Runs squeeze on binary a.rr producing an (optimized) binary my.exe.
squeeze -O Factor
Runs squeeze as usual on a.out but does not perform code factoring optimizations.

(Known) Bugs

[
top of page ]


2. Compiling Squeeze.

You need gnu-make (gmake) to compile squeeze because we need so features not available with the ordinary make. Make sure that the environment variable `OSTYPE' has the value `osf1' if you platform is Digital Unix and some other value if you platform is Linux.

If you want to produce a fast version of `squeeze' under DEC UNIX that can be optimized by itself, type `gmake squeeze_fast'.

[
top of page ]


3. Platform Issues

COFF Binaries

(A port to Linux ELF is under way !!) Currently, SQUEEZE works with COFF binaries only. It assumes that those binaries are statically compiled. It also expects relocation information and symbol table information to be present.

Segments and Sections

A COFF binary consists of 3 segments: text, data, bss. Each segment consists of sections.

Code Sections

Not all section of the text segment contain code but only sections of the text segment contain code. SQUEEZE merges the code containing sections into a single sections. It is helpful that those sections are adjacent in the text segment.

Readonly Sections

All sections in the text segment are readonly but there are sections in the data segment that are also readonly. It is necessary to know which sections are readonly so that loads from these sections can be "evaluated".

Relocation Information

SQUEEZE uses relocation information to to determine basic block boundaries and to find basic blocks that can be the target of indirect jumps. SQUEEZE will also "fix" relocatable data before the binary is written back.

Relocation Types

SQUEEZE only considers relocation entries referencing the text segment. Luckily, there aren't all this many. There 8 byte addresses (REFQUAD) and 4 byte gp relative addresses (GPREL32) and one other class of relocation entries.

Refquads indicate the beginning of a basic block that can be jumped to from anywhere.

This is a rather coarse (but safe) assumption. Most of the time the refquad is used to describe a function address which is used in an non-computed jump, it would be nice to know which ones are used for computed jumps.

Gprel32s indicate the beginning of a basic block that is target of a switch statement (computed jump).

It is a big pain to figure out what the possible targets of a switch statement are and it would be nice if the symbol table provided this information.

There is a third type of relocation information used with init and fini sections.

Symbol Table

The symbol table is not used all this much. SQUEEZE uses it to associate names with addresses (eg. function name) and to find function boundaries. The latter could also be achieved using procedure descriptors.

Procedure Descriptor table

Procedure descriptors are not used anymore but they contain important information and I might look into them again.

Useful Information That Would Be Nice To Have

Some of this information is approximated in SQUEEZE

[
top of page ]