This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C2000 v6.4.9 (C++) with -O4 and -mf5: #pragma FUNC_ALWAYS_INLINE is not inlining

Guru 20035 points

Hello,

I am using the C2000 v6.4.9 with -O4 and -mf5.  

The  #pragma FUNC_ALWAYS_INLINE is not causing the member functions to be inlined.  One of the member functions is shown below.  What am I doing wrong?

stephen

#pragma FUNC_ALWAYS_INLINE
__inline void Ssa::vWrite(SSA_ADDRESS Addr, SSADATA * ptData, U16 u16NumberOfItems)

{
    U16 i;
    SSADATA * ptMemLoc = (SSADATA*) (SSA_BASE_ADDRESS + Addr);

    for (i = 0; i < u16NumberOfItems; i++, ptMemLoc++)
    {
        ptMemLoc[i] = ptData[i];
    }
}

  • The TMS320C28x Optimizing C/C++ Compiler User's Guide documentation for FUNC_ALWAYS_INLINE says:

    The FUNC_ALWAYS_INLINE pragma instructs the compiler to always inline the named function. The compiler only inlines the function if it is legal to inline the function and the compiler is invoked with any level of optimization (--opt_level=0).

    However, from a search of the User's Guide I can't find a definition of what makes a function legal to inline.

    Maybe using the --optimizer_interlist option will cause the optimizer to comment on why the function can't be inlined.

  • I tried --optimizer_interlist and the compilier didn't give any more information about why the function can't be inlined.
  • Also,

    SSA_ADDRESS, U16 and SSADATA are defined as:

    typedef unsigned long SSA_ADDRESS;
    typedef unsigned int SSADATA;
    typedef unsigned int U16;

  • stevenh said:
    The  #pragma FUNC_ALWAYS_INLINE is not causing the member functions to be inlined.

    I tried repeating the problem with a C version of that function, but so far haven't managed to repeat the problem in that the function is inlined. Are you able to post a complete stand-alone project which shows the problem?

    stevenh said:
    for (i = 0; i < u16NumberOfItems; i++, ptMemLoc++)
    {
        ptMemLoc[i] = ptData[i];
    }

    Not sure if it is the cause of the problem, but that loop structure looks strange since it is incrementing both ptMemLoc and i each iteration, and also writing to ptMemLoc[i] on each iteration. Is the loop structure intentional?

  • I suspect that for some reason the pragma has not attached to the function symbol, but I can't tell why from this fragment.

    Otherwise, a function won't inline if there is something wrong about its call. For instance, this function returns void; if it is called somewhere that uses the return value, it won't inline. Or if the arguments don't match the parameters.

    BTW, it's also odd that this function is a member function but accesses no member data. (Unless SSA_BASE_ADDRESS is a field.) Hmm, is SSA_BASE_ADDRESS a volatile constant? That might matter, though really only a volatile local variable should.
  • You're correct.  I shouldn't be incrementing ptMemLoc.  

    I removed ", ptMemLoc++" and it still doesn't inline the function

    Thanks,
    Stephen

  • Hello,

    The following attached project has the issue.

    Stephen

    0184.TestCompile2.zip

  • The linker is also generated an undefined symbol for the member function.  If I remove the call to SsaTests(), the undefined symbol error goes away.

    What's the reason for the undefined symbol error?

    Stephen

  • stevenh said:
    The following attached project has the issue.

    When I tried a clean build of that project in CCS 6.1.1 using compiler v6.4.9 got linker errors:

    <Linking>
    warning #10210-D: creating ".esysmem" section with default size of 0x400; use the -heap option to change the default size
    
     undefined                                first referenced
      symbol                                      in file     
     ---------                                ----------------
     Ssa::vWrite(unsigned long, unsigned int) <whole-program> 
    
    error #10234-D: unresolved symbols remain
    error #10010: errors encountered during linking; "TestCompile2.out" not built
    
    >> Compilation failure
    

    The linker errors is due to the declaration of Ssa::vWrite in SsaClass.h not being marked as __inline, but the definition of Ssa::vWrite in SsaClass.cpp being marked as __inline.

  • Hello Chester,

    I changed the declaration, as shown below, and the linker still generates the undefined symbol error.

    Stephen

    class Ssa
    {
    public:
        Ssa(void);
        void vInit(void);
        __inline void vWrite(SSA_ADDRESS tAddress,SSADATA tData);
        __inline SSADATA tRead(SSA_ADDRESS tAddress);
    };

  • Chester Gillon said:
    The linker errors is due to the declaration of Ssa::vWrite in SsaClass.h not being marked as __inline, but the definition of Ssa::vWrite in SsaClass.cpp being marked as __inline.

    For inlining to work the declaration and definition should be marked as __inline and the definition needs to be visible to the users of the class.

    I have modified the example, which is re-attached 8203.TestCompile2.zip

    Looking at the assembler listing in SsaTests.asm shows the ssa.vWrite() call has been inlined:

    $C$L1:    
            MOVW      DP,#_tData            ; [CPU_U] 
    	.dwpsn	file "../SsaTests.cpp",line 19,column 13,is_stmt,isa 0
    ;----------------------------------------------------------------------
    ;  19 | ssa.vWrite((SSA_ADDRESS) S1_ADDRESS, tData);                           
    ;----------------------------------------------------------------------
            MOV       AL,@_tData            ; [CPU_] |19| 
    	.dwpsn	file "../SsaClass.h",line 24,column 5,is_stmt,isa 0
            MOV       *(0:0x5000),AL        ; [CPU_] |24| 
    	.dwpsn	file "../SsaTests.cpp",line 17,column 21,is_stmt,isa 0
            BF        $C$L1,UNC             ; [CPU_] |17| 
            ; branch occurs ; [] |17| 
    

     

  • Fantastic!

    Thanks,
    Stephen