5.9.7 Function Duplication
MPLAB XC8 compiler employs a feature that duplicates the generated code associated with any function that uses a non-reentrant model and that is called from more than one call graph.
There is one call graph associated with main-line code and one for each interrupt function, if defined. The compiler assumes that interrupts can occur at any time. Functions encoded to use the compiled stack are not reentrant, thus such functions called from main-line code and from interrupt code could result in code failure. The compiler will duplicate the output for any non-reentrant function called from more than one call graph. This makes the function appear to be reentrant; however, recursion is still not possible.
Although the compiler could alternatively compile functions using a
reentrant model, this feature is not available with all devices and the code might be less
efficient. In addition, the -mstack
option or the
__nonreentrant
specifier can be used to prevent the compiler from
choosing this model. See 6.3.3 Function Information to determine which function model was used for each function.
If a function is duplicated, main-line code will call the code generated for the original function and code in each interrupt call graph will call a unique duplicated function. The duplication takes place only in the generated code output; there is no duplication of the C source code itself.
The duplicated code and objects defined by the function use unique
identifiers. A duplicate identifier is identical to that used by the original code, but is
prefixed with i1
. Duplicated PIC18 functions use the prefixes
i1
and i2
for the low- and high-priority interrupts,
respectively.
To illustrate, in a program both the function main()
and
a function in interrupt code call a function called input()
. The generated
assembly code for the C function input()
will use the assembly label
_input
. The corresponding label used by the duplicated function output
will be i1_input
. If input()
makes reference to a
temporary variable, the generated code will use the symbol ??_input
and
the duplicate will use ??i1_input
. Even local labels within the function’s
generated code will be duplicated in the same way. The call graph in the assembly list
file, will show the calls made to both of these functions as if they were independently
written. These symbols will also be seen in the map file symbol table.
Code associated with library functions are duplicated in the same way. This also applies to implicitly-called library routines, such as those that perform division or floating-point operations associated with C operators.