diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-05-17 21:08:01 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-05-17 21:08:01 +0000 |
commit | badea57d1db45caa95e71a256f4f4cf94fe20451 (patch) | |
tree | faba442eadf4108fce37b5438fda8b2005960867 /lib/CodeGen/CGCall.cpp | |
parent | 492bafc66bdd22128327aab11804db476688b44e (diff) |
For calls returning first-class aggregates, store by element instead of creating aggregate stores in common cases. This is more friendly to fast-isel.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131490 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 6b6f3176b0..fba89a76fc 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -513,6 +513,29 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr, return CGF.Builder.CreateLoad(Tmp); } +// Function to store a first-class aggregate into memory. We prefer to +// store the elements rather than the aggregate to be more friendly to +// fast-isel. +// FIXME: Do we need to recurse here? +static void BuildAggStore(CodeGenFunction &CGF, llvm::Value *Val, + llvm::Value *DestPtr, bool DestIsVolatile, + bool LowAlignment) { + // Prefer scalar stores to first-class aggregate stores. + if (const llvm::StructType *STy = + dyn_cast<llvm::StructType>(Val->getType())) { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + llvm::Value *EltPtr = CGF.Builder.CreateConstGEP2_32(DestPtr, 0, i); + llvm::Value *Elt = CGF.Builder.CreateExtractValue(Val, i); + llvm::StoreInst *SI = CGF.Builder.CreateStore(Elt, EltPtr, + DestIsVolatile); + if (LowAlignment) + SI->setAlignment(1); + } + } else { + CGF.Builder.CreateStore(Val, DestPtr, DestIsVolatile); + } +} + /// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src, /// where the source and destination may have different types. /// @@ -553,7 +576,7 @@ static void CreateCoercedStore(llvm::Value *Src, llvm::Value *Casted = CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy)); // FIXME: Use better alignment / avoid requiring aligned store. - CGF.Builder.CreateStore(Src, Casted, DstIsVolatile)->setAlignment(1); + BuildAggStore(CGF, Src, Casted, DstIsVolatile, true); } else { // Otherwise do coercion through memory. This is stupid, but // simple. @@ -1409,7 +1432,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, DestPtr = CreateMemTemp(RetTy, "agg.tmp"); DestIsVolatile = false; } - Builder.CreateStore(CI, DestPtr, DestIsVolatile); + BuildAggStore(*this, CI, DestPtr, DestIsVolatile, false); return RValue::getAggregate(DestPtr); } return RValue::get(CI); |