Prevent repeated instantiations of some qRegisterNormalizedMetaType<>s [1/N] (QtGui)

Create macros that wrap the magic developed in
7d63efc16f65f98c657caa90e0d7e9b72a879ade and apply it to all
Q_DECLARE_METATYPE invocations that show up in Clang -ftime-trace for
a PCH'ed QtGui build.

Effects on compile times:

Clang 10 -ftme-trace:

  $ ClangBuildAnalyzer --analyze qtgui-before.trace  | head -n6
  Analyzing build trace from 'qtgui-before.trace'...
  **** Time summary:
  Compilation (523 times):
    Parsing (frontend):          628.3 s
    Codegen & opts (backend):    304.5 s

  $ ClangBuildAnalyzer --analyze qtgui-after.trace  | head -n6
  Analyzing build trace from 'qtgui-after.trace'...
  **** Time summary:
  Compilation (523 times):
    Parsing (frontend):          546.0 s
    Codegen & opts (backend):    304.4 s

GCC 11 time (bash builtin):

before:

  $ time for ((i=0; i < 3; ++i)) do touch src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done

  real    4m13,539s
  user    49m24,416s
  sys     3m18,177s

after:

  $ time for ((i=0; i < 3; ++i)) do touch src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done

  real    3m55,697s
  user    45m19,941s
  sys     3m7,370s

Task-number: QTBUG-97601
Pick-to: 6.3
Change-Id: Ia8e37a58937568a7ed21cfeb4b27274deca4d53b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Marc Mutz 2022-01-18 17:38:48 +01:00
parent 4440387b85
commit f29566c5a4
33 changed files with 82 additions and 33 deletions

View File

@ -177,6 +177,8 @@ Cpp.ignoredirectives += \
Q_CLASSINFO \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
QT_DECL_METATYPE_EXTERN \
QT_IMPL_METATYPE_EXTERN \
Q_DECLARE_OPERATORS_FOR_FLAGS \
Q_DECLARE_PRIVATE \
Q_DECLARE_PRIVATE_D \

View File

