summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp128
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp58
2 files changed, 186 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index de91150c424..fea4c167ae3 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3811,6 +3811,134 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
}
break;
}
+ // CLEANUPRET: [] or [ty,val] or [bb#] or [ty,val,bb#]
+ case bitc::FUNC_CODE_INST_CLEANUPRET: {
+ if (Record.size() < 2)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ bool HasReturnValue = !!Record[Idx++];
+ bool HasUnwindDest = !!Record[Idx++];
+ Value *RetVal = nullptr;
+ BasicBlock *UnwindDest = nullptr;
+
+ if (HasReturnValue && getValueTypePair(Record, Idx, NextValueNo, RetVal))
+ return error("Invalid record");
+ if (HasUnwindDest) {
+ if (Idx == Record.size())
+ return error("Invalid record");
+ UnwindDest = getBasicBlock(Record[Idx++]);
+ if (!UnwindDest)
+ return error("Invalid record");
+ }
+
+ if (Record.size() != Idx)
+ return error("Invalid record");
+
+ I = CleanupReturnInst::Create(Context, RetVal, UnwindDest);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#]
+ if (Record.size() != 1)
+ return error("Invalid record");
+ BasicBlock *BB = getBasicBlock(Record[0]);
+ if (!BB)
+ return error("Invalid record");
+ I = CatchReturnInst::Create(BB);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [ty,bb#,bb#,num,(ty,val)*]
+ if (Record.size() < 4)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ Type *Ty = getTypeByID(Record[Idx++]);
+ if (!Ty)
+ return error("Invalid record");
+ BasicBlock *NormalBB = getBasicBlock(Record[Idx++]);
+ if (!NormalBB)
+ return error("Invalid record");
+ BasicBlock *UnwindBB = getBasicBlock(Record[Idx++]);
+ if (!UnwindBB)
+ return error("Invalid record");
+ unsigned NumArgOperands = Record[Idx++];
+ SmallVector<Value *, 2> Args;
+ for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
+ Value *Val;
+ if (getValueTypePair(Record, Idx, NextValueNo, Val))
+ return error("Invalid record");
+ Args.push_back(Val);
+ }
+ if (Record.size() != Idx)
+ return error("Invalid record");
+
+ I = CatchPadInst::Create(Ty, NormalBB, UnwindBB, Args);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_TERMINATEPAD: { // TERMINATEPAD: [bb#,num,(ty,val)*]
+ if (Record.size() < 1)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ bool HasUnwindDest = !!Record[Idx++];
+ BasicBlock *UnwindDest = nullptr;
+ if (HasUnwindDest) {
+ if (Idx == Record.size())
+ return error("Invalid record");
+ UnwindDest = getBasicBlock(Record[Idx++]);
+ if (!UnwindDest)
+ return error("Invalid record");
+ }
+ unsigned NumArgOperands = Record[Idx++];
+ SmallVector<Value *, 2> Args;
+ for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
+ Value *Val;
+ if (getValueTypePair(Record, Idx, NextValueNo, Val))
+ return error("Invalid record");
+ Args.push_back(Val);
+ }
+ if (Record.size() != Idx)
+ return error("Invalid record");
+
+ I = TerminatePadInst::Create(Context, UnwindDest, Args);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [ty, num,(ty,val)*]
+ if (Record.size() < 2)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ Type *Ty = getTypeByID(Record[Idx++]);
+ if (!Ty)
+ return error("Invalid record");
+ unsigned NumArgOperands = Record[Idx++];
+ SmallVector<Value *, 2> Args;
+ for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
+ Value *Val;
+ if (getValueTypePair(Record, Idx, NextValueNo, Val))
+ return error("Invalid record");
+ Args.push_back(Val);
+ }
+ if (Record.size() != Idx)
+ return error("Invalid record");
+
+ I = CleanupPadInst::Create(Ty, Args);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CATCHENDPAD: { // CATCHENDPADINST: [bb#] or []
+ if (Record.size() > 1)
+ return error("Invalid record");
+ BasicBlock *BB = nullptr;
+ if (Record.size() == 1) {
+ BB = getBasicBlock(Record[0]);
+ if (!BB)
+ return error("Invalid record");
+ }
+ I = CatchEndPadInst::Create(Context, BB);
+ InstructionList.push_back(I);
+ break;
+ }
case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
// Check magic
if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 31ae0141ef8..20e31d1a102 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1851,6 +1851,64 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Code = bitc::FUNC_CODE_INST_RESUME;
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
break;
+ case Instruction::CleanupRet: {
+ Code = bitc::FUNC_CODE_INST_CLEANUPRET;
+ const auto &CRI = cast<CleanupReturnInst>(I);
+ Vals.push_back(CRI.hasReturnValue());
+ Vals.push_back(CRI.hasUnwindDest());
+ if (CRI.hasReturnValue())
+ PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE);
+ if (CRI.hasUnwindDest())
+ Vals.push_back(VE.getValueID(CRI.getUnwindDest()));
+ break;
+ }
+ case Instruction::CatchRet: {
+ Code = bitc::FUNC_CODE_INST_CATCHRET;
+ const auto &CRI = cast<CatchReturnInst>(I);
+ Vals.push_back(VE.getValueID(CRI.getSuccessor()));
+ break;
+ }
+ case Instruction::CatchPad: {
+ Code = bitc::FUNC_CODE_INST_CATCHPAD;
+ const auto &CPI = cast<CatchPadInst>(I);
+ Vals.push_back(VE.getTypeID(CPI.getType()));
+ Vals.push_back(VE.getValueID(CPI.getNormalDest()));
+ Vals.push_back(VE.getValueID(CPI.getUnwindDest()));
+ unsigned NumArgOperands = CPI.getNumArgOperands();
+ Vals.push_back(NumArgOperands);
+ for (unsigned Op = 0; Op != NumArgOperands; ++Op)
+ PushValueAndType(CPI.getArgOperand(Op), InstID, Vals, VE);
+ break;
+ }
+ case Instruction::TerminatePad: {
+ Code = bitc::FUNC_CODE_INST_TERMINATEPAD;
+ const auto &TPI = cast<TerminatePadInst>(I);
+ Vals.push_back(TPI.hasUnwindDest());
+ if (TPI.hasUnwindDest())
+ Vals.push_back(VE.getValueID(TPI.getUnwindDest()));
+ unsigned NumArgOperands = TPI.getNumArgOperands();
+ Vals.push_back(NumArgOperands);
+ for (unsigned Op = 0; Op != NumArgOperands; ++Op)
+ PushValueAndType(TPI.getArgOperand(Op), InstID, Vals, VE);
+ break;
+ }
+ case Instruction::CleanupPad: {
+ Code = bitc::FUNC_CODE_INST_CLEANUPPAD;
+ const auto &CPI = cast<CleanupPadInst>(I);
+ Vals.push_back(VE.getTypeID(CPI.getType()));
+ unsigned NumOperands = CPI.getNumOperands();
+ Vals.push_back(NumOperands);
+ for (unsigned Op = 0; Op != NumOperands; ++Op)
+ PushValueAndType(CPI.getOperand(Op), InstID, Vals, VE);
+ break;
+ }
+ case Instruction::CatchEndPad: {
+ Code = bitc::FUNC_CODE_INST_CATCHENDPAD;
+ const auto &CEPI = cast<CatchEndPadInst>(I);
+ if (CEPI.hasUnwindDest())
+ Vals.push_back(VE.getValueID(CEPI.getUnwindDest()));
+ break;
+ }
case Instruction::Unreachable:
Code = bitc::FUNC_CODE_INST_UNREACHABLE;
AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
OpenPOWER on IntegriCloud