[cfe-commits] r127227 - in /cfe/trunk/lib/CodeGen: CGDecl.cpp CodeGenFunction.h

John McCall rjmccall at apple.com
Tue Mar 8 01:11:50 PST 2011


Author: rjmccall
Date: Tue Mar  8 03:11:50 2011
New Revision: 127227

URL: http://llvm.org/viewvc/llvm-project?rev=127227&view=rev
Log:
Extract a function to emit an arbitrary expression as if it were the initializer
for a local variable.


Modified:
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=127227&r1=127226&r2=127227&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Mar  8 03:11:50 2011
@@ -877,67 +877,91 @@
   llvm::Value *Loc =
     capturedByInit ? emission.Address : emission.getObjectAddress(*this);
 
-  bool isVolatile = type.isVolatileQualified();
-    
+  if (!emission.IsConstantAggregate)
+    return EmitExprAsInit(Init, &D, Loc, alignment, capturedByInit);
+
   // If this is a simple aggregate initialization, we can optimize it
   // in various ways.
-  if (emission.IsConstantAggregate) {
-    assert(!capturedByInit && "constant init contains a capturing block?");
+  assert(!capturedByInit && "constant init contains a capturing block?");
 
-    llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), type, this);
-    assert(Init != 0 && "Wasn't a simple constant init?");
+  bool isVolatile = type.isVolatileQualified();
 
