summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/CaptureTracking.cpp5
-rw-r--r--llvm/lib/Analysis/EHPersonalities.cpp65
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp6
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp8
-rw-r--r--llvm/lib/Analysis/ScalarEvolutionExpander.cpp10
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp3
6 files changed, 80 insertions, 17 deletions
diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp
index c717a8ee2e6..1add2fa7756 100644
--- a/llvm/lib/Analysis/CaptureTracking.cpp
+++ b/llvm/lib/Analysis/CaptureTracking.cpp
@@ -80,12 +80,11 @@ namespace {
if (BB == BeforeHere->getParent()) {
// 'I' dominates 'BeforeHere' => not safe to prune.
//
- // The value defined by an invoke/catchpad dominates an instruction only
+ // The value defined by an invoke dominates an instruction only
// if it dominates every instruction in UseBB. A PHI is dominated only
// if the instruction dominates every possible use in the UseBB. Since
// UseBB == BB, avoid pruning.
- if (isa<InvokeInst>(BeforeHere) || isa<CatchPadInst>(BeforeHere) ||
- isa<PHINode>(I) || I == BeforeHere)
+ if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(I) || I == BeforeHere)
return false;
if (!OrderedBB->dominates(BeforeHere, I))
return false;
diff --git a/llvm/lib/Analysis/EHPersonalities.cpp b/llvm/lib/Analysis/EHPersonalities.cpp
index 1d1b5fe11f6..c95fcee13b8 100644
--- a/llvm/lib/Analysis/EHPersonalities.cpp
+++ b/llvm/lib/Analysis/EHPersonalities.cpp
@@ -9,7 +9,11 @@
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/Debug.h"
using namespace llvm;
/// See if the given exception handling personality function is one that we
@@ -39,3 +43,64 @@ bool llvm::canSimplifyInvokeNoUnwind(const Function *F) {
// implies that the function does not throw synchronous exceptions.
return !isAsynchronousEHPersonality(Personality);
}
+
+DenseMap<BasicBlock *, ColorVector> llvm::colorEHFunclets(Function &F) {
+ SmallVector<std::pair<BasicBlock *, BasicBlock *>, 16> Worklist;
+ BasicBlock *EntryBlock = &F.getEntryBlock();
+ DenseMap<BasicBlock *, ColorVector> BlockColors;
+
+ // Build up the color map, which maps each block to its set of 'colors'.
+ // For any block B the "colors" of B are the set of funclets F (possibly
+ // including a root "funclet" representing the main function) such that
+ // F will need to directly contain B or a copy of B (where the term "directly
+ // contain" is used to distinguish from being "transitively contained" in
+ // a nested funclet).
+ //
+ // Note: Despite not being funclets in the truest sense, terminatepad and
+ // catchswitch are considered to belong to their own funclet for the purposes
+ // of coloring.
+
+ DEBUG_WITH_TYPE("winehprepare-coloring", dbgs() << "\nColoring funclets for "
+ << F.getName() << "\n");
+
+ Worklist.push_back({EntryBlock, EntryBlock});
+
+ while (!Worklist.empty()) {
+ BasicBlock *Visiting;
+ BasicBlock *Color;
+ std::tie(Visiting, Color) = Worklist.pop_back_val();
+ DEBUG_WITH_TYPE("winehprepare-coloring",
+ dbgs() << "Visiting " << Visiting->getName() << ", "
+ << Color->getName() << "\n");
+ Instruction *VisitingHead = Visiting->getFirstNonPHI();
+ if (VisitingHead->isEHPad()) {
+ // Mark this funclet head as a member of itself.
+ Color = Visiting;
+ }
+ // Note that this is a member of the given color.
+ ColorVector &Colors = BlockColors[Visiting];
+ if (std::find(Colors.begin(), Colors.end(), Color) == Colors.end())
+ Colors.push_back(Color);
+ else
+ continue;
+
+ DEBUG_WITH_TYPE("winehprepare-coloring",
+ dbgs() << " Assigned color \'" << Color->getName()
+ << "\' to block \'" << Visiting->getName()
+ << "\'.\n");
+
+ BasicBlock *SuccColor = Color;
+ TerminatorInst *Terminator = Visiting->getTerminator();
+ if (auto *CatchRet = dyn_cast<CatchReturnInst>(Terminator)) {
+ Value *ParentPad = CatchRet->getParentPad();
+ if (isa<ConstantTokenNone>(ParentPad))
+ SuccColor = EntryBlock;
+ else
+ SuccColor = cast<Instruction>(ParentPad)->getParent();
+ }
+
+ for (BasicBlock *Succ : successors(Visiting))
+ Worklist.push_back({Succ, SuccColor});
+ }
+ return BlockColors;
+}
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 0bd18c1a35c..db17d886e4b 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -122,10 +122,10 @@ static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
return DT->dominates(I, P);
}
- // Otherwise, if the instruction is in the entry block, and is not an invoke,
- // and is not a catchpad, then it obviously dominates all phi nodes.
+ // Otherwise, if the instruction is in the entry block and is not an invoke,
+ // then it obviously dominates all phi nodes.
if (I->getParent() == &I->getParent()->getParent()->getEntryBlock() &&
- !isa<InvokeInst>(I) && !isa<CatchPadInst>(I))
+ !isa<InvokeInst>(I))
return true;
return false;
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 67a82b192e5..07fd6a2ae70 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -227,9 +227,15 @@ bool Loop::isSafeToClone() const {
if (isa<IndirectBrInst>((*I)->getTerminator()))
return false;
- if (const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator()))
+ if (const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator())) {
if (II->cannotDuplicate())
return false;
+ // Return false if any loop blocks contain invokes to EH-pads other than
+ // landingpads; we don't know how to split those edges yet.
+ auto *FirstNonPHI = II->getUnwindDest()->getFirstNonPHI();
+ if (FirstNonPHI->isEHPad() && !isa<LandingPadInst>(FirstNonPHI))
+ return false;
+ }
for (BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); BI != BE; ++BI) {
if (const CallInst *CI = dyn_cast<CallInst>(BI)) {
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
index abfcfbafb32..bcbf35b046b 100644
--- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -91,22 +91,16 @@ static BasicBlock::iterator findInsertPointAfter(Instruction *I,
BasicBlock::iterator IP = ++I->getIterator();
if (auto *II = dyn_cast<InvokeInst>(I))
IP = II->getNormalDest()->begin();
- if (auto *CPI = dyn_cast<CatchPadInst>(I))
- IP = CPI->getNormalDest()->begin();
while (isa<PHINode>(IP))
++IP;
while (IP->isEHPad()) {
- if (isa<LandingPadInst>(IP) || isa<CleanupPadInst>(IP)) {
+ if (isa<FuncletPadInst>(IP) || isa<LandingPadInst>(IP)) {
++IP;
} else if (auto *TPI = dyn_cast<TerminatePadInst>(IP)) {
IP = TPI->getUnwindDest()->getFirstNonPHI()->getIterator();
- } else if (auto *CEPI = dyn_cast<CatchEndPadInst>(IP)) {
- IP = CEPI->getUnwindDest()->getFirstNonPHI()->getIterator();
- } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(IP)) {
- IP = CEPI->getUnwindDest()->getFirstNonPHI()->getIterator();
- } else if (isa<CatchPadInst>(IP)) {
+ } else if (isa<CatchSwitchInst>(IP)) {
IP = MustDominate->getFirstInsertionPt();
} else {
llvm_unreachable("unexpected eh pad!");
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index b2a1034eeaa..4a228c30a93 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3431,11 +3431,10 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V,
case Instruction::AtomicCmpXchg:
case Instruction::LandingPad:
case Instruction::Resume:
+ case Instruction::CatchSwitch:
case Instruction::CatchPad:
- case Instruction::CatchEndPad:
case Instruction::CatchRet:
case Instruction::CleanupPad:
- case Instruction::CleanupEndPad:
case Instruction::CleanupRet:
case Instruction::TerminatePad:
return false; // Misc instructions which have effects
OpenPOWER on IntegriCloud