[clang] [NFC][Clang][CodeGen] Improve performance for vtable metadata generation (PR #67066)
Matheus Izvekov via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 2 11:22:20 PDT 2023
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/67066
>From 44d43a8e7fa5b19671bc3f56f934dfb63a632aa4 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Thu, 21 Sep 2023 22:57:27 +0200
Subject: [PATCH] [NFC][Clang][CodeGen] Improve performance for vtable metadata
generation
Mangle each AddressPoint once, instead of once per comparison.
---
clang/lib/CodeGen/CGVTables.cpp | 54 ++++++++++++++-------------------
1 file changed, 22 insertions(+), 32 deletions(-)
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index d782da2103b4c79..5ec38e0397bf4f7 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -24,6 +24,7 @@
#include "llvm/Transforms/Utils/Cloning.h"
#include <algorithm>
#include <cstdio>
+#include <utility>
using namespace clang;
using namespace CodeGen;
@@ -1308,44 +1309,33 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
CharUnits ComponentWidth = GetTargetTypeStoreSize(getVTableComponentType());
- typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
+ struct AddressPoint {
+ const CXXRecordDecl *Base;
+ size_t Offset;
+ std::string TypeName;
+ bool operator<(const AddressPoint &RHS) const {
+ int D = TypeName.compare(RHS.TypeName);
+ return D < 0 || (D == 0 && Offset < RHS.Offset);
+ }
+ };
std::vector<AddressPoint> AddressPoints;
- for (auto &&AP : VTLayout.getAddressPoints())
- AddressPoints.push_back(std::make_pair(
- AP.first.getBase(), VTLayout.getVTableOffset(AP.second.VTableIndex) +
- AP.second.AddressPointIndex));
-
- // Sort the address points for determinism.
- // FIXME: It's more efficient to mangle the types before sorting.
- llvm::sort(AddressPoints, [this](const AddressPoint &AP1,
- const AddressPoint &AP2) {
- if (&AP1 == &AP2)
- return false;
-
- std::string S1;
- llvm::raw_string_ostream O1(S1);
- getCXXABI().getMangleContext().mangleCanonicalTypeName(
- QualType(AP1.first->getTypeForDecl(), 0), O1);
- O1.flush();
-
- std::string S2;
- llvm::raw_string_ostream O2(S2);
+ for (auto &&AP : VTLayout.getAddressPoints()) {
+ AddressPoint N{AP.first.getBase(),
+ VTLayout.getVTableOffset(AP.second.VTableIndex) +
+ AP.second.AddressPointIndex};
+ llvm::raw_string_ostream Stream(N.TypeName);
getCXXABI().getMangleContext().mangleCanonicalTypeName(
- QualType(AP2.first->getTypeForDecl(), 0), O2);
- O2.flush();
-
- if (S1 < S2)
- return true;
- if (S1 != S2)
- return false;
+ QualType(N.Base->getTypeForDecl(), 0), Stream);
+ AddressPoints.push_back(std::move(N));
+ }
- return AP1.second < AP2.second;
- });
+ // Sort the address points for determinism.
+ llvm::sort(AddressPoints);
ArrayRef<VTableComponent> Comps = VTLayout.vtable_components();
for (auto AP : AddressPoints) {
// Create type metadata for the address point.
- AddVTableTypeMetadata(VTable, ComponentWidth * AP.second, AP.first);
+ AddVTableTypeMetadata(VTable, ComponentWidth * AP.Offset, AP.Base);
// The class associated with each address point could also potentially be
// used for indirect calls via a member function pointer, so we need to
@@ -1357,7 +1347,7 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
Context.getMemberPointerType(
Comps[I].getFunctionDecl()->getType(),
- Context.getRecordType(AP.first).getTypePtr()));
+ Context.getRecordType(AP.Base).getTypePtr()));
VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD);
}
}
More information about the cfe-commits
mailing list