[llvm-dev] Disabling inline compilation (Clang with VS2019)

Hans Wennborg via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 23 06:50:27 PDT 2021


On Thu, Sep 23, 2021 at 3:14 PM via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>
> > Anyway, ignoring the "/Ob0" issue for a minute, maybe there's a better
> > solution available...
> >
> > Could compilations be adapted so that wherever a symbol is found to be
> > declared as __declspec(dllimport) there's an automatic assumption that
> > it shouldn't be inlined?
>
> +rnk who is much better in tune with MSVC compatibility than I am.
>
> In general, Clang is willing to inline a function defined in-class
> because of the One Definition Rule; C++ says we can assume that the
> definition is the same everywhere.  As I said, I don't see Clang
> inlining the method, but Godbolt does, I don't know what the difference
> is there.
>
> In the specific example, moving the method definition out of the class
> should avoid the problem; but if you have a large number of methods
> like this, that's a real lot of work and it would be nice to find some
> other solution.
>
> If MSVC promises not to inline a dllimport method, that seems like
> something Clang should take into consideration in MS-compatibility
> mode.  Probably implicitly marking dllimport methods as noinline would
> be sufficient, but I think we'd be willing to do that only if MSVC
> actually makes that promise explicitly.
> --paulr

I don't believe MSVC makes such a promise. Here's a simple example:

inline int __declspec(dllimport) foo() { return 42; }
int f() { return foo(); }

MSVC will inline the call to foo() here (https://godbolt.org/z/jKWqEjKG4).

But, it seems something changed between MSVC 19.21 and 19.22. Consider
this example:

extern int __declspec(dllimport) x;
inline int __declspec(dllimport) get_x() { return x; }
int f() { return get_x(); }

int __declspec(dllimport) foo();
inline int __declspec(dllimport) bar() { return foo(); }
int g() { return bar(); }

MSVC 19.21 will inline the get_x() and bar() calls, but 19.22 will
not: https://godbolt.org/z/n1cedv3a8

Clang matches the 19.21 behaviour. The way it checks whether a
dllimport function is safe to inline is whether it only references
symbols which are also dllimport (the logic lives in
CodeGenModule::shouldEmitFunction()).

It seems that MSVC has become more conservative here. We could update
Clang to behave similarly, but it would be good to understand the
exact motivation.


More information about the llvm-dev mailing list