LLVM API Documentation

BitstreamWriter.h

Go to the documentation of this file.
00001 //===- BitstreamWriter.h - Low-level bitstream writer interface -*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This header defines the BitstreamWriter class.  This class can be used to
00011 // write an arbitrary bitstream, regardless of its contents.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef BITSTREAM_WRITER_H
00016 #define BITSTREAM_WRITER_H
00017 
00018 #include "llvm/Bitcode/BitCodes.h"
00019 #include <vector>
00020 
00021 namespace llvm {
00022 
00023 class BitstreamWriter {
00024   std::vector<unsigned char> &Out;
00025 
00026   /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
00027   unsigned CurBit;
00028   
00029   /// CurValue - The current value.  Only bits < CurBit are valid.
00030   uint32_t CurValue;
00031   
00032   /// CurCodeSize - This is the declared size of code values used for the
00033   /// current block, in bits.
00034   unsigned CurCodeSize;
00035 
00036   /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
00037   /// selected BLOCK ID.
00038   unsigned BlockInfoCurBID;
00039   
00040   /// CurAbbrevs - Abbrevs installed at in this block.
00041   std::vector<BitCodeAbbrev*> CurAbbrevs;
00042 
00043   struct Block {
00044     unsigned PrevCodeSize;
00045     unsigned StartSizeWord;
00046     std::vector<BitCodeAbbrev*> PrevAbbrevs;
00047     Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
00048   };
00049   
00050   /// BlockScope - This tracks the current blocks that we have entered.
00051   std::vector<Block> BlockScope;
00052   
00053   /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
00054   /// These describe abbreviations that all blocks of the specified ID inherit.
00055   struct BlockInfo {
00056     unsigned BlockID;
00057     std::vector<BitCodeAbbrev*> Abbrevs;
00058   };
00059   std::vector<BlockInfo> BlockInfoRecords;
00060   
00061 public:
00062   explicit BitstreamWriter(std::vector<unsigned char> &O) 
00063     : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
00064 
00065   ~BitstreamWriter() {
00066     assert(CurBit == 0 && "Unflused data remaining");
00067     assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
00068     
00069     // Free the BlockInfoRecords.
00070     while (!BlockInfoRecords.empty()) {
00071       BlockInfo &Info = BlockInfoRecords.back();
00072       // Free blockinfo abbrev info.
00073       for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
00074            i != e; ++i)
00075         Info.Abbrevs[i]->dropRef();
00076       BlockInfoRecords.pop_back();
00077     }
00078   }
00079 
00080   std::vector<unsigned char> &getBuffer() { return Out; }
00081 
00082   //===--------------------------------------------------------------------===//
00083   // Basic Primitives for emitting bits to the stream.
00084   //===--------------------------------------------------------------------===//
00085   
00086   void Emit(uint32_t Val, unsigned NumBits) {
00087     assert(NumBits <= 32 && "Invalid value size!");
00088     assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
00089     CurValue |= Val << CurBit;
00090     if (CurBit + NumBits < 32) {
00091       CurBit += NumBits;
00092       return;
00093     }
00094     
00095     // Add the current word.
00096     unsigned V = CurValue;
00097     Out.push_back((unsigned char)(V >>  0));
00098     Out.push_back((unsigned char)(V >>  8));
00099     Out.push_back((unsigned char)(V >> 16));
00100     Out.push_back((unsigned char)(V >> 24));
00101     
00102     if (CurBit)
00103       CurValue = Val >> (32-CurBit);
00104     else
00105       CurValue = 0;
00106     CurBit = (CurBit+NumBits) & 31;
00107   }
00108   
00109   void Emit64(uint64_t Val, unsigned NumBits) {
00110     if (NumBits <= 32)
00111       Emit((uint32_t)Val, NumBits);
00112     else {
00113       Emit((uint32_t)Val, 32);
00114       Emit((uint32_t)(Val >> 32), NumBits-32);
00115     }
00116   }
00117   
00118   void FlushToWord() {
00119     if (CurBit) {
00120       unsigned V = CurValue;
00121       Out.push_back((unsigned char)(V >>  0));
00122       Out.push_back((unsigned char)(V >>  8));
00123       Out.push_back((unsigned char)(V >> 16));
00124       Out.push_back((unsigned char)(V >> 24));
00125       CurBit = 0;
00126       CurValue = 0;
00127     }
00128   }
00129   
00130   void EmitVBR(uint32_t Val, unsigned NumBits) {
00131     uint32_t Threshold = 1U << (NumBits-1);
00132     
00133     // Emit the bits with VBR encoding, NumBits-1 bits at a time.
00134     while (Val >= Threshold) {
00135       Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
00136       Val >>= NumBits-1;
00137     }
00138     
00139     Emit(Val, NumBits);
00140   }
00141   
00142   void EmitVBR64(uint64_t Val, unsigned NumBits) {
00143     if ((uint32_t)Val == Val)
00144       return EmitVBR((uint32_t)Val, NumBits);
00145     
00146     uint64_t Threshold = 1U << (NumBits-1);
00147     
00148     // Emit the bits with VBR encoding, NumBits-1 bits at a time.
00149     while (Val >= Threshold) {
00150       Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) |
00151            (1 << (NumBits-1)), NumBits);
00152       Val >>= NumBits-1;
00153     }
00154     
00155     Emit((uint32_t)Val, NumBits);
00156   }
00157   
00158   /// EmitCode - Emit the specified code.
00159   void EmitCode(unsigned Val) {
00160     Emit(Val, CurCodeSize);
00161   }
00162   
00163   // BackpatchWord - Backpatch a 32-bit word in the output with the specified
00164   // value.
00165   void BackpatchWord(unsigned ByteNo, unsigned NewWord) {
00166     Out[ByteNo++] = (unsigned char)(NewWord >>  0);
00167     Out[ByteNo++] = (unsigned char)(NewWord >>  8);
00168     Out[ByteNo++] = (unsigned char)(NewWord >> 16);
00169     Out[ByteNo  ] = (unsigned char)(NewWord >> 24);
00170   }
00171   
00172   //===--------------------------------------------------------------------===//
00173   // Block Manipulation
00174   //===--------------------------------------------------------------------===//
00175   
00176   /// getBlockInfo - If there is block info for the specified ID, return it,
00177   /// otherwise return null.
00178   BlockInfo *getBlockInfo(unsigned BlockID) {
00179     // Common case, the most recent entry matches BlockID.
00180     if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
00181       return &BlockInfoRecords.back();
00182     
00183     for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
00184          i != e; ++i)
00185       if (BlockInfoRecords[i].BlockID == BlockID)
00186         return &BlockInfoRecords[i];
00187     return 0;
00188   }
00189   
00190   void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
00191     // Block header:
00192     //    [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
00193     EmitCode(bitc::ENTER_SUBBLOCK);
00194     EmitVBR(BlockID, bitc::BlockIDWidth);
00195     EmitVBR(CodeLen, bitc::CodeLenWidth);
00196     FlushToWord();
00197     
00198     unsigned BlockSizeWordLoc = static_cast<unsigned>(Out.size());
00199     unsigned OldCodeSize = CurCodeSize;
00200     
00201     // Emit a placeholder, which will be replaced when the block is popped.
00202     Emit(0, bitc::BlockSizeWidth);
00203     
00204     CurCodeSize = CodeLen;
00205     
00206     // Push the outer block's abbrev set onto the stack, start out with an
00207     // empty abbrev set.
00208     BlockScope.push_back(Block(OldCodeSize, BlockSizeWordLoc/4));
00209     BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
00210 
00211     // If there is a blockinfo for this BlockID, add all the predefined abbrevs
00212     // to the abbrev list.
00213     if (BlockInfo *Info = getBlockInfo(BlockID)) {
00214       for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
00215            i != e; ++i) {
00216         CurAbbrevs.push_back(Info->Abbrevs[i]);
00217         Info->Abbrevs[i]->addRef();
00218       }
00219     }
00220   }
00221   
00222   void ExitBlock() {
00223     assert(!BlockScope.empty() && "Block scope imbalance!");
00224     
00225     // Delete all abbrevs.
00226     for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
00227          i != e; ++i)
00228       CurAbbrevs[i]->dropRef();
00229     
00230     const Block &B = BlockScope.back();
00231     
00232     // Block tail:
00233     //    [END_BLOCK, <align4bytes>]
00234     EmitCode(bitc::END_BLOCK);
00235     FlushToWord();
00236 
00237     // Compute the size of the block, in words, not counting the size field.
00238     unsigned SizeInWords= static_cast<unsigned>(Out.size())/4-B.StartSizeWord-1;
00239     unsigned ByteNo = B.StartSizeWord*4;
00240     
00241     // Update the block size field in the header of this sub-block.
00242     BackpatchWord(ByteNo, SizeInWords);
00243     
00244     // Restore the inner block's code size and abbrev table.
00245     CurCodeSize = B.PrevCodeSize;
00246     BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
00247     BlockScope.pop_back();
00248   }
00249   
00250   //===--------------------------------------------------------------------===//
00251   // Record Emission
00252   //===--------------------------------------------------------------------===//
00253   
00254 private:
00255   /// EmitAbbreviatedField - Emit a single scalar field value with the specified
00256   /// encoding.
00257   template<typename uintty>
00258   void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
00259     if (Op.isLiteral()) {
00260       // If the abbrev specifies the literal value to use, don't emit
00261       // anything.
00262       assert(V == Op.getLiteralValue() &&
00263              "Invalid abbrev for record!");
00264       return;
00265     }
00266     
00267     // Encode the value as we are commanded.
00268     switch (Op.getEncoding()) {
00269     default: assert(0 && "Unknown encoding!");
00270     case BitCodeAbbrevOp::Fixed:
00271       Emit((unsigned)V, (unsigned)Op.getEncodingData());
00272       break;
00273     case BitCodeAbbrevOp::VBR:
00274       EmitVBR64(V, (unsigned)Op.getEncodingData());
00275       break;
00276     case BitCodeAbbrevOp::Char6:
00277       Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
00278       break;
00279     }        
00280   }
00281 public:
00282     
00283   /// EmitRecord - Emit the specified record to the stream, using an abbrev if
00284   /// we have one to compress the output.
00285   template<typename uintty>
00286   void EmitRecord(unsigned Code, SmallVectorImpl<uintty> &Vals,
00287                   unsigned Abbrev = 0) {
00288     if (Abbrev) {
00289       unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
00290       assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
00291       BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
00292       
00293       EmitCode(Abbrev);
00294       
00295       // Insert the code into Vals to treat it uniformly.
00296       Vals.insert(Vals.begin(), Code);
00297       
00298       unsigned RecordIdx = 0;
00299       for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
00300            i != e; ++i) {
00301         const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
00302         if (Op.isLiteral() || Op.getEncoding() != BitCodeAbbrevOp::Array) {
00303           assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
00304           EmitAbbreviatedField(Op, Vals[RecordIdx]);
00305           ++RecordIdx;
00306         } else {
00307           // Array case.
00308           assert(i+2 == e && "array op not second to last?");
00309           const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
00310           
00311           // Emit a vbr6 to indicate the number of elements present.
00312           EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
00313           
00314           // Emit each field.
00315           for (; RecordIdx != Vals.size(); ++RecordIdx)
00316             EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
00317         }
00318       }
00319       assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
00320     } else {
00321       // If we don't have an abbrev to use, emit this in its fully unabbreviated
00322       // form.
00323       EmitCode(bitc::UNABBREV_RECORD);
00324       EmitVBR(Code, 6);
00325       EmitVBR(static_cast<uint32_t>(Vals.size()), 6);
00326       for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i)
00327         EmitVBR64(Vals[i], 6);
00328     }
00329   }
00330 
00331   //===--------------------------------------------------------------------===//
00332   // Abbrev Emission
00333   //===--------------------------------------------------------------------===//
00334   
00335 private:
00336   // Emit the abbreviation as a DEFINE_ABBREV record.
00337   void EncodeAbbrev(BitCodeAbbrev *Abbv) {
00338     EmitCode(bitc::DEFINE_ABBREV);
00339     EmitVBR(Abbv->getNumOperandInfos(), 5);
00340     for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
00341          i != e; ++i) {
00342       const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
00343       Emit(Op.isLiteral(), 1);
00344       if (Op.isLiteral()) {
00345         EmitVBR64(Op.getLiteralValue(), 8);
00346       } else {
00347         Emit(Op.getEncoding(), 3);
00348         if (Op.hasEncodingData())
00349           EmitVBR64(Op.getEncodingData(), 5);
00350       }
00351     }
00352   }
00353 public:
00354     
00355   /// EmitAbbrev - This emits an abbreviation to the stream.  Note that this
00356   /// method takes ownership of the specified abbrev.
00357   unsigned EmitAbbrev(BitCodeAbbrev *Abbv) {
00358     // Emit the abbreviation as a record.
00359     EncodeAbbrev(Abbv);
00360     CurAbbrevs.push_back(Abbv);
00361     return static_cast<unsigned>(CurAbbrevs.size())-1 +
00362       bitc::FIRST_APPLICATION_ABBREV;
00363   }
00364   
00365   //===--------------------------------------------------------------------===//
00366   // BlockInfo Block Emission
00367   //===--------------------------------------------------------------------===//
00368   
00369   /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
00370   void EnterBlockInfoBlock(unsigned CodeWidth) {
00371     EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth);
00372     BlockInfoCurBID = -1U;
00373   }
00374 private:  
00375   /// SwitchToBlockID - If we aren't already talking about the specified block
00376   /// ID, emit a BLOCKINFO_CODE_SETBID record.
00377   void SwitchToBlockID(unsigned BlockID) {
00378     if (BlockInfoCurBID == BlockID) return;
00379     SmallVector<unsigned, 2> V;
00380     V.push_back(BlockID);
00381     EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V);
00382     BlockInfoCurBID = BlockID;
00383   }
00384 
00385   BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
00386     if (BlockInfo *BI = getBlockInfo(BlockID))
00387       return *BI;
00388     
00389     // Otherwise, add a new record.
00390     BlockInfoRecords.push_back(BlockInfo());
00391     BlockInfoRecords.back().BlockID = BlockID;
00392     return BlockInfoRecords.back();
00393   }
00394   
00395 public:
00396   
00397   /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
00398   /// BlockID.
00399   unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv) {
00400     SwitchToBlockID(BlockID);
00401     EncodeAbbrev(Abbv);
00402     
00403     // Add the abbrev to the specified block record.
00404     BlockInfo &Info = getOrCreateBlockInfo(BlockID);
00405     Info.Abbrevs.push_back(Abbv);
00406     
00407     return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
00408   }
00409 };
00410 
00411 
00412 } // End llvm namespace
00413 
00414 #endif



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.