From: Chris Lattner Date: Mon, 5 Jul 2010 20:41:41 +0000 (+0000) Subject: Generate fewer first class aggregate values for other X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9282688a296b306c4ae2d115f55101647056d1da;p=clang Generate fewer first class aggregate values for other coerce cases (e.g. {double,int}) which avoids fastisel bailing out at -O0. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107628 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 96304477ff..528a038f91 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -933,25 +933,14 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, // and the optimizer generally likes scalar values better than FCAs. if (const llvm::StructType *STy = dyn_cast(ArgI.getCoerceToType())) { - // If the argument and alloca types match up, we don't have to build the - // FCA at all, emit a series of GEPs and stores, which is better for - // fast isel. - if (STy == cast(V->getType())->getElementType()) { - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - assert(AI != Fn->arg_end() && "Argument mismatch!"); - AI->setName(Arg->getName() + ".coerce" + llvm::Twine(i)); - llvm::Value *EltPtr = Builder.CreateConstGEP2_32(V, 0, i); - Builder.CreateStore(AI++, EltPtr); - } - } else { - // Reconstruct the FCA here so we can do a coerced store. - llvm::Value *FormalArg = llvm::UndefValue::get(STy); - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - assert(AI != Fn->arg_end() && "Argument mismatch!"); - AI->setName(Arg->getName() + ".coerce" + llvm::Twine(i)); - FormalArg = Builder.CreateInsertValue(FormalArg, AI++, i); - } - CreateCoercedStore(FormalArg, V, /*DestIsVolatile=*/false, *this); + llvm::Value *Ptr = V; + Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(STy)); + + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + assert(AI != Fn->arg_end() && "Argument mismatch!"); + AI->setName(Arg->getName() + ".coerce" + llvm::Twine(i)); + llvm::Value *EltPtr = Builder.CreateConstGEP2_32(Ptr, 0, i); + Builder.CreateStore(AI++, EltPtr); } } else { // Simple case, just do a coerced store of the argument into the alloca. @@ -1166,22 +1155,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // and the optimizer generally likes scalar values better than FCAs. if (const llvm::StructType *STy = dyn_cast(ArgInfo.getCoerceToType())) { - // If the argument and alloca types match up, we don't have to build the - // FCA at all, emit a series of GEPs and loads, which is better for - // fast isel. - if (STy ==cast(SrcPtr->getType())->getElementType()){ - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - llvm::Value *EltPtr = Builder.CreateConstGEP2_32(SrcPtr, 0, i); - Args.push_back(Builder.CreateLoad(EltPtr)); - } - } else { - // Otherwise, do a coerced load the entire FCA and handle the pieces. - llvm::Value *SrcVal = - CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(), *this); - - // Extract the elements of the value to pass in. - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) - Args.push_back(Builder.CreateExtractValue(SrcVal, i)); + SrcPtr = Builder.CreateBitCast(SrcPtr, + llvm::PointerType::getUnqual(STy)); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + llvm::Value *EltPtr = Builder.CreateConstGEP2_32(SrcPtr, 0, i); + Args.push_back(Builder.CreateLoad(EltPtr)); } } else { // In the simple case, just pass the coerced loaded value.