From a9bb713130b073276a53a38fe0c37d314a3f1fc1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 8 May 2007 05:38:01 +0000 Subject: [PATCH] Make a preemptive bitcode format change to support PR1146. This lets us do pr1146 in llvm 2.1 without ugly code to emulate old behavior. This should be merged into the 2.0 release branch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36928 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 41 +++++++++++++++++----------- lib/Bitcode/Writer/BitcodeWriter.cpp | 27 +++++++++++++++--- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e9531f1e1d9..445a7c248e3 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -985,10 +985,10 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { GlobalInits.push_back(std::make_pair(NewGV, InitID-1)); break; } - // FUNCTION: [type, callingconv, isproto, linkage, alignment, section, - // visibility] + // FUNCTION: [type, callingconv, isproto, linkage, paramattr, + // alignment, section, visibility] case bitc::MODULE_CODE_FUNCTION: { - if (Record.size() < 7) + if (Record.size() < 8) return Error("Invalid MODULE_CODE_FUNCTION record"); const Type *Ty = getTypeByID(Record[0]); if (!isa(Ty)) @@ -1004,13 +1004,17 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { Func->setCallingConv(Record[1]); bool isProto = Record[2]; Func->setLinkage(GetDecodedLinkage(Record[3])); - Func->setAlignment((1 << Record[4]) >> 1); - if (Record[5]) { - if (Record[5]-1 >= SectionTable.size()) + + assert(Func->getFunctionType()->getParamAttrs() == + getParamAttrs(Record[4])); + + Func->setAlignment((1 << Record[5]) >> 1); + if (Record[6]) { + if (Record[6]-1 >= SectionTable.size()) return Error("Invalid section ID"); - Func->setSection(SectionTable[Record[5]-1]); + Func->setSection(SectionTable[Record[6]-1]); } - Func->setVisibility(GetDecodedVisibility(Record[6])); + Func->setVisibility(GetDecodedVisibility(Record[7])); ValueList.push_back(Func); @@ -1364,12 +1368,12 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } case bitc::FUNC_CODE_INST_INVOKE: { // INVOKE: [cc,fnty, op0,op1,op2, ...] - if (Record.size() < 3) return Error("Invalid INVOKE record"); - unsigned CCInfo = Record[0]; - BasicBlock *NormalBB = getBasicBlock(Record[1]); - BasicBlock *UnwindBB = getBasicBlock(Record[2]); + if (Record.size() < 4) return Error("Invalid INVOKE record"); + unsigned CCInfo = Record[1]; + BasicBlock *NormalBB = getBasicBlock(Record[2]); + BasicBlock *UnwindBB = getBasicBlock(Record[3]); - unsigned OpNum = 3; + unsigned OpNum = 4; Value *Callee; if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) return Error("Invalid INVOKE record"); @@ -1383,6 +1387,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Record.size() < OpNum+FTy->getNumParams()) return Error("Invalid INVOKE record"); + assert(FTy->getParamAttrs() == getParamAttrs(Record[0])); + SmallVector Ops; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { Ops.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i))); @@ -1484,11 +1490,12 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { break; } case bitc::FUNC_CODE_INST_CALL: { // CALL: [cc, fnty, fnid, arg0, arg1...] - if (Record.size() < 1) + if (Record.size() < 2) return Error("Invalid CALL record"); - unsigned CCInfo = Record[0]; - unsigned OpNum = 1; + unsigned CCInfo = Record[1]; + + unsigned OpNum = 2; Value *Callee; if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) return Error("Invalid CALL record"); @@ -1499,6 +1506,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (!FTy || Record.size() < FTy->getNumParams()+OpNum) return Error("Invalid CALL record"); + assert(FTy->getParamAttrs() == getParamAttrs(Record[0])); + SmallVector Args; // Read the fixed params. for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 34c838343ef..1ea76336078 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -386,6 +386,12 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(F->getCallingConv()); Vals.push_back(F->isDeclaration()); Vals.push_back(getEncodedLinkage(F)); + + // Note: we emit the param attr ID number for the function type of this + // function. In the future, we intend for attrs to be properties of + // functions, instead of on the type. This is to support this future work. + Vals.push_back(VE.getParamAttrID(F->getFunctionType()->getParamAttrs())); + Vals.push_back(Log2_32(F->getAlignment())+1); Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0); Vals.push_back(getEncodedVisibility(F)); @@ -736,15 +742,21 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.push_back(VE.getValueID(I.getOperand(i))); break; case Instruction::Invoke: { + const PointerType *PTy = cast(I.getOperand(0)->getType()); + const FunctionType *FTy = cast(PTy->getElementType()); Code = bitc::FUNC_CODE_INST_INVOKE; + + // Note: we emit the param attr ID number for the function type of this + // function. In the future, we intend for attrs to be properties of + // functions, instead of on the type. This is to support this future work. + Vals.push_back(VE.getParamAttrID(FTy->getParamAttrs())); + Vals.push_back(cast(I).getCallingConv()); Vals.push_back(VE.getValueID(I.getOperand(1))); // normal dest Vals.push_back(VE.getValueID(I.getOperand(2))); // unwind dest PushValueAndType(I.getOperand(0), InstID, Vals, VE); // callee // Emit value #'s for the fixed parameters. - const PointerType *PTy = cast(I.getOperand(0)->getType()); - const FunctionType *FTy = cast(PTy->getElementType()); for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) Vals.push_back(VE.getValueID(I.getOperand(i+3))); // fixed param. @@ -806,14 +818,21 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.push_back(cast(I).isVolatile()); break; case Instruction::Call: { + const PointerType *PTy = cast(I.getOperand(0)->getType()); + const FunctionType *FTy = cast(PTy->getElementType()); + Code = bitc::FUNC_CODE_INST_CALL; + + // Note: we emit the param attr ID number for the function type of this + // function. In the future, we intend for attrs to be properties of + // functions, instead of on the type. This is to support this future work. + Vals.push_back(VE.getParamAttrID(FTy->getParamAttrs())); + Vals.push_back((cast(I).getCallingConv() << 1) | unsigned(cast(I).isTailCall())); PushValueAndType(I.getOperand(0), InstID, Vals, VE); // Callee // Emit value #'s for the fixed parameters. - const PointerType *PTy = cast(I.getOperand(0)->getType()); - const FunctionType *FTy = cast(PTy->getElementType()); for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) Vals.push_back(VE.getValueID(I.getOperand(i+1))); // fixed param.