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.

c28xx compiler 6.0.2: how to force compiler to respect my inline wishes?

I'm at my wit's end. I've got a number of inlined functions that I absolutely need to inline because they're in a critical section of code, and I want to maintain the source-code conceptual modularity for having these as separate functions in the source code.

Code is structured vaguely like this (names changed for confidentiality; in reality Bar has 5 members and the total # of bottom-level int members is 14)

// bar.h
class Bar
{
  class Baz
  {
     int x, y;
  public:
     inline Baz& copyFrom(const volatile Quux& other) { x = other.x; y = other.y; return *this;}
     inline bool any() const volatile { return x != 0 || y != 0; }
  };
  class Quux
  {
     int z;
  public:
     inline Quux& copyFrom(const volatile Quux& other) { z = other.z; return *this;}
     inline bool any() const volatile { return z != 0; }
  };
  Baz baz;
  Quux quux;
public:
  inline Bar& copyFrom(const volatile Bar& other) { baz.copyFrom(other.baz); quux.copyFrom(other.quux); return *this; }
  inline bool any() const volatile { return baz.any() || quux.any(); }
};

// foo.h
class Foo
{
  Bar bar;
  volatile Bar vbar;
  inline bool update() {
     bar.copyFrom(vbar);
     return bar.any();
  }
  void step();
}

// foo.cpp
void Foo::step()
{
  if (update())
  {
     // do some other stuff
  }
}

My problem is that the compiler doesn't inline Bar::copyFrom() or Bar::any(), instead generating separate functions with mangled names that start with ___CPR80__copyFrom__Q2_, which I assume is the compiler's way of telling me it tried really hard to inline the function but it failed.

These functions get called only once, and the function call overhead is really hurting me.

Is there a way to cajole the compiler into doing what I want? I've tried raising --auto_inline to a large value (8192) but it doesn't make a difference and from the docs, I assume --auto_inline allows me to limit inlining more than normal, but not encourage it.

Help!

  • It is probably the volatile parameters that spoil inlining.  I cannot diagnose this further without a compilable test case that demonstrates the problem.

    A name beginning __CPR indicates "compressed name mangling".  It is just a symbol name size optimization, it is not caused by inlining.

  • Archaeologist said:
    It is probably the volatile parameters that spoil inlining.  I cannot diagnose this further without a compilable test case that demonstrates the problem.

    OK, I'll put that in my queue (if it's not quickly reproducible as a standalone testcase, it may take me a few weeks to get the time to do it).

  • There might be a reason why the compiler is not inlining those functions.  You may be able to see the reason by using the options --opt_level=3 --gen_opt_info=2.  That will give you a .nfo file you can inspect.  

    There is a pragma named FUNC_ALWAYS_INLINE.  Be very careful with that one.  It is possible to create a function that is so large the compiler will never finish processing it.

    Thanks and regards,

    -George

  • Georgem said:
    There might be a reason why the compiler is not inlining those functions.  You may be able to see the reason by using the options --opt_level=3 --gen_opt_info=2.  That will give you a .nfo file you can inspect.

    Already done -- that was the reason for my question about --gen-opt-level.


    Here's an excerpt from the .nfo file:

    Inlineable function any() was marked for suppression,
    but it cannot be because of a problematic use in step().

    Inlineable function _CPR81() was marked for suppression,
    but it cannot be because of a problematic use in step().

    Inlineable function _CPR80() was marked for suppression,
    but it cannot be because of a problematic use in step().

    I have no idea what "a problematic use" is. Again, I'll try to put together a test case.

  • Note that by including the body of the member functions in the class definition, you have already implicitly declared them inline;  the "inline" keyword is redundant.

    Functions declared inline are not affected by --auto_inline;  "auto-inlining" is the process of automatically inlining functions that were not so declared.

    Declared-inline functions (for C2x) are affected by an internal size limit that is very coarse:  it has only two values, and takes its smaller value when --opt_for_space is present or --opt_for_speed is 0 or 1.

    Ignore the "problematic use" messages, because they aren't telling you about inlining, but rather about whether the function bodies could be removed completely from the compiler output.  Typical reasons are argument/parameter mismatches, use as a function synonym, a potential anonymous call, etc.  In general, it means that the function is extern and the compiler can't guarantee it isn't called from another file.  In many of those cases the function was inlined.

    If your functions are really only called once, there's a --single_inline option that is more liberal about inlining called-only-once functions -- if they can be suppressed.  (Because it doesn't want to increase code size.)

    And then there's the FUNC_ALWAYS_INLINE pragma, which seems like a good fit because you have a small number of well-controlled call sites.  But as George warned, if the compiler blows up it's not our fault.

  • pf said:
    If your functions are really only called once, there's a --single_inline option that is more liberal about inlining called-only-once functions

    where's that documented? I can't find it... is it a compiler option that affects the whole file?

  • I guess we didn't document it.  Maybe it's not supposed to be public.  Yes, it's a compiler option that affects the whole file.

  • pf said:
    I guess we didn't document it.  Maybe it's not supposed to be public.  Yes, it's a compiler option that affects the whole file.

    OK, thanks.

    If it's not feasible to update the compiler PDF file (or even if it is), it would be helpful to have some entries in the wiki that describe each of the compiler / assembler / linker options, so you could keep things like this up to date.

  • Jason,

    I've been complaining about this issue for a couple of years now. 

    What you can do is keep a link to C6000 compiler user's guide (spru187). It is updated much more often and a number of the features documented there (single_inline included) are also available in C2000 compiler I assume they share front-end (or back-end, I forgot the details about the compiler construction).

    It also helps to discover any features that make sense only with C6000 family, but the documentation about them got "accidentally" copy/pasted to C2000 compiler user's guide.

    It seems that C6000 series has a lot higher priority with TI. Or at least the documentation part.

    Regards, Mitja