LLVM API Documentation

BitcodeReader.h

Go to the documentation of this file.
00001 //===- BitcodeReader.h - Internal BitcodeReader impl ------------*- 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 BitcodeReader class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef BITCODE_READER_H
00015 #define BITCODE_READER_H
00016 
00017 #include "llvm/ModuleProvider.h"
00018 #include "llvm/Attributes.h"
00019 #include "llvm/Type.h"
00020 #include "llvm/OperandTraits.h"
00021 #include "llvm/Bitcode/BitstreamReader.h"
00022 #include "llvm/Bitcode/LLVMBitCodes.h"
00023 #include "llvm/ADT/DenseMap.h"
00024 #include <vector>
00025 
00026 namespace llvm {
00027   class MemoryBuffer;
00028   
00029 //===----------------------------------------------------------------------===//
00030 //                          BitcodeReaderValueList Class
00031 //===----------------------------------------------------------------------===//
00032 
00033 class BitcodeReaderValueList : public User {
00034   unsigned Capacity;
00035   
00036   /// ResolveConstants - As we resolve forward-referenced constants, we add
00037   /// information about them to this vector.  This allows us to resolve them in
00038   /// bulk instead of resolving each reference at a time.  See the code in
00039   /// ResolveConstantForwardRefs for more information about this.
00040   ///
00041   /// The key of this vector is the placeholder constant, the value is the slot
00042   /// number that holds the resolved value.
00043   typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
00044   ResolveConstantsTy ResolveConstants;
00045 public:
00046   BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0)
00047                            , Capacity(0) {}
00048   ~BitcodeReaderValueList() {
00049     assert(ResolveConstants.empty() && "Constants not resolved?");
00050   }
00051 
00052   /// Provide fast operand accessors
00053   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00054 
00055   // vector compatibility methods
00056   unsigned size() const { return getNumOperands(); }
00057   void resize(unsigned);
00058   void push_back(Value *V) {
00059     unsigned OldOps(NumOperands), NewOps(NumOperands + 1);
00060     resize(NewOps);
00061     NumOperands = NewOps;
00062     OperandList[OldOps] = V;
00063   }
00064   
00065   void clear() {
00066     assert(ResolveConstants.empty() && "Constants not resolved?");
00067     if (OperandList) dropHungoffUses(OperandList);
00068     Capacity = 0;
00069   }
00070   
00071   Value *operator[](unsigned i) const { return getOperand(i); }
00072   
00073   Value *back() const { return getOperand(size() - 1); }
00074   void pop_back() { setOperand(size() - 1, 0); --NumOperands; }
00075   bool empty() const { return NumOperands == 0; }
00076   void shrinkTo(unsigned N) {
00077     assert(N <= NumOperands && "Invalid shrinkTo request!");
00078     while (NumOperands > N)
00079       pop_back();
00080   }
00081   virtual void print(std::ostream&) const {}
00082   
00083   Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);
00084   Value *getValueFwdRef(unsigned Idx, const Type *Ty);
00085   
00086   void AssignValue(Value *V, unsigned Idx) {
00087     if (Idx == size()) {
00088       push_back(V);
00089     } else if (Value *OldV = getOperand(Idx)) {
00090       // Handle constants and non-constants (e.g. instrs) differently for
00091       // efficiency.
00092       if (Constant *PHC = dyn_cast<Constant>(OldV)) {
00093         ResolveConstants.push_back(std::make_pair(PHC, Idx));
00094         setOperand(Idx, V);
00095       } else {
00096         // If there was a forward reference to this value, replace it.
00097         setOperand(Idx, V);
00098         OldV->replaceAllUsesWith(V);
00099         delete OldV;
00100       }
00101     } else {
00102       initVal(Idx, V);
00103     }
00104   }
00105   
00106   /// ResolveConstantForwardRefs - Once all constants are read, this method bulk
00107   /// resolves any forward references.
00108   void ResolveConstantForwardRefs();
00109   
00110 private:
00111   void initVal(unsigned Idx, Value *V) {
00112     if (Idx >= size()) {
00113       // Insert a bunch of null values.
00114       resize(Idx * 2 + 1);
00115     }
00116     assert(getOperand(Idx) == 0 && "Cannot init an already init'd Use!");
00117     OperandList[Idx] = V;
00118   }
00119 };
00120 
00121 template <>
00122 struct OperandTraits<BitcodeReaderValueList>
00123   : HungoffOperandTraits</*16 FIXME*/> {
00124 };
00125 
00126 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value)  
00127 
00128 class BitcodeReader : public ModuleProvider {
00129   MemoryBuffer *Buffer;
00130   BitstreamReader Stream;
00131   
00132   const char *ErrorString;
00133   
00134   std::vector<PATypeHolder> TypeList;
00135   BitcodeReaderValueList ValueList;
00136   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
00137   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
00138   
00139   /// MAttributes - The set of attributes by index.  Index zero in the
00140   /// file is for null, and is thus not represented here.  As such all indices
00141   /// are off by one.
00142   std::vector<AttrListPtr> MAttributes;
00143   
00144   /// FunctionBBs - While parsing a function body, this is a list of the basic
00145   /// blocks for the function.
00146   std::vector<BasicBlock*> FunctionBBs;
00147   
00148   // When reading the module header, this list is populated with functions that
00149   // have bodies later in the file.
00150   std::vector<Function*> FunctionsWithBodies;
00151 
00152   // When intrinsic functions are encountered which require upgrading they are 
00153   // stored here with their replacement function.
00154   typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap;
00155   UpgradedIntrinsicMap UpgradedIntrinsics;
00156   
00157   // After the module header has been read, the FunctionsWithBodies list is 
00158   // reversed.  This keeps track of whether we've done this yet.
00159   bool HasReversedFunctionsWithBodies;
00160   
00161   /// DeferredFunctionInfo - When function bodies are initially scanned, this
00162   /// map contains info about where to find deferred function body (in the
00163   /// stream) and what linkage the original function had.
00164   DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo;
00165 public:
00166   explicit BitcodeReader(MemoryBuffer *buffer)
00167       : Buffer(buffer), ErrorString(0) {
00168     HasReversedFunctionsWithBodies = false;
00169   }
00170   ~BitcodeReader() {
00171     FreeState();
00172   }
00173   
00174   void FreeState();
00175   
00176   /// releaseMemoryBuffer - This causes the reader to completely forget about
00177   /// the memory buffer it contains, which prevents the buffer from being
00178   /// destroyed when it is deleted.
00179   void releaseMemoryBuffer() {
00180     Buffer = 0;
00181   }
00182   
00183   virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0);
00184   virtual Module *materializeModule(std::string *ErrInfo = 0);
00185   virtual void dematerializeFunction(Function *F);
00186   virtual Module *releaseModule(std::string *ErrInfo = 0);
00187 
00188   bool Error(const char *Str) {
00189     ErrorString = Str;
00190     return true;
00191   }
00192   const char *getErrorString() const { return ErrorString; }
00193   
00194   /// @brief Main interface to parsing a bitcode buffer.
00195   /// @returns true if an error occurred.
00196   bool ParseBitcode();
00197 private:
00198   const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
00199   Value *getFnValueByID(unsigned ID, const Type *Ty) {
00200     return ValueList.getValueFwdRef(ID, Ty);
00201   }
00202   BasicBlock *getBasicBlock(unsigned ID) const {
00203     if (ID >= FunctionBBs.size()) return 0; // Invalid ID
00204     return FunctionBBs[ID];
00205   }
00206   AttrListPtr getAttributes(unsigned i) const {
00207     if (i-1 < MAttributes.size())
00208       return MAttributes[i-1];
00209     return AttrListPtr();
00210   }
00211   
00212   /// getValueTypePair - Read a value/type pair out of the specified record from
00213   /// slot 'Slot'.  Increment Slot past the number of slots used in the record.
00214   /// Return true on failure.
00215   bool getValueTypePair(SmallVector<uint64_t, 64> &Record, unsigned &Slot,
00216                         unsigned InstNum, Value *&ResVal) {
00217     if (Slot == Record.size()) return true;
00218     unsigned ValNo = (unsigned)Record[Slot++];
00219     if (ValNo < InstNum) {
00220       // If this is not a forward reference, just return the value we already
00221       // have.
00222       ResVal = getFnValueByID(ValNo, 0);
00223       return ResVal == 0;
00224     } else if (Slot == Record.size()) {
00225       return true;
00226     }
00227     
00228     unsigned TypeNo = (unsigned)Record[Slot++];
00229     ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
00230     return ResVal == 0;
00231   }
00232   bool getValue(SmallVector<uint64_t, 64> &Record, unsigned &Slot,
00233                 const Type *Ty, Value *&ResVal) {
00234     if (Slot == Record.size()) return true;
00235     unsigned ValNo = (unsigned)Record[Slot++];
00236     ResVal = getFnValueByID(ValNo, Ty);
00237     return ResVal == 0;
00238   }
00239 
00240   
00241   bool ParseModule(const std::string &ModuleID);
00242   bool ParseAttributeBlock();
00243   bool ParseTypeTable();
00244   bool ParseTypeSymbolTable();
00245   bool ParseValueSymbolTable();
00246   bool ParseConstants();
00247   bool RememberAndSkipFunctionBody();
00248   bool ParseFunctionBody(Function *F);
00249   bool ResolveGlobalAndAliasInits();
00250 };
00251   
00252 } // End llvm namespace
00253 
00254 #endif



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