Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW
« no previous file with comments | « lib/Bitcode/NaCl/Reader/NaClBitcodeParser.cpp ('k') | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698