[llvm-commits] [llvm-gcc-4.2] r46671 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h

Duncan Sands baldrick at free.fr
Sat Feb 2 12:54:52 PST 2008


Author: baldrick
Date: Sat Feb  2 14:54:52 2008
New Revision: 46671

URL: http://llvm.org/viewvc/llvm-project?rev=46671&view=rev
Log:
Revert the fixes for PR1942: gcc doesn't always
introduce the temporary (it's not yet clear how
it decides this), and introducing it for a C++
object with constructor/destructor can be fatal.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=46671&r1=46670&r2=46671&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sat Feb  2 14:54:52 2008
@@ -415,7 +415,7 @@
                                      Function::arg_iterator &ai,
                                      const LLVMBuilder &B)
       : FunctionDecl(FnDecl), AI(ai), Builder(B) {}
-
+    
     void setName(const std::string &Name) {
       NameStack.push_back(Name);
     }
@@ -435,10 +435,8 @@
       // instead.
       assert(AI != Builder.GetInsertBlock()->getParent()->arg_end() &&
              "No explicit return value?");
-      assert(AI == Builder.GetInsertBlock()->getParent()->arg_begin() &&
-             "Struct return is not first argument!");
       AI->setName("agg.result");
-
+        
       tree ResultDecl = DECL_RESULT(FunctionDecl);
       tree RetTy = TREE_TYPE(TREE_TYPE(FunctionDecl));
       if (TREE_CODE(RetTy) == TREE_CODE(TREE_TYPE(ResultDecl))) {
@@ -446,14 +444,14 @@
         ++AI;
         return;
       }
-
+      
       // Otherwise, this must be something returned with NRVO.
       assert(TREE_CODE(TREE_TYPE(ResultDecl)) == REFERENCE_TYPE &&
              "Not type match and not passing by reference?");
       // Create an alloca for the ResultDecl.
       Value *Tmp = TheTreeToLLVM->CreateTemporary(AI->getType());
       Builder.CreateStore(AI, Tmp);
