Any mechanism available for link time inlineing?

Hi,

trying to develop this idea of splitting c++ classes into real interface and implementation and to make a std isocpp proposal out of it. Need some help and info to make the proposal cover as many details as possible.

The idea is to split the class declaration into a part that will stay in the header and will contain only the public members. (let’s ignore protected for the moment). The c++ part will contain the private stuff including private data. The part in the header I call for simplicity white and the part in the C++ black (from blackbox vs. whitebox).

Having this in place could reduce compilation time, open a simple way for classes in DLL, etc. etc. I know about modules, reflection, I know, etc. let’s don’t introduce for the moment noise.

Two main problems come from the idea above are sizeof() (for allocation, passing by value/reference) and offsets of data members. Let’s ignore for the moment sizeof related problems and just look at offsets.

At the moment if we have
class A {
private:
MyType data;

public:
MyType &getData() {return data}
void setData(MyType &in) {data = in;}
};

The above setters/getters can be easily inlined by the compiler to avoid a function call for such a trivial case.

/* inside A.h */
class white A {
public:

MyType &getData() {return data}
void setData(MyType &in) {data = in;}

};

/* inside A.cpp */
class black A {
public:
MyType data;

};

The problem is that in the model I am proposing the layout of the class is not available at compilation time, for consumers of A.h other than A.cpp. It will be only available at link time.

Now the question: is there any mechanism available/proposed to do the inlining at static or dynamic linking phase? The question refers both to LLVM, or other compilers. Well, the idea would be that LLVM generates some placeholder that could be easily identified by the static/dynamic linker and replaced by the inlined function readily baked. Probably the size of the code to patch has to have fixed length etc. In the case above the compiler will generate the inline code for the getter setter from A.cpp based on the offset information it knows. The linker should glue together the parts.

I am aware about the non -fPIC way of linking functions from dynamic libraries, which seems to be an abandoned direction.

Thanks for help, and please ask questions if my brief presentation is not clear

regards,
mobiphil

sorry to insist. While I do not beleive the question was the dumbest in the
world, would love to know to find out some info, please find belowe the
short version of the question:

Is there already in LLVM or is there any plan to support some mechanism for
static/dynamic inline-ing?

thanks a lot
mobiphil

It is already statically possible at link-time using LTO. I *think* it is enabled by default looking at https://llvm.org/svn/llvm-project/llvm/trunk/tools/llvm-lto/llvm-lto.cpp
Try googling “LLVM LTO inlining” for more info.

Mehdi

thanks, sounds great, heard about llvm-lto, but was not following in
details. I have an llvm-lto in my dev branch build....now what I do not
find are some example on how to use it for link time inline-ing. In worst
case have to deal with the overhead to experiment

mobi phil

mobi phil wrote:

thanks, sounds great, heard about llvm-lto, but was not following in
details. I have an llvm-lto in my dev branch build....now what I do not
find are some example on how to use it for link time inline-ing. In
worst case have to deal with the overhead to experiment

With what linker?

LLVM LTO is available by default with Apple's XCode development environment, just specify -O4.

For linux or similar, see llvm.org/docs/GoldPlugin.html . You may be able to just use -O4 on linux too, depending on how your llvm and linker are installed, and assuming you run "clang" for your link steps.

Inlining occurs because it's a standard part of the link time optimization pipeline. If you need to turn off the rest of LTO, reducing it down to only inlining, that would take more work.

Nick

LLVM LTO is available by default with Apple's XCode development environment,
just specify -O4.

I'm not sure exactly what -O4 does these days, but it's not the
suggested way of doing LTO. For that you should pass "-flto" with a
more normal optimisation level.

Cheers.

Tim.

To add to what Nick and Tim have said: `llvm-lto` is more of a debugging
tool (for testcases, repros, etc.) than anything else.

Unless you're looking to contribute to LTO, you should be strictly using
`clang -flto`.

+llvmdev (I assume you dropped the list by accident?)

Thanks for the feedback. I think this is a valuable detail lot of people do not know about it. As described above was playing with the idea of a PIMPL like C++ language extension where parts of the class (mainly the data layout) would be moved away from the header into the source file. Public data members would be accessed through setters/getters but in some cases this could mean an annoying overhead of a function call. However with lto (inline) this problem is solved!

I did not find any roadmap about lto development. Is this supposed to become a standard?

There are still some issues with LTO on projects that are large or
that need different subtargets for different compile units. We're
actively working on improving it though.

Not so important, but this idea is itchy in my brain: based on your experience with lto, optimizers, what would be the pitfalls for implementing such inlining at dynamic linking. The use case would be straightforward: given a main executable with some unresolved function symbols, inline functions instead of dynamic link. In order to be fast such dynamic-inlining would probably ignore any strategy to see if inlining would result in code-bloat etc.

This sounds more like load-time optimization than link-time. I
don't think our model would work well there. CodeGen is too
expensive.