aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2012-01-20 00:53:28 +0000
committerBill Wendling <isanbard@gmail.com>2012-01-20 00:53:28 +0000
commitb618ea5ff97182381107ab6bf52b0c2d8f783d7d (patch)
tree6cf09975013773c63d821590c5bd6f711f0e1246
parent9a2478ac1a9aafcd5e89808868e170cfdfefcdc1 (diff)
When lowering the 'resume' instruction, look to see if we can eliminate the
'insertvalue' instructions that recreate the structure returned by the 'landingpad' instruction. Because the 'insertvalue' instruction isn't supported by FastISel, this can save a bit of time during -O0 compilation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148520 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/DwarfEHPrepare.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp
index aa442233e5..f2b2977275 100644
--- a/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/lib/CodeGen/DwarfEHPrepare.cpp
@@ -101,10 +101,40 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) {
I = Resumes.begin(), E = Resumes.end(); I != E; ++I) {
ResumeInst *RI = *I;
BranchInst::Create(UnwindBB, RI->getParent());
- ExtractValueInst *ExnObj = ExtractValueInst::Create(RI->getOperand(0),
- 0, "exn.obj", RI);
+
+ Value *V = RI->getOperand(0);
+ Instruction *ExnObj = 0;
+ InsertValueInst *SelIVI = dyn_cast<InsertValueInst>(V);
+ LoadInst *SelLoad = 0;
+ InsertValueInst *ExcIVI = 0;
+ bool EraseIVIs = false;
+ if (SelIVI) {
+ if (SelIVI->getNumIndices() == 1 && *SelIVI->idx_begin() == 1) {
+ ExcIVI = dyn_cast<InsertValueInst>(SelIVI->getOperand(0));
+ if (ExcIVI && isa<UndefValue>(ExcIVI->getOperand(0)) &&
+ ExcIVI->getNumIndices() == 1 && *ExcIVI->idx_begin() == 0) {
+ ExnObj = cast<Instruction>(ExcIVI->getOperand(1));
+ SelLoad = dyn_cast<LoadInst>(SelIVI->getOperand(1));
+ EraseIVIs = true;
+ }
+ }
+ }
+
+ if (!ExnObj)
+ ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI);
+
PN->addIncoming(ExnObj, RI->getParent());
RI->eraseFromParent();
+
+ if (EraseIVIs) {
+ if (SelIVI->getNumUses() == 0)
+ SelIVI->eraseFromParent();
+ if (ExcIVI->getNumUses() == 0)
+ ExcIVI->eraseFromParent();
+ if (SelLoad && SelLoad->getNumUses() == 0)
+ SelLoad->eraseFromParent();
+ }
+
++NumResumesLowered;
}