blob: 8f157a64984efcb52154366f0fb93e59b04dc901 [file] [log] [blame]
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001//===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the PNaCl bitcode file to Ice, to machine code
11// translator.
12//
13//===----------------------------------------------------------------------===//
14
15#include "PNaClTranslator.h"
16#include "IceCfg.h"
Karl Schimpfd6064a12014-08-27 15:34:58 -070017#include "IceCfgNode.h"
18#include "IceClFlags.h"
19#include "IceDefs.h"
20#include "IceInst.h"
21#include "IceOperand.h"
22#include "IceTypeConverter.h"
Karl Schimpf8d7abae2014-07-07 14:50:30 -070023#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
24#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
25#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
26#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
27#include "llvm/IR/Constants.h"
28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/Module.h"
30#include "llvm/Support/Format.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include "llvm/Support/raw_ostream.h"
33#include "llvm/Support/ValueHandle.h"
34
35#include <vector>
36#include <cassert>
37
38using namespace llvm;
39
40namespace {
41
Karl Schimpfd6064a12014-08-27 15:34:58 -070042// TODO(kschimpf) Remove error recovery once implementation complete.
43static cl::opt<bool> AllowErrorRecovery(
44 "allow-pnacl-reader-error-recovery",
45 cl::desc("Allow error recovery when reading PNaCl bitcode."),
46 cl::init(false));
47
Karl Schimpf8d7abae2014-07-07 14:50:30 -070048// Top-level class to read PNaCl bitcode files, and translate to ICE.
49class TopLevelParser : public NaClBitcodeParser {
50 TopLevelParser(const TopLevelParser &) LLVM_DELETED_FUNCTION;
51 TopLevelParser &operator=(const TopLevelParser &) LLVM_DELETED_FUNCTION;
52
53public:
Karl Schimpfd6064a12014-08-27 15:34:58 -070054 TopLevelParser(Ice::Translator &Translator, const std::string &InputName,
55 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor,
56 bool &ErrorStatus)
57 : NaClBitcodeParser(Cursor), Translator(Translator),
Karl Schimpf8d7abae2014-07-07 14:50:30 -070058 Mod(new Module(InputName, getGlobalContext())), Header(Header),
Karl Schimpfd6064a12014-08-27 15:34:58 -070059 TypeConverter(getLLVMContext()), ErrorStatus(ErrorStatus), NumErrors(0),
60 NumFunctionIds(0), NumFunctionBlocks(0),
61 GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -070062 Mod->setDataLayout(PNaClDataLayout);
63 }
64
65 virtual ~TopLevelParser() {}
66 LLVM_OVERRIDE;
67
Karl Schimpfd6064a12014-08-27 15:34:58 -070068 Ice::Translator &getTranslator() { return Translator; }
69
70 // Generates error with given Message. Always returns true.
Karl Schimpf8d7abae2014-07-07 14:50:30 -070071 virtual bool Error(const std::string &Message) LLVM_OVERRIDE {
Karl Schimpfb164d202014-07-11 10:26:34 -070072 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -070073 ++NumErrors;
Karl Schimpfd6064a12014-08-27 15:34:58 -070074 NaClBitcodeParser::Error(Message);
75 if (!AllowErrorRecovery)
76 report_fatal_error("Unable to continue");
77 return true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -070078 }
79
80 /// Returns the number of errors found while parsing the bitcode
81 /// file.
82 unsigned getNumErrors() const { return NumErrors; }
83
84 /// Returns the LLVM module associated with the translation.
85 Module *getModule() const { return Mod.get(); }
86
87 /// Returns the number of bytes in the bitcode header.
88 size_t getHeaderSize() const { return Header.getHeaderSize(); }
89
90 /// Returns the llvm context to use.
91 LLVMContext &getLLVMContext() const { return Mod->getContext(); }
92
93 /// Changes the size of the type list to the given size.
94 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); }
95
96 /// Returns the type associated with the given index.
97 Type *getTypeByID(unsigned ID) {
98 // Note: method resizeTypeIDValues expands TypeIDValues
99 // to the specified size, and fills elements with NULL.
100 Type *Ty = ID < TypeIDValues.size() ? TypeIDValues[ID] : NULL;
101 if (Ty)
102 return Ty;
103 return reportTypeIDAsUndefined(ID);
104 }
105
106 /// Defines type for ID.
107 void setTypeID(unsigned ID, Type *Ty) {
108 if (ID < TypeIDValues.size() && TypeIDValues[ID] == NULL) {
109 TypeIDValues[ID] = Ty;
110 return;
111 }
112 reportBadSetTypeID(ID, Ty);
113 }
114
115 /// Sets the next function ID to the given LLVM function.
116 void setNextFunctionID(Function *Fcn) {
117 ++NumFunctionIds;
118 ValueIDValues.push_back(Fcn);
119 }
120
121 /// Defines the next function ID as one that has an implementation
122 /// (i.e a corresponding function block in the bitcode).
123 void setNextValueIDAsImplementedFunction() {
124 DefiningFunctionsList.push_back(ValueIDValues.size());
125 }
126
Karl Schimpfd6064a12014-08-27 15:34:58 -0700127 /// Returns the value id that should be associated with the the
128 /// current function block. Increments internal counters during call
129 /// so that it will be in correct position for next function block.
130 unsigned getNextFunctionBlockValueID() {
131 if (NumFunctionBlocks >= DefiningFunctionsList.size())
132 report_fatal_error(
133 "More function blocks than defined function addresses");
134 return DefiningFunctionsList[NumFunctionBlocks++];
135 }
136
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700137 /// Returns the LLVM IR value associatd with the global value ID.
138 Value *getGlobalValueByID(unsigned ID) const {
139 if (ID >= ValueIDValues.size())
Karl Schimpfd6064a12014-08-27 15:34:58 -0700140 return NULL;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700141 return ValueIDValues[ID];
142 }
143
144 /// Returns the number of function addresses (i.e. ID's) defined in
145 /// the bitcode file.
146 unsigned getNumFunctionIDs() const { return NumFunctionIds; }
147
148 /// Returns the number of global values defined in the bitcode
149 /// file.
150 unsigned getNumGlobalValueIDs() const { return ValueIDValues.size(); }
151
152 /// Resizes the list of value IDs to include Count global variable
153 /// IDs.
154 void resizeValueIDsForGlobalVarCount(unsigned Count) {
155 ValueIDValues.resize(ValueIDValues.size() + Count);
156 }
157
158 /// Returns the global variable address associated with the given
159 /// value ID. If the ID refers to a global variable address not yet
160 /// defined, a placeholder is created so that we can fix it up
161 /// later.
162 Constant *getOrCreateGlobalVarRef(unsigned ID) {
163 if (ID >= ValueIDValues.size())
Karl Schimpfd6064a12014-08-27 15:34:58 -0700164 return NULL;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700165 if (Value *C = ValueIDValues[ID])
166 return dyn_cast<Constant>(C);
167 Constant *C = new GlobalVariable(*Mod, GlobalVarPlaceHolderType, false,
168 GlobalValue::ExternalLinkage, 0);
169 ValueIDValues[ID] = C;
170 return C;
171 }
172
173 /// Assigns the given global variable (address) to the given value
174 /// ID. Returns true if ID is a valid global variable ID. Otherwise
175 /// returns false.
176 bool assignGlobalVariable(GlobalVariable *GV, unsigned ID) {
177 if (ID < NumFunctionIds || ID >= ValueIDValues.size())
178 return false;
179 WeakVH &OldV = ValueIDValues[ID];
Karl Schimpfd6064a12014-08-27 15:34:58 -0700180 if (OldV == NULL) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700181 ValueIDValues[ID] = GV;
182 return true;
183 }
184
185 // If reached, there was a forward reference to this value. Replace it.
186 Value *PrevVal = OldV;
187 GlobalVariable *Placeholder = cast<GlobalVariable>(PrevVal);
188 Placeholder->replaceAllUsesWith(
189 ConstantExpr::getBitCast(GV, Placeholder->getType()));
190 Placeholder->eraseFromParent();
191 ValueIDValues[ID] = GV;
192 return true;
193 }
194
Karl Schimpfd6064a12014-08-27 15:34:58 -0700195 /// Returns the corresponding ICE type for LLVMTy.
196 Ice::Type convertToIceType(Type *LLVMTy) {
197 Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy);
198 if (IceTy >= Ice::IceType_NUM) {
199 return convertToIceTypeError(LLVMTy);
200 }
201 return IceTy;
202 }
203
204 /// Returns the corresponding LLVM type for IceTy.
205 Type *convertToLLVMType(Ice::Type IceTy) const {
206 return TypeConverter.convertToLLVMType(IceTy);
207 }
208
209 /// Returns the LLVM integer type with the given number of Bits. If
210 /// Bits is not a valid PNaCl type, returns NULL.
211 Type *getLLVMIntegerType(unsigned Bits) const {
212 return TypeConverter.getLLVMIntegerType(Bits);
213 }
214
215 /// Returns the LLVM vector with the given Size and Ty. If not a
216 /// valid PNaCl vector type, returns NULL.
217 Type *getLLVMVectorType(unsigned Size, Ice::Type Ty) const {
218 return TypeConverter.getLLVMVectorType(Size, Ty);
219 }
220
221 /// Returns the model for pointer types in ICE.
222 Ice::Type getIcePointerType() const {
223 return TypeConverter.getIcePointerType();
224 }
225
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700226private:
Karl Schimpfd6064a12014-08-27 15:34:58 -0700227 // The translator associated with the parser.
228 Ice::Translator &Translator;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700229 // The parsed module.
230 OwningPtr<Module> Mod;
231 // The bitcode header.
232 NaClBitcodeHeader &Header;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700233 // Converter between LLVM and ICE types.
234 Ice::TypeConverter TypeConverter;
Karl Schimpfb164d202014-07-11 10:26:34 -0700235 // The exit status that should be set to true if an error occurs.
236 bool &ErrorStatus;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700237 // The number of errors reported.
238 unsigned NumErrors;
239 // The types associated with each type ID.
240 std::vector<Type *> TypeIDValues;
241 // The (global) value IDs.
242 std::vector<WeakVH> ValueIDValues;
243 // The number of function IDs.
244 unsigned NumFunctionIds;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700245 // The number of function blocks (processed so far).
246 unsigned NumFunctionBlocks;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700247 // The list of value IDs (in the order found) of defining function
248 // addresses.
249 std::vector<unsigned> DefiningFunctionsList;
250 // Cached global variable placeholder type. Used for all forward
251 // references to global variable addresses.
252 Type *GlobalVarPlaceHolderType;
253
254 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
255
256 /// Reports that type ID is undefined, and then returns
257 /// the void type.
258 Type *reportTypeIDAsUndefined(unsigned ID);
259
260 /// Reports error about bad call to setTypeID.
261 void reportBadSetTypeID(unsigned ID, Type *Ty);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700262
263 // Reports that there is no corresponding ICE type for LLVMTy, and
264 // returns ICE::IceType_void.
265 Ice::Type convertToIceTypeError(Type *LLVMTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700266};
267
268Type *TopLevelParser::reportTypeIDAsUndefined(unsigned ID) {
269 std::string Buffer;
270 raw_string_ostream StrBuf(Buffer);
271 StrBuf << "Can't find type for type id: " << ID;
272 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700273 // TODO(kschimpf) Remove error recovery once implementation complete.
274 Type *Ty = TypeConverter.convertToLLVMType(Ice::IceType_void);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700275 // To reduce error messages, update type list if possible.
276 if (ID < TypeIDValues.size())
277 TypeIDValues[ID] = Ty;
278 return Ty;
279}
280
281void TopLevelParser::reportBadSetTypeID(unsigned ID, Type *Ty) {
282 std::string Buffer;
283 raw_string_ostream StrBuf(Buffer);
284 if (ID >= TypeIDValues.size()) {
285 StrBuf << "Type index " << ID << " out of range: can't install.";
286 } else {
287 // Must be case that index already defined.
288 StrBuf << "Type index " << ID << " defined as " << *TypeIDValues[ID]
289 << " and " << *Ty << ".";
290 }
291 Error(StrBuf.str());
292}
293
Karl Schimpfd6064a12014-08-27 15:34:58 -0700294Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
295 std::string Buffer;
296 raw_string_ostream StrBuf(Buffer);
297 StrBuf << "Invalid LLVM type: " << *LLVMTy;
298 Error(StrBuf.str());
299 return Ice::IceType_void;
300}
301
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700302// Base class for parsing blocks within the bitcode file. Note:
303// Because this is the base class of block parsers, we generate error
304// messages if ParseBlock or ParseRecord is not overridden in derived
305// classes.
306class BlockParserBaseClass : public NaClBitcodeParser {
307public:
308 // Constructor for the top-level module block parser.
309 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
310 : NaClBitcodeParser(BlockID, Context), Context(Context) {}
311
312 virtual ~BlockParserBaseClass() LLVM_OVERRIDE {}
313
314protected:
315 // The context parser that contains the decoded state.
316 TopLevelParser *Context;
317
318 // Constructor for nested block parsers.
319 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
320 : NaClBitcodeParser(BlockID, EnclosingParser),
321 Context(EnclosingParser->Context) {}
322
Karl Schimpfd6064a12014-08-27 15:34:58 -0700323 // Gets the translator associated with the bitcode parser.
324 Ice::Translator &getTranslator() { return Context->getTranslator(); }
325
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700326 // Generates an error Message with the bit address prefixed to it.
327 virtual bool Error(const std::string &Message) LLVM_OVERRIDE {
328 uint64_t Bit = Record.GetStartBit() + Context->getHeaderSize() * 8;
329 std::string Buffer;
330 raw_string_ostream StrBuf(Buffer);
331 StrBuf << "(" << format("%" PRIu64 ":%u", (Bit / 8),
332 static_cast<unsigned>(Bit % 8)) << ") " << Message;
333 return Context->Error(StrBuf.str());
334 }
335
336 // Default implementation. Reports that block is unknown and skips
337 // its contents.
338 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
339
340 // Default implementation. Reports that the record is not
341 // understood.
342 virtual void ProcessRecord() LLVM_OVERRIDE;
343
Karl Schimpfd6064a12014-08-27 15:34:58 -0700344 // Checks if the size of the record is Size. Return true if valid.
345 // Otherwise generates an error and returns false.
346 bool isValidRecordSize(unsigned Size, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700347 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700348 if (Values.size() == Size)
349 return true;
350 ReportRecordSizeError(Size, RecordName, NULL);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700351 return false;
352 }
353
Karl Schimpfd6064a12014-08-27 15:34:58 -0700354 // Checks if the size of the record is at least as large as the
355 // LowerLimit. Returns true if valid. Otherwise generates an error
356 // and returns false.
357 bool isValidRecordSizeAtLeast(unsigned LowerLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700358 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700359 if (Values.size() >= LowerLimit)
360 return true;
361 ReportRecordSizeError(LowerLimit, RecordName, "at least");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700362 return false;
363 }
364
Karl Schimpfd6064a12014-08-27 15:34:58 -0700365 // Checks if the size of the record is no larger than the
366 // UpperLimit. Returns true if valid. Otherwise generates an error
367 // and returns false.
368 bool isValidRecordSizeAtMost(unsigned UpperLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700369 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700370 if (Values.size() <= UpperLimit)
371 return true;
372 ReportRecordSizeError(UpperLimit, RecordName, "no more than");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700373 return false;
374 }
375
Karl Schimpfd6064a12014-08-27 15:34:58 -0700376 // Checks if the size of the record is at least as large as the
377 // LowerLimit, and no larger than the UpperLimit. Returns true if
378 // valid. Otherwise generates an error and returns false.
379 bool isValidRecordSizeInRange(unsigned LowerLimit, unsigned UpperLimit,
380 const char *RecordName) {
381 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
382 isValidRecordSizeAtMost(UpperLimit, RecordName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700383 }
384
385private:
386 /// Generates a record size error. ExpectedSize is the number
387 /// of elements expected. RecordName is the name of the kind of
Karl Schimpfd6064a12014-08-27 15:34:58 -0700388 /// record that has incorrect size. ContextMessage (if not NULL)
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700389 /// is appended to "record expects" to describe how ExpectedSize
390 /// should be interpreted.
Karl Schimpfd6064a12014-08-27 15:34:58 -0700391 void ReportRecordSizeError(unsigned ExpectedSize, const char *RecordName,
392 const char *ContextMessage);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700393};
394
Karl Schimpfd6064a12014-08-27 15:34:58 -0700395void BlockParserBaseClass::ReportRecordSizeError(unsigned ExpectedSize,
396 const char *RecordName,
397 const char *ContextMessage) {
398 std::string Buffer;
399 raw_string_ostream StrBuf(Buffer);
400 StrBuf << RecordName << " record expects";
401 if (ContextMessage)
402 StrBuf << " " << ContextMessage;
403 StrBuf << " " << ExpectedSize << " argument";
404 if (ExpectedSize > 1)
405 StrBuf << "s";
406 StrBuf << ". Found: " << Record.GetValues().size();
407 Error(StrBuf.str());
408}
409
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700410bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
411 // If called, derived class doesn't know how to handle block.
412 // Report error and skip.
413 std::string Buffer;
414 raw_string_ostream StrBuf(Buffer);
415 StrBuf << "Don't know how to parse block id: " << BlockID;
416 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700417 // TODO(kschimpf) Remove error recovery once implementation complete.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700418 SkipBlock();
419 return false;
420}
421
422void BlockParserBaseClass::ProcessRecord() {
423 // If called, derived class doesn't know how to handle.
424 std::string Buffer;
425 raw_string_ostream StrBuf(Buffer);
426 StrBuf << "Don't know how to process record: " << Record;
427 Error(StrBuf.str());
428}
429
430// Class to parse a types block.
431class TypesParser : public BlockParserBaseClass {
432public:
433 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
434 : BlockParserBaseClass(BlockID, EnclosingParser), NextTypeId(0) {}
435
436 ~TypesParser() LLVM_OVERRIDE {}
437
438private:
439 // The type ID that will be associated with the next type defining
440 // record in the types block.
441 unsigned NextTypeId;
442
443 virtual void ProcessRecord() LLVM_OVERRIDE;
444};
445
446void TypesParser::ProcessRecord() {
447 Type *Ty = NULL;
448 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
449 switch (Record.GetCode()) {
450 case naclbitc::TYPE_CODE_NUMENTRY:
451 // NUMENTRY: [numentries]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700452 if (!isValidRecordSize(1, "Type count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700453 return;
454 Context->resizeTypeIDValues(Values[0]);
455 return;
456 case naclbitc::TYPE_CODE_VOID:
457 // VOID
Karl Schimpfd6064a12014-08-27 15:34:58 -0700458 if (!isValidRecordSize(0, "Type void"))
459 return;
460 Ty = Context->convertToLLVMType(Ice::IceType_void);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700461 break;
462 case naclbitc::TYPE_CODE_FLOAT:
463 // FLOAT
Karl Schimpfd6064a12014-08-27 15:34:58 -0700464 if (!isValidRecordSize(0, "Type float"))
465 return;
466 Ty = Context->convertToLLVMType(Ice::IceType_f32);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700467 break;
468 case naclbitc::TYPE_CODE_DOUBLE:
469 // DOUBLE
Karl Schimpfd6064a12014-08-27 15:34:58 -0700470 if (!isValidRecordSize(0, "Type double"))
471 return;
472 Ty = Context->convertToLLVMType(Ice::IceType_f64);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700473 break;
474 case naclbitc::TYPE_CODE_INTEGER:
475 // INTEGER: [width]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700476 if (!isValidRecordSize(1, "Type integer"))
477 return;
478 Ty = Context->getLLVMIntegerType(Values[0]);
479 if (Ty == NULL) {
480 std::string Buffer;
481 raw_string_ostream StrBuf(Buffer);
482 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
483 Error(StrBuf.str());
484 // TODO(kschimpf) Remove error recovery once implementation complete.
485 // Fix type so that we can continue.
486 Ty = Context->convertToLLVMType(Ice::IceType_i32);
487 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700488 break;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700489 case naclbitc::TYPE_CODE_VECTOR: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700490 // VECTOR: [numelts, eltty]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700491 if (!isValidRecordSize(2, "Type vector"))
492 return;
493 Type *BaseTy = Context->getTypeByID(Values[1]);
494 Ty = Context->getLLVMVectorType(Values[0],
495 Context->convertToIceType(BaseTy));
496 if (Ty == NULL) {
497 std::string Buffer;
498 raw_string_ostream StrBuf(Buffer);
499 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << *BaseTy
500 << ">";
501 Error(StrBuf.str());
502 Ty = Context->convertToLLVMType(Ice::IceType_void);
503 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700504 break;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700505 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700506 case naclbitc::TYPE_CODE_FUNCTION: {
507 // FUNCTION: [vararg, retty, paramty x N]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700508 if (!isValidRecordSizeAtLeast(2, "Type signature"))
509 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700510 SmallVector<Type *, 8> ArgTys;
511 for (unsigned i = 2, e = Values.size(); i != e; ++i) {
512 ArgTys.push_back(Context->getTypeByID(Values[i]));
513 }
514 Ty = FunctionType::get(Context->getTypeByID(Values[1]), ArgTys, Values[0]);
515 break;
516 }
517 default:
518 BlockParserBaseClass::ProcessRecord();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700519 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700520 }
521 // If Ty not defined, assume error. Use void as filler.
522 if (Ty == NULL)
Karl Schimpfd6064a12014-08-27 15:34:58 -0700523 Ty = Context->convertToLLVMType(Ice::IceType_void);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700524 Context->setTypeID(NextTypeId++, Ty);
525}
526
527/// Parses the globals block (i.e. global variables).
528class GlobalsParser : public BlockParserBaseClass {
529public:
530 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
531 : BlockParserBaseClass(BlockID, EnclosingParser), InitializersNeeded(0),
532 Alignment(1), IsConstant(false) {
533 NextGlobalID = Context->getNumFunctionIDs();
534 }
535
536 virtual ~GlobalsParser() LLVM_OVERRIDE {}
537
538private:
539 // Holds the sequence of initializers for the global.
540 SmallVector<Constant *, 10> Initializers;
541
542 // Keeps track of how many initializers are expected for
543 // the global variable being built.
544 unsigned InitializersNeeded;
545
546 // The alignment assumed for the global variable being built.
547 unsigned Alignment;
548
549 // True if the global variable being built is a constant.
550 bool IsConstant;
551
552 // The index of the next global variable.
553 unsigned NextGlobalID;
554
555 virtual void ExitBlock() LLVM_OVERRIDE {
556 verifyNoMissingInitializers();
557 unsigned NumIDs = Context->getNumGlobalValueIDs();
558 if (NextGlobalID < NumIDs) {
559 unsigned NumFcnIDs = Context->getNumFunctionIDs();
560 std::string Buffer;
561 raw_string_ostream StrBuf(Buffer);
562 StrBuf << "Globals block expects " << (NumIDs - NumFcnIDs)
563 << " global definitions. Found: " << (NextGlobalID - NumFcnIDs);
564 Error(StrBuf.str());
565 }
566 BlockParserBaseClass::ExitBlock();
567 }
568
569 virtual void ProcessRecord() LLVM_OVERRIDE;
570
571 // Checks if the number of initializers needed is the same as the
572 // number found in the bitcode file. If different, and error message
573 // is generated, and the internal state of the parser is fixed so
574 // this condition is no longer violated.
575 void verifyNoMissingInitializers() {
576 if (InitializersNeeded != Initializers.size()) {
577 std::string Buffer;
578 raw_string_ostream StrBuf(Buffer);
579 StrBuf << "Global variable @g"
580 << (NextGlobalID - Context->getNumFunctionIDs()) << " expected "
581 << InitializersNeeded << " initializer";
582 if (InitializersNeeded > 1)
583 StrBuf << "s";
584 StrBuf << ". Found: " << Initializers.size();
585 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700586 // TODO(kschimpf) Remove error recovery once implementation complete.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700587 // Fix up state so that we can continue.
588 InitializersNeeded = Initializers.size();
589 installGlobalVar();
590 }
591 }
592
593 // Reserves a slot in the list of initializers being built. If there
594 // isn't room for the slot, an error message is generated.
595 void reserveInitializer(const char *RecordName) {
596 if (InitializersNeeded <= Initializers.size()) {
597 Error(std::string(RecordName) +
598 " record: Too many initializers, ignoring.");
599 }
600 }
601
602 // Takes the initializers (and other parser state values) and
603 // installs a global variable (with the initializers) into the list
604 // of ValueIDs.
605 void installGlobalVar() {
606 Constant *Init = NULL;
607 switch (Initializers.size()) {
608 case 0:
609 Error("No initializer for global variable in global vars block");
610 return;
611 case 1:
612 Init = Initializers[0];
613 break;
614 default:
615 Init = ConstantStruct::getAnon(Context->getLLVMContext(), Initializers,
616 true);
617 break;
618 }
619 GlobalVariable *GV =
620 new GlobalVariable(*Context->getModule(), Init->getType(), IsConstant,
621 GlobalValue::InternalLinkage, Init, "");
622 GV->setAlignment(Alignment);
623 if (!Context->assignGlobalVariable(GV, NextGlobalID)) {
624 std::string Buffer;
625 raw_string_ostream StrBuf(Buffer);
626 StrBuf << "Defining global V[" << NextGlobalID
627 << "] not allowed. Out of range.";
628 Error(StrBuf.str());
629 }
630 ++NextGlobalID;
631 Initializers.clear();
632 InitializersNeeded = 0;
633 Alignment = 1;
634 IsConstant = false;
635 }
636};
637
638void GlobalsParser::ProcessRecord() {
639 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
640 switch (Record.GetCode()) {
641 case naclbitc::GLOBALVAR_COUNT:
642 // COUNT: [n]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700643 if (!isValidRecordSize(1, "Globals count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700644 return;
645 if (NextGlobalID != Context->getNumFunctionIDs()) {
646 Error("Globals count record not first in block.");
647 return;
648 }
649 verifyNoMissingInitializers();
650 Context->resizeValueIDsForGlobalVarCount(Values[0]);
651 return;
652 case naclbitc::GLOBALVAR_VAR: {
653 // VAR: [align, isconst]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700654 if (!isValidRecordSize(2, "Globals variable"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700655 return;
656 verifyNoMissingInitializers();
657 InitializersNeeded = 1;
658 Initializers.clear();
659 Alignment = (1 << Values[0]) >> 1;
660 IsConstant = Values[1] != 0;
661 return;
662 }
663 case naclbitc::GLOBALVAR_COMPOUND:
664 // COMPOUND: [size]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700665 if (!isValidRecordSize(1, "globals compound"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700666 return;
667 if (Initializers.size() > 0 || InitializersNeeded != 1) {
668 Error("Globals compound record not first initializer");
669 return;
670 }
671 if (Values[0] < 2) {
672 std::string Buffer;
673 raw_string_ostream StrBuf(Buffer);
674 StrBuf << "Globals compound record size invalid. Found: " << Values[0];
675 Error(StrBuf.str());
676 return;
677 }
678 InitializersNeeded = Values[0];
679 return;
680 case naclbitc::GLOBALVAR_ZEROFILL: {
681 // ZEROFILL: [size]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700682 if (!isValidRecordSize(1, "Globals zerofill"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700683 return;
684 reserveInitializer("Globals zerofill");
685 Type *Ty =
Karl Schimpfd6064a12014-08-27 15:34:58 -0700686 ArrayType::get(Context->convertToLLVMType(Ice::IceType_i8), Values[0]);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700687 Constant *Zero = ConstantAggregateZero::get(Ty);
688 Initializers.push_back(Zero);
689 break;
690 }
691 case naclbitc::GLOBALVAR_DATA: {
692 // DATA: [b0, b1, ...]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700693 if (!isValidRecordSizeAtLeast(1, "Globals data"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700694 return;
695 reserveInitializer("Globals data");
696 unsigned Size = Values.size();
697 SmallVector<uint8_t, 32> Buf;
698 for (unsigned i = 0; i < Size; ++i)
699 Buf.push_back(static_cast<uint8_t>(Values[i]));
700 Constant *Init = ConstantDataArray::get(
701 Context->getLLVMContext(), ArrayRef<uint8_t>(Buf.data(), Buf.size()));
702 Initializers.push_back(Init);
703 break;
704 }
705 case naclbitc::GLOBALVAR_RELOC: {
706 // RELOC: [val, [addend]]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700707 if (!isValidRecordSizeInRange(1, 2, "Globals reloc"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700708 return;
709 Constant *BaseVal = Context->getOrCreateGlobalVarRef(Values[0]);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700710 if (BaseVal == NULL) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700711 std::string Buffer;
712 raw_string_ostream StrBuf(Buffer);
713 StrBuf << "Can't find global relocation value: " << Values[0];
714 Error(StrBuf.str());
715 return;
716 }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700717 Type *IntPtrType = Context->convertToLLVMType(Context->getIcePointerType());
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700718 Constant *Val = ConstantExpr::getPtrToInt(BaseVal, IntPtrType);
719 if (Values.size() == 2) {
720 Val = ConstantExpr::getAdd(Val, ConstantInt::get(IntPtrType, Values[1]));
721 }
722 Initializers.push_back(Val);
723 break;
724 }
725 default:
726 BlockParserBaseClass::ProcessRecord();
727 return;
728 }
729 // If reached, just processed another initializer. See if time
730 // to install global.
731 if (InitializersNeeded == Initializers.size())
732 installGlobalVar();
733}
734
735// Parses a valuesymtab block in the bitcode file.
736class ValuesymtabParser : public BlockParserBaseClass {
737 typedef SmallString<128> StringType;
738
739public:
740 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
741 bool AllowBbEntries)
742 : BlockParserBaseClass(BlockID, EnclosingParser),
743 AllowBbEntries(AllowBbEntries) {}
744
745 virtual ~ValuesymtabParser() LLVM_OVERRIDE {}
746
747private:
748 // True if entries to name basic blocks allowed.
749 bool AllowBbEntries;
750
751 virtual void ProcessRecord() LLVM_OVERRIDE;
752
753 void ConvertToString(StringType &ConvertedName) {
754 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
755 for (size_t i = 1, e = Values.size(); i != e; ++i) {
756 ConvertedName += static_cast<char>(Values[i]);
757 }
758 }
759};
760
761void ValuesymtabParser::ProcessRecord() {
762 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
763 StringType ConvertedName;
764 switch (Record.GetCode()) {
765 case naclbitc::VST_CODE_ENTRY: {
766 // VST_ENTRY: [ValueId, namechar x N]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700767 if (!isValidRecordSizeAtLeast(2, "Valuesymtab value entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700768 return;
769 ConvertToString(ConvertedName);
770 Value *V = Context->getGlobalValueByID(Values[0]);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700771 if (V == NULL) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700772 std::string Buffer;
773 raw_string_ostream StrBuf(Buffer);
774 StrBuf << "Invalid global address ID in valuesymtab: " << Values[0];
775 Error(StrBuf.str());
776 return;
777 }
778 V->setName(StringRef(ConvertedName.data(), ConvertedName.size()));
779 return;
780 }
781 case naclbitc::VST_CODE_BBENTRY: {
782 // VST_BBENTRY: [BbId, namechar x N]
783 // For now, since we aren't processing function blocks, don't handle.
784 if (AllowBbEntries) {
785 Error("Valuesymtab bb entry not implemented");
786 return;
787 }
788 break;
789 }
790 default:
791 break;
792 }
793 // If reached, don't know how to handle record.
794 BlockParserBaseClass::ProcessRecord();
795 return;
796}
797
Karl Schimpfd6064a12014-08-27 15:34:58 -0700798/// Parses function blocks in the bitcode file.
799class FunctionParser : public BlockParserBaseClass {
800 FunctionParser(const FunctionParser &) LLVM_DELETED_FUNCTION;
801 FunctionParser &operator=(const FunctionParser &) LLVM_DELETED_FUNCTION;
802
803public:
804 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
805 : BlockParserBaseClass(BlockID, EnclosingParser),
806 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0),
807 FcnId(Context->getNextFunctionBlockValueID()),
808 LLVMFunc(cast<Function>(Context->getGlobalValueByID(FcnId))),
809 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()),
810 InstIsTerminating(false) {
811 Func->setFunctionName(LLVMFunc->getName());
812 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType()));
813 Func->setInternal(LLVMFunc->hasInternalLinkage());
814 CurrentNode = InstallNextBasicBlock();
815 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(),
816 ArgE = LLVMFunc->arg_end();
817 ArgI != ArgE; ++ArgI) {
818 Func->addArg(NextInstVar(Context->convertToIceType(ArgI->getType())));
819 }
820 }
821
822 ~FunctionParser() LLVM_OVERRIDE;
823
824private:
825 // Timer for reading function bitcode and converting to ICE.
826 Ice::Timer TConvert;
827 // The corresponding ICE function defined by the function block.
828 Ice::Cfg *Func;
829 // The index to the current basic block being built.
830 uint32_t CurrentBbIndex;
831 // The basic block being built.
832 Ice::CfgNode *CurrentNode;
833 // The ID for the function.
834 unsigned FcnId;
835 // The corresponding LLVM function.
836 Function *LLVMFunc;
837 // Holds operands local to the function block, based on indices
838 // defined in the bitcode file.
839 std::vector<Ice::Operand *> LocalOperands;
840 // Holds the dividing point between local and global absolute value indices.
841 uint32_t CachedNumGlobalValueIDs;
842 // True if the last processed instruction was a terminating
843 // instruction.
844 bool InstIsTerminating;
845
846 virtual void ProcessRecord() LLVM_OVERRIDE;
847
848 virtual void ExitBlock() LLVM_OVERRIDE;
849
850 // Creates and appends a new basic block to the list of basic blocks.
851 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); }
852
853 // Returns the Index-th basic block in the list of basic blocks.
854 Ice::CfgNode *GetBasicBlock(uint32_t Index) {
855 const Ice::NodeList &Nodes = Func->getNodes();
856 if (Index >= Nodes.size()) {
857 std::string Buffer;
858 raw_string_ostream StrBuf(Buffer);
859 StrBuf << "Reference to basic block " << Index
860 << " not found. Must be less than " << Nodes.size();
861 Error(StrBuf.str());
862 // TODO(kschimpf) Remove error recovery once implementation complete.
863 Index = 0;
864 }
865 return Nodes[Index];
866 }
867
868 // Generates the next available local variable using the given
869 // type. Note: if Ty is void, this function returns NULL.
870 Ice::Variable *NextInstVar(Ice::Type Ty) {
871 if (Ty == Ice::IceType_void)
872 return NULL;
873 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode);
874 LocalOperands.push_back(Var);
875 return Var;
876 }
877
878 // Converts a relative index (to the next instruction to be read) to
879 // an absolute value index.
880 uint32_t convertRelativeToAbsIndex(int32_t Id) {
881 int32_t AbsNextId = CachedNumGlobalValueIDs + LocalOperands.size();
Jan Voungce581632014-08-28 10:04:03 -0700882 if (Id > 0 && AbsNextId < Id) {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700883 std::string Buffer;
884 raw_string_ostream StrBuf(Buffer);
885 StrBuf << "Invalid relative value id: " << Id
886 << " (must be <= " << AbsNextId << ")";
887 Error(StrBuf.str());
888 // TODO(kschimpf) Remove error recovery once implementation complete.
889 return 0;
890 }
891 return AbsNextId - Id;
892 }
893
894 // Returns the value referenced by the given value Index.
895 Ice::Operand *getOperand(uint32_t Index) {
896 if (Index < CachedNumGlobalValueIDs) {
897 // TODO(kschimpf): Define implementation.
898 report_fatal_error("getOperand of global addresses not implemented");
899 }
900 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
901 if (LocalIndex >= LocalOperands.size()) {
902 std::string Buffer;
903 raw_string_ostream StrBuf(Buffer);
904 StrBuf << "Value index " << Index << " out of range. Must be less than "
905 << (LocalOperands.size() + CachedNumGlobalValueIDs);
906 Error(StrBuf.str());
907 report_fatal_error("Unable to continue");
908 }
909 return LocalOperands[LocalIndex];
910 }
911
912 // Generates type error message for binary operator Op
913 // operating on Type OpTy.
914 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
915
916 // Validates if integer logical Op, for type OpTy, is valid.
917 // Returns true if valid. Otherwise generates error message and
918 // returns false.
919 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
920 if (Ice::isIntegerType(OpTy))
921 return true;
922 ReportInvalidBinaryOp(Op, OpTy);
923 return false;
924 }
925
926 // Validates if integer (or vector of integers) arithmetic Op, for type
927 // OpTy, is valid. Returns true if valid. Otherwise generates
928 // error message and returns false.
929 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
930 if (Ice::isIntegerArithmeticType(OpTy))
931 return true;
932 ReportInvalidBinaryOp(Op, OpTy);
933 return false;
934 }
935
936 // Checks if floating arithmetic Op, for type OpTy, is valid.
937 // Returns false if valid. Otherwise generates an error message and
938 // returns true.
939 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
940 if (Ice::isFloatingType(OpTy))
941 return true;
942 ReportInvalidBinaryOp(Op, OpTy);
943 return false;
944 }
945
946 // Reports that the given binary Opcode, for the given type Ty,
947 // is not understood.
948 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty);
949
950 // Takes the PNaCl bitcode binary operator Opcode, and the opcode
951 // type Ty, and sets Op to the corresponding ICE binary
952 // opcode. Returns true if able to convert, false otherwise.
953 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
954 Ice::InstArithmetic::OpKind &Op) {
955 Instruction::BinaryOps LLVMOpcode;
956 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty),
957 LLVMOpcode)) {
958 ReportInvalidBinopOpcode(Opcode, Ty);
959 // TODO(kschimpf) Remove error recovery once implementation complete.
960 Op = Ice::InstArithmetic::Add;
961 return false;
962 }
963 switch (LLVMOpcode) {
964 default: {
965 ReportInvalidBinopOpcode(Opcode, Ty);
966 // TODO(kschimpf) Remove error recovery once implementation complete.
967 Op = Ice::InstArithmetic::Add;
968 return false;
969 }
970 case Instruction::Add:
971 Op = Ice::InstArithmetic::Add;
972 return isValidIntegerArithOp(Op, Ty);
973 case Instruction::FAdd:
974 Op = Ice::InstArithmetic::Fadd;
975 return isValidFloatingArithOp(Op, Ty);
976 case Instruction::Sub:
977 Op = Ice::InstArithmetic::Sub;
978 return isValidIntegerArithOp(Op, Ty);
979 case Instruction::FSub:
980 Op = Ice::InstArithmetic::Fsub;
981 return isValidFloatingArithOp(Op, Ty);
982 case Instruction::Mul:
983 Op = Ice::InstArithmetic::Mul;
984 return isValidIntegerArithOp(Op, Ty);
985 case Instruction::FMul:
986 Op = Ice::InstArithmetic::Fmul;
987 return isValidFloatingArithOp(Op, Ty);
988 case Instruction::UDiv:
989 Op = Ice::InstArithmetic::Udiv;
990 return isValidIntegerArithOp(Op, Ty);
991 case Instruction::SDiv:
992 Op = Ice::InstArithmetic::Sdiv;
993 return isValidIntegerArithOp(Op, Ty);
994 case Instruction::FDiv:
995 Op = Ice::InstArithmetic::Fdiv;
996 return isValidFloatingArithOp(Op, Ty);
997 case Instruction::URem:
998 Op = Ice::InstArithmetic::Urem;
999 return isValidIntegerArithOp(Op, Ty);
1000 case Instruction::SRem:
1001 Op = Ice::InstArithmetic::Srem;
1002 return isValidIntegerArithOp(Op, Ty);
1003 case Instruction::FRem:
1004 Op = Ice::InstArithmetic::Frem;
1005 return isValidFloatingArithOp(Op, Ty);
1006 case Instruction::Shl:
1007 Op = Ice::InstArithmetic::Shl;
1008 return isValidIntegerArithOp(Op, Ty);
1009 case Instruction::LShr:
1010 Op = Ice::InstArithmetic::Lshr;
1011 return isValidIntegerArithOp(Op, Ty);
1012 case Instruction::AShr:
1013 Op = Ice::InstArithmetic::Ashr;
1014 return isValidIntegerArithOp(Op, Ty);
1015 case Instruction::And:
1016 Op = Ice::InstArithmetic::And;
1017 return isValidIntegerLogicalOp(Op, Ty);
1018 case Instruction::Or:
1019 Op = Ice::InstArithmetic::Or;
1020 return isValidIntegerLogicalOp(Op, Ty);
1021 case Instruction::Xor:
1022 Op = Ice::InstArithmetic::Xor;
1023 return isValidIntegerLogicalOp(Op, Ty);
1024 }
1025 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001026
1027 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice
1028 /// cast opcode and assigns to CastKind. Returns true if successful,
1029 /// false otherwise.
1030 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp,
1031 Ice::InstCast::OpKind &CastKind) {
1032 switch (LLVMCastOp) {
1033 case Instruction::ZExt:
1034 CastKind = Ice::InstCast::Zext;
1035 break;
1036 case Instruction::SExt:
1037 CastKind = Ice::InstCast::Sext;
1038 break;
1039 case Instruction::Trunc:
1040 CastKind = Ice::InstCast::Trunc;
1041 break;
1042 case Instruction::FPTrunc:
1043 CastKind = Ice::InstCast::Fptrunc;
1044 break;
1045 case Instruction::FPExt:
1046 CastKind = Ice::InstCast::Fpext;
1047 break;
1048 case Instruction::FPToSI:
1049 CastKind = Ice::InstCast::Fptosi;
1050 break;
1051 case Instruction::FPToUI:
1052 CastKind = Ice::InstCast::Fptoui;
1053 break;
1054 case Instruction::SIToFP:
1055 CastKind = Ice::InstCast::Sitofp;
1056 break;
1057 case Instruction::UIToFP:
1058 CastKind = Ice::InstCast::Uitofp;
1059 break;
1060 case Instruction::BitCast:
1061 CastKind = Ice::InstCast::Bitcast;
1062 break;
1063 default:
1064 return false;
1065 }
1066 return true;
1067 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001068};
1069
1070FunctionParser::~FunctionParser() {
1071 if (getTranslator().getFlags().SubzeroTimingEnabled) {
1072 errs() << "[Subzero timing] Convert function " << Func->getFunctionName()
1073 << ": " << TConvert.getElapsedSec() << " sec\n";
1074 }
1075}
1076
1077void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) {
1078 std::string Buffer;
1079 raw_string_ostream StrBuf(Buffer);
1080 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1081 Error(StrBuf.str());
1082}
1083
1084void FunctionParser::ExitBlock() {
1085 // Before translating, check for blocks without instructions, and
1086 // insert unreachable. This shouldn't happen, but be safe.
1087 unsigned Index = 0;
1088 const Ice::NodeList &Nodes = Func->getNodes();
1089 for (std::vector<Ice::CfgNode *>::const_iterator Iter = Nodes.begin(),
1090 IterEnd = Nodes.end();
1091 Iter != IterEnd; ++Iter, ++Index) {
1092 Ice::CfgNode *Node = *Iter;
1093 if (Node->getInsts().size() == 0) {
1094 std::string Buffer;
1095 raw_string_ostream StrBuf(Buffer);
1096 StrBuf << "Basic block " << Index << " contains no instructions";
1097 Error(StrBuf.str());
1098 // TODO(kschimpf) Remove error recovery once implementation complete.
1099 Node->appendInst(Ice::InstUnreachable::create(Func));
1100 }
1101 }
1102 getTranslator().translateFcn(Func);
1103}
1104
1105void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
1106 Ice::Type OpTy) {
1107 std::string Buffer;
1108 raw_string_ostream StrBuf(Buffer);
1109 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
1110 << ". Found " << OpTy;
1111 Error(StrBuf.str());
1112}
1113
1114void FunctionParser::ProcessRecord() {
1115 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1116 if (InstIsTerminating) {
1117 InstIsTerminating = false;
1118 CurrentNode = GetBasicBlock(++CurrentBbIndex);
1119 }
1120 Ice::Inst *Inst = NULL;
1121 switch (Record.GetCode()) {
1122 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
1123 // DECLAREBLOCKS: [n]
1124 if (!isValidRecordSize(1, "function block count"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001125 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001126 if (Func->getNodes().size() != 1) {
1127 Error("Duplicate function block count record");
1128 return;
1129 }
1130 uint32_t NumBbs = Values[0];
1131 if (NumBbs == 0) {
1132 Error("Functions must contain at least one basic block.");
1133 // TODO(kschimpf) Remove error recovery once implementation complete.
1134 NumBbs = 1;
1135 }
1136 // Install the basic blocks, skipping bb0 which was created in the
1137 // constructor.
1138 for (size_t i = 1; i < NumBbs; ++i)
1139 InstallNextBasicBlock();
1140 break;
1141 }
1142 case naclbitc::FUNC_CODE_INST_BINOP: {
1143 // BINOP: [opval, opval, opcode]
1144 if (!isValidRecordSize(3, "function block binop"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001145 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001146 Ice::Operand *Op1 = getOperand(convertRelativeToAbsIndex(Values[0]));
1147 Ice::Operand *Op2 = getOperand(convertRelativeToAbsIndex(Values[1]));
1148 Ice::Type Type1 = Op1->getType();
1149 Ice::Type Type2 = Op2->getType();
1150 if (Type1 != Type2) {
1151 std::string Buffer;
1152 raw_string_ostream StrBuf(Buffer);
1153 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
1154 Error(StrBuf.str());
1155 // TODO(kschimpf) Remove error recovery once implementation complete.
1156 Op2 = Op1;
1157 }
1158
1159 Ice::InstArithmetic::OpKind Opcode;
1160 if (!convertBinopOpcode(Values[2], Type1, Opcode))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001161 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001162 Ice::Variable *Dest = NextInstVar(Type1);
1163 Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2);
1164 break;
1165 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001166 case naclbitc::FUNC_CODE_INST_CAST: {
1167 // CAST: [opval, destty, castopc]
1168 if (!isValidRecordSize(3, "function block cast"))
1169 return;
1170 Ice::Operand *Src = getOperand(convertRelativeToAbsIndex(Values[0]));
1171 Type *CastType = Context->getTypeByID(Values[1]);
1172 Instruction::CastOps LLVMCastOp;
1173 Ice::InstCast::OpKind CastKind;
1174 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) ||
1175 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) {
1176 std::string Buffer;
1177 raw_string_ostream StrBuf(Buffer);
1178 StrBuf << "Cast opcode not understood: " << Values[2];
1179 Error(StrBuf.str());
1180 return;
1181 }
1182 Type *SrcType = Context->convertToLLVMType(Src->getType());
1183 if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) {
1184 std::string Buffer;
1185 raw_string_ostream StrBuf(Buffer);
1186 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
1187 << " " << *SrcType << " to " << *CastType;
1188 Error(StrBuf.str());
1189 return;
1190 }
1191 Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType));
1192 Inst = Ice::InstCast::create(Func, CastKind, Dest, Src);
1193 break;
1194 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001195 case naclbitc::FUNC_CODE_INST_RET: {
1196 // RET: [opval?]
1197 InstIsTerminating = true;
1198 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001199 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001200 if (Values.size() == 0) {
1201 Inst = Ice::InstRet::create(Func);
1202 } else {
1203 Inst = Ice::InstRet::create(
1204 Func, getOperand(convertRelativeToAbsIndex(Values[0])));
1205 }
1206 break;
1207 }
1208 default:
1209 // Generate error message!
1210 BlockParserBaseClass::ProcessRecord();
1211 break;
1212 }
1213 if (Inst)
1214 CurrentNode->appendInst(Inst);
1215}
1216
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001217/// Parses the module block in the bitcode file.
1218class ModuleParser : public BlockParserBaseClass {
1219public:
1220 ModuleParser(unsigned BlockID, TopLevelParser *Context)
1221 : BlockParserBaseClass(BlockID, Context) {}
1222
1223 virtual ~ModuleParser() LLVM_OVERRIDE {}
1224
1225protected:
1226 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
1227
1228 virtual void ProcessRecord() LLVM_OVERRIDE;
1229};
1230
1231bool ModuleParser::ParseBlock(unsigned BlockID) LLVM_OVERRIDE {
1232 switch (BlockID) {
1233 case naclbitc::BLOCKINFO_BLOCK_ID:
1234 return NaClBitcodeParser::ParseBlock(BlockID);
1235 case naclbitc::TYPE_BLOCK_ID_NEW: {
1236 TypesParser Parser(BlockID, this);
1237 return Parser.ParseThisBlock();
1238 }
1239 case naclbitc::GLOBALVAR_BLOCK_ID: {
1240 GlobalsParser Parser(BlockID, this);
1241 return Parser.ParseThisBlock();
1242 }
1243 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
1244 ValuesymtabParser Parser(BlockID, this, false);
1245 return Parser.ParseThisBlock();
1246 }
1247 case naclbitc::FUNCTION_BLOCK_ID: {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001248 FunctionParser Parser(BlockID, this);
1249 return Parser.ParseThisBlock();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001250 }
1251 default:
1252 return BlockParserBaseClass::ParseBlock(BlockID);
1253 }
1254}
1255
1256void ModuleParser::ProcessRecord() {
1257 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1258 switch (Record.GetCode()) {
1259 case naclbitc::MODULE_CODE_VERSION: {
1260 // VERSION: [version#]
Karl Schimpfd6064a12014-08-27 15:34:58 -07001261 if (!isValidRecordSize(1, "Module version"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001262 return;
1263 unsigned Version = Values[0];
1264 if (Version != 1) {
1265 std::string Buffer;
1266 raw_string_ostream StrBuf(Buffer);
1267 StrBuf << "Unknown bitstream version: " << Version;
1268 Error(StrBuf.str());
1269 }
1270 return;
1271 }
1272 case naclbitc::MODULE_CODE_FUNCTION: {
1273 // FUNCTION: [type, callingconv, isproto, linkage]
Karl Schimpfd6064a12014-08-27 15:34:58 -07001274 if (!isValidRecordSize(4, "Function heading"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001275 return;
1276 Type *Ty = Context->getTypeByID(Values[0]);
1277 FunctionType *FTy = dyn_cast<FunctionType>(Ty);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001278 if (FTy == NULL) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001279 std::string Buffer;
1280 raw_string_ostream StrBuf(Buffer);
1281 StrBuf << "Function heading expects function type. Found: " << Ty;
1282 Error(StrBuf.str());
1283 return;
1284 }
1285 CallingConv::ID CallingConv;
1286 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
1287 std::string Buffer;
1288 raw_string_ostream StrBuf(Buffer);
1289 StrBuf << "Function heading has unknown calling convention: "
1290 << Values[1];
1291 Error(StrBuf.str());
1292 return;
1293 }
1294 GlobalValue::LinkageTypes Linkage;
1295 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
1296 std::string Buffer;
1297 raw_string_ostream StrBuf(Buffer);
1298 StrBuf << "Function heading has unknown linkage. Found " << Values[3];
1299 Error(StrBuf.str());
1300 return;
1301 }
1302 Function *Func = Function::Create(FTy, Linkage, "", Context->getModule());
1303 Func->setCallingConv(CallingConv);
1304 if (Values[2] == 0)
1305 Context->setNextValueIDAsImplementedFunction();
1306 Context->setNextFunctionID(Func);
1307 // TODO(kschimpf) verify if Func matches PNaCl ABI.
1308 return;
1309 }
1310 default:
1311 BlockParserBaseClass::ProcessRecord();
1312 return;
1313 }
1314}
1315
1316bool TopLevelParser::ParseBlock(unsigned BlockID) {
1317 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
1318 ModuleParser Parser(BlockID, this);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001319 return Parser.ParseThisBlock();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001320 }
1321 // Generate error message by using default block implementation.
1322 BlockParserBaseClass Parser(BlockID, this);
1323 return Parser.ParseThisBlock();
1324}
1325
Jim Stichnoth989a7032014-08-08 10:13:44 -07001326} // end of anonymous namespace
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001327
1328namespace Ice {
1329
1330void PNaClTranslator::translate(const std::string &IRFilename) {
1331 OwningPtr<MemoryBuffer> MemBuf;
1332 if (error_code ec =
1333 MemoryBuffer::getFileOrSTDIN(IRFilename.c_str(), MemBuf)) {
1334 errs() << "Error reading '" << IRFilename << "': " << ec.message() << "\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001335 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001336 return;
1337 }
1338
1339 if (MemBuf->getBufferSize() % 4 != 0) {
1340 errs() << IRFilename
1341 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001342 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001343 return;
1344 }
1345
1346 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
1347 const unsigned char *EndBufPtr = BufPtr + MemBuf->getBufferSize();
1348
1349 // Read header and verify it is good.
1350 NaClBitcodeHeader Header;
1351 if (Header.Read(BufPtr, EndBufPtr) || !Header.IsSupported()) {
1352 errs() << "Invalid PNaCl bitcode header.\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001353 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001354 return;
1355 }
1356
1357 // Create a bitstream reader to read the bitcode file.
1358 NaClBitstreamReader InputStreamFile(BufPtr, EndBufPtr);
1359 NaClBitstreamCursor InputStream(InputStreamFile);
1360
Karl Schimpfd6064a12014-08-27 15:34:58 -07001361 TopLevelParser Parser(*this, MemBuf->getBufferIdentifier(), Header,
1362 InputStream, ErrorStatus);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001363 int TopLevelBlocks = 0;
1364 while (!InputStream.AtEndOfStream()) {
1365 if (Parser.Parse()) {
Karl Schimpfb164d202014-07-11 10:26:34 -07001366 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001367 return;
1368 }
1369 ++TopLevelBlocks;
1370 }
1371
1372 if (TopLevelBlocks != 1) {
1373 errs() << IRFilename
1374 << ": Contains more than one module. Found: " << TopLevelBlocks
1375 << "\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001376 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001377 }
1378 return;
1379}
1380
Jim Stichnoth989a7032014-08-08 10:13:44 -07001381} // end of namespace Ice