diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-01-20 23:03:55 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-01-20 23:03:55 +0000 |
commit | 8d77cc8c5f47f2dbab867441251f5df796b78a6e (patch) | |
tree | 8d2f6a7347f8c671db7dd9be99313bb193a1a211 /lib/CodeGen | |
parent | 10d33a4937f8449e9ca6bbb6981bb07e4fd9c781 (diff) | |
download | llvm-8d77cc8c5f47f2dbab867441251f5df796b78a6e.tar.gz llvm-8d77cc8c5f47f2dbab867441251f5df796b78a6e.tar.bz2 llvm-8d77cc8c5f47f2dbab867441251f5df796b78a6e.tar.xz |
SjLj EH introduces can introduce an additional edge to a landing pad and pad
normalization needs to take this into account.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94046 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/DwarfEHPrepare.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 9b516ed75a..39fc85e764 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -21,6 +21,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Module.h" #include "llvm/Pass.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" @@ -114,6 +115,9 @@ FunctionPass *llvm::createDwarfEHPass(const TargetLowering *tli, bool fast) { bool DwarfEHPrepare::NormalizeLandingPads() { bool Changed = false; + const MCAsmInfo *MAI = TLI->getTargetMachine().getMCAsmInfo(); + bool usingSjLjEH = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { TerminatorInst *TI = I->getTerminator(); if (!isa<InvokeInst>(TI)) @@ -125,9 +129,18 @@ bool DwarfEHPrepare::NormalizeLandingPads() { // Check that only invoke unwind edges end at the landing pad. bool OnlyUnwoundTo = true; + bool SwitchOK = usingSjLjEH; for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad); PI != PE; ++PI) { TerminatorInst *PT = (*PI)->getTerminator(); + // The SjLj dispatch block uses a switch instruction. This is effectively + // an unwind edge, so we can disregard it here. There will only ever + // be one dispatch, however, so if there are multiple switches, one + // of them truly is a normal edge, not an unwind edge. + if (SwitchOK && isa<SwitchInst>(PT)) { + SwitchOK = false; + continue; + } if (!isa<InvokeInst>(PT) || LPad == PT->getSuccessor(0)) { OnlyUnwoundTo = false; break; |