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.

Compiler/TMS320C6678: Loop not optimized due to call to an inline function non-inlined by the compiler

Part Number: TMS320C6678
Other Parts Discussed in Thread: MATHLIB

Tool/software: TI C/C++ Compiler

Hi,

I have a function that calculate the phase of two complex vector (execute atan2() over two vectors) and use the optimized atan2 from the C6678 MATHLIB (atan2sp_i). I compile with all optimization active:

  • opt_level=3
  • opt_for_speed=5
  • speculate_loads=auto
  • optimize_with_debug=on (tied also with supress all debug)

When I compile the function inside a bigger file that call it (test_atan) inside an out loop, test_atan() is SOFTWARE PIPELINED with ii=85 (anyway it doesn't use SPLOOP), and the function atan2sp_i is compiled inline.

The problem is that when I put test_atan (together witth all the called functions declared inline) in a separate file, it is not optimized due:

Loop at line 141 cannot be scheduled efficiently, as it contains a function call ("_Z27atan2f_sr1i_atan2spi_inlineffiii"). Try making "_Z27atan2f_sr1i_atan2spi_inlineffiii" an inline function.

Even if atan2f_sr1i_atan2spi_inline is already declared inline and it is the same that is correctly inlined when I don't compile it isolated.

I would like to keep it in a separate compilation unit both for re-usability reason and also since the compilation process take a lot of time when it is correctly optimized.

atan_no_optimize.cpp

  • Alberto,

    The person that needs to look at this is out today. I will flag this for them to take a look at when they are back tomorrow.

    Regards,
    John
  • For inlining to work, the source of the called function must be visible at the call site. Otherwise, how does it know what to replace the call with? That generally means the callee is defined in the same source file or in a header file.
    Link-time optimisation would provide a way to accomplish it with separate compilation units, except that (I think) we don't have that in any available C6000 compilers. (It's -o4 for ARM and others.)
  • Hi,

    In my previously attached file You can see All the functions are defined as "static inline" in the same compilation unit. Note that the source does not include any header file (except for c6x.h), does not declare any extern reference and compile without errors, therefore all required functions are declared and defined in same compilation unit:

    static inline float divspMod_atan2spi_inline (float a, float b) {...}
    
    static inline float atan2f_sr1i_atan2spi_inline (float g1, float pih, int s, int bn, int an) {...}
    
    static inline float atan2sp_inline (float a, float b)
    {
        ...
        g = divspMod_atan2spi_inline (b, a);
    
       res = atan2f_sr1i_atan2spi_inline (g, pih, s, bn, an);  //problem here, even if it is defined inline in same compilation unit
    
    }
    
    void test_atan(...)
    {
        for(...)
            atan2sp_inline(...);
        
    }

  • I'm sorry, I misunderstood your question (and was away from my desk and didn't check your test case first) -- I thought you wanted to make the callee separate, not the whole combination.

    Okay, the problem is with size.  The compiler has some internal limits on how much inlining it will do, partly for the --opt_for_speed control and partly to avoid certain bad situations that expand too fast and crash the compiler.  Those limits are represented as a maximum size growth that is proportional to the total size of the compilation unit.  When you were compiling all together, the proportional increase was a larger absolute number than when the atan file was separated, and while the larger number was room enough to inline all the calls, the smaller number isn't.

    This appears to be a good place to use the FUNC_ALWAYS_INLINE pragma:  you do want all the calls to inline and the file is self-contained.  The "inline" keyword is a suggestion to the compiler, but the FUNC_ALWAYS_INLINE pragma is a command and overrides any growth limits.