aboutsummaryrefslogtreecommitdiff
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
commitfa113f815513414a874c5801a5b4dc0ef7dfe8ef (patch)
tree1305d3a76590fd339ca2946835ef1f8aa894f2be
parentc0755a6f984f17c269c2a7a4b48c74d201403c9b (diff)
Factor the profitability check for return slot optimization out into a static function.
At some point in the future, this check will become smarter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47310 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/GVN.cpp40
1 files changed, 26 insertions, 14 deletions
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index 4de0f3dc72..203bd751e2 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/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;