diff options
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 66 | ||||
-rw-r--r-- | llvm/lib/IR/Dominators.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/IR/Instruction.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 347 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 155 |
5 files changed, 249 insertions, 356 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index e41815aafa8..fbb27773c11 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2890,19 +2890,36 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(LPI->getClause(i), true); } - } else if (const auto *CPI = dyn_cast<CatchPadInst>(&I)) { + } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(&I)) { + Out << " within "; + writeOperand(CatchSwitch->getParentPad(), /*PrintType=*/false); Out << " ["; - for (unsigned Op = 0, NumOps = CPI->getNumArgOperands(); Op < NumOps; + unsigned Op = 0; + for (const BasicBlock *PadBB : CatchSwitch->handlers()) { + if (Op > 0) + Out << ", "; + writeOperand(PadBB, /*PrintType=*/true); + ++Op; + } + Out << "] unwind "; + if (const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest()) + writeOperand(UnwindDest, /*PrintType=*/true); + else + Out << "to caller"; + } else if (const auto *FPI = dyn_cast<FuncletPadInst>(&I)) { + Out << " within "; + writeOperand(FPI->getParentPad(), /*PrintType=*/false); + Out << " ["; + for (unsigned Op = 0, NumOps = FPI->getNumArgOperands(); Op < NumOps; ++Op) { if (Op > 0) Out << ", "; - writeOperand(CPI->getArgOperand(Op), /*PrintType=*/true); + writeOperand(FPI->getArgOperand(Op), /*PrintType=*/true); } - Out << "]\n to "; - writeOperand(CPI->getNormalDest(), /*PrintType=*/true); - Out << " unwind "; - writeOperand(CPI->getUnwindDest(), /*PrintType=*/true); + Out << ']'; } else if (const auto *TPI = dyn_cast<TerminatePadInst>(&I)) { + Out << " within "; + writeOperand(TPI->getParentPad(), /*PrintType=*/false); Out << " ["; for (unsigned Op = 0, NumOps = TPI->getNumArgOperands(); Op < NumOps; ++Op) { @@ -2915,44 +2932,21 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(TPI->getUnwindDest(), /*PrintType=*/true); else Out << "to caller"; - } else if (const auto *CPI = dyn_cast<CleanupPadInst>(&I)) { - Out << " ["; - for (unsigned Op = 0, NumOps = CPI->getNumOperands(); Op < NumOps; ++Op) { - if (Op > 0) - Out << ", "; - writeOperand(CPI->getOperand(Op), /*PrintType=*/true); - } - Out << "]"; } else if (isa<ReturnInst>(I) && !Operand) { Out << " void"; } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) { - Out << ' '; - writeOperand(CRI->getCatchPad(), /*PrintType=*/false); + Out << " from "; + writeOperand(CRI->getOperand(0), /*PrintType=*/false); Out << " to "; - writeOperand(CRI->getSuccessor(), /*PrintType=*/true); + writeOperand(CRI->getOperand(1), /*PrintType=*/true); } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) { - Out << ' '; - writeOperand(CRI->getCleanupPad(), /*PrintType=*/false); + Out << " from "; + writeOperand(CRI->getOperand(0), /*PrintType=*/false); Out << " unwind "; if (CRI->hasUnwindDest()) - writeOperand(CRI->getUnwindDest(), /*PrintType=*/true); - else - Out << "to caller"; - } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(&I)) { - Out << " unwind "; - if (CEPI->hasUnwindDest()) - writeOperand(CEPI->getUnwindDest(), /*PrintType=*/true); - else - Out << "to caller"; - } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(&I)) { - Out << ' '; - writeOperand(CEPI->getCleanupPad(), /*PrintType=*/false); - - Out << " unwind "; - if (CEPI->hasUnwindDest()) - writeOperand(CEPI->getUnwindDest(), /*PrintType=*/true); + writeOperand(CRI->getOperand(1), /*PrintType=*/true); else Out << "to caller"; } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) { diff --git a/llvm/lib/IR/Dominators.cpp b/llvm/lib/IR/Dominators.cpp index d94e31d4875..b9d4fb7de88 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/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<CatchPadInst>(Def) || isa<PHINode>(User)) + // 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. + if (isa<InvokeInst>(Def) || isa<PHINode>(User)) return dominates(Def, UseBB); if (DefBB != UseBB) @@ -126,18 +126,13 @@ bool DominatorTree::dominates(const Instruction *Def, if (DefBB == UseBB) return false; - // Invoke/CatchPad results are only usable in the normal destination, not in - // the exceptional destination. + // Invoke 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); - } return dominates(DefBB, UseBB); } @@ -239,8 +234,8 @@ bool DominatorTree::dominates(const Instruction *Def, const Use &U) const { if (!isReachableFromEntry(DefBB)) return false; - // Invoke/CatchPad instructions define their return values on the edges - // to their normal successors, so we have to handle them specially. + // Invoke 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 // walk the block in any case. @@ -249,11 +244,6 @@ 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/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 7bd50328b12..ce2e1d8c02b 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -202,11 +202,10 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Invoke: return "invoke"; case Resume: return "resume"; case Unreachable: return "unreachable"; - case CleanupEndPad: return "cleanupendpad"; case CleanupRet: return "cleanupret"; - case CatchEndPad: return "catchendpad"; case CatchRet: return "catchret"; case CatchPad: return "catchpad"; + case CatchSwitch: return "catchswitch"; case TerminatePad: return "terminatepad"; // Standard binary operators... @@ -476,10 +475,8 @@ bool Instruction::mayThrow() const { return !CI->doesNotThrow(); if (const auto *CRI = dyn_cast<CleanupReturnInst>(this)) return CRI->unwindsToCaller(); - if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(this)) - return CEPI->unwindsToCaller(); - if (const auto *CEPI = dyn_cast<CatchEndPadInst>(this)) - return CEPI->unwindsToCaller(); + if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(this)) + return CatchSwitch->unwindsToCaller(); if (const auto *TPI = dyn_cast<TerminatePadInst>(this)) return TPI->unwindsToCaller(); return isa<ResumeInst>(this); diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 11c55865135..82eb1e0f2f7 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -764,61 +764,6 @@ BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const { } //===----------------------------------------------------------------------===// -// CleanupEndPadInst Implementation -//===----------------------------------------------------------------------===// - -CleanupEndPadInst::CleanupEndPadInst(const CleanupEndPadInst &CEPI) - : TerminatorInst(CEPI.getType(), Instruction::CleanupEndPad, - OperandTraits<CleanupEndPadInst>::op_end(this) - - CEPI.getNumOperands(), - CEPI.getNumOperands()) { - setInstructionSubclassData(CEPI.getSubclassDataFromInstruction()); - setCleanupPad(CEPI.getCleanupPad()); - if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) - setUnwindDest(UnwindDest); -} - -void CleanupEndPadInst::init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB) { - setCleanupPad(CleanupPad); - if (UnwindBB) { - setInstructionSubclassData(getSubclassDataFromInstruction() | 1); - setUnwindDest(UnwindBB); - } -} - -CleanupEndPadInst::CleanupEndPadInst(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, unsigned Values, - Instruction *InsertBefore) - : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), - Instruction::CleanupEndPad, - OperandTraits<CleanupEndPadInst>::op_end(this) - Values, - Values, InsertBefore) { - init(CleanupPad, UnwindBB); -} - -CleanupEndPadInst::CleanupEndPadInst(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, unsigned Values, - BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), - Instruction::CleanupEndPad, - OperandTraits<CleanupEndPadInst>::op_end(this) - Values, - Values, InsertAtEnd) { - init(CleanupPad, UnwindBB); -} - -BasicBlock *CleanupEndPadInst::getSuccessorV(unsigned Idx) const { - assert(Idx == 0); - return getUnwindDest(); -} -unsigned CleanupEndPadInst::getNumSuccessorsV() const { - return getNumSuccessors(); -} -void CleanupEndPadInst::setSuccessorV(unsigned Idx, BasicBlock *B) { - assert(Idx == 0); - setUnwindDest(B); -} - -//===----------------------------------------------------------------------===// // CleanupReturnInst Implementation //===----------------------------------------------------------------------===// @@ -828,23 +773,22 @@ CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI) CRI.getNumOperands(), CRI.getNumOperands()) { setInstructionSubclassData(CRI.getSubclassDataFromInstruction()); - Op<-1>() = CRI.Op<-1>(); + Op<0>() = CRI.Op<0>(); if (CRI.hasUnwindDest()) - Op<-2>() = CRI.Op<-2>(); + Op<1>() = CRI.Op<1>(); } -void CleanupReturnInst::init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB) { +void CleanupReturnInst::init(Value *CleanupPad, BasicBlock *UnwindBB) { if (UnwindBB) setInstructionSubclassData(getSubclassDataFromInstruction() | 1); - Op<-1>() = CleanupPad; + Op<0>() = CleanupPad; if (UnwindBB) - Op<-2>() = UnwindBB; + Op<1>() = UnwindBB; } -CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, unsigned Values, - Instruction *InsertBefore) +CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, + unsigned Values, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), Instruction::CleanupRet, OperandTraits<CleanupReturnInst>::op_end(this) - Values, @@ -852,9 +796,8 @@ CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad, init(CleanupPad, UnwindBB); } -CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, unsigned Values, - BasicBlock *InsertAtEnd) +CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, + unsigned Values, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()), Instruction::CleanupRet, OperandTraits<CleanupReturnInst>::op_end(this) - Values, @@ -875,58 +818,9 @@ void CleanupReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) { } //===----------------------------------------------------------------------===// -// CatchEndPadInst Implementation -//===----------------------------------------------------------------------===// - -CatchEndPadInst::CatchEndPadInst(const CatchEndPadInst &CRI) - : TerminatorInst(CRI.getType(), Instruction::CatchEndPad, - OperandTraits<CatchEndPadInst>::op_end(this) - - CRI.getNumOperands(), - CRI.getNumOperands()) { - setInstructionSubclassData(CRI.getSubclassDataFromInstruction()); - if (BasicBlock *UnwindDest = CRI.getUnwindDest()) - setUnwindDest(UnwindDest); -} - -void CatchEndPadInst::init(BasicBlock *UnwindBB) { - if (UnwindBB) { - setInstructionSubclassData(getSubclassDataFromInstruction() | 1); - setUnwindDest(UnwindBB); - } -} - -CatchEndPadInst::CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, - unsigned Values, Instruction *InsertBefore) - : TerminatorInst(Type::getVoidTy(C), Instruction::CatchEndPad, - OperandTraits<CatchEndPadInst>::op_end(this) - Values, - Values, InsertBefore) { - init(UnwindBB); -} - -CatchEndPadInst::CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, - unsigned Values, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getVoidTy(C), Instruction::CatchEndPad, - OperandTraits<CatchEndPadInst>::op_end(this) - Values, - Values, InsertAtEnd) { - init(UnwindBB); -} - -BasicBlock *CatchEndPadInst::getSuccessorV(unsigned Idx) const { - assert(Idx == 0); - return getUnwindDest(); -} -unsigned CatchEndPadInst::getNumSuccessorsV() const { - return getNumSuccessors(); -} -void CatchEndPadInst::setSuccessorV(unsigned Idx, BasicBlock *B) { - assert(Idx == 0); - setUnwindDest(B); -} - -//===----------------------------------------------------------------------===// // CatchReturnInst Implementation //===----------------------------------------------------------------------===// -void CatchReturnInst::init(CatchPadInst *CatchPad, BasicBlock *BB) { +void CatchReturnInst::init(Value *CatchPad, BasicBlock *BB) { Op<0>() = CatchPad; Op<1>() = BB; } @@ -938,7 +832,7 @@ CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI) Op<1>() = CRI.Op<1>(); } -CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, +CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore) : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, OperandTraits<CatchReturnInst>::op_begin(this), 2, @@ -946,7 +840,7 @@ CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, init(CatchPad, BB); } -CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, +CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd) : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, OperandTraits<CatchReturnInst>::op_begin(this), 2, @@ -967,64 +861,136 @@ void CatchReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) { } //===----------------------------------------------------------------------===// -// CatchPadInst Implementation +// CatchSwitchInst Implementation //===----------------------------------------------------------------------===// -void CatchPadInst::init(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, const Twine &NameStr) { - assert(getNumOperands() == 2 + Args.size() && "NumOperands not set up?"); - Op<-2>() = IfNormal; - Op<-1>() = IfException; - std::copy(Args.begin(), Args.end(), op_begin()); + +CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumReservedValues, + const Twine &NameStr, + Instruction *InsertBefore) + : TerminatorInst(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0, + InsertBefore) { + if (UnwindDest) + ++NumReservedValues; + init(ParentPad, UnwindDest, NumReservedValues + 1); setName(NameStr); } -CatchPadInst::CatchPadInst(const CatchPadInst &CPI) - : TerminatorInst(CPI.getType(), Instruction::CatchPad, - OperandTraits<CatchPadInst>::op_end(this) - - CPI.getNumOperands(), - CPI.getNumOperands()) { - std::copy(CPI.op_begin(), CPI.op_end(), op_begin()); +CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumReservedValues, + const Twine &NameStr, BasicBlock *InsertAtEnd) + : TerminatorInst(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0, + InsertAtEnd) { + if (UnwindDest) + ++NumReservedValues; + init(ParentPad, UnwindDest, NumReservedValues + 1); + setName(NameStr); } -CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, unsigned Values, - const Twine &NameStr, Instruction *InsertBefore) - : TerminatorInst(Type::getTokenTy(IfNormal->getContext()), - Instruction::CatchPad, - OperandTraits<CatchPadInst>::op_end(this) - Values, Values, - InsertBefore) { - init(IfNormal, IfException, Args, NameStr); +CatchSwitchInst::CatchSwitchInst(const CatchSwitchInst &CSI) + : TerminatorInst(CSI.getType(), Instruction::CatchSwitch, nullptr, + CSI.getNumOperands()) { + init(CSI.getParentPad(), CSI.getUnwindDest(), CSI.getNumOperands()); + setNumHungOffUseOperands(ReservedSpace); + Use *OL = getOperandList(); + const Use *InOL = CSI.getOperandList(); + for (unsigned I = 1, E = ReservedSpace; I != E; ++I) + OL[I] = InOL[I]; } -CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef<Value *> Args, unsigned Values, - const Twine &NameStr, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getTokenTy(IfNormal->getContext()), - Instruction::CatchPad, - OperandTraits<CatchPadInst>::op_end(this) - Values, Values, - InsertAtEnd) { - init(IfNormal, IfException, Args, NameStr); +void CatchSwitchInst::init(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumReservedValues) { + assert(ParentPad && NumReservedValues); + + ReservedSpace = NumReservedValues; + setNumHungOffUseOperands(UnwindDest ? 2 : 1); + allocHungoffUses(ReservedSpace); + + Op<0>() = ParentPad; + if (UnwindDest) { + setInstructionSubclassData(getSubclassDataFromInstruction() | 1); + setUnwindDest(UnwindDest); + } } -BasicBlock *CatchPadInst::getSuccessorV(unsigned Idx) const { - return getSuccessor(Idx); +/// growOperands - grow operands - This grows the operand list in response to a +/// push_back style of operation. This grows the number of ops by 2 times. +void CatchSwitchInst::growOperands(unsigned Size) { + unsigned NumOperands = getNumOperands(); + assert(NumOperands >= 1); + if (ReservedSpace >= NumOperands + Size) + return; + ReservedSpace = (NumOperands + Size / 2) * 2; + growHungoffUses(ReservedSpace); +} + +void CatchSwitchInst::addHandler(BasicBlock *Handler) { + unsigned OpNo = getNumOperands(); + growOperands(1); + assert(OpNo < ReservedSpace && "Growing didn't work!"); + setNumHungOffUseOperands(getNumOperands() + 1); + getOperandList()[OpNo] = Handler; +} + +BasicBlock *CatchSwitchInst::getSuccessorV(unsigned idx) const { + return getSuccessor(idx); } -unsigned CatchPadInst::getNumSuccessorsV() const { +unsigned CatchSwitchInst::getNumSuccessorsV() const { return getNumSuccessors(); } -void CatchPadInst::setSuccessorV(unsigned Idx, BasicBlock *B) { - return setSuccessor(Idx, B); +void CatchSwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) { + setSuccessor(idx, B); +} + +//===----------------------------------------------------------------------===// +// FuncletPadInst Implementation +//===----------------------------------------------------------------------===// +void FuncletPadInst::init(Value *ParentPad, ArrayRef<Value *> Args, + const Twine &NameStr) { + assert(getNumOperands() == 1 + Args.size() && "NumOperands not set up?"); + std::copy(Args.begin(), Args.end(), op_begin()); + setParentPad(ParentPad); + setName(NameStr); +} + +FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI) + : Instruction(FPI.getType(), FPI.getOpcode(), + OperandTraits<FuncletPadInst>::op_end(this) - + FPI.getNumOperands(), + FPI.getNumOperands()) { + std::copy(FPI.op_begin(), FPI.op_end(), op_begin()); + setParentPad(FPI.getParentPad()); +} + +FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, + ArrayRef<Value *> Args, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore) + : Instruction(ParentPad->getType(), Op, + OperandTraits<FuncletPadInst>::op_end(this) - Values, Values, + InsertBefore) { + init(ParentPad, Args, NameStr); +} + +FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, + ArrayRef<Value *> Args, unsigned Values, + const Twine &NameStr, BasicBlock *InsertAtEnd) + : Instruction(ParentPad->getType(), Op, + OperandTraits<FuncletPadInst>::op_end(this) - Values, Values, + InsertAtEnd) { + init(ParentPad, Args, NameStr); } //===----------------------------------------------------------------------===// // TerminatePadInst Implementation //===----------------------------------------------------------------------===// -void TerminatePadInst::init(BasicBlock *BB, ArrayRef<Value *> Args) { - if (BB) +void TerminatePadInst::init(Value *ParentPad, BasicBlock *BB, + ArrayRef<Value *> Args) { + if (BB) { setInstructionSubclassData(getSubclassDataFromInstruction() | 1); - if (BB) - Op<-1>() = BB; - std::copy(Args.begin(), Args.end(), op_begin()); + setUnwindDest(BB); + } + std::copy(Args.begin(), Args.end(), arg_begin()); + setParentPad(ParentPad); } TerminatePadInst::TerminatePadInst(const TerminatePadInst &TPI) @@ -1036,22 +1002,24 @@ TerminatePadInst::TerminatePadInst(const TerminatePadInst &TPI) std::copy(TPI.op_begin(), TPI.op_end(), op_begin()); } -TerminatePadInst::TerminatePadInst(LLVMContext &C, BasicBlock *BB, +TerminatePadInst::TerminatePadInst(Value *ParentPad, BasicBlock *BB, ArrayRef<Value *> Args, unsigned Values, Instruction *InsertBefore) - : TerminatorInst(Type::getVoidTy(C), Instruction::TerminatePad, + : TerminatorInst(Type::getVoidTy(ParentPad->getContext()), + Instruction::TerminatePad, OperandTraits<TerminatePadInst>::op_end(this) - Values, Values, InsertBefore) { - init(BB, Args); + init(ParentPad, BB, Args); } -TerminatePadInst::TerminatePadInst(LLVMContext &C, BasicBlock *BB, +TerminatePadInst::TerminatePadInst(Value *ParentPad, BasicBlock *BB, ArrayRef<Value *> Args, unsigned Values, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getVoidTy(C), Instruction::TerminatePad, + : TerminatorInst(Type::getVoidTy(ParentPad->getContext()), + Instruction::TerminatePad, OperandTraits<TerminatePadInst>::op_end(this) - Values, Values, InsertAtEnd) { - init(BB, Args); + init(ParentPad, BB, Args); } BasicBlock *TerminatePadInst::getSuccessorV(unsigned Idx) const { @@ -1067,39 +1035,6 @@ void TerminatePadInst::setSuccessorV(unsigned Idx, BasicBlock *B) { } //===----------------------------------------------------------------------===// -// CleanupPadInst Implementation -//===----------------------------------------------------------------------===// -void CleanupPadInst::init(ArrayRef<Value *> Args, const Twine &NameStr) { - assert(getNumOperands() == Args.size() && "NumOperands not set up?"); - std::copy(Args.begin(), Args.end(), op_begin()); - setName(NameStr); -} - -CleanupPadInst::CleanupPadInst(const CleanupPadInst &CPI) - : Instruction(CPI.getType(), Instruction::CleanupPad, - OperandTraits<CleanupPadInst>::op_end(this) - - CPI.getNumOperands(), - CPI.getNumOperands()) { - std::copy(CPI.op_begin(), CPI.op_end(), op_begin()); -} - -CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args, - const Twine &NameStr, Instruction *InsertBefore) - : Instruction(Type::getTokenTy(C), Instruction::CleanupPad, - OperandTraits<CleanupPadInst>::op_end(this) - Args.size(), - Args.size(), InsertBefore) { - init(Args, NameStr); -} - -CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args, - const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(Type::getTokenTy(C), Instruction::CleanupPad, - OperandTraits<CleanupPadInst>::op_end(this) - Args.size(), - Args.size(), InsertAtEnd) { - init(Args, NameStr); -} - -//===----------------------------------------------------------------------===// // UnreachableInst Implementation //===----------------------------------------------------------------------===// @@ -4074,32 +4009,24 @@ InvokeInst *InvokeInst::cloneImpl() const { ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); } -CleanupEndPadInst *CleanupEndPadInst::cloneImpl() const { - return new (getNumOperands()) CleanupEndPadInst(*this); -} - CleanupReturnInst *CleanupReturnInst::cloneImpl() const { return new (getNumOperands()) CleanupReturnInst(*this); } -CatchEndPadInst *CatchEndPadInst::cloneImpl() const { - return new (getNumOperands()) CatchEndPadInst(*this); -} - CatchReturnInst *CatchReturnInst::cloneImpl() const { return new (getNumOperands()) CatchReturnInst(*this); } -CatchPadInst *CatchPadInst::cloneImpl() const { - return new (getNumOperands()) CatchPadInst(*this); +CatchSwitchInst *CatchSwitchInst::cloneImpl() const { + return new CatchSwitchInst(*this); } -TerminatePadInst *TerminatePadInst::cloneImpl() const { - return new (getNumOperands()) TerminatePadInst(*this); +FuncletPadInst *FuncletPadInst::cloneImpl() const { + return new (getNumOperands()) FuncletPadInst(*this); } -CleanupPadInst *CleanupPadInst::cloneImpl() const { - return new (getNumOperands()) CleanupPadInst(*this); +TerminatePadInst *TerminatePadInst::cloneImpl() const { + return new (getNumOperands()) TerminatePadInst(*this); } UnreachableInst *UnreachableInst::cloneImpl() const { diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 58f9c5388bf..9862bfcc4fa 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -399,9 +399,9 @@ private: void visitEHPadPredecessors(Instruction &I); void visitLandingPadInst(LandingPadInst &LPI); void visitCatchPadInst(CatchPadInst &CPI); - void visitCatchEndPadInst(CatchEndPadInst &CEPI); + void visitCatchReturnInst(CatchReturnInst &CatchReturn); void visitCleanupPadInst(CleanupPadInst &CPI); - void visitCleanupEndPadInst(CleanupEndPadInst &CEPI); + void visitCatchSwitchInst(CatchSwitchInst &CatchSwitch); void visitCleanupReturnInst(CleanupReturnInst &CRI); void visitTerminatePadInst(TerminatePadInst &TPI); @@ -2885,25 +2885,24 @@ void Verifier::visitEHPadPredecessors(Instruction &I) { } return; } + if (auto *CPI = dyn_cast<CatchPadInst>(&I)) { + if (!pred_empty(BB)) + Assert(BB->getUniquePredecessor() == CPI->getCatchSwitch()->getParent(), + "Block containg CatchPadInst must be jumped to " + "only by its catchswitch.", + CPI); + return; + } for (BasicBlock *PredBB : predecessors(BB)) { TerminatorInst *TI = PredBB->getTerminator(); - if (auto *II = dyn_cast<InvokeInst>(TI)) + if (auto *II = dyn_cast<InvokeInst>(TI)) { Assert(II->getUnwindDest() == BB && II->getNormalDest() != BB, "EH pad must be jumped to via an unwind edge", &I, II); - else if (auto *CPI = dyn_cast<CatchPadInst>(TI)) - Assert(CPI->getUnwindDest() == BB && CPI->getNormalDest() != BB, - "EH pad must be jumped to via an unwind edge", &I, CPI); - else if (isa<CatchEndPadInst>(TI)) - ; - else if (isa<CleanupReturnInst>(TI)) - ; - else if (isa<CleanupEndPadInst>(TI)) - ; - else if (isa<TerminatePadInst>(TI)) - ; - else + } else if (!isa<CleanupReturnInst>(TI) && !isa<TerminatePadInst>(TI) && + !isa<CatchSwitchInst>(TI)) { Assert(false, "EH pad must be jumped to via an unwind edge", &I, TI); + } } } @@ -2952,67 +2951,29 @@ void Verifier::visitCatchPadInst(CatchPadInst &CPI) { visitEHPadPredecessors(CPI); BasicBlock *BB = CPI.getParent(); + Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), "CatchPadInst needs to be in a function with a personality.", &CPI); + Assert(isa<CatchSwitchInst>(CPI.getParentPad()), + "CatchPadInst needs to be directly nested in a CatchSwitchInst.", + CPI.getParentPad()); + // The catchpad instruction must be the first non-PHI instruction in the // block. Assert(BB->getFirstNonPHI() == &CPI, - "CatchPadInst not the first non-PHI instruction in the block.", - &CPI); + "CatchPadInst not the first non-PHI instruction in the block.", &CPI); - if (!BB->getSinglePredecessor()) - for (BasicBlock *PredBB : predecessors(BB)) { - Assert(!isa<CatchPadInst>(PredBB->getTerminator()), - "CatchPadInst with CatchPadInst predecessor cannot have any other " - "predecessors.", - &CPI); - } - - BasicBlock *UnwindDest = CPI.getUnwindDest(); - Instruction *I = UnwindDest->getFirstNonPHI(); - Assert( - isa<CatchPadInst>(I) || isa<CatchEndPadInst>(I), - "CatchPadInst must unwind to a CatchPadInst or a CatchEndPadInst.", - &CPI); - - visitTerminatorInst(CPI); + visitInstruction(CPI); } -void Verifier::visitCatchEndPadInst(CatchEndPadInst &CEPI) { - visitEHPadPredecessors(CEPI); - - BasicBlock *BB = CEPI.getParent(); - Function *F = BB->getParent(); - Assert(F->hasPersonalityFn(), - "CatchEndPadInst needs to be in a function with a personality.", - &CEPI); - - // The catchendpad instruction must be the first non-PHI instruction in the - // block. - Assert(BB->getFirstNonPHI() == &CEPI, - "CatchEndPadInst not the first non-PHI instruction in the block.", - &CEPI); - - unsigned CatchPadsSeen = 0; - for (BasicBlock *PredBB : predecessors(BB)) - if (isa<CatchPadInst>(PredBB->getTerminator())) - ++CatchPadsSeen; - - Assert(CatchPadsSeen <= 1, "CatchEndPadInst must have no more than one " - "CatchPadInst predecessor.", - &CEPI); +void Verifier::visitCatchReturnInst(CatchReturnInst &CatchReturn) { + Assert(isa<CatchPadInst>(CatchReturn.getOperand(0)), + "CatchReturnInst needs to be provided a CatchPad", &CatchReturn, + CatchReturn.getOperand(0)); - if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) { - Instruction *I = UnwindDest->getFirstNonPHI(); - Assert( - I->isEHPad() && !isa<LandingPadInst>(I), - "CatchEndPad must unwind to an EH block which is not a landingpad.", - &CEPI); - } - - visitTerminatorInst(CEPI); + visitTerminatorInst(CatchReturn); } void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { @@ -3030,57 +2991,76 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { "CleanupPadInst not the first non-PHI instruction in the block.", &CPI); + auto *ParentPad = CPI.getParentPad(); + Assert(isa<CatchSwitchInst>(ParentPad) || isa<ConstantTokenNone>(ParentPad) || + isa<CleanupPadInst>(ParentPad) || isa<CatchPadInst>(ParentPad), + "CleanupPadInst has an invalid parent.", &CPI); + User *FirstUser = nullptr; BasicBlock *FirstUnwindDest = nullptr; for (User *U : CPI.users()) { BasicBlock *UnwindDest; if (CleanupReturnInst *CRI = dyn_cast<CleanupReturnInst>(U)) { UnwindDest = CRI->getUnwindDest(); + } else if (isa<CleanupPadInst>(U) || isa<CatchSwitchInst>(U) || + isa<TerminatePadInst>(U)) { + continue; } else { - UnwindDest = cast<CleanupEndPadInst>(U)->getUnwindDest(); + Assert(false, "bogus cleanuppad use", &CPI); } if (!FirstUser) { FirstUser = U; FirstUnwindDest = UnwindDest; } else { - Assert(UnwindDest == FirstUnwindDest, - "Cleanuprets/cleanupendpads from the same cleanuppad must " - "have the same unwind destination", - FirstUser, U); + Assert( + UnwindDest == FirstUnwindDest, + "cleanupret instructions from the same cleanuppad must have the same " + "unwind destination", + FirstUser, U); } } visitInstruction(CPI); } -void Verifier::visitCleanupEndPadInst(CleanupEndPadInst &CEPI) { - visitEHPadPredecessors(CEPI); +void Verifier::visitCatchSwitchInst(CatchSwitchInst &CatchSwitch) { + visitEHPadPredecessors(CatchSwitch); + + BasicBlock *BB = CatchSwitch.getParent(); - BasicBlock *BB = CEPI.getParent(); Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), - "CleanupEndPadInst needs to be in a function with a personality.", - &CEPI); + "CatchSwitchInst needs to be in a function with a personality.", + &CatchSwitch); - // The cleanupendpad instruction must be the first non-PHI instruction in the + // The catchswitch instruction must be the first non-PHI instruction in the // block. - Assert(BB->getFirstNonPHI() == &CEPI, - "CleanupEndPadInst not the first non-PHI instruction in the block.", - &CEPI); + Assert(BB->getFirstNonPHI() == &CatchSwitch, + "CatchSwitchInst not the first non-PHI instruction in the block.", + &CatchSwitch); - if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) { + if (BasicBlock *UnwindDest = CatchSwitch.getUnwindDest()) { Instruction *I = UnwindDest->getFirstNonPHI(); - Assert( - I->isEHPad() && !isa<LandingPadInst>(I), - "CleanupEndPad must unwind to an EH block which is not a landingpad.", - &CEPI); + Assert(I->isEHPad() && !isa<LandingPadInst>(I), + "CatchSwitchInst must unwind to an EH block which is not a " + "landingpad.", + &CatchSwitch); } - visitTerminatorInst(CEPI); + auto *ParentPad = CatchSwitch.getParentPad(); + Assert(isa<CatchSwitchInst>(ParentPad) || isa<ConstantTokenNone>(ParentPad) || + isa<CleanupPadInst>(ParentPad) || isa<CatchPadInst>(ParentPad), + "CatchSwitchInst has an invalid parent.", ParentPad); + + visitTerminatorInst(CatchSwitch); } void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) { + Assert(isa<CleanupPadInst>(CRI.getOperand(0)), + "CleanupReturnInst needs to be provided a CleanupPad", &CRI, + CRI.getOperand(0)); + if (BasicBlock *UnwindDest = CRI.getUnwindDest()) { Instruction *I = UnwindDest->getFirstNonPHI(); Assert(I->isEHPad() && !isa<LandingPadInst>(I), @@ -3115,6 +3095,11 @@ void Verifier::visitTerminatePadInst(TerminatePadInst &TPI) { &TPI); } + auto *ParentPad = TPI.getParentPad(); + Assert(isa<CatchSwitchInst>(ParentPad) || isa<ConstantTokenNone>(ParentPad) || + isa<CleanupPadInst>(ParentPad) || isa<CatchPadInst>(ParentPad), + "TerminatePadInst has an invalid parent.", ParentPad); + visitTerminatorInst(TPI); } |