force inlining

Asked by Thomas Grieger

Hi all,

I have a question regarding inlining of functions.

To fulfill some hw timing requirements the usage of "nop" is required. Additionally the actual MISRA rules have to be taken into account. Therefor the assembler operations have to be encapsulated.

I tried to use an assembler function consisting of a single "nop" in a .sx file and a header file containing

void utilities_nop(void)__attribute__( ( naked, always_inline ) );

According to the documentation this should be sufficient to insert the single nop instead of the function call "utilities_nop();".
But with the gcc compiler 4.7 Q42012 a branch operation is generated. The inline keyword is also not sufficient nor is the compiler flag for activating inlining of functions.

Did I miss something or is there another option to tell the compiler to inline the function?

Best regards,
Thomas

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Thomas Preud'homme
Solved:
Last query:
Last reply:
Revision history for this message
Best Thomas Preud'homme (thomas-preudhomme) said :
#1

Is the function to be inlined included in the file where it is used? To inline the compiler needs the body of the function to be found before the functions that use it so if this function is used in several files you should put its body in a header file and include it from all the source file that want to use this function.

Revision history for this message
Tamas Kleiber (kleiber-tamas) said :
#2

The inline keyword does not enforce inlining. It allows the complier to inline if the compiler thinks its beneficial. So you should not rely on the inline keyword, instead you should use the always_inline attribute.

If you use ARM Cortex-M MCUs, CMSIS defines an intrinsic function for the nop instruction called void __NOP(void);

The function is declared as follows in a CMSYS system header file, called core_cmInstr.h:

/** \brief No Operation

    No Operation does nothing. This instruction can be used for code alignment purposes.
 */
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
  __ASM volatile ("nop");
}

If this level of abstraction is not sufficient then I think you are left with a real function. Also if you are checking against MISRA:2004, you are bound to ISO-C90 where the inline keyword was not defined and I think you should not use it at all. Nor language extensions like GCC's attributes system...

Please note that you should use the volatile keyword for your assembler code so that the optimizer does not remove the opcode from the SW when it thinks that it is useless.

Also, please note that you should not rely on the NOP instruction for time delays! NOP should only be used for padding and alignment. See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/Cjafcggi.html for further reference. Quote from the page: "NOP is not necessarily a time-consuming NOP. The processor might remove it from the pipeline before it reaches the execution stage.

You can use NOP for padding, for example to place the following instruction on a 64-bit boundary in ARM, or a 32-bit boundary in Thumb."

Also, ARM MCUs may have caches so you might end up with longer or shorter execution times based on cache hits for your opcode fetches and behaviour could be context dependent...

Revision history for this message
Thomas Grieger (t-grieger) said :
#3

Thanks Thomas Preud'homme, that solved my question.