-
+      
       SET_DECL_LLVM(ResultDecl, Tmp);
       if (TheDebugInfo) {
         TheDebugInfo->EmitDeclare(ResultDecl,
@@ -2310,7 +2308,6 @@
     CallingConv::ID &CallingConvention;
     LLVMBuilder &Builder;
     const MemRef *DestLoc;
-    MemRef BufLoc;
     std::vector<Value*> LocStack;
 
     FunctionCallArgumentConversion(tree exp, SmallVector<Value*, 16> &ops,
@@ -2342,19 +2339,7 @@
       assert(LocStack.size() == 1 && "Imbalance!");
       LocStack.clear();
     }
-
-    // CopyOutResult - If the (aggregate) return result was redirected to a
-    // buffer, copy it to the final destination.
-    void CopyOutResult(tree result_type) {
-      if (BufLoc.Ptr && DestLoc) {
-        // A buffer was used for the aggregate return result.  Copy it out now.
-        assert(ConvertType(result_type) ==
-               cast<PointerType>(BufLoc.Ptr->getType())->getElementType() &&
-               "Inconsistent result types!");
-        TheTreeToLLVM->EmitAggregateCopy(*DestLoc, BufLoc, result_type);
-      }
-    }
-
+    
     /// HandleScalarResult - This callback is invoked if the function returns a
     /// simple scalar result value.
     void HandleScalarResult(const Type *RetTy) {
@@ -2369,7 +2354,7 @@
     void HandleAggregateResultAsScalar(const Type *ScalarTy) {
       // There is nothing to do here.
     }
-
+    
     /// HandleAggregateShadowArgument - This callback is invoked if the function
     /// returns an aggregate value by using a "shadow" first parameter.  If
     /// RetPtr is set to true, the pointer argument itself is returned from the
@@ -2377,15 +2362,19 @@
     void HandleAggregateShadowArgument(const PointerType *PtrArgTy,
                                        bool RetPtr) {
       // We need to pass a buffer to return into.  If the caller uses the
-      // result, DestLoc will be set.  Since DestLoc may alias a parameter,
-      // the result needs to be stored in a buffer then copied to DestLoc
-      // after the call.  If DestLoc is not set then the result is unused,
-      // in which case we need to create a dummy buffer but not copy it out.
-      assert(!DestLoc || PtrArgTy == DestLoc->Ptr->getType());
-      BufLoc = TheTreeToLLVM->CreateTempLoc(PtrArgTy->getElementType());
-      CallOperands.push_back(BufLoc.Ptr);
+      // result, DestLoc will be set.  If it ignores it, it could be unset,
+      // in which case we need to create a dummy buffer.
+      // FIXME: The alignment and volatility of the buffer are being ignored!
+      Value *DestPtr;
+      if (DestLoc == 0) {
+        DestPtr = TheTreeToLLVM->CreateTemporary(PtrArgTy->getElementType());
+      } else {
+        DestPtr = DestLoc->Ptr;
+        assert(PtrArgTy == DestPtr->getType());
+      }
+      CallOperands.push_back(DestPtr);
     }
-
+    
     void HandleScalarArgument(const llvm::Type *LLVMTy, tree type) {
       assert(!LocStack.empty());
       Value *Loc = LocStack.back();
@@ -2554,9 +2543,7 @@
     cast<InvokeInst>(Call)->setParamAttrs(PAL);
     EmitBlock(NextBlock);
   }
-
-  Client.CopyOutResult(TREE_TYPE(exp));
-
+  
   if (Call->getType() == Type::VoidTy)
     return 0;
   
@@ -2693,9 +2680,20 @@
     // Non-bitfield aggregate value.
     MemRef NewLoc(LV.Ptr, Alignment, isVolatile);
 
-    Emit(TREE_OPERAND(exp, 1), &NewLoc);
-    if (DestLoc)
+    if (DestLoc) {
+      Emit(TREE_OPERAND(exp, 1), &NewLoc);
       EmitAggregateCopy(*DestLoc, NewLoc, TREE_TYPE(exp));
+    } else if (TREE_CODE(TREE_OPERAND(exp, 0)) != RESULT_DECL) {
+      Emit(TREE_OPERAND(exp, 1), &NewLoc);
+    } else {
+      // We do this for stores into RESULT_DECL because it is possible for that
+      // memory area to overlap with the object being stored into it; see 
+      // gcc.c-torture/execute/20010124-1.c.
+
+      MemRef Tmp = CreateTempLoc(ConvertType(TREE_TYPE(TREE_OPERAND(exp,1))));
+      Emit(TREE_OPERAND(exp, 1), &Tmp);
+      EmitAggregateCopy(NewLoc, Tmp, TREE_TYPE(TREE_OPERAND(exp,1)));
+    }
     return 0;
   }
 

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=46671&r1=46670&r2=46671&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Sat Feb  2 14:54:52 2008
@@ -285,7 +285,7 @@
   // AllocaInsertionPoint - Place to insert alloca instructions.  Lazily created
   // and managed by CreateTemporary.
   Instruction *AllocaInsertionPoint;
-
+  
   //===---------------------- Exception Handling --------------------------===//
 
   /// LandingPads - The landing pad for a given EH region.
@@ -386,13 +386,6 @@
   /// instruction's type is a pointer to the specified type.
   AllocaInst *CreateTemporary(const Type *Ty);
 
-  /// CreateTempLoc - Like CreateTemporary, but returns a MemRef.
-  MemRef CreateTempLoc(const Type *Ty);
-
-  /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
-  /// GCC type specified by GCCType to know which elements to copy.
-  void EmitAggregateCopy(MemRef DestLoc, MemRef SrcLoc, tree_node *GCCType);
-
 private: // Helper functions.
 
   /// StartFunctionBody - Start the emission of 'fndecl', outputing all
@@ -413,6 +406,10 @@
   /// the previous block falls through into it, add an explicit branch.
   void EmitBlock(BasicBlock *BB);
   
+  /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
+  /// GCC type specified by GCCType to know which elements to copy.
+  void EmitAggregateCopy(MemRef DestLoc, MemRef SrcLoc, tree_node *GCCType);
+
   /// EmitAggregateZero - Zero the elements of DestLoc.
   ///
   void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);
@@ -446,6 +443,9 @@
   BasicBlock *getPostPad(unsigned RegionNo);
 
 private:
+  /// CreateTempLoc - Like CreateTemporary, but returns a MemRef.
+  MemRef CreateTempLoc(const Type *Ty);
+
   void EmitAutomaticVariableDecl(tree_node *decl);
 
   /// isNoopCast - Return true if a cast from V to Ty does not change any bits.





More information about the llvm-commits mailing list