diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/CaptureTracking.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/IR/Dominators.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CodeExtractor.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LCSSA.cpp | 11 |
12 files changed, 104 insertions, 42 deletions
diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp index fc23aa53d7c..de5ec29c857 100644 --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -80,11 +80,12 @@ namespace { if (BB == BeforeHere->getParent()) { // 'I' dominates 'BeforeHere' => not safe to prune. // - // 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 + // The value defined by an invoke/catchpad 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<PHINode>(I) || I == BeforeHere) + if (isa<InvokeInst>(BeforeHere) || isa<CatchPadInst>(BeforeHere) || + isa<PHINode>(I) || I == BeforeHere) return false; if (!OrderedBB->dominates(BeforeHere, I)) return false; diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index fa42b48b6cd..f9d4524f012 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -123,9 +123,9 @@ static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) { } // Otherwise, if the instruction is in the entry block, and is not an invoke, - // then it obviously dominates all phi nodes. + // and is not a catchpad, then it obviously dominates all phi nodes. if (I->getParent() == &I->getParent()->getParent()->getEntryBlock() && - !isa<InvokeInst>(I)) + !isa<InvokeInst>(I) && !isa<CatchPadInst>(I)) return true; return false; diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp index 42069d29403..7789423cf6c 100644 --- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp @@ -146,6 +146,8 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) { BasicBlock::iterator IP = I; ++IP; if (InvokeInst *II = dyn_cast<InvokeInst>(I)) IP = II->getNormalDest()->begin(); + if (CatchPadInst *CPI = dyn_cast<CatchPadInst>(I)) + IP = CPI->getNormalDest()->begin(); while (isa<PHINode>(IP) || isa<LandingPadInst>(IP)) ++IP; return ReuseOrCreateCast(I, Ty, Op, IP); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f098babb9f4..83bc33d0e6c 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5027,13 +5027,24 @@ bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { } /// ParseCatchRet -/// ::= 'catchret' TypeAndValue +/// ::= 'catchret' ('void' | TypeAndValue) 'to' TypeAndValue bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { + Type *RetTy = nullptr; + Value *RetVal = nullptr; + + if (ParseType(RetTy, /*AllowVoid=*/true)) + return true; + + if (!RetTy->isVoidTy()) + if (ParseValue(RetTy, RetVal, PFS)) + return true; + BasicBlock *BB; - if (ParseTypeAndBasicBlock(BB, PFS)) + if (ParseToken(lltok::kw_to, "expected 'to' in catchret") || + ParseTypeAndBasicBlock(BB, PFS)) return true; - Inst = CatchReturnInst::Create(BB); + Inst = CatchReturnInst::Create(BB, RetVal); return false; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 06935f7ab1b..b379e59236d 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3847,12 +3847,18 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { break; } case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#] - if (Record.size() != 1) + if (Record.size() != 1 && Record.size() != 3) return error("Invalid record"); - BasicBlock *BB = getBasicBlock(Record[0]); + unsigned Idx = 0; + BasicBlock *BB = getBasicBlock(Record[Idx++]); if (!BB) return error("Invalid record"); - I = CatchReturnInst::Create(BB); + Value *RetVal = nullptr; + if (Record.size() == 3 && + getValueTypePair(Record, Idx, NextValueNo, RetVal)) + return error("Invalid record"); + + I = CatchReturnInst::Create(BB, RetVal); InstructionList.push_back(I); break; } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 03650ec37b7..87b02e3dca4 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1867,6 +1867,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Code = bitc::FUNC_CODE_INST_CATCHRET; const auto &CRI = cast<CatchReturnInst>(I); Vals.push_back(VE.getValueID(CRI.getSuccessor())); + if (CRI.hasReturnValue()) + PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE); break; } case Instruction::CatchPad: { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 9ce384825f4..5ec111869f0 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2900,6 +2900,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << "]"; } else if (isa<ReturnInst>(I) && !Operand) { Out << " void"; + } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) { + if (CRI->hasReturnValue()) { + Out << ' '; + writeOperand(CRI->getReturnValue(), /*PrintType=*/true); + } else { + Out << " void"; + } + + Out << " to "; + writeOperand(CRI->getSuccessor(), /*PrintType=*/true); } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) { if (CRI->hasReturnValue()) { Out << ' '; diff --git a/llvm/lib/IR/Dominators.cpp b/llvm/lib/IR/Dominators.cpp index b6a8bbcbe5f..775bd92f2ed 100644 --- a/llvm/lib/IR/Dominators.cpp +++ b/llvm/lib/IR/Dominators.cpp @@ -91,11 +91,11 @@ bool DominatorTree::dominates(const Instruction *Def, if (Def == User) return false; - // The value defined by an invoke dominates an instruction only if + // The value defined by an invoke/catchpad 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. - if (isa<InvokeInst>(Def) || isa<PHINode>(User)) + if (isa<InvokeInst>(Def) || isa<CatchPadInst>(Def) || isa<PHINode>(User)) return dominates(Def, UseBB); if (DefBB != UseBB) @@ -126,15 +126,20 @@ bool DominatorTree::dominates(const Instruction *Def, if (DefBB == UseBB) return false; - const InvokeInst *II = dyn_cast<InvokeInst>(Def); - if (!II) - return dominates(DefBB, UseBB); + // Invoke/CatchPad results are only usable in the normal destination, not in + // the exceptional destination. + if (const auto *II = dyn_cast<InvokeInst>(Def)) { + BasicBlock *NormalDest = II->getNormalDest(); + BasicBlockEdge E(DefBB, NormalDest); + return dominates(E, UseBB); + } + if (const auto *CPI = dyn_cast<CatchPadInst>(Def)) { + BasicBlock *NormalDest = CPI->getNormalDest(); + BasicBlockEdge E(DefBB, NormalDest); + return dominates(E, UseBB); + } - // Invoke results are only usable in the normal destination, not in the - // exceptional destination. - BasicBlock *NormalDest = II->getNormalDest(); - BasicBlockEdge E(DefBB, NormalDest); - return dominates(E, UseBB); + return dominates(DefBB, UseBB); } bool DominatorTree::dominates(const BasicBlockEdge &BBE, @@ -232,7 +237,7 @@ bool DominatorTree::dominates(const Instruction *Def, const Use &U) const { if (!isReachableFromEntry(DefBB)) return false; - // Invoke instructions define their return values on the edges + // Invoke/CatchPad instructions define their return values on the edges // to their normal successors, so we have to handle them specially. // Among other things, this means they don't dominate anything in // their own block, except possibly a phi, so we don't need to @@ -242,6 +247,11 @@ bool DominatorTree::dominates(const Instruction *Def, const Use &U) const { BasicBlockEdge E(DefBB, NormalDest); return dominates(E, U); } + if (const auto *CPI = dyn_cast<CatchPadInst>(Def)) { + BasicBlock *NormalDest = CPI->getNormalDest(); + BasicBlockEdge E(DefBB, NormalDest); + return dominates(E, U); + } // If the def and use are in different blocks, do a simple CFG dominator // tree query. diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 79fb30e4734..46c799ece2c 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -797,27 +797,38 @@ void CatchEndPadInst::setSuccessorV(unsigned Idx, BasicBlock *B) { //===----------------------------------------------------------------------===// // CatchReturnInst Implementation //===----------------------------------------------------------------------===// +void CatchReturnInst::init(BasicBlock *BB, Value *RetVal) { + Op<-1>() = BB; + if (RetVal) + Op<-2>() = RetVal; +} CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI) : TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet, OperandTraits<CatchReturnInst>::op_end(this) - CRI.getNumOperands(), CRI.getNumOperands()) { - Op<0>() = CRI.Op<0>(); + Op<-1>() = CRI.Op<-1>(); + if (CRI.getNumOperands() != 1) { + assert(CRI.getNumOperands() == 2); + Op<-2>() = CRI.Op<-2>(); + } } -CatchReturnInst::CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore) +CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values, + Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, - OperandTraits<CatchReturnInst>::op_begin(this), 1, - InsertBefore) { - Op<0>() = BB; + OperandTraits<CatchReturnInst>::op_end(this) - Values, + Values, InsertBefore) { + init(BB, RetVal); } -CatchReturnInst::CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd) +CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values, + BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, - OperandTraits<CatchReturnInst>::op_begin(this), 1, - InsertAtEnd) { - Op<0>() = BB; + OperandTraits<CatchReturnInst>::op_end(this) - Values, + Values, InsertAtEnd) { + init(BB, RetVal); } BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const { @@ -3924,7 +3935,7 @@ CatchEndPadInst *CatchEndPadInst::cloneImpl() const { } CatchReturnInst *CatchReturnInst::cloneImpl() const { - return new (1) CatchReturnInst(*this); + return new (getNumOperands()) CatchReturnInst(*this); } CatchPadInst *CatchPadInst::cloneImpl() const { diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 1626548541f..21245864544 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -951,6 +951,8 @@ static Value *NegateValue(Value *V, Instruction *BI) { if (Instruction *InstInput = dyn_cast<Instruction>(V)) { if (InvokeInst *II = dyn_cast<InvokeInst>(InstInput)) { InsertPt = II->getNormalDest()->begin(); + } else if (auto *CPI = dyn_cast<CatchPadInst>(InstInput)) { + InsertPt = CPI->getNormalDest()->begin(); } else { InsertPt = InstInput; ++InsertPt; diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 896cff1bae9..e76a9d4ba2d 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -560,14 +560,20 @@ emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer, // Restore values just before we exit Function::arg_iterator OAI = OutputArgBegin; for (unsigned out = 0, e = outputs.size(); out != e; ++out) { - // For an invoke, the normal destination is the only one that is - // dominated by the result of the invocation + // For an invoke/catchpad, the normal destination is the only one + // that is dominated by the result of the invocation BasicBlock *DefBlock = cast<Instruction>(outputs[out])->getParent(); bool DominatesDef = true; - if (InvokeInst *Invoke = dyn_cast<InvokeInst>(outputs[out])) { - DefBlock = Invoke->getNormalDest(); + BasicBlock *NormalDest = nullptr; + if (auto *Invoke = dyn_cast<InvokeInst>(outputs[out])) + NormalDest = Invoke->getNormalDest(); + if (auto *CatchPad = dyn_cast<CatchPadInst>(outputs[out])) + NormalDest = CatchPad->getNormalDest(); + + if (NormalDest) { + DefBlock = NormalDest; // Make sure we are looking at the original successor block, not // at a newly inserted exit block, which won't be in the dominator diff --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp index 9d40b6989d6..d45944d47cf 100644 --- a/llvm/lib/Transforms/Utils/LCSSA.cpp +++ b/llvm/lib/Transforms/Utils/LCSSA.cpp @@ -82,14 +82,15 @@ static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, ++NumLCSSA; // We are applying the transformation - // Invoke instructions are special in that their result value is not available - // along their unwind edge. The code below tests to see whether DomBB - // dominates - // the value, so adjust DomBB to the normal destination block, which is - // effectively where the value is first usable. + // Invoke/CatchPad instructions are special in that their result value is not + // available along their unwind edge. The code below tests to see whether + // DomBB dominates the value, so adjust DomBB to the normal destination block, + // which is effectively where the value is first usable. BasicBlock *DomBB = Inst.getParent(); if (InvokeInst *Inv = dyn_cast<InvokeInst>(&Inst)) DomBB = Inv->getNormalDest(); + if (auto *CPI = dyn_cast<CatchPadInst>(&Inst)) + DomBB = CPI->getNormalDest(); DomTreeNode *DomNode = DT.getNode(DomBB); |