[cfe-commits] r131490 - in /cfe/trunk: lib/CodeGen/CGCall.cpp test/CodeGenObjCXX/property-object-conditional-exp.mm
Eli Friedman
eli.friedman at gmail.com
Tue May 17 14:08:01 PDT 2011
Author: efriedma
Date: Tue May 17 16:08:01 2011
New Revision: 131490
URL: http://llvm.org/viewvc/llvm-project?rev=131490&view=rev
Log:
For calls returning first-class aggregates, store by element instead of creating aggregate stores in common cases. This is more friendly to fast-isel.
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/test/CodeGenObjCXX/property-object-conditional-exp.mm
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=131490&r1=131489&r2=131490&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue May 17 16:08:01 2011
@@ -513,6 +513,29 @@
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 @@
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 @@
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);
Modified: cfe/trunk/test/CodeGenObjCXX/property-object-conditional-exp.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/property-object-conditional-exp.mm?rev=131490&r1=131489&r2=131490&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/property-object-conditional-exp.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/property-object-conditional-exp.mm Tue May 17 16:08:01 2011
@@ -23,7 +23,12 @@
CGRect virtualBounds;
// CHECK: [[SRC:%.*]] = call %struct.CGRect bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK-NEXT:store %struct.CGRect [[SRC]], %struct.CGRect*
+// CHECK-NEXT:getelementptr %struct.CGRect* [[SRC:%.*]]
+// CHECK-NEXT:extractvalue
+// CHECK-NEXT:store
+// CHECK-NEXT:getelementptr %struct.CGRect* [[SRC:%.*]]
+// CHECK-NEXT:extractvalue
+// CHECK-NEXT:store
dataRect = CGRectIsEmpty(virtualBounds) ? self.bounds : virtualBounds;
dataRect = CGRectIsEmpty(virtualBounds) ? [self bounds] : virtualBounds;
dataRect = CGRectIsEmpty(virtualBounds) ? virtualBounds : self.bounds;
More information about the cfe-commits
mailing list