Working with the compiler optimizer and Code Debug


This section describes the best practices for optimization and debugging.

Compiler optimization

Compiler optimization was the primary feature that attracted early adopters to migrate to the newer language versions. Reducing the 4HRA footprint can have a measurable reduction on the monthly invoice, which is an outstanding benefit.

However, compiler optimization introduces significant difficulties in debugging and determining the cause of optimized program failures. For optimized code, the complexity of associating source code and generated binary code is well known as problematic in compiler optimization literature. For a comprehensive discussion of COBOL V5/6 optimization implementation, see our blog about compiler optimization.

Furthermore, it can be challenging to debug an optimized program because optimization is not confined to individual language statements but across all statements. When cross statement optimization occurs, the IBM optimizer may move some machine instructions in each statement to a preceding or following statement—sometimes for more than one statement.

Compiler optimization requires using a compiler source listing to debug programs properly. Therefore, the complete compiler listing that details the optimization generated is paramount to a successful debugging experience. Code Debug is enabled for this optimized source listing and tested with all OPT levels to give you the best debugging experience.

Debugging at OPT(0)

Higher optimization levels, such as OPT(1) and OPT(2), will likely introduce changes to the program that will limit the use of a source debugging tool. Hence, debugging a program with higher optimization levels can give incorrect or invalid results because it no longer behaves as it did with OPT(0). For example, a common optimization technique uses registers instead of data areas, which speeds program execution. The optimized program listing might reflect this register optimization. Hence, any source code debugging would likely have problems, as data areas are expected to be updated but are not because the data is in a register.

For this reason, we recommend that even though programs should run at the highest reasonable OPT level for user acceptance, staging, and production levels, debugging might have to occur at the OPT(0) level. Doing so will either require a recompile at OPT(0) or have a second binary at OPT(0) available for debugging. It is true for both COBOL and PL/I, as the COBOL V6 and PL/I V5 compilers seem to implement similar optimization techniques.

TEST and OPT compiler options

IBM COBOL optimization and debugging using IBM tools are tightly bound together. Compiler options specified for debugging affect the capability of debugging, affecting the sizes of both the COBOL listing and executable binary.

Specifically, using these IBM debugging tools depends on the TEST compiler option, which adds binary information to the executable.

Comparatively, BMC AMI products implement a debugging methodology with highly customized code and the common CSS routines that provide services and functions shared between our products.

We also use the COBOL listing but does not use any IBM-generated debugging data written to the executable binary.

With COBOL V6 optimization, specifically, when using OPT(1) or OPT(2) compile-time optimization, optimized code can make debugging very difficult as the COBOL statement flow seems to jump back and forth between a few COBOL statements. This behavior is an artifact of the optimization process and in no way is a shortcoming of the debugger.

For optimized code, the complexity of associating the COBOL source code and generated binary machine code is considered problematic in compiler optimization literature. This jumping behavior led us to develop a more smooth stepping experience and minimize any statement jumping. The TEST compiler option is required to solve this.

To reduce the DASD size of executable program object binaries, we worked with the IBM COBOL Compiler team to develop and introduce the TEST(NODWARF), parameter which eliminates the IBM debugging (DWARF) information written to the executable program object binary.

Both TEST and OPT add substantial data to the executable binary.

Similarly, as you can see in the following chart, the EJPD and SOURCE options can add quite a lot of additional data to the program object executable. Because both options are IBM debugger options, BMC AMI products do not need them, and you should disable them with NOEJP and NOSOURCE.

Alternatively, for optimization, OPT(0) disk sizes are static, and OPT(1) and OPT(2) sizes are optimized similarly. The fact that OPT(1) and OPT(2) sizes are similar is an artifact of the optimization process. With the highest level 2, there is seemingly no additional optimization possible over what the compiler already provides for level 1.

Another observation is that CPU times for compilation increase dramatically for higher optimization levels. We ran tests on a sample COBOL program to exemplify how DASD usage varies with these options.
worddav3fae6296ef716b1286e54391162f0107.png

Considerations

  • For BMC AMI tools, you can minimize the undesired COBOL jumping behavior by using the TEST compiler option, for Code Debug tools, and successfully generating a test case using Total Test. However, TEST is not needed or recommended for all other BMC AMI products.
  • When developing and with initial testing, you might be performing repeated compilations. We recommend avoiding OPT(1 and 2) if you are doing functional testing as these waste CPU time. Final testing (and performance testing), promotion to higher development levels, and production should be with the higher OPT(1 or 2) levels.

Recommendations

To enable Code Debug debugging, creating unit tests with Total Test, and rerun unit tests created by Total Test, use the following compile options:

Cobol v5 and above

OPT(0),LIST
OPT(1) or OPT(2) with TEST(NOEJPD,NOSOURCE,NODWARF) and LIST

Cobol below v5

NOOPT and LIST 


 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*