Re: Non-inlined functions and mixed architectures
On Dienstag, 4. August 2020 19:44:57 CEST Florian Weimer wrote: > * Allan Sandfeld Jensen: > > On Montag, 27. Juli 2020 10:54:02 CEST Florian Weimer wrote: > >> * Allan Sandfeld Jensen: > >> > On Montag, 27. Juli 2020 10:33:35 CEST Florian Weimer wrote: > >> >> * Allan Sandfeld Jensen: > >> >> > A problem that I keep running into is functions defined headers, but > >> >> > used > >> >> > in sources files that are compiled with different CPU feature flags > >> >> > (for > >> >> > runtime CPU feature selection). > >> >> > > >> >> > We know to make sure the functions are inlinable and their address > >> >> > never > >> >> > taken, but of course in debug builds they are still not inlined. > >> >> > Every > >> >> > so > >> >> > often the functions get compiled using some of the optional CPU > >> >> > instructions, and if the linker selects the optimized versions those > >> >> > instructions can then leak through to instances compiled with > >> >> > different > >> >> > CPU flags where the instructions aren't supposed to be used. This > >> >> > happens > >> >> > even in unoptimized debug builds as the extended instruction > >> >> > selections > >> >> > doesn't count as an optimization. > >> >> > >> >> You need to provide source code examples. This isn't supposed to > >> >> happen > >> >> if you declare the functions as static inline. If a function is > >> >> emitted > >> >> for any reason, it will be local this particular object file. > >> >> > >> >> Plain inline (for C++) works differently and will attempt to share > >> >> implementations. > >> > > >> > static inline? Hadn't thought of that in a shared header file. > >> > > >> > Is harder to do with inline methods in C++ classes though. > >> > >> Ahh, and anonymous namespaces (the equivalent for that for member > >> functions) do not work in such cases because the representation of the > >> class still needs to be shared across API boundaries. With an anonymous > >> namspace, that would be undefined. > > > > So, would it be possible to have a gcc extension or future C++ attribute > > that worked like static on global functions but could be used on member > > functions (both static and otherwise)? > > > > Perhaps make it universal so it did the same no matter where it was used > > instead of being contextual like 'static'. > > One caveat is that things get somewhat interesting if such a function > returns an object of static or thread storage duration. In your > application, you probably want to globalize such objects because they > are all equivalent. But there might be other cases where this is > different. > > vtables are tricky as well, but you probably avoid them in your > scenario. > Right vtables would be a different story completely. I guess it would only make sense for non-virtual inline declared methods, which means a universal attribute doesn't make sense. Application controlled runtime CPU switching with C++ interfaces will remain an unreliable hack. Thanks Allan
Re: Non-inlined functions and mixed architectures
* Allan Sandfeld Jensen: > On Montag, 27. Juli 2020 10:54:02 CEST Florian Weimer wrote: >> * Allan Sandfeld Jensen: >> > On Montag, 27. Juli 2020 10:33:35 CEST Florian Weimer wrote: >> >> * Allan Sandfeld Jensen: >> >> > A problem that I keep running into is functions defined headers, but >> >> > used >> >> > in sources files that are compiled with different CPU feature flags >> >> > (for >> >> > runtime CPU feature selection). >> >> > >> >> > We know to make sure the functions are inlinable and their address >> >> > never >> >> > taken, but of course in debug builds they are still not inlined. Every >> >> > so >> >> > often the functions get compiled using some of the optional CPU >> >> > instructions, and if the linker selects the optimized versions those >> >> > instructions can then leak through to instances compiled with different >> >> > CPU flags where the instructions aren't supposed to be used. This >> >> > happens >> >> > even in unoptimized debug builds as the extended instruction selections >> >> > doesn't count as an optimization. >> >> >> >> You need to provide source code examples. This isn't supposed to happen >> >> if you declare the functions as static inline. If a function is emitted >> >> for any reason, it will be local this particular object file. >> >> >> >> Plain inline (for C++) works differently and will attempt to share >> >> implementations. >> > >> > static inline? Hadn't thought of that in a shared header file. >> > >> > Is harder to do with inline methods in C++ classes though. >> >> Ahh, and anonymous namespaces (the equivalent for that for member >> functions) do not work in such cases because the representation of the >> class still needs to be shared across API boundaries. With an anonymous >> namspace, that would be undefined. >> > So, would it be possible to have a gcc extension or future C++ attribute that > worked like static on global functions but could be used on member functions > (both static and otherwise)? > > Perhaps make it universal so it did the same no matter where it was used > instead of being contextual like 'static'. One caveat is that things get somewhat interesting if such a function returns an object of static or thread storage duration. In your application, you probably want to globalize such objects because they are all equivalent. But there might be other cases where this is different. vtables are tricky as well, but you probably avoid them in your scenario. Thanks, Florian
Re: Non-inlined functions and mixed architectures
On Montag, 27. Juli 2020 10:54:02 CEST Florian Weimer wrote: > * Allan Sandfeld Jensen: > > On Montag, 27. Juli 2020 10:33:35 CEST Florian Weimer wrote: > >> * Allan Sandfeld Jensen: > >> > A problem that I keep running into is functions defined headers, but > >> > used > >> > in sources files that are compiled with different CPU feature flags > >> > (for > >> > runtime CPU feature selection). > >> > > >> > We know to make sure the functions are inlinable and their address > >> > never > >> > taken, but of course in debug builds they are still not inlined. Every > >> > so > >> > often the functions get compiled using some of the optional CPU > >> > instructions, and if the linker selects the optimized versions those > >> > instructions can then leak through to instances compiled with different > >> > CPU flags where the instructions aren't supposed to be used. This > >> > happens > >> > even in unoptimized debug builds as the extended instruction selections > >> > doesn't count as an optimization. > >> > >> You need to provide source code examples. This isn't supposed to happen > >> if you declare the functions as static inline. If a function is emitted > >> for any reason, it will be local this particular object file. > >> > >> Plain inline (for C++) works differently and will attempt to share > >> implementations. > > > > static inline? Hadn't thought of that in a shared header file. > > > > Is harder to do with inline methods in C++ classes though. > > Ahh, and anonymous namespaces (the equivalent for that for member > functions) do not work in such cases because the representation of the > class still needs to be shared across API boundaries. With an anonymous > namspace, that would be undefined. > So, would it be possible to have a gcc extension or future C++ attribute that worked like static on global functions but could be used on member functions (both static and otherwise)? Perhaps make it universal so it did the same no matter where it was used instead of being contextual like 'static'. Best regards 'Allan
Re: Non-inlined functions and mixed architectures
* Allan Sandfeld Jensen: > On Montag, 27. Juli 2020 10:33:35 CEST Florian Weimer wrote: >> * Allan Sandfeld Jensen: >> > A problem that I keep running into is functions defined headers, but used >> > in sources files that are compiled with different CPU feature flags (for >> > runtime CPU feature selection). >> > >> > We know to make sure the functions are inlinable and their address never >> > taken, but of course in debug builds they are still not inlined. Every so >> > often the functions get compiled using some of the optional CPU >> > instructions, and if the linker selects the optimized versions those >> > instructions can then leak through to instances compiled with different >> > CPU flags where the instructions aren't supposed to be used. This happens >> > even in unoptimized debug builds as the extended instruction selections >> > doesn't count as an optimization. >> >> You need to provide source code examples. This isn't supposed to happen >> if you declare the functions as static inline. If a function is emitted >> for any reason, it will be local this particular object file. >> >> Plain inline (for C++) works differently and will attempt to share >> implementations. >> > static inline? Hadn't thought of that in a shared header file. > > Is harder to do with inline methods in C++ classes though. Ahh, and anonymous namespaces (the equivalent for that for member functions) do not work in such cases because the representation of the class still needs to be shared across API boundaries. With an anonymous namspace, that would be undefined. Thanks, Florian
Re: Non-inlined functions and mixed architectures
On Montag, 27. Juli 2020 10:33:35 CEST Florian Weimer wrote: > * Allan Sandfeld Jensen: > > A problem that I keep running into is functions defined headers, but used > > in sources files that are compiled with different CPU feature flags (for > > runtime CPU feature selection). > > > > We know to make sure the functions are inlinable and their address never > > taken, but of course in debug builds they are still not inlined. Every so > > often the functions get compiled using some of the optional CPU > > instructions, and if the linker selects the optimized versions those > > instructions can then leak through to instances compiled with different > > CPU flags where the instructions aren't supposed to be used. This happens > > even in unoptimized debug builds as the extended instruction selections > > doesn't count as an optimization. > > You need to provide source code examples. This isn't supposed to happen > if you declare the functions as static inline. If a function is emitted > for any reason, it will be local this particular object file. > > Plain inline (for C++) works differently and will attempt to share > implementations. > static inline? Hadn't thought of that in a shared header file. Is harder to do with inline methods in C++ classes though. A recent example I hit into was methods using a qfloat16 class that specializes for F16C when available, see https://codereview.qt-project.org/c/ qt/qtbase/+/307772. Which I guess ought to be split into different classes with different constructors, so they don't violate ODR rules to be really safe across compilers. But I guess a case like https://codereview.qt-project.org/c/qt/qtbase/+/308163 could be solved with static inline instead. Best regards Allan
Re: Non-inlined functions and mixed architectures
* Allan Sandfeld Jensen: > A problem that I keep running into is functions defined headers, but used in > sources files that are compiled with different CPU feature flags (for runtime > CPU feature selection). > > We know to make sure the functions are inlinable and their address never > taken, but of course in debug builds they are still not inlined. Every so > often the functions get compiled using some of the optional CPU instructions, > and if the linker selects the optimized versions those instructions can then > leak through to instances compiled with different CPU flags where the > instructions aren't supposed to be used. This happens even in unoptimized > debug builds as the extended instruction selections doesn't count as an > optimization. You need to provide source code examples. This isn't supposed to happen if you declare the functions as static inline. If a function is emitted for any reason, it will be local this particular object file. Plain inline (for C++) works differently and will attempt to share implementations. Thanks, Florian
Non-inlined functions and mixed architectures
A problem that I keep running into is functions defined headers, but used in sources files that are compiled with different CPU feature flags (for runtime CPU feature selection). We know to make sure the functions are inlinable and their address never taken, but of course in debug builds they are still not inlined. Every so often the functions get compiled using some of the optional CPU instructions, and if the linker selects the optimized versions those instructions can then leak through to instances compiled with different CPU flags where the instructions aren't supposed to be used. This happens even in unoptimized debug builds as the extended instruction selections doesn't count as an optimization. So far the main workaround for gcc has been to mark the functions as always_inline. I have been wondering if you couldn't use the same technique you used for fix similar problems for mixed archs for LTO builds and tag shared functions with their archs so they don't get merged by linker? I know the whole thing could technially be seen as an ODR violation, but it would still be great if it was something GCC could just handle it out of the box. Alternatively an compile time option to mark non-inline inline functions as weak or not generated at all would when compiling certain files would also work. Best regards 'Allan