diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-08-15 02:46:08 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-08-15 02:46:08 +0000 |
| commit | 0bc0eef71c09ddc0c7ef73a0dc54a7875c965c03 (patch) | |
| tree | a785179c274e965ce43e8f3a83f13ffd05b5e1f6 /llvm/lib/IR | |
| parent | 5567bafe93d8dfce39c4f9fa909165ef9ff0c30f (diff) | |
| download | bcm5719-llvm-0bc0eef71c09ddc0c7ef73a0dc54a7875c965c03.tar.gz bcm5719-llvm-0bc0eef71c09ddc0c7ef73a0dc54a7875c965c03.zip | |
[IR] Give catchret an optional 'return value' operand
Some personality routines require funclet exit points to be clearly
marked, this is done by producing a token at the funclet pad and
consuming it at the corresponding ret instruction. CleanupReturnInst
already had a spot for this operand but CatchReturnInst did not.
Other personality routines don't need to use this which is why it has
been made optional.
llvm-svn: 245149
Diffstat (limited to 'llvm/lib/IR')
| -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 |
3 files changed, 52 insertions, 21 deletions
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 { |

