diff options
| author | Owen Anderson <resistor@mac.com> | 2008-02-19 03:27:34 +0000 |
|---|---|---|
| committer | Owen Anderson <resistor@mac.com> | 2008-02-19 03:27:34 +0000 |
| commit | c0c3cd8e27eb7622078b20601eb8c3b2a104c27f (patch) | |
| tree | ce1afd62370eafaae4066d43f549f4be753e692d | |
| parent | 551b8eeb5cc9252116933a3670e92ee9a568ec3d (diff) | |
| download | bcm5719-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.cpp | 40 |
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; |