@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(qfloat16)
/*!
\class qfloat16
\keyword 16-bit Floating Point Support

View File

@ -367,7 +367,7 @@ inline auto qHypot(qfloat16 x, qfloat16 y, qfloat16 z)
QT_END_NAMESPACE
Q_DECLARE_METATYPE(qfloat16)
QT_DECL_METATYPE_EXTERN(qfloat16, Q_CORE_EXPORT)
namespace std {
template<>

View File

@ -46,6 +46,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QFileInfo)
QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
{
if (cache_enabled && !fileNames[(int)name].isNull())

View File

@ -212,6 +212,6 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QFileInfo &);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QFileInfo)
QT_DECL_METATYPE_EXTERN(QFileInfo, Q_CORE_EXPORT)
#endif // QFILEINFO_H

View File

@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QStorageInfo)
/*!
\class QStorageInfo
\inmodule QtCore

View File

@ -120,6 +120,6 @@ Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QStorageInfo &);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QStorageInfo)
QT_DECL_METATYPE_EXTERN(QStorageInfo, Q_CORE_EXPORT)
#endif // QSTORAGEINFO_H

View File

@ -60,8 +60,7 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcCheckIndex, "qt.core.qabstractitemmodel.checkindex")
int qRegisterNormalizedMetaType_QList_QModelIndex(const QByteArray &name)
{ return qRegisterNormalizedMetaTypeImplementation<QList<QModelIndex>>(name); }
QT_IMPL_METATYPE_EXTERN(QModelIndexList)
QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &index)
{

View File

@ -537,12 +537,8 @@ inline Qt::ItemFlags QModelIndex::flags() const
inline size_t qHash(const QModelIndex &index, size_t seed = 0) noexcept
{ return size_t((size_t(index.row()) << 4) + size_t(index.column()) + index.internalId()) ^ seed; }
Q_CORE_EXPORT int qRegisterNormalizedMetaType_QList_QModelIndex(const QByteArray &name);
template <> inline int qRegisterNormalizedMetaType<QList<QModelIndex>>(const QByteArray &name)
{ return qRegisterNormalizedMetaType_QList_QModelIndex(name); }
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QModelIndexList)
QT_DECL_METATYPE_EXTERN(QModelIndexList, Q_CORE_EXPORT)
#endif // QABSTRACTITEMMODEL_H

View File

@ -50,6 +50,9 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QItemSelectionRange)
QT_IMPL_METATYPE_EXTERN(QItemSelection)
/*!
\class QItemSelectionRange
\inmodule QtCore

View File

@ -238,7 +238,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QItemSelectionRange &);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QItemSelectionRange)
Q_DECLARE_METATYPE(QItemSelection)
QT_DECL_METATYPE_EXTERN(QItemSelectionRange, Q_CORE_EXPORT)
QT_DECL_METATYPE_EXTERN(QItemSelection, Q_CORE_EXPORT)
#endif // QITEMSELECTIONMODEL_H

View File

@ -43,6 +43,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDeadlineTimer)
namespace {
class TimeReference
{

View File

@ -224,6 +224,6 @@ Q_DECLARE_SHARED(QDeadlineTimer)
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDeadlineTimer)
QT_DECL_METATYPE_EXTERN(QDeadlineTimer, Q_CORE_EXPORT)
#endif // QDEADLINETIMER_H

View File

@ -97,6 +97,7 @@ QT_BEGIN_NAMESPACE
#define NS(x) QT_PREPEND_NAMESPACE(x)
QT_IMPL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl, QPairVariantInterfaceImpl)
namespace {
struct DefinedTypesFilter {

View File

@ -1257,19 +1257,36 @@ int qRegisterNormalizedMetaTypeImplementation(const QT_PREPEND_NAMESPACE(QByteAr
// This primary template calls the -Implementation, like all other specialisations should.
// But the split allows to
// - in a header:
// - declare, but not define, a specialization of this template
// - add an explicit instantiation declaration (extern template ...)
// - define a specialization of this template calling an out-of-line function
// (QT_DECL_METATYPE_EXTERN{,_TAGGED})
// - in the .cpp file:
// - define the specialization to call the -Implementation
// - add an explicit instantiation definition
// This prevents the compiler from taking the leeway for inline functions in
// [temp.explicit]/13 Note 4
// - define the out-of-line wrapper to call the -Implementation
// (QT_IMPL_METATYPE_EXTERN{,_TAGGED})
// The _TAGGED variants let you choose a tag (must be a C identifier) to disambiguate
// the out-of-line function; the non-_TAGGED variants use the passed class name as tag.
template <typename T>
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
{
return qRegisterNormalizedMetaTypeImplementation<T>(normalizedTypeName);
}
#define QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TAG, EXPORT) \
QT_BEGIN_NAMESPACE \
EXPORT int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &); \
template <> inline int qRegisterNormalizedMetaType< TYPE >(const QByteArray &name) \
{ return qRegisterNormalizedMetaType_ ## TAG (name); } \
QT_END_NAMESPACE \
Q_DECLARE_METATYPE(TYPE) \
/* end */
#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG) \
int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &name) \
{ return qRegisterNormalizedMetaTypeImplementation< TYPE >(name); } \
/* end */
#define QT_DECL_METATYPE_EXTERN(TYPE, EXPORT) \
QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TYPE, EXPORT)
#define QT_IMPL_METATYPE_EXTERN(TYPE) \
QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TYPE)
template <typename T>
int qRegisterMetaType(const char *typeName)
{
@ -2521,6 +2538,7 @@ constexpr const QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
QT_DECL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl,
QPairVariantInterfaceImpl, Q_CORE_EXPORT)
#endif // QMETATYPE_H

View File

@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcSocketNotifierDeprecation)
Q_LOGGING_CATEGORY(lcSocketNotifierDeprecation, "qt.core.socketnotifier_deprecation");
QT_IMPL_METATYPE_EXTERN_TAGGED(QSocketNotifier::Type, QSocketNotifier_Type)
QT_IMPL_METATYPE_EXTERN(QSocketDescriptor)
class QSocketNotifierPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QSocketNotifier)

View File

@ -137,7 +137,8 @@ private:
};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QSocketNotifier::Type)
Q_DECLARE_METATYPE(QSocketDescriptor)
QT_DECL_METATYPE_EXTERN_TAGGED(QSocketNotifier::Type, QSocketNotifier_Type, Q_CORE_EXPORT)
QT_DECL_METATYPE_EXTERN(QSocketDescriptor, Q_CORE_EXPORT)
#endif // QSOCKETNOTIFIER_H

View File