-    llvm::Value *SizeVal =
-      llvm::ConstantInt::get(IntPtrTy, 
-                             getContext().getTypeSizeInChars(type).getQuantity());
-
-    const llvm::Type *BP = Int8PtrTy;
-    if (Loc->getType() != BP)
-      Loc = Builder.CreateBitCast(Loc, BP, "tmp");
-
-    // If the initializer is all or mostly zeros, codegen with memset then do
-    // a few stores afterward.
-    if (shouldUseMemSetPlusStoresToInitialize(Init, 
-                      CGM.getTargetData().getTypeAllocSize(Init->getType()))) {
-      Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
-                           alignment.getQuantity(), isVolatile);
-      if (!Init->isNullValue()) {
-        Loc = Builder.CreateBitCast(Loc, Init->getType()->getPointerTo());
-        emitStoresForInitAfterMemset(Init, Loc, isVolatile, Builder);
-      }
-    } else {
-      // Otherwise, create a temporary global with the initializer then 
-      // memcpy from the global to the alloca.
-      std::string Name = GetStaticDeclName(*this, D, ".");
-      llvm::GlobalVariable *GV =
-        new llvm::GlobalVariable(CGM.getModule(), Init->getType(), true,
-                                 llvm::GlobalValue::InternalLinkage,
-                                 Init, Name, 0, false, 0);
-      GV->setAlignment(alignment.getQuantity());
-        
-      llvm::Value *SrcPtr = GV;
-      if (SrcPtr->getType() != BP)
-        SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+  llvm::Constant *constant = CGM.EmitConstantExpr(D.getInit(), type, this);
+  assert(constant != 0 && "Wasn't a simple constant init?");
 
-      Builder.CreateMemCpy(Loc, SrcPtr, SizeVal, alignment.getQuantity(),
-                           isVolatile);
+  llvm::Value *SizeVal =
+    llvm::ConstantInt::get(IntPtrTy, 
+                           getContext().getTypeSizeInChars(type).getQuantity());
+
+  const llvm::Type *BP = Int8PtrTy;
+  if (Loc->getType() != BP)
+    Loc = Builder.CreateBitCast(Loc, BP, "tmp");
+
+  // If the initializer is all or mostly zeros, codegen with memset then do
+  // a few stores afterward.
+  if (shouldUseMemSetPlusStoresToInitialize(constant, 
+                CGM.getTargetData().getTypeAllocSize(constant->getType()))) {
+    Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
+                         alignment.getQuantity(), isVolatile);
+    if (!constant->isNullValue()) {
+      Loc = Builder.CreateBitCast(Loc, constant->getType()->getPointerTo());
+      emitStoresForInitAfterMemset(constant, Loc, isVolatile, Builder);
     }
-  } else if (type->isReferenceType()) {
-    RValue RV = EmitReferenceBindingToExpr(Init, &D);
-    if (capturedByInit) Loc = BuildBlockByrefAddress(Loc, &D);
-    EmitStoreOfScalar(RV.getScalarVal(), Loc, false, alignment.getQuantity(),
-                      type);
+  } else {
+    // Otherwise, create a temporary global with the initializer then 
+    // memcpy from the global to the alloca.
+    std::string Name = GetStaticDeclName(*this, D, ".");
+    llvm::GlobalVariable *GV =
+      new llvm::GlobalVariable(CGM.getModule(), constant->getType(), true,
+                               llvm::GlobalValue::InternalLinkage,
+                               constant, Name, 0, false, 0);
+    GV->setAlignment(alignment.getQuantity());
+        
+    llvm::Value *SrcPtr = GV;
+    if (SrcPtr->getType() != BP)
+      SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+
+    Builder.CreateMemCpy(Loc, SrcPtr, SizeVal, alignment.getQuantity(),
+                         isVolatile);
+  }
+}
+
+/// Emit an expression as an initializer for a variable at the given
+/// location.  The expression is not necessarily the normal
+/// initializer for the variable, and the address is not necessarily
+/// its normal location.
+///
+/// \param init the initializing expression
+/// \param var the variable to act as if we're initializing
+/// \param loc the address to initialize; its type is a pointer
+///   to the LLVM mapping of the variable's type
+/// \param alignment the alignment of the address
+/// \param capturedByInit true if the variable is a __block variable
+///   whose address is potentially changed by the initializer
+void CodeGenFunction::EmitExprAsInit(const Expr *init,
+                                     const VarDecl *var,
+                                     llvm::Value *loc,
+                                     CharUnits alignment,
+                                     bool capturedByInit) {
+  QualType type = var->getType();
+  bool isVolatile = type.isVolatileQualified();
+
+  if (type->isReferenceType()) {
+    RValue RV = EmitReferenceBindingToExpr(init, var);
+    if (capturedByInit) loc = BuildBlockByrefAddress(loc, var);
+    EmitStoreOfScalar(RV.getScalarVal(), loc, false,
+                      alignment.getQuantity(), type);
   } else if (!hasAggregateLLVMType(type)) {
-    llvm::Value *V = EmitScalarExpr(Init);
-    if (capturedByInit) Loc = BuildBlockByrefAddress(Loc, &D);
-    EmitStoreOfScalar(V, Loc, isVolatile, alignment.getQuantity(), type);
+    llvm::Value *V = EmitScalarExpr(init);
+    if (capturedByInit) loc = BuildBlockByrefAddress(loc, var);
+    EmitStoreOfScalar(V, loc, isVolatile, alignment.getQuantity(), type);
   } else if (type->isAnyComplexType()) {
-    ComplexPairTy complex = EmitComplexExpr(Init);
-    if (capturedByInit) Loc = BuildBlockByrefAddress(Loc, &D);
-    StoreComplexToAddr(complex, Loc, isVolatile);
+    ComplexPairTy complex = EmitComplexExpr(init);
+    if (capturedByInit) loc = BuildBlockByrefAddress(loc, var);
+    StoreComplexToAddr(complex, loc, isVolatile);
   } else {
     // TODO: how can we delay here if D is captured by its initializer?
-    EmitAggExpr(Init, AggValueSlot::forAddr(Loc, isVolatile, true, false));
+    EmitAggExpr(init, AggValueSlot::forAddr(loc, isVolatile, true, false));
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=127227&r1=127226&r2=127227&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Mar  8 03:11:50 2011
@@ -1361,12 +1361,18 @@
   /// always be accessible even if no aggregate location is provided.
   RValue EmitAnyExprToTemp(const Expr *E);
 
-  /// EmitsAnyExprToMem - Emits the code necessary to evaluate an
+  /// EmitAnyExprToMem - Emits the code necessary to evaluate an
   /// arbitrary expression into the given memory location.
   void EmitAnyExprToMem(const Expr *E, llvm::Value *Location,
                         bool IsLocationVolatile,
                         bool IsInitializer);
 
+  /// EmitExprAsInit - Emits the code necessary to initialize a
+  /// location in memory with the given initializer.
+  void EmitExprAsInit(const Expr *init, const VarDecl *var,
+                      llvm::Value *loc, CharUnits alignment,
+                      bool capturedByInit);
+
   /// EmitAggregateCopy - Emit an aggrate copy.
   ///
   /// \param isVolatile - True iff either the source or the destination is





More information about the cfe-commits mailing list