Example 1. all C parts

The simplest case for IPA is an application that does not import any information from a DLL, and that is all in a single language that supports IPA. The following example covers this case. The sample programs mentioned here can be found in the sample data set with the member names given here.

The first example shows a simple application that is made up of three source files. The target is to compile it with IPA(Level(2)) and OPT(2). We also want a full inline report and pseudo-assembly listing. This is the only example where the full source will be shown.

CCNGHI1.C

Figure 1. hello1.c example source code
hello1.c:
    int seen_main;                                       
    int seen_unused3;                                    
                                                     
    char *string1 = "Hello";                             
    char *stringU1 = "I'm not going to use this one!";   
                                                     
                                                     
    int func2( char *);                                  
                                                     
    int main (void) {                                    
                                                     
      seen_main++;                                       
      func2(string1);                                    
                                                     
      return 0;                                          
   }                                                    
                                                     
   float unused3( int a ) {                             
     seen_unused3++;                                    
     return (float) a+seen_unused3;                     
   }                                                    

CCNGHI2.C

Figure 2. hello2.c example source code
hello2.c:
   #include <stdio.h>          
                             
   int seen_func2;              
   int seen_unused2;            
   char *string2 = "world!";    
                             
   int func3 (char *);          
                             
   int func2( char * s1) {      
                             
     seen_func2++;             
                             
     printf("%s ",s1);         
                             
     return func3(string2);     
  }                            
                             
  double unused2(float x) {    
                             
    seen_unused2++;            
                             
    return x+ seen_unused2;    
  }                                                 

CCNGHI3.C

Figure 3. hello3.c example source code
 hello3.c:
  #include <stdio.h>     
                              
  int seen_func3;                
  int seen_unused1;             
                              
  int unused1(int x) {          
                              
    seen_unused1++;             
                              
    return x+ seen_unused1;     
  }                             
                              
  int func3( char * string2) {    
                              
     seen_func3++;              
                              
     printf("%s\n",string2);    
                              
    return seen_func3;          
  }            

Building example 1. under z/OS UNIX System Services

For this example, the following table shows the mapping of SCCNSAM data set members to given file names:

SCCNSAM member name Name used in this example
CCNGHI1 hello1.c
CCNGHI2 hello2.c
CCNGHI3 hello3.c
The following commands can be used to create this module under z/OS® UNIX System Services:
c89 -c -2 -WI,NOOBJECT,LIST hello1.c hello2.c hello3.c
c89 -2 -WI,MAP,LEVEL\(2\) -Wl,I,INLRPT,LIST\(hello.lst\) -o hello hello1.o
  hello2.o hello3.o
The first c89 command performs an IPA Compile on hello1.c, hello2.c, and hello3.c. The options after -WI are IPA suboptions, which are described below (for further information on these suboptions, see IPA | NOIPA):
NOOBJECT
This compile performs an IPA Compile (since -c was specified). This option specifies that only IPA objects should be generated by the IPA compile step. The NOOBJECT suboption will reduce the size of the output object files. It causes only the IPA object to be written to the output file. The NOOBJECT option should be used unless the traditional object is needed for debugging purposes or the object file may be passed in a non-IPA Link. NOOBJECT significantly shortens the overall compile time.
LIST
This option tells IPA to save enough information that a listing with source file and line number information can be generated during the IPA(LINK) phase.
Note: -2 was specified on the IPA compile step. While it is not strictly necessary, it does allow for faster code to be generated in some cases.

The second c89 command does the IPA Link processing. Since -WI and Wl,I were specified with .o files, c89 automatically turns on the LINK suboption of IPA. The -WI suboptions within this command are those that are valid for IPA(LINK):

MAP
Generates additional information in the listing that shows where variables and data came from. For more information on specifying IPA(MAP), see Using the IPA link step listing.
LEVEL(2)
Specifies that the maximum level of IPA optimization is to be used

The -Wl,I option keyword specifies that these are compiler options that are to be passed to the IPA(LINK) step. Compiler options documents the compiler options and whether they are valid during the IPA link step. INLRPT triggers an inline report that shows the inlining that was done by IPA. LIST triggers a pseudo assembly listing for each partition.

Notes:
  1. In this case, the name of the output file for the listing was provided as a suboption.
  2. Even with IPA, the -2 or -3 option should be used to specify the opt level that the traditional optimizer should be called with.