@ -46,6 +46,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QCborTag)
#include <cborerrorstrings.c>
/*!

View File

@ -151,7 +151,7 @@ enum class QCborNegativeInteger : quint64 {};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QCborTag)
QT_DECL_METATYPE_EXTERN(QCborTag, Q_CORE_EXPORT)
// To avoid changing namespace we need to reinstate defines, even though our .cpp
// will then have to remove them again.

View File

@ -57,6 +57,9 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QVersionNumber)
QT_IMPL_METATYPE_EXTERN(QTypeRevision)
/*!
\class QVersionNumber
\inmodule QtCore

View File

@ -494,7 +494,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QTypeRevision &revision);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QVersionNumber)
Q_DECLARE_METATYPE(QTypeRevision)
QT_DECL_METATYPE_EXTERN(QVersionNumber, Q_CORE_EXPORT)
QT_DECL_METATYPE_EXTERN(QTypeRevision, Q_CORE_EXPORT)
#endif // QVERSIONNUMBER_H

View File

@ -53,6 +53,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDBusError)
static constexpr const auto errorMessages = qOffsetStringArray(
"NoError",
"other",

View File

@ -140,7 +140,7 @@ Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusError &);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusError)
QT_DECL_METATYPE_EXTERN(QDBusError, Q_DBUS_EXPORT)
#else
QT_BEGIN_NAMESPACE
class Q_DBUS_EXPORT QDBusError {}; // dummy class for moc

View File

@ -44,6 +44,10 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDBusVariant)
QT_IMPL_METATYPE_EXTERN(QDBusObjectPath)
QT_IMPL_METATYPE_EXTERN(QDBusSignature)
void QDBusObjectPath::doCheck()
{
if (!QDBusUtil::isValidObjectPath(m_path)) {

View File

@ -189,9 +189,9 @@ inline bool operator==(const QDBusVariant &v1, const QDBusVariant &v2)
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusVariant)
Q_DECLARE_METATYPE(QDBusObjectPath)
Q_DECLARE_METATYPE(QDBusSignature)
QT_DECL_METATYPE_EXTERN(QDBusVariant, Q_DBUS_EXPORT)
QT_DECL_METATYPE_EXTERN(QDBusObjectPath, Q_DBUS_EXPORT)
QT_DECL_METATYPE_EXTERN(QDBusSignature, Q_DBUS_EXPORT)
#endif // QT_NO_DBUS
#endif

View File

@ -56,6 +56,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDBusMessage)
static_assert(QDBusMessage::InvalidMessage == DBUS_MESSAGE_TYPE_INVALID);
static_assert(QDBusMessage::MethodCallMessage == DBUS_MESSAGE_TYPE_METHOD_CALL);
static_assert(QDBusMessage::ReplyMessage == DBUS_MESSAGE_TYPE_METHOD_RETURN);

View File

@ -131,7 +131,7 @@ Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusMessage &);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusMessage)
QT_DECL_METATYPE_EXTERN(QDBusMessage, Q_DBUS_EXPORT)
#else
class Q_DBUS_EXPORT QDBusMessage {}; // dummy class for moc

View File

@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DBUS
QT_IMPL_METATYPE_EXTERN(QDBusUnixFileDescriptor)
/*!
\class QDBusUnixFileDescriptor
\inmodule QtDBus

View File

@ -85,7 +85,7 @@ Q_DECLARE_SHARED(QDBusUnixFileDescriptor)
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusUnixFileDescriptor)
QT_DECL_METATYPE_EXTERN(QDBusUnixFileDescriptor, Q_DBUS_EXPORT)
#endif // QT_NO_DBUS
#endif // QDBUSUNIXFILEDESCRIPTOR_H

View File

@ -44,6 +44,7 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr)
/*!
\class QSurface

View File

@ -96,6 +96,6 @@ protected:
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QSurface*)
QT_DECL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr, Q_GUI_EXPORT)
#endif //QSURFACE_H

View File

@ -43,6 +43,8 @@
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN_TAGGED(QTextOption::Tab, QTextOption_Tab)
struct QTextOptionPrivate
{
QList<QTextOption::Tab> tabStops;

View File

@ -151,6 +151,6 @@ inline void QTextOption::setTabStopDistance(qreal atabStop)
QT_END_NAMESPACE
Q_DECLARE_METATYPE( QTextOption::Tab )
QT_DECL_METATYPE_EXTERN_TAGGED(QTextOption::Tab, QTextOption_Tab, Q_GUI_EXPORT)
#endif // QTEXTOPTION_H