[clang][Interp][NFC] Avoid unnecessary work in compileFunc()
authorTimm Bäder <tbaeder@redhat.com>
Sun, 30 Oct 2022 09:13:18 +0000 (10:13 +0100)
committerTimm Bäder <tbaeder@redhat.com>
Wed, 30 Nov 2022 15:07:29 +0000 (16:07 +0100)
We don't need to create the paramter descriptors etc. if we've already
done that in the past.

clang/lib/AST/Interp/ByteCodeEmitter.cpp

index 1d72a90..b67e696 100644 (file)
@@ -26,50 +26,52 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
   // will (maybe) happen later.
   bool HasBody = FuncDecl->hasBody(FuncDecl);
 
-  // Set up argument indices.
-  unsigned ParamOffset = 0;
-  SmallVector<PrimType, 8> ParamTypes;
-  llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
-
-  // If the return is not a primitive, a pointer to the storage where the value
-  // is initialized in is passed as the first argument.
-  // See 'RVO' elsewhere in the code.
-  QualType Ty = FuncDecl->getReturnType();
-  bool HasRVO = false;
-  if (!Ty->isVoidType() && !Ctx.classify(Ty)) {
-    HasRVO = true;
-    ParamTypes.push_back(PT_Ptr);
-    ParamOffset += align(primSize(PT_Ptr));
-  }
+  // Create a handle over the emitted code.
+  Function *Func = P.getFunction(FuncDecl);
+  if (!Func) {
+    // Set up argument indices.
+    unsigned ParamOffset = 0;
+    SmallVector<PrimType, 8> ParamTypes;
+    llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
+
+    // If the return is not a primitive, a pointer to the storage where the
+    // value is initialized in is passed as the first argument. See 'RVO'
+    // elsewhere in the code.
+    QualType Ty = FuncDecl->getReturnType();
+    bool HasRVO = false;
+    if (!Ty->isVoidType() && !Ctx.classify(Ty)) {
+      HasRVO = true;
+      ParamTypes.push_back(PT_Ptr);
+      ParamOffset += align(primSize(PT_Ptr));
+    }
 
-  // If the function decl is a member decl, the next parameter is
-  // the 'this' pointer. This parameter is pop()ed from the
-  // InterpStack when calling the function.
-  bool HasThisPointer = false;
-  if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
-      MD && MD->isInstance()) {
-    HasThisPointer = true;
-    ParamTypes.push_back(PT_Ptr);
-    ParamOffset += align(primSize(PT_Ptr));
-  }
+    // If the function decl is a member decl, the next parameter is
+    // the 'this' pointer. This parameter is pop()ed from the
+    // InterpStack when calling the function.
+    bool HasThisPointer = false;
+    if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
+        MD && MD->isInstance()) {
+      HasThisPointer = true;
+      ParamTypes.push_back(PT_Ptr);
+      ParamOffset += align(primSize(PT_Ptr));
+    }
 
-  // Assign descriptors to all parameters.
-  // Composite objects are lowered to pointers.
-  for (const ParmVarDecl *PD : FuncDecl->parameters()) {
-    PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr);
-    Descriptor *Desc = P.createDescriptor(PD, Ty);
-    ParamDescriptors.insert({ParamOffset, {Ty, Desc}});
-    Params.insert({PD, ParamOffset});
-    ParamOffset += align(primSize(Ty));
-    ParamTypes.push_back(Ty);
-  }
+    // Assign descriptors to all parameters.
+    // Composite objects are lowered to pointers.
+    for (const ParmVarDecl *PD : FuncDecl->parameters()) {
+      PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr);
+      Descriptor *Desc = P.createDescriptor(PD, Ty);
+      ParamDescriptors.insert({ParamOffset, {Ty, Desc}});
+      Params.insert({PD, ParamOffset});
+      ParamOffset += align(primSize(Ty));
+      ParamTypes.push_back(Ty);
+    }
 
-  // Create a handle over the emitted code.
-  Function *Func = P.getFunction(FuncDecl);
-  if (!Func)
     Func =
         P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
                          std::move(ParamDescriptors), HasThisPointer, HasRVO);
+  }
+
   assert(Func);
   if (!HasBody)
     return Func;