https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/155668
>From 7a3f59c3f250f9730dc3479f2b5e1b28ec2f2354 Mon Sep 17 00:00:00 2001 From: Andy Kaylor <akay...@nvidia.com> Date: Wed, 27 Aug 2025 10:28:55 -0700 Subject: [PATCH 1/2] [Clang][CodeGen]NFC] Modernize loops in EmitCtorPrologue This patch updates the loops in EmitCtorPrologue to use range-based for loops rather than looping over a single iterator which was being shared between three loops. Setting up three separate ranges adds a very small amount of overhead, but it improves the readability and maintainability of the code. --- clang/lib/CodeGen/CGClass.cpp | 43 ++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index bae55aa1e1928..b4a6acc0f2d5f 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1271,10 +1271,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, const CXXRecordDecl *ClassDecl = CD->getParent(); - CXXConstructorDecl::init_const_iterator B = CD->init_begin(), - E = CD->init_end(); - - // Virtual base initializers first, if any. They aren't needed if: + // Virtual base initializers aren't needed if: // - This is a base ctor variant // - There are no vbases // - The class is abstract, so a complete object of it cannot be constructed @@ -1296,15 +1293,36 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, assert(BaseCtorContinueBB); } - for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { + // Create three separate ranges for the different types of initializers. + auto AllInits = CD->inits(); + + // Find the boundaries between the three groups. + auto VirtualBaseEnd = std::find_if( + AllInits.begin(), AllInits.end(), [](const CXXCtorInitializer *Init) { + return !(Init->isBaseInitializer() && Init->isBaseVirtual()); + }); + + auto NonVirtualBaseEnd = std::find_if(VirtualBaseEnd, AllInits.end(), + [](const CXXCtorInitializer *Init) { + return !Init->isBaseInitializer(); + }); + + // Create the three ranges. + auto VirtualBaseInits = llvm::make_range(AllInits.begin(), VirtualBaseEnd); + auto NonVirtualBaseInits = + llvm::make_range(VirtualBaseEnd, NonVirtualBaseEnd); + auto MemberInits = llvm::make_range(NonVirtualBaseEnd, AllInits.end()); + + // Process virtual base initializers. + for (CXXCtorInitializer *Initializer : VirtualBaseInits) { if (!ConstructVBases) continue; SaveAndRestore ThisRAII(CXXThisValue); if (CGM.getCodeGenOpts().StrictVTablePointers && CGM.getCodeGenOpts().OptimizationLevel > 0 && - isInitializerOfDynamicClass(*B)) + isInitializerOfDynamicClass(Initializer)) CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); - EmitBaseInitializer(*this, ClassDecl, *B); + EmitBaseInitializer(*this, ClassDecl, Initializer); } if (BaseCtorContinueBB) { @@ -1314,14 +1332,14 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, } // Then, non-virtual base initializers. - for (; B != E && (*B)->isBaseInitializer(); B++) { - assert(!(*B)->isBaseVirtual()); + for (CXXCtorInitializer *Initializer : NonVirtualBaseInits) { + assert(!Initializer->isBaseVirtual()); SaveAndRestore ThisRAII(CXXThisValue); if (CGM.getCodeGenOpts().StrictVTablePointers && CGM.getCodeGenOpts().OptimizationLevel > 0 && - isInitializerOfDynamicClass(*B)) + isInitializerOfDynamicClass(Initializer)) CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); - EmitBaseInitializer(*this, ClassDecl, *B); + EmitBaseInitializer(*this, ClassDecl, Initializer); } InitializeVTablePointers(ClassDecl); @@ -1329,8 +1347,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, // And finally, initialize class members. FieldConstructionScope FCS(*this, LoadCXXThisAddress()); ConstructorMemcpyizer CM(*this, CD, Args); - for (; B != E; B++) { - CXXCtorInitializer *Member = (*B); + for (CXXCtorInitializer *Member : MemberInits) { assert(!Member->isBaseInitializer()); assert(Member->isAnyMemberInitializer() && "Delegating initializer on non-delegating constructor"); >From d69f1a6aac3d7ada43fbf8e48570b47c4b9bb3e7 Mon Sep 17 00:00:00 2001 From: Andy Kaylor <akay...@nvidia.com> Date: Thu, 28 Aug 2025 14:02:47 -0700 Subject: [PATCH 2/2] Address review feedback --- clang/lib/CodeGen/CGClass.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index b4a6acc0f2d5f..378f2c8fdef6e 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1313,16 +1313,16 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, llvm::make_range(VirtualBaseEnd, NonVirtualBaseEnd); auto MemberInits = llvm::make_range(NonVirtualBaseEnd, AllInits.end()); - // Process virtual base initializers. - for (CXXCtorInitializer *Initializer : VirtualBaseInits) { - if (!ConstructVBases) - continue; - SaveAndRestore ThisRAII(CXXThisValue); - if (CGM.getCodeGenOpts().StrictVTablePointers && - CGM.getCodeGenOpts().OptimizationLevel > 0 && - isInitializerOfDynamicClass(Initializer)) - CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); - EmitBaseInitializer(*this, ClassDecl, Initializer); + // Process virtual base initializers, if necessary. + if (ConstructVBases) { + for (CXXCtorInitializer *Initializer : VirtualBaseInits) { + SaveAndRestore ThisRAII(CXXThisValue); + if (CGM.getCodeGenOpts().StrictVTablePointers && + CGM.getCodeGenOpts().OptimizationLevel > 0 && + isInitializerOfDynamicClass(Initializer)) + CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); + EmitBaseInitializer(*this, ClassDecl, Initializer); + } } if (BaseCtorContinueBB) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits