summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-01-20 23:03:55 +0000
committerJim Grosbach <grosbach@apple.com>2010-01-20 23:03:55 +0000
commit8d77cc8c5f47f2dbab867441251f5df796b78a6e (patch)
tree8d2f6a7347f8c671db7dd9be99313bb193a1a211 /lib/CodeGen
parent10d33a4937f8449e9ca6bbb6981bb07e4fd9c781 (diff)
downloadllvm-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.cpp13
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;