llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Andy Kaylor (andykaylor)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/155668.diff


1 Files Affected:

- (modified) clang/lib/CodeGen/CGClass.cpp (+30-13) 


``````````diff
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");

``````````

</details>


https://github.com/llvm/llvm-project/pull/155668
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to