svn commit: r338748 - stable/11/contrib/llvm/tools/clang/lib/CodeGen

Dimitry Andric dim at FreeBSD.org
Tue Sep 18 07:29:02 UTC 2018


Author: dim
Date: Tue Sep 18 07:29:01 2018
New Revision: 338748
URL: https://svnweb.freebsd.org/changeset/base/338748

Log:
  MFC r338697:
  
  Pull in r325478 from upstream clang trunk (by Ivan A. Kosarev):
  
    [CodeGen] Initialize large arrays by copying from a global
  
    Currently, clang compiles explicit initializers for array elements
    into series of store instructions. For large arrays of built-in types
    this results in bloated output code and significant amount of time
    spent on the instruction selection phase. This patch fixes the issue
    by initializing such arrays with global constants that store the
    binary image of the initializer.
  
    Differential Revision: https://reviews.llvm.org/D43181
  
  This should fix a compiler hang (and excessive memory usage) while
  building the science/rmg port.
  
  Reported by:	yuri at tsoft.com
  See also:	https://bugs.llvm.org/show_bug.cgi?id=38798

Modified:
  stable/11/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp
==============================================================================
--- stable/11/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp	Tue Sep 18 01:51:28 2018	(r338747)
+++ stable/11/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp	Tue Sep 18 07:29:01 2018	(r338748)
@@ -14,6 +14,7 @@
 #include "CodeGenFunction.h"
 #include "CGObjCRuntime.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
@@ -85,7 +86,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitt
   void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
 
   void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
-                     QualType elementType, InitListExpr *E);
+                     QualType ArrayQTy, InitListExpr *E);
 
   AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
     if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
@@ -392,12 +393,15 @@ static bool isTrivialFiller(Expr *E) {
 
 /// \brief Emit initialization of an array from an initializer list.
 void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
-                                   QualType elementType, InitListExpr *E) {
+                                   QualType ArrayQTy, InitListExpr *E) {
   uint64_t NumInitElements = E->getNumInits();
 
   uint64_t NumArrayElements = AType->getNumElements();
   assert(NumInitElements <= NumArrayElements);
 
+  QualType elementType =
+      CGF.getContext().getAsArrayType(ArrayQTy)->getElementType();
+
   // DestPtr is an array*.  Construct an elementType* by drilling
   // down a level.
   llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
@@ -409,6 +413,29 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, ll
   CharUnits elementAlign =
     DestPtr.getAlignment().alignmentOfArrayElement(elementSize);
 
+  // Consider initializing the array by copying from a global. For this to be
+  // more efficient than per-element initialization, the size of the elements
+  // with explicit initializers should be large enough.
+  if (NumInitElements * elementSize.getQuantity() > 16 &&
+      elementType.isTriviallyCopyableType(CGF.getContext())) {
+    CodeGen::CodeGenModule &CGM = CGF.CGM;
+    ConstantEmitter Emitter(CGM);
+    LangAS AS = ArrayQTy.getAddressSpace();
+    if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) {
+      auto GV = new llvm::GlobalVariable(
+          CGM.getModule(), C->getType(),
+          CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true),
+          llvm::GlobalValue::PrivateLinkage, C, "constinit",
+          /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal,
+          CGM.getContext().getTargetAddressSpace(AS));
+      Emitter.finalize(GV);
+      CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy);
+      GV->setAlignment(Align.getQuantity());
+      EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GV, ArrayQTy, Align));
+      return;
+    }
+  }
+
   // Exception safety requires us to destroy all the
   // already-constructed members if an initializer throws.
   // For that, we'll need an EH cleanup.
@@ -1156,11 +1183,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E
 
   // Handle initialization of an array.
   if (E->getType()->isArrayType()) {
-    QualType elementType =
-        CGF.getContext().getAsArrayType(E->getType())->getElementType();
-
     auto AType = cast<llvm::ArrayType>(Dest.getAddress().getElementType());
-    EmitArrayInit(Dest.getAddress(), AType, elementType, E);
+    EmitArrayInit(Dest.getAddress(), AType, E->getType(), E);
     return;
   }
 


More information about the svn-src-all mailing list