From 170b1816b2cd6f02a8d0d5f1e13d9bda2f247012 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 11 Jan 2008 19:34:32 +0000 Subject: [PATCH] a byval argument is guaranteed to be valid to load. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45877 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/ArgumentPromotion.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index 42a7067f23b..1c739adcea3 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -193,7 +193,15 @@ static bool AllCalleesPassInValidPointerForArgument(Argument *Arg) { bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const { // We can only promote this argument if all of the uses are loads, or are GEP // instructions (with constant indices) that are subsequently loaded. - bool HasLoadInEntryBlock = false; + + // We can also only promote the load if we can guarantee that it will happen. + // Promoting a load causes the load to be unconditionally executed in the + // caller, so we can't turn a conditional load into an unconditional load in + // general. + bool SafeToUnconditionallyLoad = false; + if (isByVal) // ByVal arguments are always safe to load from. + SafeToUnconditionallyLoad = true; + BasicBlock *EntryBlock = Arg->getParent()->begin(); SmallVector Loads; std::vector > GEPIndices; @@ -202,7 +210,10 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const { if (LoadInst *LI = dyn_cast(*UI)) { if (LI->isVolatile()) return false; // Don't hack volatile loads Loads.push_back(LI); - HasLoadInEntryBlock |= LI->getParent() == EntryBlock; + + // If this load occurs in the entry block, then the pointer is + // unconditionally loaded. + SafeToUnconditionallyLoad |= LI->getParent() == EntryBlock; } else if (GetElementPtrInst *GEP = dyn_cast(*UI)) { if (GEP->use_empty()) { // Dead GEP's cause trouble later. Just remove them if we run into @@ -225,7 +236,10 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const { if (LoadInst *LI = dyn_cast(*UI)) { if (LI->isVolatile()) return false; // Don't hack volatile loads Loads.push_back(LI); - HasLoadInEntryBlock |= LI->getParent() == EntryBlock; + + // If this load occurs in the entry block, then the pointer is + // unconditionally loaded. + SafeToUnconditionallyLoad |= LI->getParent() == EntryBlock; } else { return false; } @@ -257,7 +271,8 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, bool isByVal) const { // of the pointer in the entry block of the function) or if we can prove that // all pointers passed in are always to legal locations (for example, no null // pointers are passed in, no pointers to free'd memory, etc). - if (!HasLoadInEntryBlock && !AllCalleesPassInValidPointerForArgument(Arg)) + if (!SafeToUnconditionallyLoad && + !AllCalleesPassInValidPointerForArgument(Arg)) return false; // Cannot prove that this is safe!! // Okay, now we know that the argument is only used by load instructions and