summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2008-02-19 03:27:34 +0000
committerOwen Anderson <resistor@mac.com>2008-02-19 03:27:34 +0000
commitc0c3cd8e27eb7622078b20601eb8c3b2a104c27f (patch)
treece1afd62370eafaae4066d43f549f4be753e692d
parent551b8eeb5cc9252116933a3670e92ee9a568ec3d (diff)
downloadbcm5719-llvm-c0c3cd8e27eb7622078b20601eb8c3b2a104c27f.tar.gz
bcm5719-llvm-c0c3cd8e27eb7622078b20601eb8c3b2a104c27f.zip
Factor the profitability check for return slot optimization out into a static function.
At some point in the future, this check will become smarter. llvm-svn: 47310
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp40
1 files changed, 26 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 4de0f3dc725..203bd751e20 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1052,6 +1052,28 @@ bool GVN::processLoad(LoadInst* L,
return deletedLoad;
}
+/// isReturnSlotOptznProfitable - Determine if performing a return slot
+/// fusion with the slot dest is profitable
+static bool isReturnSlotOptznProfitable(Value* dest, MemCpyInst* cpy) {
+ // We currently consider it profitable if dest is otherwise dead.
+ SmallVector<User*, 8> useList(dest->use_begin(), dest->use_end());
+ while (!useList.empty()) {
+ User* UI = useList.back();
+
+ if (isa<GetElementPtrInst>(UI) || isa<BitCastInst>(UI)) {
+ useList.pop_back();
+ for (User::use_iterator I = UI->use_begin(), E = UI->use_end();
+ I != E; ++I)
+ useList.push_back(*I);
+ } else if (UI == cpy)
+ useList.pop_back();
+ else
+ return false;
+ }
+
+ return true;
+}
+
/// performReturnSlotOptzn - takes a memcpy and a call that it depends on,
/// and checks for the possibility of a return slot optimization by having
/// the call write its result directly into the callees return parameter
@@ -1068,26 +1090,16 @@ bool GVN::performReturnSlotOptzn(MemCpyInst* cpy, CallInst* C,
if (!sretArg->hasStructRetAttr())
return false;
- // Make sure the return slot is otherwise dead
- std::set<User*> useList(sretArg->use_begin(), sretArg->use_end());
- while (!useList.empty()) {
- User* UI = *useList.begin();
-
- if (isa<GetElementPtrInst>(UI) || isa<BitCastInst>(UI)) {
- useList.insert(UI->use_begin(), UI->use_end());
- useList.erase(UI);
- } else if (UI == cpy)
- useList.erase(UI);
- else
- return false;
- }
+ // We only perform the transformation if it will be profitable.
+ if (!isReturnSlotOptznProfitable(sretArg, cpy))
+ return false;
// Make sure the call cannot modify the return slot in some unpredicted way
AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
if (AA.getModRefInfo(C, cpy->getRawDest(), ~0UL) != AliasAnalysis::NoModRef)
return false;
- // If all checks passed, then we can perform the transformation
+ // If all checks passed, then we can perform the transformation.
CallSite CS = CallSite::get(C);
if (CS.getArgument(0)->getType() != cpyDest->getType())
return false;
OpenPOWER on IntegriCloud