OLD | NEW |
(Empty) | |
| 1 //===- NaClBitcodeReader.h ------------------------------------*- C++ -*-===// |
| 2 // Internal NaClBitcodeReader implementation |
| 3 // |
| 4 // The LLVM Compiler Infrastructure |
| 5 // |
| 6 // This file is distributed under the University of Illinois Open Source |
| 7 // License. See LICENSE.TXT for details. |
| 8 // |
| 9 //===----------------------------------------------------------------------===// |
| 10 // |
| 11 // This header defines the NaClBitcodeReader class. |
| 12 // |
| 13 //===----------------------------------------------------------------------===// |
| 14 |
| 15 #ifndef NACL_BITCODE_READER_H |
| 16 #define NACL_BITCODE_READER_H |
| 17 |
| 18 #include "llvm/ADT/DenseMap.h" |
| 19 #include "llvm/Analysis/NaCl/PNaClAllowedIntrinsics.h" |
| 20 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
| 21 #include "llvm/Bitcode/NaCl/NaClBitstreamReader.h" |
| 22 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" |
| 23 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
| 24 #include "llvm/IR/DerivedTypes.h" |
| 25 #include "llvm/IR/GVMaterializer.h" |
| 26 #include "llvm/IR/Instruction.h" |
| 27 #include "llvm/IR/OperandTraits.h" |
| 28 #include "llvm/IR/Type.h" |
| 29 #include "llvm/IR/ValueHandle.h" |
| 30 #include <vector> |
| 31 |
| 32 namespace llvm { |
| 33 class MemoryBuffer; |
| 34 class LLVMContext; |
| 35 class CastInst; |
| 36 |
| 37 // Models a Cast. Used to cache casts created in a basic block by the |
| 38 // PNaCl bitcode reader. |
| 39 struct NaClBitcodeReaderCast { |
| 40 // Fields of the conversion. |
| 41 Instruction::CastOps Op; |
| 42 Type *Ty; |
| 43 Value *Val; |
| 44 |
| 45 NaClBitcodeReaderCast(Instruction::CastOps Op, Type *Ty, Value *Val) |
| 46 : Op(Op), Ty(Ty), Val(Val) {} |
| 47 }; |
| 48 |
| 49 // Models the data structure used to hash/compare Casts in a DenseMap. |
| 50 template<> |
| 51 struct DenseMapInfo<NaClBitcodeReaderCast> { |
| 52 public: |
| 53 static NaClBitcodeReaderCast getEmptyKey() { |
| 54 return NaClBitcodeReaderCast(Instruction::CastOpsEnd, |
| 55 DenseMapInfo<Type*>::getEmptyKey(), |
| 56 DenseMapInfo<Value*>::getEmptyKey()); |
| 57 } |
| 58 static NaClBitcodeReaderCast getTombstoneKey() { |
| 59 return NaClBitcodeReaderCast(Instruction::CastOpsEnd, |
| 60 DenseMapInfo<Type*>::getTombstoneKey(), |
| 61 DenseMapInfo<Value*>::getTombstoneKey()); |
| 62 } |
| 63 static unsigned getHashValue(const NaClBitcodeReaderCast &C) { |
| 64 std::pair<int, std::pair<Type*, Value*> > Tuple; |
| 65 Tuple.first = C.Op; |
| 66 Tuple.second.first = C.Ty; |
| 67 Tuple.second.second = C.Val; |
| 68 return DenseMapInfo<std::pair<int, std::pair<Type*, Value*> > >::getHashValu
e(Tuple); |
| 69 } |
| 70 static bool isEqual(const NaClBitcodeReaderCast &LHS, |
| 71 const NaClBitcodeReaderCast &RHS) { |
| 72 return LHS.Op == RHS.Op && LHS.Ty == RHS.Ty && LHS.Val == RHS.Val; |
| 73 } |
| 74 }; |
| 75 |
| 76 //===----------------------------------------------------------------------===// |
| 77 // NaClBitcodeReaderValueList Class |
| 78 //===----------------------------------------------------------------------===// |
| 79 |
| 80 class NaClBitcodeReaderValueList { |
| 81 std::vector<WeakVH> ValuePtrs; |
| 82 public: |
| 83 NaClBitcodeReaderValueList() {} |
| 84 ~NaClBitcodeReaderValueList() {} |
| 85 |
| 86 // vector compatibility methods |
| 87 unsigned size() const { return ValuePtrs.size(); } |
| 88 void resize(unsigned N) { ValuePtrs.resize(N); } |
| 89 void push_back(Value *V) { |
| 90 ValuePtrs.push_back(V); |
| 91 } |
| 92 |
| 93 void clear() { |
| 94 ValuePtrs.clear(); |
| 95 } |
| 96 |
| 97 Value *operator[](unsigned i) const { |
| 98 assert(i < ValuePtrs.size()); |
| 99 return ValuePtrs[i]; |
| 100 } |
| 101 |
| 102 Value *back() const { return ValuePtrs.back(); } |
| 103 void pop_back() { ValuePtrs.pop_back(); } |
| 104 bool empty() const { return ValuePtrs.empty(); } |
| 105 void shrinkTo(unsigned N) { |
| 106 assert(N <= size() && "Invalid shrinkTo request!"); |
| 107 ValuePtrs.resize(N); |
| 108 } |
| 109 |
| 110 // Declares the type of the forward-referenced value Idx. Returns |
| 111 // true if an error occurred. It is an error if Idx's type has |
| 112 // already been declared. |
| 113 bool createValueFwdRef(unsigned Idx, Type *Ty); |
| 114 |
| 115 // Gets the forward reference value for Idx. |
| 116 Value *getValueFwdRef(unsigned Idx); |
| 117 |
| 118 // Assigns V to value index Idx. |
| 119 void AssignValue(Value *V, unsigned Idx); |
| 120 |
| 121 // Assigns Idx to the given value, overwriting the existing entry |
| 122 // and possibly modifying the type of the entry. |
| 123 void OverwriteValue(Value *V, unsigned Idx); |
| 124 }; |
| 125 |
| 126 |
| 127 class NaClBitcodeReader : public GVMaterializer { |
| 128 NaClBitcodeHeader Header; // Header fields of the PNaCl bitcode file. |
| 129 LLVMContext &Context; |
| 130 Module *TheModule; |
| 131 // If non-null, stream to write verbose errors to. |
| 132 raw_ostream *Verbose; |
| 133 PNaClAllowedIntrinsics AllowedIntrinsics; |
| 134 std::unique_ptr<MemoryBuffer> Buffer; |
| 135 std::unique_ptr<NaClBitstreamReader> StreamFile; |
| 136 NaClBitstreamCursor Stream; |
| 137 StreamingMemoryObject *LazyStreamer; |
| 138 uint64_t NextUnreadBit; |
| 139 bool SeenValueSymbolTable; |
| 140 std::vector<Type*> TypeList; |
| 141 NaClBitcodeReaderValueList ValueList; |
| 142 |
| 143 // Holds information about each BasicBlock in the function being read. |
| 144 struct BasicBlockInfo { |
| 145 // A basic block within the function being modeled. |
| 146 BasicBlock *BB; |
| 147 // The set of generated conversions. |
| 148 DenseMap<NaClBitcodeReaderCast, CastInst*> CastMap; |
| 149 // The set of generated conversions that were added for phi nodes, |
| 150 // and may need thier parent basic block defined. |
| 151 std::vector<CastInst*> PhiCasts; |
| 152 }; |
| 153 |
| 154 /// FunctionBBs - While parsing a function body, this is a list of the basic |
| 155 /// blocks for the function. |
| 156 std::vector<BasicBlockInfo> FunctionBBs; |
| 157 |
| 158 // When reading the module header, this list is populated with functions that |
| 159 // have bodies later in the file. |
| 160 std::vector<Function*> FunctionsWithBodies; |
| 161 |
| 162 // When intrinsic functions are encountered which require upgrading they are |
| 163 // stored here with their replacement function. |
| 164 typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap; |
| 165 UpgradedIntrinsicMap UpgradedIntrinsics; |
| 166 |
| 167 // Several operations happen after the module header has been read, but |
| 168 // before function bodies are processed. This keeps track of whether |
| 169 // we've done this yet. |
| 170 bool SeenFirstFunctionBody; |
| 171 |
| 172 /// DeferredFunctionInfo - When function bodies are initially scanned, this |
| 173 /// map contains info about where to find deferred function body in the |
| 174 /// stream. |
| 175 DenseMap<Function*, uint64_t> DeferredFunctionInfo; |
| 176 |
| 177 /// \brief True if we should only accept supported bitcode format. |
| 178 bool AcceptSupportedBitcodeOnly; |
| 179 |
| 180 /// \brief Integer type use for PNaCl conversion of pointers. |
| 181 Type *IntPtrType; |
| 182 |
| 183 static const std::error_category &BitcodeErrorCategory(); |
| 184 |
| 185 public: |
| 186 |
| 187 /// Types of errors reported. |
| 188 enum ErrorType { |
| 189 CouldNotFindFunctionInStream, // Unable to find function in bitcode stream. |
| 190 InsufficientFunctionProtos, |
| 191 InvalidBitstream, // Error in bitstream format. |
| 192 InvalidBlock, // Invalid block found in bitcode. |
| 193 InvalidConstantReference, // Bad constant reference. |
| 194 InvalidDataAfterModule, // Invalid data after module. |
| 195 InvalidInstructionWithNoBB, // No basic block for instruction. |
| 196 InvalidMultipleBlocks, // Multiple blocks for a kind of block that should |
| 197 // have only one. |
| 198 InvalidRecord, // Record doesn't have expected size or structure. |
| 199 InvalidSkippedBlock, // Unable to skip unknown block in bitcode file. |
| 200 InvalidType, // Invalid type in record. |
| 201 InvalidTypeForValue, // Type of value incorrect. |
| 202 InvalidValue, // Invalid value in record. |
| 203 MalformedBlock // Unable to advance over block. |
| 204 }; |
| 205 |
| 206 explicit NaClBitcodeReader(MemoryBuffer *buffer, LLVMContext &C, |
| 207 raw_ostream *Verbose, |
| 208 bool AcceptSupportedOnly) |
| 209 : Context(C), TheModule(nullptr), Verbose(Verbose), AllowedIntrinsics(&C), |
| 210 Buffer(buffer), |
| 211 LazyStreamer(nullptr), NextUnreadBit(0), SeenValueSymbolTable(false), |
| 212 ValueList(), |
| 213 SeenFirstFunctionBody(false), |
| 214 AcceptSupportedBitcodeOnly(AcceptSupportedOnly), |
| 215 IntPtrType(IntegerType::get(C, PNaClIntPtrTypeBitSize)) { |
| 216 } |
| 217 explicit NaClBitcodeReader(StreamingMemoryObject *streamer, |
| 218 LLVMContext &C, |
| 219 raw_ostream *Verbose, |
| 220 bool AcceptSupportedOnly) |
| 221 : Context(C), TheModule(nullptr), Verbose(Verbose), AllowedIntrinsics(&C), |
| 222 Buffer(nullptr), |
| 223 LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false), |
| 224 ValueList(), |
| 225 SeenFirstFunctionBody(false), |
| 226 AcceptSupportedBitcodeOnly(AcceptSupportedOnly), |
| 227 IntPtrType(IntegerType::get(C, PNaClIntPtrTypeBitSize)) { |
| 228 } |
| 229 ~NaClBitcodeReader() override { |
| 230 FreeState(); |
| 231 } |
| 232 |
| 233 void FreeState(); |
| 234 |
| 235 bool isDematerializable(const GlobalValue *GV) const override; |
| 236 std::error_code materialize(GlobalValue *GV) override; |
| 237 std::error_code MaterializeModule(Module *M) override; |
| 238 void Dematerialize(GlobalValue *GV) override; |
| 239 void releaseBuffer(); |
| 240 |
| 241 std::error_code Error(ErrorType E) const { |
| 242 return std::error_code(E, BitcodeErrorCategory()); |
| 243 } |
| 244 |
| 245 /// Generates the corresponding verbose Message, then generates error. |
| 246 std::error_code Error(ErrorType E, const std::string &Message) const; |
| 247 |
| 248 /// @brief Main interface to parsing a bitcode buffer. |
| 249 /// @returns true if an error occurred. |
| 250 std::error_code ParseBitcodeInto(Module *M); |
| 251 |
| 252 /// Convert alignment exponent (i.e. power of two (or zero)) to the |
| 253 /// corresponding alignment to use. If alignment is too large, it generates |
| 254 /// an error message and returns corresponding error code. |
| 255 std::error_code getAlignmentValue(uint64_t Exponent, unsigned &Alignment); |
| 256 |
| 257 private: |
| 258 // Returns false if Header is acceptable. |
| 259 bool AcceptHeader() const { |
| 260 return !(Header.IsSupported() || |
| 261 (!AcceptSupportedBitcodeOnly && Header.IsReadable())); |
| 262 } |
| 263 uint32_t GetPNaClVersion() const { |
| 264 return Header.GetPNaClVersion(); |
| 265 } |
| 266 Type *getTypeByID(unsigned ID); |
| 267 // Returns the value associated with ID. The value must already exist, |
| 268 // or a forward referenced value created by getOrCreateFnVaueByID. |
| 269 Value *getFnValueByID(unsigned ID) { |
| 270 return ValueList.getValueFwdRef(ID); |
| 271 } |
| 272 BasicBlock *getBasicBlock(unsigned ID) const { |
| 273 if (ID >= FunctionBBs.size()) return 0; // Invalid ID |
| 274 return FunctionBBs[ID].BB; |
| 275 } |
| 276 |
| 277 /// \brief Read a value out of the specified record from slot '*Slot'. |
| 278 /// Increment *Slot past the number of slots used by the value in the record. |
| 279 /// Return true if there is an error. |
| 280 bool popValue(const SmallVector<uint64_t, 64> &Record, unsigned *Slot, |
| 281 unsigned InstNum, Value **ResVal) { |
| 282 if (*Slot == Record.size()) return true; |
| 283 // ValNo is encoded relative to the InstNum. |
| 284 unsigned ValNo = InstNum - (unsigned)Record[(*Slot)++]; |
| 285 *ResVal = getFnValueByID(ValNo); |
| 286 return *ResVal == 0; |
| 287 } |
| 288 |
| 289 /// getValue -- Version of getValue that returns ResVal directly, |
| 290 /// or 0 if there is an error. |
| 291 Value *getValue(const SmallVector<uint64_t, 64> &Record, unsigned Slot, |
| 292 unsigned InstNum) { |
| 293 if (Slot == Record.size()) return 0; |
| 294 // ValNo is encoded relative to the InstNum. |
| 295 unsigned ValNo = InstNum - (unsigned)Record[Slot]; |
| 296 return getFnValueByID(ValNo); |
| 297 } |
| 298 |
| 299 /// getValueSigned -- Like getValue, but decodes signed VBRs. |
| 300 Value *getValueSigned(const SmallVector<uint64_t, 64> &Record, unsigned Slot, |
| 301 unsigned InstNum) { |
| 302 if (Slot == Record.size()) return 0; |
| 303 // ValNo is encoded relative to the InstNum. |
| 304 unsigned ValNo = InstNum - |
| 305 (unsigned) NaClDecodeSignRotatedValue(Record[Slot]); |
| 306 return getFnValueByID(ValNo); |
| 307 } |
| 308 |
| 309 /// \brief Create an (elided) cast instruction for basic block |
| 310 /// BBIndex. Op is the type of cast. V is the value to cast. CT |
| 311 /// is the type to convert V to. DeferInsertion defines whether the |
| 312 /// generated conversion should also be installed into basic block |
| 313 /// BBIndex. Note: For PHI nodes, we don't insert when created |
| 314 /// (i.e. DeferInsertion=true), since they must be inserted at the end |
| 315 /// of the corresponding incoming basic block. |
| 316 CastInst *CreateCast(unsigned BBIndex, Instruction::CastOps Op, |
| 317 Type *CT, Value *V, bool DeferInsertion = false); |
| 318 |
| 319 /// \brief Add instructions to cast Op to the given type T into |
| 320 /// block BBIndex. Follows rules for pointer conversion as defined |
| 321 /// in llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp. |
| 322 /// |
| 323 /// Returns 0 if unable to generate conversion value (also generates |
| 324 /// an appropriate error message and calls Error). |
| 325 Value *ConvertOpToType(Value *Op, Type *T, unsigned BBIndex); |
| 326 |
| 327 /// \brief If Op is a scalar value, this is a nop. If Op is a |
| 328 /// pointer value, a PtrToInt instruction is inserted (in BBIndex) |
| 329 /// to convert Op to an integer. For defaults on DeferInsertion, |
| 330 /// see comments for method CreateCast. |
| 331 Value *ConvertOpToScalar(Value *Op, unsigned BBIndex, |
| 332 bool DeferInsertion = false); |
| 333 |
| 334 /// \brief Install instruction I into basic block BB. |
| 335 std::error_code InstallInstruction(BasicBlock *BB, Instruction *I); |
| 336 |
| 337 FunctionType *AddPointerTypesToIntrinsicType(StringRef Name, |
| 338 FunctionType *FTy); |
| 339 void AddPointerTypesToIntrinsicParams(); |
| 340 std::error_code ParseModule(bool Resume); |
| 341 std::error_code ParseTypeTable(); |
| 342 std::error_code ParseTypeTableBody(); |
| 343 std::error_code ParseGlobalVars(); |
| 344 std::error_code ParseValueSymbolTable(); |
| 345 std::error_code ParseConstants(); |
| 346 std::error_code RememberAndSkipFunctionBody(); |
| 347 std::error_code ParseFunctionBody(Function *F); |
| 348 std::error_code GlobalCleanup(); |
| 349 std::error_code InitStream(); |
| 350 std::error_code InitStreamFromBuffer(); |
| 351 std::error_code InitLazyStream(); |
| 352 std::error_code FindFunctionInStream( |
| 353 Function *F, |
| 354 DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator); |
| 355 }; |
| 356 |
| 357 } // End llvm namespace |
| 358 |
| 359 #endif |
OLD | NEW |