(original) (raw)

>From 610da73d6afb092cb2028056b6db35437701905b Mon Sep 17 00:00:00 2001 From: Peter Collingbourne pcc@google.com Date: Sat, 29 Mar 2014 22:21:49 -0700 Subject: [PATCH 1/3] Create UnwindPoint as a base class of InvokeInst --- include/llvm/IR/InstrTypes.h | 45 ++++++++++++++++++++++ include/llvm/IR/Instructions.h | 46 +++++++---------------- lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 4 +- lib/IR/AsmWriter.cpp | 11 +++--- lib/IR/Instructions.cpp | 23 ++++++++---- lib/IR/Verifier.cpp | 9 +++-- lib/Transforms/Scalar/SCCP.cpp | 4 +- test/Verifier/invoke.ll | 2 +- 8 files changed, 88 insertions(+), 56 deletions(-) diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index e1a5130..34375b1 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -24,6 +24,7 @@ namespace llvm { class LLVMContext; +class LandingPadInst; //===----------------------------------------------------------------------===// // TerminatorInst Class @@ -81,6 +82,50 @@ public: } }; +//===----------------------------------------------------------------------===// +// UnwindPoint Class +//===----------------------------------------------------------------------===// + +/// UnwindPoint models an instruction which may unwind to a specified landing +/// pad. +class UnwindPoint : public TerminatorInst { +private: + void init(BasicBlock *IfNormal, BasicBlock *IfException, + const Twine &NameStr); + +protected: + inline UnwindPoint(Type *Ty, Instruction::TermOps iType, Use *Ops, + unsigned NumOps, Instruction *InsertBefore = 0) + : TerminatorInst(Ty, iType, Ops, NumOps, InsertBefore) {} + + inline UnwindPoint(Type *Ty, Instruction::TermOps iType, Use *Ops, + unsigned NumOps, BasicBlock *InsertAtEnd) + : TerminatorInst(Ty, iType, Ops, NumOps, InsertAtEnd) {} + + // Out of line virtual method, so the vtable, etc has a home. + ~UnwindPoint(); + +public: + // get*Dest - Return the destination basic blocks... + BasicBlock *getNormalDest() const { + return getSuccessor(0); + } + BasicBlock *getUnwindDest() const { + return getSuccessor(1); + } + void setNormalDest(BasicBlock *B) { + setSuccessor(0, B); + } + void setUnwindDest(BasicBlock *B) { + setSuccessor(1, B); + } + + /// getLandingPadInst - Get the landingpad instruction from the landing pad + /// block (the unwind destination). + LandingPadInst *getLandingPadInst() const; + + unsigned getNumSuccessors() const { return 2; } +}; //===----------------------------------------------------------------------===// // UnaryInstruction Class diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 06d7287..bf72fd7 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -2903,7 +2903,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) /// InvokeInst - Invoke instruction. The SubclassData field is used to hold the /// calling convention of the call. /// -class InvokeInst : public TerminatorInst { +class InvokeInst : public UnwindPoint { AttributeSet AttributeList; InvokeInst(const InvokeInst &BI); void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, @@ -2964,6 +2964,16 @@ public: return iterator_range(op_begin(), op_end() - 3); } + BasicBlock *getSuccessor(unsigned i) const { + assert(i < 2 && "Successor # out of range for invoke!"); + return cast(*(&Op<-2>() + i)); + } + + void setSuccessor(unsigned idx, BasicBlock *NewSucc) { + assert(idx < 2 && "Successor # out of range for invoke!"); + *(&Op<-2>() + idx) = reinterpret_cast<value*>(NewSucc); + } + /// \brief Wrappers for getting the \c Use of a invoke argument. const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } @@ -3084,36 +3094,6 @@ public: Op<-3>() = Fn; } - // get*Dest - Return the destination basic blocks... - BasicBlock *getNormalDest() const { - return cast(Op<-2>()); - } - BasicBlock *getUnwindDest() const { - return cast(Op<-1>()); - } - void setNormalDest(BasicBlock *B) { - Op<-2>() = reinterpret_cast<value*>(B); - } - void setUnwindDest(BasicBlock *B) { - Op<-1>() = reinterpret_cast<value*>(B); - } - - /// getLandingPadInst - Get the landingpad instruction from the landing pad - /// block (the unwind destination). - LandingPadInst *getLandingPadInst() const; - - BasicBlock *getSuccessor(unsigned i) const { - assert(i < 2 && "Successor # out of range for invoke!"); - return i == 0 ? getNormalDest() : getUnwindDest(); - } - - void setSuccessor(unsigned idx, BasicBlock *NewSucc) { - assert(idx < 2 && "Successor # out of range for invoke!"); - *(&Op<-2>() + idx) = reinterpret_cast<value*>(NewSucc); - } - - unsigned getNumSuccessors() const { return 2; } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Invoke); @@ -3144,7 +3124,7 @@ InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) - : TerminatorInst(cast(cast(Func->getType()) + : UnwindPoint(cast(cast(Func->getType()) ->getElementType())->getReturnType(), Instruction::Invoke, OperandTraits::op_end(this) - Values, @@ -3155,7 +3135,7 @@ InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) - : TerminatorInst(cast(cast(Func->getType()) + : UnwindPoint(cast(cast(Func->getType()) ->getElementType())->getReturnType(), Instruction::Invoke, OperandTraits::op_end(this) - Values, diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 5f0006e..72de60f 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -217,8 +217,8 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // Mark landing pad blocks. for (BB = Fn->begin(); BB != EB; ++BB) - if (const InvokeInst *Invoke = dyn_cast(BB->getTerminator())) - MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad(); + if (const UnwindPoint *UP = dyn_cast(BB->getTerminator())) + MBBMap[UP->getSuccessor(1)]->setIsLandingPad(); } /// clear - Clear out all the function-specific state. This returns this diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index d4670e4..25ecf98 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1965,12 +1965,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ')'; if (PAL.hasAttributes(AttributeSet::FunctionIndex)) Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes()); - - Out << "\n to "; - writeOperand(II->getNormalDest(), true); - Out << " unwind "; - writeOperand(II->getUnwindDest(), true); - } else if (const AllocaInst *AI = dyn_cast(&I)) { Out << ' '; if (AI->isUsedWithInAlloca()) @@ -2051,6 +2045,11 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeAtomic(RMWI->getOrdering(), RMWI->getSynchScope()); } else if (const FenceInst *FI = dyn_cast(&I)) { writeAtomic(FI->getOrdering(), FI->getSynchScope()); + } else if (const UnwindPoint *UP = dyn_cast(&I)) { + Out << "\n to "; + writeOperand(UP->getNormalDest(), true); + Out << " unwind "; + writeOperand(UP->getUnwindDest(), true); } // Print Metadata info. diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index 3aa8413..646ac0b 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -46,6 +46,18 @@ TerminatorInst::~TerminatorInst() { } //===----------------------------------------------------------------------===// +// UnwindPoint Class +//===----------------------------------------------------------------------===// + +// Out of line virtual method, so the vtable, etc has a home. +UnwindPoint::~UnwindPoint() { +} + +LandingPadInst *UnwindPoint::getLandingPadInst() const { + return cast(getUnwindDest()->getFirstNonPHI()); +} + +//===----------------------------------------------------------------------===// // UnaryInstruction Class //===----------------------------------------------------------------------===// @@ -554,10 +566,9 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, } InvokeInst::InvokeInst(const InvokeInst &II) - : TerminatorInst(II.getType(), Instruction::Invoke, - OperandTraits::op_end(this) - - II.getNumOperands(), - II.getNumOperands()) { + : UnwindPoint(II.getType(), Instruction::Invoke, + OperandTraits::op_end(this) - II.getNumOperands(), + II.getNumOperands()) { setAttributes(II.getAttributes()); setCallingConv(II.getCallingConv()); std::copy(II.op_begin(), II.op_end(), op_begin()); @@ -604,10 +615,6 @@ void InvokeInst::removeAttribute(unsigned i, Attribute attr) { setAttributes(PAL); } -LandingPadInst *InvokeInst::getLandingPadInst() const { - return cast(getUnwindDest()->getFirstNonPHI()); -} - //===----------------------------------------------------------------------===// // ReturnInst Implementation //===----------------------------------------------------------------------===// diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 089ad1c..7b901b3 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -1931,12 +1931,13 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { "LandingPadInst needs at least one clause or to be a cleanup.", &LPI); // The landingpad instruction defines its parent as a landing pad block. The - // landing pad block may be branched to only by the unwind edge of an invoke. + // landing pad block may be branched to only by the unwind edge of an unwind + // point. for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) { - const InvokeInst *II = dyn_cast((*I)->getTerminator()); - Assert1(II && II->getUnwindDest() == BB && II->getNormalDest() != BB, + const UnwindPoint *UP = dyn_cast((*I)->getTerminator()); + Assert1(UP && UP->getUnwindDest() == BB && UP->getNormalDest() != BB, "Block containing LandingPadInst must be jumped to " - "only by the unwind edge of an invoke.", &LPI); + "only by the unwind edge of an unwind point.", &LPI); } // The landingpad instruction must be the first non-PHI instruction in the diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index b8f10e9..b920ac5 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -535,8 +535,8 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI, return; } - if (isa(TI)) { - // Invoke instructions successors are always executable. + if (isa(TI)) { + // Unwind point successors are always executable. Succs[0] = Succs[1] = true; return; } diff --git a/test/Verifier/invoke.ll b/test/Verifier/invoke.ll index c2750bb..9dbc165 100644 --- a/test/Verifier/invoke.ll +++ b/test/Verifier/invoke.ll @@ -72,7 +72,7 @@ entry: to label %cont unwind label %cont cont: -; CHECK: Block containing LandingPadInst must be jumped to only by the unwind edge of an invoke. +; CHECK: Block containing LandingPadInst must be jumped to only by the unwind edge of an unwind point. %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) filter [0 x i8*] zeroinitializer ret void -- 1.9.1.423.g4596e3a</value*></value*></value*></value*>/pcc@google.com