Forcing inlining of instrumentation functions in GCC

Hi,

This question might be a little too esoteric even for GQ on SDMB (or anywhere else for that matter), but I can’t seem to be able to find an answer by searching other forums, and hey this is my home!

I’m running SDE 4.1 GCC 2.96 custom version for MIPS 4k (yeah I know, ancient, but we won’t get into that) and I need to do something rather weird. I need to force inlining of

__cyg_profile_func_enter
__cyg_profile_func_exit

instrumentation function calls that GCC can add with -finstrument-functions. Simply declaring those as “static inline” inside each file has not proved successful - specifically on the assembly dump it still generates the function code and a global address for them, and in each instrumented function I see a “jal __cyg_profile_func_enter” in the beginning and “jal __cyg_profile_func_exit” in the end, i.e. not inlined at all (even those the functions are defined in that very same file and are right there next to it in the assembly dump)

Now, I don’t have an environment handy for compiling this particular version of GCC, nor can I find the sources right now (and using other versions, even slightly, has proved unsuccessful in the past). Besides, diving into GCC sources head first is a good way to earn oneself an aneurism. What I am willing to settle for is a way to insert/generate function entry/exit inline code into about a million lines of C code. I’m willing to write this code myself in assembly if need be, but I don’t want to change the build environment too much.

Any suggestions on how to force GCC to either inline those functions or how to force it to generate my own custom profiling code?
Thank you very much,

Best regards,

Groman
P.S. Bonus lightning round question: Does anybody know of a trick to inform each function during the linking stage what section it gets linked into? (Using GCC + GNU LD, optimally) Something like automatically putting a static var __ld_section; into each function and then having LD backpatch all those with the section address or something along those lines? In my custom profiling code I will need to know what object file section it got loaded from somehow.

Does it have to be an inline function, or can you use a macro? Macros will definitely expand inline, though if you need the function for its return value it may not be trivial to convert the function statement(s) to an expression.

Well, I would love a macro but I don’t see a way to force a MACRO to automatically expand in the beginning and end of every of some several thousand functions, other than putting it in by hand, and even then, this being reasonably standard C it would have to somehow expand into code that’s guaranteed to run before any declarations of the form “int i = blah();” at the top of the function. I do not think C guarantees that the first variable declaration’s initial value gets evaluated first, does it?

Ah, I understand now. I don’t know what the standard says (or, more important, what your version of gcc does) for variable initialization order, though you may be able to figure it out by experimentation. But I think that the “;”, even following a variable declaration, is a sequence point, meaning that the side effects of the preceding statement must be complete before the following statement begins. So manually adding the entry and exit code in every function should capture variable initialization as well. (This is not strict ANSI C, since ANSI requires declaration/initialization before code; but unless you’re using -pedantic gcc should allow it.)

I guess you could still use macros at the calling side, though it would be very ugly. (Replace all “a=f(b)” with “(ENTRY,a=f(b),EXIT,a)” where ENTRY and EXIT are the profiling functions.)

Is “inline” even supported by your version of gcc? Are you using -ansi or some similar -std? I suppose you’ve read the gcc man, but just in case:

There may also be options controlling the maximum size of inlined functions (there are on my gcc, but your version may differ).

Have you looked at the actual linked code to see what’s happening? The inlining may be done by the linker, so you wouldn’t necessarily see it in the per-file assembly dump.

Like you said, if each variable initialization is a separate statement, the compiler will honor the order of statements. IIRC, the C++ standard doesn’t even specify in what order function parameters will be evaluated, so that’s where you see cross-compiler variation.