This example shows the advantage of using discrete listing options (MAP, LIST, INLRPT) over using -V. -V may give you so much information that it creates a huge file. By using the individual options, you get more control and (with LIST) the ability to route the listing to the location of your choice without redirecting the output of your c89 command.

Building example 1. in batch

For this example the following table shows the mapping of SCCNSAM data set members to given file names:

SCCNSAM member name Name used in this example
CCNGHI1 IPA.SOURCE(HELLO1)
CCNGHI2 IPA.SOURCE(HELLO2)
CCNGHI3 IPA.SOURCE(HELLO3)
The following JCL can be used to create an object deck that can be linked to create the module (the link JCL is omitted for brevity):
/USERID1A JOB (127A,0329),'$MEM$',                               
//  MSGLEVEL=(2,0),MSGCLASS=S,CLASS=A,                            
//  NOTIFY=USERID1,REGION=1024M                                   
//PROC JCLLIB ORDER=(CBC.SCCNPRC)                                 
//*---------------------------------------------------------------
//* IPA compile step for hello1.c                                 
//*---------------------------------------------------------------
//C001F336  EXEC EDCC,                                            
//          INFILE='USERID1.IPA.SOURCE(HELLO1)',                  
//          OUTFILE='USERID1.IPA.OBJECT(HELLO1),DISP=SHR',        
//          CPARM='OPTFILE(DD:OPTIONS)'                           
//OPTIONS  DD *                                                   
    IPA(NOOBJECT,LIST) RENT LONG OPT(2)                           
/*                                                                
//*---------------------------------------------------------------
//* IPA compile step for hello2.c                                 
//*---------------------------------------------------------------
//C001F336  EXEC EDCC,                                            
//          INFILE='USERID1.IPA.SOURCE(HELLO2)',                  
//          OUTFILE='USERID1.IPA.OBJECT(HELLO2),DISP=SHR',        
//          CPARM='OPTFILE(DD:OPTIONS)'                           
//OPTIONS  DD *                                                   
    IPA(NOOBJECT,LIST) RENT LONG OPT(2)                           
/*                                                                
//*---------------------------------------------------------------
//* IPA compile step for hello3.c                                 
//*---------------------------------------------------------------
//C001F336  EXEC EDCC,                                            
//          INFILE='USERID1.IPA.SOURCE(HELLO3)',                  
//          OUTFILE='USERID1.IPA.OBJECT(HELLO3),DISP=SHR',        
//          CPARM='OPTFILE(DD:OPTIONS)'                           
//OPTIONS  DD *                                                   
    IPA(NOOBJECT,LIST) RENT LONG OPT(2)                           
/*                                                                
//*-----------------------------------------------------------------
//* IPA link step for the hello module                              
//*-----------------------------------------------------------------
//C001F336  EXEC EDCI,                                              
//          OUTFILE='USERID1.IPALINK.OBJECT(HELLO),DISP=SHR',       
//          IPARM='OPTFILE(DD:OPTIONS)'                             
//* The following line sets up an input file that just includes all 
//*   the IPA compile step object files.                            
//SYSIN  DD DATA,DLM='/>'                                           
  INCLUDE OBJECT(HELLO1,HELLO2,HELLO3)                              
/>                                                                  
//* The following line redirects the listing                        
//SYSCPRT DD DSN=USERID1.IPA.LISTING(HELLO),DISP=SHR                
//* These are the options used                                      
//OPTIONS  DD DATA,DLM='/>'                                         
    IPA(LINK,MAP,LEVEL(2)) OPT(2) INLRPT LIST RENT LONGNAME         
/>                                                                  
//* The following line gives the object library                     
//OBJECT DD DSN=USERID1.IPA.OBJECT,DISP=SHR     
The options used are the same as those given in Building example 1. under z/OS UNIX System Services with the exception that IPA(LINK) should be explicitly specified, and RENT, and LONGNAME are not the default for C in batch so they also need to be specified. This sample JCL was created using the standard cataloged procedures shipped with the z/OS XL C/C++ compiler.

The generated file hello.lst is as follows:

After a traditional compile, there are three object files, six external functions, and eight external variables. Without a global view of the application, the compiler looks at hello1.c and cannot tell that unused3 is really unused and that stringU1 is never referenced. So the compiler has to keep all of the code and variables. IPA has the global view so it can remove the unused functions. As you can see from Figure 4, only the main function remains. The other functions were inlined, and because they were not exported, and their address was not taken, they were removed.