via llvm-dev
2021-Sep-23 13:14 UTC
[llvm-dev] Disabling inline compilation (Clang with VS2019)
> 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
Hans Wennborg via llvm-dev
2021-Sep-23 13:50 UTC
[llvm-dev] Disabling inline compilation (Clang with VS2019)
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. > --paulrI 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.