Author: Matheus Izvekov Date: 2023-10-03T03:23:34+02:00 New Revision: e8970141ec4326acb139789db01fb7c51538a4be
URL: https://github.com/llvm/llvm-project/commit/e8970141ec4326acb139789db01fb7c51538a4be DIFF: https://github.com/llvm/llvm-project/commit/e8970141ec4326acb139789db01fb7c51538a4be.diff LOG: [NFC][Clang][CodeGen] Improve performance for vtable metadata generation (#67066) Mangle each AddressPoint once, instead of once per comparison. Added: Modified: clang/lib/CodeGen/CGVTables.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index d782da2103b4c79..c81b67ecf4fee0d 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,34 @@ 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 +1348,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); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits