Creation Zone

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Friday, 15 April 2005

Sun C/C++ compilers: Inlining routines

Posted on 18:21 by Unknown
The C++ compiler has two kinds of inlining: front-end (parser) and back-end (code generator). The C and Fortran compilers have only back-end inlining. The same code generator is used for all compilers on a platform.

Function inlining improves performance by replacing a call to a function with the body of the function itself. This eliminates the overhead of jumping to and returning from a subroutine. An additional advantage is that placing the function code "inline" exposes it to further optimization, enhancing performance even more.

The C++ compiler front end will attempt to expand inline a function declared implicitly or explicitly as inline. If the function is too large, the front end emits a warning when the +w or +w2 ("more warnings") option is used. The +d option prevents the front end from attempting to inline any function. The -g option also turns off front-end inlining. The -O options do not affect front-end inlining. For C++, with -g and -O options, you lose function inlining in the front end of the compiler. This can result is serious loss of performance. To avoid this problem, use -g0 instead of -g. C does not have -g0, use -g instead.

The C++ compiler performs front-end inlining because it can use its knowledge of C++ semantics to eliminate extra copies of objects, among other things that the code generator would not be able to do.

The back-end inlining does not depend on the programming language. With an optimization level of -O4 or higher, the code generator will examine all functions, independent of how they were declared in source code, and replace function calls with inline code where it thinks the replacement will be beneficial. No messages are emitted about back-end inlining (or failure to inline). The +d option does not affect back-end inlining.

Notes:
  1. Don't use "if(0)" in an inline function. Use "#if 0" instead.
  2. Also, don't put a return statement in the "then" part of an if-statement.
    Rearrange the code to put the return in the "else" part, or outside
    the if-else entirely.

Example #1:

% more inline.c
#include <stdio.h>

inline void printmespam() {
printf("print me"); printf("print me");
printf("print me"); printf("print me");
printf("print me"); printf("print me");
printf("print me"); printf("print me");
printf("print me"); printf("print me");
printf("print me"); printf("print me");
printf("print me"); printf("print me");
printf("print me"); printf("print me");
printf("print me");
}

inline void printme() {
printf("print me");
}

int main() {
printme();
printmespam();
return (0);
}

% CC +w2 inline.c
"inline.c", line 17: Warning: "printmespam()" is too large and will not be expanded inline.
1 Warning(s) detected.

In this example, printmespam() was not inlined by the compiler though we requested it to "inline" it. The keyword "inline" is a request, not a guarantee.

How to check if the routine is inlined:
Check the symbol table of the executable. If the routine doesn't showup in the symbol table, it is an indication that the missing routine is inlined. This is because the compiler might have replaced the function call with the body of the function.

% elfdump -CsN.symtab a.out | grep printme
[85] 0x00010e68 0x000000a4 FUNC GLOB D 0 .text void printmespam()

printme is inlined, where as printmespam is not.

The other way is to check the assembly code being generated. To generate the assembly code, compile the code with -S option of Sun Studio compilers.

% more swap.c
void swap (int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}

int main() {
int x = 5, y = 2;
swap(&x,&y);
return (0);
}

% CC +w2 -S swap.c

% grep call swap.s
call __1cEswap6Fpi0_v_

% dem __1cEswap6Fpi0_v_
__1cEswap6Fpi0_v_ == void swap(int*,int*)

From the above output(s), it is clear that the function is not inlined since an assembly instruction has been generated with a call to routine swap.

% more swap.c
inline void swap (int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}

int main() {
int x = 5, y = 2;
swap(&x,&y);
return (0);
}
% CC +w2 -S swap.c
% grep call swap.s

Now after instructing the compiler to inline the routine swap, the compiler was able to inline the function in main(), since it was not too big. That's why no assembly instruction has been generated with a call to swap.

Example #2:

%more inline2.c
#include <stdio.h>

int globvar = 0;

inline void setglob () {
globvar= 25;
}

int main(int argc, char *argv[]) {
globvar= 5;
setglob();
printf("Now global variable holds %d\n", globvar);
return (0);
}

%cc -o test inline2.c
Undefined first referenced
symbol in file
setglob inline2.o
ld: fatal: Symbol referencing errors. No output written to test

The above code violates a C rule. An inline definition without an "extern" directive does not create an instance of the function. Calling the function has undefined results.

The fix is to declare setglob with external linkage.

C++ has a different rule for inline functions. The compiler is required to figure out how to generate a defining instance if one is needed, without any special action by the programmer. So, the above example (#2) is valid C++ code, but not valid C code.

Modified code:

% more inline2.c
#include <stdio.h>

int globvar = 0;

extern inline void setglob () {
globvar= 25;
}

int main(int argc, char *argv[]) {
globvar= 5;
setglob();
printf("Now global variable holds %d\n", globvar);
return (0);
}

% cc inline2.c
% ./a.out
Now global variable holds 25

Acknowledgements:
Steve Clamage
Email ThisBlogThis!Share to XShare to Facebook
Posted in | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • *nix: Workaround to cannot find zipfile directory in one of file.zip or file.zip.zip ..
    Symptom: You are trying to extract the archived files off of a huge (any file with size > 2 GB or 4GB, depending on the OS) ZIP file with...
  • C/C++: Printing Stack Trace with printstack() on Solaris
    libc on Solaris 9 and later, provides a useful function called printstack , to print a symbolic stack trace to the specified file descripto...
  • JDS: Installing Sun Java Desktop System 2.0
    This document will guide you through the process of installing JDS 2.0 on a PC from integrated CDROM images Requirements I...
  • Binary compatibility
    What's It? "Binary compatibility" (BC) is the ability of one machine to run software that was written for another without hav...
  • Solaris: NULL pointer bugs & /usr/lib/0@0.so.1 library
    Some programmers assume that a NULL character pointer is the same as a pointer to a NULL string. However de-referencing a NULL pointer (ie.,...
  • Database: Oracle Server Architecture (overview)
    Oracle server consists of the following core components: 1) database(s) & 2) instance(s) 1) database consists of: 1) datafil...
  • Sun: OpenJDK
    Open source JDK, that is. Sun Microsystems did it again -- As promised during JavaOne event back in May 2006, Sun made the implementation of...
  • Consolidating Siebel CRM 8.0 on a Single Sun SPARC Enterprise Server, T5440
    .. blueprint document is now available on wikis.sun.com . Here is the direct link to the blueprint:              Consolidating Oracle Siebel...
  • Oracle Internet Directory 11g Benchmark on SPARC T5
    SUMMARY System Under Test (SUT)     Oracle's SPARC T5-2 server Software     Oracle Internet Directory 11 g R1-PS6 Target Load     50...
  • Fix to Firefox 3 Crash on Solaris 10 x86
    Symptom : Firefox 3 crashes on Solaris 10 x86 when the web browser tries to render some of the HTML pages with SWF content in them. For exam...

