diff options
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/CaptureTracking.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Analysis/EHPersonalities.cpp | 65 | ||||
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopInfo.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 3 |
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 |