Building Portable Code with Linker Optimization

To build executables on a PA-RISC 2.0 system that run on 1.1 and 2.0 systems, compiled for optimization with +O4, +P, or +I, explicitly compile those components with +DAportable or +DA1.1. This is due to the code generation that the linker invokes at link-time for optimization. When you compile with +O4, +P or +I, your compiler builds an I-SOM (Intermediate code-System Object Module) file instead of a SOM file at compile time. (See Instrumenting (+I/-I) for more information). At link-time, the linker invokes the code generator (ucomp) to generate SOM files from the I-SOM files and to complete the optimization. If you did not build the I-SOM file with +DAportable or +DA1.1, ucomp generates a SOM file that contains code for the PA-RISC architecture of the machine on which you are building.

For example, if you build an archive library on a 1.1 system with +O4, +P, or +I, without specifying the architecture, the I-SOM files in the library do not contain a specific option for 1.1 code generation. If you move the archive library to a 2.0 system and use it to build an executable, the executable is built as a 2.0 executable because of the link-time code generation. To build a 1.1 executable, rebuild the archive library with +DAportable or +DA1.1. Another approach is to combine objects that have been compiled with +O4, +P, or +I into a merged object file with the linker -roption: the -roption produces an object file (SOM) not an I-SOM file. Since code generation occurs when the merged file is built, if this file is built on a 1.1 system, the file is safe to ship to other systems for building 1.1 applications. To determine if an object file is an I-SOM file, use the size(1) command. I-SOM files have zero listed for the size of all the sections (text, data and bss (uninitialized data)):

$ size foo.o

0 + 0 + 0 = 0

Profiling

After instrumenting a program, you can run it one or more times to generate profile data, which is ultimately used to perform the optimizations in the final step of PBO. This section provides information on the following profiling topics:

“Choosing Input Data” (page 208)

“The flow.data File” (page 208)

“Storing Profile Information for Multiple Programs” (page 209)

“Sharing the flow.data File Among Multiple Processes” (page 209)

“Forking an Instrumented Application” (page 210)

Choosing Input Data

For best results from PBO, use representative input data when running an instrumented program. Input data that represents rare cases or error conditions is usually not effective for profiling. Run the instrumented program with input data that closely resembles the data in a typical user's environment. Then, the optimizer focuses its efforts on the parts of the program that are critical to performance in the user's environment. You need not do a large number of profiling runs before the optimization phase. Usually it is adequate to select a small number of representative input data sets.

The flow.data File

When an instrumented program terminates with the exit(2) system call, special code in the 32-bit icrt0.o startup file or the 64-bit /usr/ccs/lib/pa20_64/fdp_init.ofile writes profile data to a file called flow.data in the current working directory. This file contains binary data, which cannot be viewed or updated with a text editor. The flow.data file is not updated when a process terminates without calling exit. That happens, for example, when a process aborts because of an unexpected signal, or when the program calls exec(2) to replace itself with another program.

208 Improving Your Application Performance