[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