The purpose of the -qoptdebug compiler option is to aid the debugging of optimized programs. It does this by creating pseudocode that maps more closely to the instructions and values of an optimized program than the original source code. When a program compiled with this option is loaded into a debugger, you will be debugging the pseudocode rather than your original source. By making optimizations explicit in pseudocode, you can gain a better understanding of how your program is really behaving under optimization. Files containing the pseudocode for your program are generated with the file suffix .optdbg. Only line debugging is supported for this feature.
xlc myprogram.c -O3 -qhot -g -qoptdebug
In
this example, your source file is compiled to a.out. The pseudocode
for the optimized program is written to a file called myprogram.optdbg which
can be referred to while debugging your program.From the following examples, you can see how the compiler might apply optimizations to a simple program and how debugging it can differ from debugging your original source.
Example 1: Represents the original non-optimized code for a simple program. It presents a couple of optimization opportunities to the compiler. For example, the variables z and d are both assigned by the equivalent expressions x + y. Therefore, these two variables can be consolidated in the optimized source. Also, the loop can be unrolled. In the optimized source, you can see iterations of the loop listed explicitly.
Example 2: Represents a listing of the optimized source as shown in the debugger. Note the unrolled loop and the consolidation of values assigned by the x + y expression.
Example 3: Shows an example of stepping through the optimized source using the debugger. Note, there is no longer a correspondence between the line numbers for these statements in the optimized source as compared to the line numbers in the original source.
#include "stdio.h"
void foo(int x, int y, char* w)
{
char* s = w+1;
char* t = w+1;
int z = x + y;
int d = x + y;
int a = printf("TEST\n");
for (int i = 0; i < 4; i++)
printf("%d %d %d %s %s\n", a, z, d, s, t);
}
int main()
{
char d[] = "DEBUG";
foo(3, 4, d);
return 0;
}
(dbx) list
1 3 | void foo(long x, long y, char * w)
2 4 | {
3 9 | a = printf("TEST\n");
4 12 | printf("%d %d %d %s %s\n",a,x + y,x + y,
((char *)w + 1),((char *)w + 1));
5 printf("%d %d %d %s %s\n",a,x + y,x + y,
((char *)w + 1),((char *)w + 1));
6 printf("%d %d %d %s %s\n",a,x + y,x + y,
((char *)w + 1),((char *)w + 1));
7 printf("%d %d %d %s %s\n",a,x + y,x + y,
((char *)w + 1),((char *)w + 1));
8 13 | return;
9 } /* function */
10
11
12 15 | long main()
13 16 | {
14 17 | d$init$0 = "DEBUG";
15 18 | @PARM.x0 = 3;
16 @PARM.y1 = 4;
17 @PARM.w2 = &d;
18 9 | a = printf("TEST\n");
19 12 | printf("%d %d %d %s %s\n",a,@PARM.x0 + @PARM.y1,
@PARM.x0 + @PARM.y1,((char *)@PARM.w2 + 1),
((char *)@PARM.w2 + 1));
20 printf("%d %d %d %s %s\n",a,@PARM.x0 + @PARM.y1,
@PARM.x0 + @PARM.y1,((char *)@PARM.w2 + 1),
((char *)@PARM.w2 + 1));
21 printf("%d %d %d %s %s\n",a,@PARM.x0 + @PARM.y1,
@PARM.x0 + @PARM.y1,((char *)@PARM.w2 + 1),
((char *)@PARM.w2 + 1));
22 printf("%d %d %d %s %s\n",a,@PARM.x0 + @PARM.y1,
@PARM.x0 + @PARM.y1,((char *)@PARM.w2 + 1),
((char *)@PARM.w2 + 1));
23 19 | rstr = 0;
24 return rstr;
25 20 | } /* function */
(dbx) stop at 18
[1] stop at "myprogram.o.optdbg":18
(dbx) run
[1] stopped in main at line 18 in file "myprogram.o.optdbg"
18 9 | a = printf("TEST\n");
(dbx) cont
TEST
5 7 7 EBUG EBUG
5 7 7 EBUG EBUG
5 7 7 EBUG EBUG
5 7 7 EBUG EBUG
execution completed