summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SjLjEHPrepare.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-12-13 09:22:43 +0000
committerBill Wendling <isanbard@gmail.com>2011-12-13 09:22:43 +0000
commit4762f7525162ddcd3a527677ed8a2d53856f21d9 (patch)
tree4087fe22a1b05ac995e629a8686c9edb6814bb22 /lib/CodeGen/SjLjEHPrepare.cpp
parent13aaca5edf538f967c16b8bdbfe293e2f9d75fc1 (diff)
downloadllvm-4762f7525162ddcd3a527677ed8a2d53856f21d9.tar.gz
llvm-4762f7525162ddcd3a527677ed8a2d53856f21d9.tar.bz2
llvm-4762f7525162ddcd3a527677ed8a2d53856f21d9.tar.xz
Avoid using the 'insertvalue' instruction here.
Fast ISel isn't able to handle 'insertvalue' and it causes a large slowdown during -O0 compilation. We don't necessarily need to generate an aggregate of the values here if they're just going to be extracted directly afterwards. <rdar://problem/10530851> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146481 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SjLjEHPrepare.cpp')
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp39
1 files changed, 33 insertions, 6 deletions
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index c8651926c2..ac99cca27b 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -69,6 +69,8 @@ namespace {
private:
bool setupEntryBlockAndCallSites(Function &F);
+ void substituteLPadValues(LandingPadInst *LPI, Value *ExnVal,
+ Value *SelVal, IRBuilder<> &Builder);
Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads);
void lowerIncomingArguments(Function &F);
void lowerAcrossUnwindEdges(Function &F, ArrayRef<InvokeInst*> Invokes);
@@ -138,6 +140,36 @@ static void MarkBlocksLiveIn(BasicBlock *BB,
MarkBlocksLiveIn(*PI, LiveBBs);
}
+/// substituteLPadValues - Substitute the values returned by the landingpad
+/// instruction with those returned by the personality function.
+void SjLjEHPass::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal,
+ Value *SelVal, IRBuilder<> &Builder) {
+ SmallVector<Value*, 8> UseWorkList(LPI->use_begin(), LPI->use_end());
+ while (!UseWorkList.empty()) {
+ Value *Val = UseWorkList.pop_back_val();
+ ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val);
+ if (!EVI) continue;
+ if (EVI->getNumIndices() != 1) continue;
+ if (*EVI->idx_begin() == 0)
+ EVI->replaceAllUsesWith(ExnVal);
+ else if (*EVI->idx_begin() == 1)
+ EVI->replaceAllUsesWith(SelVal);
+ if (EVI->getNumUses() == 0)
+ EVI->eraseFromParent();
+ }
+
+ if (LPI->getNumUses() == 0) return;
+
+ // There are still some uses of LPI. Construct an aggregate with the exception
+ // values and replace the LPI with that aggregate.
+ Type *LPadType = LPI->getType();
+ Value *LPadVal = UndefValue::get(LPadType);
+ LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val");
+ LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val");
+
+ LPI->replaceAllUsesWith(LPadVal);
+}
+
/// setupFunctionContext - Allocate the function context on the stack and fill
/// it with all of the data that we know at this point.
Value *SjLjEHPass::
@@ -189,12 +221,7 @@ setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) {
ExnVal = Builder.CreateIntToPtr(ExnVal, Type::getInt8PtrTy(F.getContext()));
Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val");
- Type *LPadType = LPI->getType();
- Value *LPadVal = UndefValue::get(LPadType);
- LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val");
- LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val");
-
- LPI->replaceAllUsesWith(LPadVal);
+ substituteLPadValues(LPI, ExnVal, SelVal, Builder);
}
// Personality function