Why does the XC16 compiler remove the built-in function if the definition appears after use?

The XC16 compiler manual says the following:

The compiler will exclude only built-in functions if they are declared to be static, and if the function definition is preceded by all functions.

At the top of foo.c I declared

static inline void nop_10_times(void); 

Then in the definition for ISR it is defined as:

 void _CNInterrupt(void) { nop_10_times(); // rest of function } 

Then, as a test, I put the definition of nop_10_times at the bottom of the file.

 static inline void nop_10_times(void) { __builtin_nop(); __builtin_nop(); __builtin_nop(); __builtin_nop(); __builtin_nop(); __builtin_nop(); __builtin_nop(); __builtin_nop(); __builtin_nop(); __builtin_nop(); } 

When I compile my project and look at the assembly, it seems that the compiler was really able to completely remove this function in the assembly and leave only the embedded code where it was called in the ISR.

Does anyone know how this worked out? According to the definition in the manual, he said that he would exclude the built-in function if โ€œthe definition of a function precedes all uses of the functionโ€.

+6
source share
2 answers

Both manual restrictions seem reasonable. They were probably true for an earlier version of the compiler, or at least they were true in the spec at some point.

  • If the function is not declared static, it can be called from outside the current translation unit (source file). To do this, a non-inline function must be placed.

  • If a function is called somewhere before its definition, then the compiler does not have enough information at the point of use for the built-in function, only to generate a function call.

It seems that the optimizer guys are ahead of the guys from the documentation. The current optimizer is probably working on a parse tree for the full translation unit and sees that it can remove the call / redo sequence.

+1
source

First, remember that the inline directive is just a hint for compilers. Compilers are free to enter or not when they want.

Does anyone know how this worked out?

This is called a two-pass compiler. Wether inlay is performed during parsing, optimization time, code emitting phase, etc. It doesn't matter here.

According to the definition in the manual, he said that he would eliminate the built-in function if "the definition of the function precedes all the function."

It seems that โ€œif and only ifโ€ is now replaced by a simple โ€œifโ€, therefore, if the definition follows the call, it can sometimes be included ... Or it is an optimizer effect, so the insert can be considered as a border effect.

0
source

Source: https://habr.com/ru/post/986320/


All Articles