diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 12 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 1 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 2 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 8 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 1 | ||||
-rw-r--r-- | lib/CodeGen/ShadowStackGC.cpp | 6 | ||||
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 4 | ||||
-rw-r--r-- | lib/Target/CppBackend/CPPBackend.cpp | 5 | ||||
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineCalls.cpp | 8 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 1 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/Instruction.cpp | 1 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 39 |
17 files changed, 95 insertions, 8 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 95b40c9838..c3a5a4d0db 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -636,6 +636,7 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(switch, Switch); INSTKEYWORD(indirectbr, IndirectBr); INSTKEYWORD(invoke, Invoke); + INSTKEYWORD(resume, Resume); INSTKEYWORD(unwind, Unwind); INSTKEYWORD(unreachable, Unreachable); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 4727fac8ef..82fab917fe 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2885,6 +2885,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_switch: return ParseSwitch(Inst, PFS); case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); + case lltok::kw_resume: return ParseResume(Inst, PFS); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -3253,7 +3254,18 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return false; } +/// ParseResume +/// ::= 'resume' TypeAndValue +bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { + Value *Exn; LocTy ExnLoc; + LocTy Loc = Lex.getLoc(); + if (ParseTypeAndValue(Exn, ExnLoc, PFS)) + return true; + ResumeInst *RI = ResumeInst::Create(Exn); + Inst = RI; + return false; +} //===----------------------------------------------------------------------===// // Binary Operators. diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 2a7210a311..df058edd76 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -347,6 +347,7 @@ namespace llvm { bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS); bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); + bool ParseResume(Instruction *&Inst, PerFunctionState &PFS); bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc, unsigned OperandType); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 75b332b6be..3da85ad5d7 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -124,7 +124,7 @@ namespace lltok { kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast, kw_select, kw_va_arg, - kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, + kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, kw_resume, kw_unreachable, kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index b4f47ad670..b4e105055e 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2508,6 +2508,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { cast<InvokeInst>(I)->setAttributes(PAL); break; } + case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval] + unsigned Idx = 0; + Value *Val = 0; + if (getValueTypePair(Record, Idx, NextValueNo, Val)) + return Error("Invalid RESUME record"); + I = ResumeInst::Create(Val); + break; + } case bitc::FUNC_CODE_INST_UNWIND: // UNWIND I = new UnwindInst(Context); InstructionList.push_back(I); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index dd071d89a6..9954400e5e 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1143,6 +1143,10 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, } break; } + case Instruction::Resume: + Code = bitc::FUNC_CODE_INST_RESUME; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + break; case Instruction::Unwind: Code = bitc::FUNC_CODE_INST_UNWIND; break; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 86d32c218b..449f87ebda 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1810,6 +1810,10 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) { } +void SelectionDAGBuilder::visitResume(const ResumeInst &RI) { + llvm_unreachable("SelectionDAGBuilder shouldn't visit resume instructions!"); +} + /// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for /// small case ranges). bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index aae56ba06a..050b86fb60 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -467,6 +467,7 @@ public: private: // These all get lowered before this pass. void visitInvoke(const InvokeInst &I); + void visitResume(const ResumeInst &I); void visitUnwind(const UnwindInst &I); void visitBinary(const User &I, unsigned OpCode); diff --git a/lib/CodeGen/ShadowStackGC.cpp b/lib/CodeGen/ShadowStackGC.cpp index 9807c8cb27..daab89b8f2 100644 --- a/lib/CodeGen/ShadowStackGC.cpp +++ b/lib/CodeGen/ShadowStackGC.cpp @@ -113,9 +113,11 @@ namespace { while (StateBB != StateE) { BasicBlock *CurBB = StateBB++; - // Branches and invokes do not escape, only unwind and return do. + // Branches and invokes do not escape, only unwind, resume, and return + // do. TerminatorInst *TI = CurBB->getTerminator(); - if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI)) + if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI) && + !isa<ResumeInst>(TI)) continue; Builder.SetInsertPoint(TI->getParent(), TI); diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 18a27d2dc3..5b9a0a297f 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -288,10 +288,12 @@ namespace { void visitInvokeInst(InvokeInst &I) { llvm_unreachable("Lowerinvoke pass didn't work!"); } - void visitUnwindInst(UnwindInst &I) { llvm_unreachable("Lowerinvoke pass didn't work!"); } + void visitResumeInst(ResumeInst &I) { + llvm_unreachable("DwarfEHPrepare pass didn't work!"); + } void visitUnreachableInst(UnreachableInst &I); void visitPHINode(PHINode &I); diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 7f5f5e189e..108023da95 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -1064,6 +1064,11 @@ void CppWriter::printInstruction(const Instruction *I, } break; } + case Instruction::Resume: { + Out << "ResumeInst::Create(mod->getContext(), " << opNames[0] + << ", " << bbname << ");"; + break; + } case Instruction::Invoke: { const InvokeInst* inv = cast<InvokeInst>(I); Out << "std::vector<Value*> " << iName << "_params;"; diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 0283568f2c..771a50b49d 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -2506,7 +2506,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, CallStack.pop_back(); // return from fn. return true; // We succeeded at evaluating this ctor! } else { - // invoke, unwind, unreachable. + // invoke, unwind, resume, unreachable. return false; // Cannot handle this terminator. } diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index c33dec1740..09edc41997 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -732,9 +732,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { } } - // If the stack restore is in a return/unwind block and if there are no - // allocas or calls between the restore and the return, nuke the restore. - if (!CannotRemove && (isa<ReturnInst>(TI) || isa<UnwindInst>(TI))) + // If the stack restore is in a return, resume, or unwind block and if there + // are no allocas or calls between the restore and the return, nuke the + // restore. + if (!CannotRemove && (isa<ReturnInst>(TI) || isa<ResumeInst>(TI) || + isa<UnwindInst>(TI))) return EraseInstFromFunction(CI); break; } diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 749ba40a64..4e1c27446c 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -528,6 +528,7 @@ private: visitTerminatorInst(II); } void visitCallSite (CallSite CS); + void visitResumeInst (TerminatorInst &I) { /*returns void*/ } void visitUnwindInst (TerminatorInst &I) { /*returns void*/ } void visitUnreachableInst(TerminatorInst &I) { /*returns void*/ } void visitFenceInst (FenceInst &I) { /*returns void*/ } diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 3c93736ce1..ce010c1b7d 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -1687,6 +1687,10 @@ LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef B) { return wrap(unwrap(B)->CreateUnwind()); } +LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) { + return wrap(unwrap(B)->CreateResume(unwrap(Exn))); +} + LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) { return wrap(unwrap(B)->CreateUnreachable()); } diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index c4365fcca6..216bb35d4d 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -101,6 +101,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Switch: return "switch"; case IndirectBr: return "indirectbr"; case Invoke: return "invoke"; + case Resume: return "resume"; case Unwind: return "unwind"; case Unreachable: return "unreachable"; diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 75458babfb..c36102d706 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -574,6 +574,41 @@ BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const { } //===----------------------------------------------------------------------===// +// ResumeInst Implementation +//===----------------------------------------------------------------------===// + +ResumeInst::ResumeInst(const ResumeInst &RI) + : TerminatorInst(Type::getVoidTy(RI.getContext()), Instruction::Resume, + OperandTraits<ResumeInst>::op_begin(this), 1) { + Op<0>() = RI.Op<0>(); +} + +ResumeInst::ResumeInst(Value *Exn, Instruction *InsertBefore) + : TerminatorInst(Type::getVoidTy(Exn->getContext()), Instruction::Resume, + OperandTraits<ResumeInst>::op_begin(this), 1, InsertBefore) { + Op<0>() = Exn; +} + +ResumeInst::ResumeInst(Value *Exn, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getVoidTy(Exn->getContext()), Instruction::Resume, + OperandTraits<ResumeInst>::op_begin(this), 1, InsertAtEnd) { + Op<0>() = Exn; +} + +unsigned ResumeInst::getNumSuccessorsV() const { + return getNumSuccessors(); +} + +void ResumeInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { + llvm_unreachable("ResumeInst has no successors!"); +} + +BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const { + llvm_unreachable("ResumeInst has no successors!"); + return 0; +} + +//===----------------------------------------------------------------------===// // UnreachableInst Implementation //===----------------------------------------------------------------------===// @@ -3254,6 +3289,10 @@ InvokeInst *InvokeInst::clone_impl() const { return new(getNumOperands()) InvokeInst(*this); } +ResumeInst *ResumeInst::clone_impl() const { + return new(1) ResumeInst(*this); +} + UnwindInst *UnwindInst::clone_impl() const { LLVMContext &Context = getContext(); return new UnwindInst(Context); |