diff options
author | David Blaikie <dblaikie@gmail.com> | 2015-02-25 01:08:52 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2015-02-25 01:08:52 +0000 |
commit | b5b5efd2d19839d2810ce4404d7ed717da2beecb (patch) | |
tree | ac082d9d178e8ebd670118eb851e4f33f79264e6 /llvm/lib/Bitcode | |
parent | 8503565eecfa630f8ee65266efc4a82e796ebc64 (diff) | |
download | bcm5719-llvm-b5b5efd2d19839d2810ce4404d7ed717da2beecb.tar.gz bcm5719-llvm-b5b5efd2d19839d2810ce4404d7ed717da2beecb.zip |
[opaque pointer type] Bitcode support for explicit type parameter on GEP.
Like r230414, add bitcode support including backwards compatibility, for
an explicit type parameter to GEP.
At the suggestion of Duncan I tried coalescing the two older bitcodes into a
single new bitcode, though I did hit a wrinkle: I couldn't figure out how to
create an explicit abbreviation for a record with a variable number of
arguments (the indicies to the gep). This means the discriminator between
inbounds and non-inbounds gep is a full variable-length field I believe? Is my
understanding correct? Is there a way to create such an abbreviation? Should I
just use two bitcodes as before?
Reviewers: dexonsmith
Differential Revision: http://reviews.llvm.org/D7736
llvm-svn: 230415
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 24 |
2 files changed, 37 insertions, 7 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index c45e9645adc..92af0f8603b 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3062,9 +3062,22 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_INBOUNDS_GEP: - case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands] + case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands] unsigned OpNum = 0; + + Type *Ty; + bool InBounds; + + if (BitCode == bitc::FUNC_CODE_INST_GEP) { + InBounds = Record[OpNum++]; + Ty = getTypeByID(Record[OpNum++]); + } else { + InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; + Ty = nullptr; + } + Value *BasePtr; if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) return Error("Invalid record"); @@ -3078,8 +3091,9 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { } I = GetElementPtrInst::Create(BasePtr, GEPIdx); + assert(!Ty || Ty == cast<GetElementPtrInst>(I)->getSourceElementType()); InstructionList.push_back(I); - if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP) + if (InBounds) cast<GetElementPtrInst>(I)->setIsInBounds(true); break; } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 16658009b18..ecb6f7c130a 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -56,7 +56,8 @@ enum { FUNCTION_INST_CAST_ABBREV, FUNCTION_INST_RET_VOID_ABBREV, FUNCTION_INST_RET_VAL_ABBREV, - FUNCTION_INST_UNREACHABLE_ABBREV + FUNCTION_INST_UNREACHABLE_ABBREV, + FUNCTION_INST_GEP_ABBREV, }; static unsigned GetEncodedCastOpcode(unsigned Opcode) { @@ -1675,13 +1676,16 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, } break; - case Instruction::GetElementPtr: + case Instruction::GetElementPtr: { Code = bitc::FUNC_CODE_INST_GEP; - if (cast<GEPOperator>(&I)->isInBounds()) - Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP; + AbbrevToUse = FUNCTION_INST_GEP_ABBREV; + auto &GEPInst = cast<GetElementPtrInst>(I); + Vals.push_back(GEPInst.isInBounds()); + Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType())); for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) PushValueAndType(I.getOperand(i), InstID, Vals, VE); break; + } case Instruction::ExtractValue: { Code = bitc::FUNC_CODE_INST_EXTRACTVAL; PushValueAndType(I.getOperand(0), InstID, Vals, VE); @@ -2287,6 +2291,18 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } + { + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_GEP)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty + Log2_32_Ceil(VE.getTypes().size() + 1))); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) != + FUNCTION_INST_GEP_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } Stream.ExitBlock(); } |