Categories

  • 80s music playlist
  • bandwidth iperf network solaris
  • best
  • black friday
  • breakdown database groups locality oracle pmap sga solaris
  • buy
  • deal
  • ebiz ebs hrms oracle payroll
  • emca oracle rdbms database ORA-01034
  • friday
  • Garmin
  • generic+discussion software installer
  • GPS
  • how-to solaris mmap
  • impdp ora-01089 oracle rdbms solaris tips upgrade workarounds zombie
  • Magellan
  • music
  • Navigation
  • OATS Oracle
  • Oracle Business+Intelligence Analytics Solaris SPARC T4
  • oracle database flashback FDA
  • Oracle Database RDBMS Redo Flash+Storage
  • oracle database solaris
  • oracle database solaris resource manager virtualization consolidation
  • Oracle EBS E-Business+Suite SPARC SuperCluster Optimized+Solution
  • Oracle EBS E-Business+Suite Workaround Tip
  • oracle lob bfile blob securefile rdbms database tips performance clob
  • oracle obiee analytics presentation+services
  • Oracle OID LDAP ADS
  • Oracle OID LDAP SPARC T5 T5-2 Benchmark
  • oracle pls-00201 dbms_system
  • oracle siebel CRM SCBroker load+balancing
  • Oracle Siebel Sun SPARC T4 Benchmark
  • Oracle Siebel Sun SPARC T5 Benchmark T5-2
  • Oracle Solaris
  • Oracle Solaris Database RDBMS Redo Flash F40 AWR
  • oracle solaris rpc statd RPC troubleshooting
  • oracle solaris svm solaris+volume+manager
  • Oracle Solaris Tips
  • oracle+solaris
  • RDC
  • sale
  • Smartphone Samsung Galaxy S2 Phone+Shutter Tip Android ICS
  • solaris oracle database fmw weblogic java dfw
  • SuperCluster Oracle Database RDBMS RAC Solaris Zones
  • tee
  • thanksgiving sale
  • tips
  • TomTom
  • windows

Blog Archive

  • ►  2013 (16)
    • ►  December (3)
    • ►  November (2)
    • ►  October (1)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (2)
    • ►  January (1)
  • ►  2012 (14)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (2)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (2)
  • ►  2011 (15)
    • ►  December (2)
    • ►  November (1)
    • ►  October (2)
    • ►  September (1)
    • ►  August (2)
    • ►  July (1)
    • ►  May (2)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2010 (19)
    • ►  December (3)
    • ►  November (1)
    • ►  October (2)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (5)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2009 (25)
    • ►  December (1)
    • ►  November (2)
    • ►  October (1)
    • ►  September (1)
    • ►  August (2)
    • ►  July (2)
    • ►  June (1)
    • ►  May (2)
    • ►  April (3)
    • ►  March (1)
    • ►  February (5)
    • ►  January (4)
  • ►  2008 (34)
    • ►  December (2)
    • ►  November (2)
    • ►  October (2)
    • ►  September (1)
    • ►  August (4)
    • ►  July (2)
    • ►  June (3)
    • ►  May (3)
    • ►  April (2)
    • ►  March (5)
    • ►  February (4)
    • ►  January (4)
  • ►  2007 (33)
    • ►  December (2)
    • ►  November (4)
    • ►  October (2)
    • ►  September (5)
    • ►  August (3)
    • ►  June (2)
    • ►  May (3)
    • ►  April (5)
    • ►  March (3)
    • ►  February (1)
    • ►  January (3)
  • ►  2006 (40)
    • ►  December (2)
    • ►  November (6)
    • ►  October (2)
    • ►  September (2)
    • ►  August (1)
    • ►  July (2)
    • ►  June (2)
    • ►  May (4)
    • ►  April (5)
    • ►  March (5)
    • ►  February (3)
    • ►  January (6)
  • ▼  2005 (72)
    • ►  December (5)
    • ►  November (2)
    • ►  October (6)
    • ►  September (5)
    • ►  August (5)
    • ►  July (10)
    • ►  June (8)
    • ►  May (9)
    • ▼  April (6)
      • C/C++: Functions with variable numbers of arguments
      • Solaris: Fixing sound card woes
      • Solaris: Recovering from a Runtime Linker Failure -2
      • Sun C/C++ compilers: Inlining routines
      • Solaris Linker: -B {static | dynamic}
      • Solaris: Useful Commands - 1
    • ►  March (6)
    • ►  February (5)
    • ►  January (5)
  • ►  2004 (36)
    • ►  December (1)
    • ►  November (5)
    • ►  October (12)
    • ►  September (18)
Powered by Blogger.

About Me

Unknown
View my complete profile