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 | d7cf27a1d135896c1038e73cc2a37c1b25444dfa (patch) | |
tree | 0160d71492d1d76cfb7376a56ab8affff5276d6a /llvm/lib/CodeGen/DwarfEHPrepare.cpp | |
parent | 4efdec067731bf2d28c9cf09b7ae050ef5e41176 (diff) | |
download | bcm5719-llvm-d7cf27a1d135896c1038e73cc2a37c1b25444dfa.tar.gz bcm5719-llvm-d7cf27a1d135896c1038e73cc2a37c1b25444dfa.zip |
SjLj EH introduces can introduce an additional edge to a landing pad and pad
normalization needs to take this into account.
llvm-svn: 94046
Diffstat (limited to 'llvm/lib/CodeGen/DwarfEHPrepare.cpp')
-rw-r--r-- | llvm/lib/CodeGen/DwarfEHPrepare.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp index 9b516ed75a8..39fc85e7649 100644 --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp +++ b/llvm/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; |