From 5e2e6f28554c323018ad1ad6de952b38369fe42d Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 25 Feb 2015 01:07:20 +0000 Subject: [PATCH] [opaque pointer type] bitcode support for explicit type parameter to the load instruction Summary: I've taken my best guess at this, but I've cargo culted in places & so explanations/corrections would be great. This seems to pass all the tests (check-all, covering clang and llvm) so I believe that pretty well exercises both the backwards compatibility and common (same version) compatibility given the number of checked in bitcode files we already have. Is that a reasonable approach to testing here? Would some more explicit tests be desired? 1) is this the right way to do back-compat in this case (looking at the number of entries in the bitcode record to disambiguate between the old schema and the new?) 2) I don't quite understand the logarithm logic to choose the encoding type of the type parameter in the abbreviation description, but I found another instruction doing the same thing & it seems to work. Is that the right approach? Reviewers: dexonsmith Differential Revision: http://reviews.llvm.org/D7655 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230414 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 21 +++++++++++++++++++-- lib/Bitcode/Writer/BitcodeWriter.cpp | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 3b3a6eb43d1..c45e9645adc 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3574,12 +3574,21 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - OpNum+2 != Record.size()) + (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) return Error("Invalid record"); + + Type *Ty = nullptr; + if (OpNum + 3 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + unsigned Align; if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) return EC; I = new LoadInst(Op, "", Record[OpNum+1], Align); + + assert((!Ty || Ty == I->getType()) && + "Explicit type doesn't match pointee type of the first operand"); + InstructionList.push_back(I); break; } @@ -3588,9 +3597,13 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - OpNum+4 != Record.size()) + (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) return Error("Invalid record"); + Type *Ty = nullptr; + if (OpNum + 5 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); if (Ordering == NotAtomic || Ordering == Release || Ordering == AcquireRelease) @@ -3603,6 +3616,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) return EC; I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope); + + assert((!Ty || Ty == I->getType()) && + "Explicit type doesn't match pointee type of the first operand"); + InstructionList.push_back(I); break; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 26549d59e6d..16658009b18 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1871,6 +1871,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) // ptr AbbrevToUse = FUNCTION_INST_LOAD_ABBREV; } + Vals.push_back(VE.getTypeID(I.getType())); Vals.push_back(Log2_32(cast(I).getAlignment())+1); Vals.push_back(cast(I).isVolatile()); if (cast(I).isAtomic()) { @@ -2223,6 +2224,8 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { BitCodeAbbrev *Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty + VE.computeBitsRequiredForTypeIndicies())); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,