New EH representation for MSVC compatibility
Summary:
This introduces new instructions neccessary to implement MSVC-compatible
exception handling support. Most of the middle-end and none of the
back-end haven't been audited or updated to take them into account.
Reviewers: rnk, JosephTremoulet, reames, nlewycky, rjmccall
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D11041
llvm-svn: 241888
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 286a563..bcc39ef 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -2653,6 +2653,26 @@
setOrigin(&I, getCleanOrigin());
}
+ void visitCleanupBlockInst(CleanupBlockInst &I) {
+ setShadow(&I, getCleanShadow(&I));
+ setOrigin(&I, getCleanOrigin());
+ }
+
+ void visitCatchBlock(CatchBlockInst &I) {
+ setShadow(&I, getCleanShadow(&I));
+ setOrigin(&I, getCleanOrigin());
+ }
+
+ void visitTerminateBlock(TerminateBlockInst &I) {
+ setShadow(&I, getCleanShadow(&I));
+ setOrigin(&I, getCleanOrigin());
+ }
+
+ void visitCatchEndBlockInst(CatchEndBlockInst &I) {
+ setShadow(&I, getCleanShadow(&I));
+ setOrigin(&I, getCleanOrigin());
+ }
+
void visitGetElementPtrInst(GetElementPtrInst &I) {
handleShadowOr(I);
}
@@ -2696,6 +2716,16 @@
// Nothing to do here.
}
+ void visitCleanupReturnInst(CleanupReturnInst &CRI) {
+ DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
+ // Nothing to do here.
+ }
+
+ void visitCatchReturnInst(CatchReturnInst &CRI) {
+ DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
+ // Nothing to do here.
+ }
+
void visitInstruction(Instruction &I) {
// Everything else: stop propagating and check for poisoned shadow.
if (ClDumpStrictInstructions)
diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp
index d6fc916..0c707c4 100644
--- a/llvm/lib/Transforms/Scalar/ADCE.cpp
+++ b/llvm/lib/Transforms/Scalar/ADCE.cpp
@@ -58,8 +58,8 @@
// Collect the set of "root" instructions that are known live.
for (Instruction &I : inst_range(F)) {
- if (isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) ||
- isa<LandingPadInst>(I) || I.mayHaveSideEffects()) {
+ if (isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) || I.isEHBlock() ||
+ I.mayHaveSideEffects()) {
Alive.insert(&I);
Worklist.push_back(&I);
}
diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp
index 09c605e..e484069 100644
--- a/llvm/lib/Transforms/Scalar/BDCE.cpp
+++ b/llvm/lib/Transforms/Scalar/BDCE.cpp
@@ -77,8 +77,8 @@
false, false)
static bool isAlwaysLive(Instruction *I) {
- return isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) ||
- isa<LandingPadInst>(I) || I->mayHaveSideEffects();
+ return isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) || I->isEHBlock() ||
+ I->mayHaveSideEffects();
}
void BDCE::determineLiveOperandBits(const Instruction *UserI,
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 1130d22..e845a7f 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -669,7 +669,8 @@
// because now the condition in this block can be threaded through
// predecessors of our predecessor block.
if (BasicBlock *SinglePred = BB->getSinglePredecessor()) {
- if (SinglePred->getTerminator()->getNumSuccessors() == 1 &&
+ const TerminatorInst *TI = SinglePred->getTerminator();
+ if (!TI->isExceptional() && TI->getNumSuccessors() == 1 &&
SinglePred != BB && !hasAddressTakenAndUsed(BB)) {
// If SinglePred was a loop header, BB becomes one.
if (LoopHeaders.erase(SinglePred))
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index 4d3a708..c625b0f 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -539,9 +539,9 @@
return;
}
- if (isa<InvokeInst>(TI)) {
- // Invoke instructions successors are always executable.
- Succs[0] = Succs[1] = true;
+ // Unwinding instructions successors are always executable.
+ if (TI.isExceptional()) {
+ Succs.assign(TI.getNumSuccessors(), true);
return;
}
@@ -605,8 +605,8 @@
return BI->getSuccessor(CI->isZero()) == To;
}
- // Invoke instructions successors are always executable.
- if (isa<InvokeInst>(TI))
+ // Unwinding instructions successors are always executable.
+ if (TI->isExceptional())
return true;
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 53471de..c761934 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -119,8 +119,9 @@
// Don't break self-loops.
if (PredBB == BB) return false;
- // Don't break invokes.
- if (isa<InvokeInst>(PredBB->getTerminator())) return false;
+ // Don't break unwinding instructions.
+ if (PredBB->getTerminator()->isExceptional())
+ return false;
succ_iterator SI(succ_begin(PredBB)), SE(succ_end(PredBB));
BasicBlock *OnlySucc = BB;
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 5608557..e1788c9 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -283,8 +283,9 @@
const TargetLibraryInfo *TLI) {
if (!I->use_empty() || isa<TerminatorInst>(I)) return false;
- // We don't want the landingpad instruction removed by anything this general.
- if (isa<LandingPadInst>(I))
+ // We don't want the landingpad-like instructions removed by anything this
+ // general.
+ if (I->isEHBlock())
return false;
// We don't want debug info removed by anything this general, unless