Table of contents * 1. Getting started o 1.1 Set environment variables - the quick way o 1.2 Set environment variables - details * 2. Using the compiler o 2.1 Standard compiler features o 2.2 Profiling o 2.3 Source code visibility o 2.4 Pointer analysis (aka alias analysis or PIP) o 2.5 Software pipelining o 2.6 Inlining o 2.7 Quick library compilation o 2.8 Other OpenIMPACT options o 2.9 GCC compatibility options * 3. Debugging options o 3.1 Inserting debugging symbols o 3.2 Inspecting compiler progress o 3.3 Debugging a compiler module o 3.4 Compiler performance o 3.5 Intermediate files * 4. Compiler theory of operation o 4.1 Compilation phases o 4.2 Pointer analysis * 5. oicc options * 6. oicc error messages o 6.1 General oicc errors o 6.2 Pointer analysis errors 1. Getting started 1.1 Set environment variables - the quick way Source the init-impact script. If you are running from the build directory, this is found in /init-impact. If you have installed OpenIMPACT using 'make install', init-impact is found in /bin/init-impact. By default, is /usr/local. init-impact should work with either sh or csh derived shells. Use one of the following commands to set up your environment. * sh shell, running from build directory sh$ . /init-impact * sh shell, running from install directory sh$ . /bin/init-impact * csh shell, running from build directory csh% source /init-impact * csh shell, running from install directory csh% source /bin/init-impact 1.2 Set environment variables - details OpenIMPACT requires the following environment variables. They are set automatically when the compiler is built and can be set at any time using 'init-impact'. This section is primarily for reference. 1.2.1 IMPACT_REL_PATH This is the path to the the directory containing the data files shipped with OpenIMPACT (mdes, platform, etc). When building the compiler or running from the build tree, this should be set to the source directory. For example, if you unpacked the OpenIMPACT tarball into your home directory, you would set IMPACT_REL_PATH to ~/openimpact-. After installation, IMPACT_REL_PATH should be set to the installation prefix. If you did not specify the --prefix option to configure, this will be /usr/local. 1.2.2 IMPACT_ROOT This is the path to the build tree. It is used mainly to locate data files generated from others in IMPACT_REL_PATH. When building the compiler or running from the build tree, this should be set to the build directory. For example, if you built the compiler in a directory 'build' in your home directory, you would set IMPACT_ROOT to ~/build. After installation, IMPACT_ROOT should be set to the installation prefix. If you did not specify the --prefix option to configure, this will be /usr/local. 1.2.3 DEFAULT_PROJECT For historical reasons, OpenIMPACT requires DEFAULT_PROJECT to be set to 'full'. 1.2.4 IMPACT_BUILD_TYPE This indicates the target for the code. For typical use on Linux/Itanium, this should be set to 'ia64lin'. 1.2.5 IMPACT_HOST_PLATFORM This indicates the platform on which the compiler is run. For typical use on Linux/Itanium, this should be set to 'ia64lin'. 1.2.6 IMPACT_HOST_COMPILER This indicates the name of a standard ANSI C compiler to use for preprocessing. For Linux/Itanium, this should be set to 'gcc'. 1.2.7 STD_PARMS_FILE This is the standard set of parameters for the OpenIMPACT modules. The parameter files are found under $IMPACT_REL_PATH/parms. For Linux/Itanium, this should be set to $IMPACT_REL_PATH/parms/STD_PARMS.IPF-MCKINLEY. 1.2.8 PATH In addition to the bin directory, OpenIMPACT needs to have its scripts and driver directories in the path. bin is found in IMPACT_ROOT. driver and scripts are found in IMPACT_REL_PATH. 2. Using the compiler The driver for OpenIMPACT is named 'oicc'. After sourcing init-impact (section 1.1), oicc will be in your path. 2.1 Standard compiler features The driver accepts all standard compiler arguments. -c Compile to a .o file; do not link. -O0 Turn off optimizations. -O, -O1 Optimization level 1. This is the default. This turns on most standard optimizations (Lopti, Lblock, Lsuperscalar). -O2 Perform pointer analysis and software pipelining in addition to all optimizations performed in level 1. -O3 Perform inlining in addition to all optimizations performed in level 2. -o Specify the output file name. -D Define a preprocessor symbol. -E Preprocess only. The driver runs gcc as the preprocessor and exits. -I Specify a path to search for include files. -L Specify a path to search for libraries. -R Specify a path to search for dynamically linked libraries. -l Specify a library to link into the final binary. -v, --verbose Print the output of each compilation stage to standard output. 2.2 Profiling Profiling is required to take full advantage of many optimizations. Profiling with oicc is a three or five step process. Most programs can get by with the three step process. The three step process is faster and less error prone than the full five step process. * Run oicc with the option '--pprof-gen'. oicc will generate a probed binary from the C-like intermediate representation (Pcode). This binary will have a .prof extension (a.out.prof by default). oicc adds the .prof extension to the name specified with the -o option, so 'oicc --pprof-gen -o foo' will result in a probed binary named foo.prof. * Run this binary one or more times on some typical input to collect a profile. * Run oicc again, with the option '--pprof-use'. oicc will read the collected profile and produce the final binary. The translation to the assembly-like intermediate representation (Lcode) sometimes reveals structures that the Pcode profiler cannot currently detect. This usually manifests as a mismatched loop count in the later stages of the compiler. In this case, you must use the five step profiling process. Note that the five step profiling process is currently incompatible with programs that use threads or signal handlers. * Run oicc with the option '--pprof-gen' (or '--profile-stage 1'). oicc will generate a probed binary from the C-like intermediate representation (Pcode). * Run this binary one or more times on some typical input to collect a profile. * Run oicc again, with the options '--pprof-use' and '--lprof-gen' (or '--profile-stage 2)'. oicc will generate a probed binary from the assembly-like intermediate representation (Lcode). * Run this second binary on the same input used in the second step. Note that this binary will run significantly slower than the first. * Run oicc again, with the option '--lprof-use' (or '--profile-stage 3') to produce the final binary. 2.3 Source code visibility When generating a library, OpenIMPACT stores its C-like intermediate representation (Pcode) in the library for future use. This representation is very similar to the preprocessed source for the library. If you do not wish to distribute your source code, it is necessary to specify the '--no-insert-pcode' option to oicc. Note that specifying this option may prevent OpenIMPACT from performing some optimizations when linking against this library in the future. 2.4 Pointer analysis (aka alias analysis or PIP) Turning on pointer analysis allows the compiler to be more aggressive when optimizing expressions using pointers. Pointer analysis is potentially very time consuming, so it is turned off by default. Specify '--do-pointer-analysis' (or O2 or greater) to turn it on. 2.4.1 PIP files for library functions Pointer analysis requires information on each function used by a program. The PIPGen module creates this information for each function in the program being compiled and stores it in the 'pip' subdirectory of the compilation directory. Pointer analysis also requires this information for functions in system libraries for which source code is not necessarily available. The most commonly used system functions already have pip files that were generated when the compiler was built. These files are generated from the file /platform/lib.c. This file contains stubs that emulate the real function's access to its arguments. If PIPAnal exits with an error due to a missing pip file for a system function (section 6.2.1), adding a stub for the function to lib.c and rebuilding the compiler should resolve the error. See section 4.2 for more information. 2.4.2 PIP files for libraries for which source is available (method 1) If you have the source for a library, the best way to resolve missing pip file errors is to compile the library with oicc and link against it (see also section 2.7). oicc will extract its intermediate representation from the library and recompile the library functions from source. This will optimize the library functions along with the program source, but will also increase compilation time. 2.4.3 PIP files for libraries for which source is available (method 2) If you have the source for a library, but do not wish to take the time necessary to optimize the library functions, you can use oicc to generate pip files for a library and proceed no further. To do this, compile your library using 'oicc --do-pip-gen-only' as the compiler. The pip files will be saved to the pip directory in the compile directory. They can then be copied to the /platform/ia64lin_gcc/PIP_info directory. When you compile your program, link against a version of the library not compiled with oicc (or compiled with the '--no-insert-pcode' option) so that oicc does not recompile the library. 2.5 Software pipelining Specify '--pipe' to turn on software pipelining. Software pipelining requires pointer analysis, so specifying '--pipe' automatically turns on pointer analysis. 2.6 Inlining Specify '--do-inlining' to turn on inlining. This performs both single file and cross file inlining. 2.7 Quick library compilation If you intend to use a library only to link against a program being compiled with oicc, you can specify the option '--insert-pcode-only' when compiling that library. oicc will generate the C-like intermediate representation and insert it into a library generated by gcc. When this library is linked using oicc, the intermediate representation is extracted and compiled at that time. Note that the compiled code in this library is generated by gcc. If you link against this library using any other compiler you will not see any optimizations from oicc. 2.8 Other OpenIMPACT options The following are some useful OpenIMPACT specific options. -j Run up to jobs in parallel in the second stage when possible. --keep-intermediate-files Keep all temporary files around after compilation. --max-unroll Unroll loops a maximum of times. This defaults to 8 on Linux/Itanium. --mitanium, --mmckinley Select a set of parameters for a first (itanium) or second (mckinley) generation Itanium processor. This defaults to mckinley. --no-control-speculation Turn off control speculation. Control speculation increases performance, but currently requires the general speculation kernel patch. --no-insert-pcode By default, oicc inserts pcode in the final output binary just as it does to the object generated by gcc when the -c option is specified (see section 4.1.1). This lets oicc optimize code linking against libraries generated by OpenIMPACT. The Pcode is a slightly transformed version of the original source code, so it may be desirable not to have it inserted in the binary. --parmfile Use as the parameter file instead of the default STD_PARMS.IPF-MCKINLEY. --resume Resume compilation from the latest completed stage. This assumes that --keep-intermediate-files was specified on the previous compiler run. --stop-after-assembling The --stop* options stop oicc after a certain stage. --stop-after-ctop --stop-after-converting-to-gp --stop-after-generating-host-layout-info --stop-after-lblock --stop-after-lcode-profiling --stop-after-lopti --stop-after-lsuperscalar --stop-after-ltahoe --stop-after-pcode-profiling --stop-after-pflatten --stop-after-pinline --stop-after-pointer-analysis --stop-after-psplit --stop-after-ptol --use-ias Write assembly code that can be assembled by Intel's assembler, ias. oicc then uses ias to assemble the code. 2.9 GCC compatibility options The driver accepts many GCC options for compatibility with build schemes expecting GCC. GCC is used as the preprocessor and linker, so all GCC options affecting those stages are accepted and passed through. GCC specific options affecting other stages are typically accepted and silently ignored. 3. Debugging options oicc does not yet fully support debugging symbols. It can instruct the underlying assembler to insert assembly level debugging symbols, but that is the extent of the support for debugging the user program. Many of these options are intended more for debugging the compiler than the user program. 3.1 Inserting debugging symbols Specify the '-g' option to insert assembly level debugging symbols into the output binary. 3.2 Inspecting compiler progress Specify the '--verbose' option to get debugging output from the compiler, including each command executed and its results. 3.3 Debugging a compiler module Occasionally a module will exhibit a bug that occurs only when it is called from the driver. In order to debug these, oicc can call your preferred debugger instead of executing the command directly. 3.3.1 --prompt-to-debug If this option is specified, oicc will prompt you to debug any command that matches the given regular expression. 3.3.2 --debugger Specify the debugger to use call when debugging a module. This defaults to gdb. 3.4 Compiler performance oicc has support for collecting performance data on the compiler modules to help optimize the compiler itself. 3.4.1 --collect-gprof-info If the command to be executed matches the given regular expression, oicc will collect the gmon.out file after the command is executed. This option assumes the module was compiled with gprof support. The gmon.out file is moved to the oicc.gprof directory and renamed to indicate the module that generated it. 3.4.2 --analyze-gprof-info This option instructs oicc to run gprof on the gmon.out file as it is collected. This may slow compilation significantly. 3.5 Intermediate files Most oicc modules read a temporary version of the source file, perform some processing, then write a new temporary version. In normal operation oicc deletes these temporary files as soon as they are no longer needed. 3.5.1 --keep-intermediate-files oicc will not delete any temporary file created during compilation. 3.5.2 --clean oicc will delete all temporary files created during the previous compilation. To use this option, perform a normal compilation with this option. oicc will find the temporary files based on the given source files and delete only those files it created. 4. Compiler theory of operation 4.1 Compilation phases Compilation with a normal compiler (gcc) is normally broken up into two phases. In the first phase, each source file is processed individually and compiled to an object file. In the second phase, all object files are linked together to produce the output binary. Some OpenIMPACT modules require knowledge of all source files during the compilation phase. If a project has several source files, OpenIMPACT cannot produce an object file from a single source file. Therefore, OpenIMPACT's two phases are different than a normal compiler. 4.1.1 oicc phase 1 In phase 1, oicc does as much as it can with a single file. This amounts to little more than preprocessing the source. After going as far as it can in phase 1, oicc calls gcc to compile the source file to an object. The output of OpenIMPACT's first phase is then packed into the object. This allows build schemes based on standard compilers to get the object they expect after the first phase. 4.1.2 Libraries Many build schemes use the ar command to generate libraries from the objects generated in the first phase. The object files written by oicc are compatible with ar, so this poses no problem. OpenIMPACT's output is preserved in the library. 4.1.3 oicc phase 2 In the second phase, oicc gets all object files and libraries generated in the first phase. OpenIMPACT can now see all files in the project, so it can now produce an output binary. oicc extracts the phase 1 output from the incoming objects and libraries and processes it through the rest of the compiler. Most of the compilation takes place here, so phase 2 takes much longer than with a standard compiler. After OpenIMPACT has generated object files, it rebuilds any libraries generated after phase 1. The GCC generated object inside the library is replaced with an OpenIMPACT one. By default, the intermediate representation from OpenIMPACT's first phase is also stored in the library for future use. 4.2 Pointer analysis Pointer analysis requires inspecting each function, even ones in system libraries. To work around the lack of source code for library functions, the file /platform/lib.c defines stand-in functions that emulate the function's access to input and output variables. If oicc exits with the error 'library template file for not found', the system function is simply unknown. The solution is to add a definition for the needed function to lib.c, the rebuild the platform directory by running 'make platform'. 4.2.1 lib.c function definitions The definitions in lib.c are simply stubs that emulate the real function's access to input and output variables. Only access to pointers needs to be emulated, so an empty definition suffices for a function like 'cos'. double cos(double x) { } For a function that takes a pointer, it is necessary to access the pointer's data in a similar way to the real function. For something like 'strlen', this simply means accessing every character in the input string. size_t strlen(const char *s) { int i; for (i = 0; s[i]; i++); } Functions that return pointers need to write the pointer's data, like 'strcpy'. char *strcpy(char *s1, const char *s2) { int i; for (i = 0; s1[i] = s2[i]; i++); return s1; } 4.2.2 Function definitions for libraries with available source If you have the source code for a system library, it may be possible to get function definitions for that library without first compiling the library with OpenIMPACT. Assuming the library does not use inline assembly or other features that OpenIMPACT does not currently support, you can compile the library using 'oicc --insert-pcode-only' as your compiler command. The objects and libraries generated by this command are the output of gcc with the OpenIMPACT intermediate representation packed inside. 4.2.3 Conditionally defining lib.c functions Some functions defined in lib.c may be from optional system libraries, such as the jpeg library. Since definitions in lib.c typically rely on prototypes from system headers, it may be necessary to conditionally define these functions so that they are not processed on a system without the proper headers. The 'configure' script can check for the presence of these extra libraries and define a preprocessor symbol to conditionally define the function in lib.c. 'configure' uses the AC_CHECK_LIB macro to check for extra libraries. By default, this macro adds the newly found library to the $LIBS variable, which is then used when linking every program built by the resulting makefile. To prevent these unneeded libraries from being linked into the OpenIMPACT binaries, you should use AC_CHECK_LIB in the following manner: AC_CHECK_LIB([jpeg], [jpeg_read_header], [AC_DEFINE([HAVE_LIBJPEG], 1, [Define to 1 if you have the `jpeg' library (-ljpeg).]) AM_CONDITIONAL([HAVE_LIBJPEG], [true])], [AM_CONDITIONAL([HAVE_LIBJPEG], [false])], []) The AM_CONDITIONAL macros will define HAVE_LIBJPEG in the context of Makefile.am, so that you can conditionally add targets to the list of pip files generated by the Makefile. This will make sure that all pip files are listed as the result of a rule iff they can be built. See platform/ia64lin_gcc/PIP_info/Makefile.am to see how these conditionals are used. 5. oicc options This is the complete list of oicc options (also viewable by running 'oicc -h'). ' Options: Long options can be specified with one dash or two. --analyze-gprof-info Run gprof on the info collected with the --collect-gprof-info option as it is collected. This may slow compilation significantly. --ansi Input is ANSI C (default). -C Tell the preprocessor not to discard comments. Implies -E. Passed directly to gcc. -c Stop after converting to Pcode. The compiler does as much as it can when it is called with a subset of the source files. --clean Delete all intermediate files associated with the source files given on the command line. This option must be added to the exact compiler invocation that created the intermediate files. --collect-gprof-info Collect the gmon.out files created by commands profiled for gprof. The files will be moved to the oicc.gprof directory. Profiles are only collected for commands matching the regular expression . -D Define symbol . --debugger Use as the debugger. This defaults to gdb. --do-induct Run code through Linduct to determine non-loop-variant load/store pairs. --do-inlining Perform function inlining. --do-pip-gen-only Generate the PIP files for the file(s) or library given on the command line. --do-pointer-analysis Run pointer analysis on the code. -E Stop after the preprocessing stage. -F Set a parameter that will be passed to each IMPACT module. -g Generate assembly level debugging symbols. -H Prints the name of each header file used. Passed directly to gcc. -h, --help Print this message. -I Add to the list of directories to search for include files. -i See -r. --idirafter Add to the tail end of the -I include search path. --imacros Process to get macro definitions. Passed directly to preprocessor (gcc). --include Process before the specified input file. Passed directly to preprocessor (gcc). --insert-pcode-only Compile source using gcc, but insert OpenIMPACT's intermediate representation into the objects. --iprefix Prepend to the directories specified in later --iwithprefix options. Passed directly to preprocessor (gcc). --iwithprefix (See also --iprefix). Add / to the tail end of the -I list of directories. Passed directly to preprocessor (gcc). -j When possible, run up to jobs in parallel. --keep-intermediate-files Keep extra files generated during each stage of the compilation. See also --resume. --krc Input is in K&R C form instead of ANSI C. -L Add to the list of directories to search for libraries. -l Link against . --lprof-gen Generate a profiled binary for profile guided optimization (Lcode stage). Lcode profiling requires that Pcode profiling has already been done (--lprof-gen is typically specified at the same time as --pprof-use). --lprof-use After running the profiled binary, use the profile information to guide the optimization (Lcode stage). -M, -MD, -MM, -MMD Options for the preprocessor. Implies -E. Passed directly to gcc. --max-unroll Unroll loops a maximum of times. --mitanium Generate code for a first generation Itanium. --mmckinley Generate code for a second generation Itanium. (default). --model The same as specifying --mitanium or --mmckinley. --no-control-speculation Turn off control speculation. --no-insert-pcode When generating the final object files, do not pack the Pcode into the object. --nostartfiles Do not use the standard system startup files when linking. Passed directly to linker (gcc). --nostdinc Do not search the standard system directories for header files. Passed directly to preprocessor (gcc). --nostdlib Do not use the standard system libraries when linking. Passed directly to linker (gcc). -O0, -O, -O1, -O2, -O3 Set the optimization level. -O0 no optimization -O, -O1 (default) Perform most standard optizations (Lopti, Lblock, Lsuperscalar) -O2 O1 + pointer analysis and pipelining -O3 O2 + inlining -o Save the resulting binary in . -P Tell the preprocessor not to generate '#line' directives. Implies -E. Passed directly to gcc. --parmfile Specify a parameter file to override the default (STD_PARMS.IPF-MCKINLEY). --pipe Turn on software pipelining. This also turns on pointer analysis. --pprof-gen Generate a profiled binary for profile guided optimization (Pcode stage). --pprof-use After running the profiled binary, use the profile information to guide the optimization (Pcode stage). --lprof-gen may be specified at the same time. --preprocessor-opti Pass the optimization flags to the preprocessor (gcc). This inlines optimized forms of some functions, but may rely on unsupported gcc extensions. --print-file-name= Print the full absolute name of library. Passed directly to gcc. --print-libgcc-file-name Same as --print-file-name=libgcc.a. Passed directly to gcc. --print-prog-name= Print the full absolute name of a program. Passed directly to gcc. --profile-stage Specify which profiling stage to run. Stage Effective option 1 --pprof-gen 2 --pprof-use --lprof-gen 3 --lprof-use --prompt-to-debug Prompt the user to run the command matching in the debugger. See also --debugger. -R Add to the list of directories to search for shared libraries. -r, --relocatable Link objects into a relocatable object that can be used as input to ld. --resume The compiler will try to resume compilation from the last completed stage. For the greatest benefit, --keep-intermediate-files should have been specified on the previous run. --rc Insert recovery code. --stop-after-assembling Stop compilation after assembling to object files. --stop-after-converting-to-gp Stop compilation after the Lgp_rel stage. --stop-after-ctop, -c Stop compilation after translating the C source to Pcode. Note that the object files written at this point are generated by gcc, and do not have any IMPACT optimizations. --stop-after-generating-host-layout-info Stop compilation after generating the host_layout_info.md file for all source files. --stop-after-lblock Stop compilation after the Lblock stage. --stop-after-lcode-profiling Stop compilation after merging Lcode profile information back to the source files. --stop-after-lopti Stop compilation after the Lopti stage. --stop-after-lsuperscalar Stop compilation after the Lsuperscalar stage. --stop-after-ltahoe, -S Stop compilation after translating the C source to assembly code. --stop-after-pcode-profiling Stop compilation after merging Pcode profile information back to the source files. --stop-after-pflatten Stop compilation after the Pflatten stage. --stop-after-pinline Stop compilation after the Pinline stage. --stop-after-pointer-analysis Stop compilation after running pointer analysis. --stop-after-psplit Stop compilation just after running Psplit (just before running Pinline). --stop-after-ptol Stop compilation after translating Pcode to Lcode. --target Select the machine description for scheduling. -U Undefine preprocessor symbol . Passed directly to preprocessor (gcc). -u Undefine linker symbol . Passed directly to linker (gcc). --undef Do not define any unstandard macros. Passed directly to preprocessor (gcc). --use-ias Write assembly code that can be assembled using Intel's assembler. When assembling, uses Intel's assembler. By default, the GNU format and assembler are used. -v, --verbose Print status information during compilation. -Wl,