blob: bde906ab8bee81be43aecfe6bb1f611ace8b6628 [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
Karl Schimpff12355e2014-09-08 13:41:09 -0700824 // Set the next constant ID to the given constant C.
825 void setNextConstantID(Ice::Constant *C) { LocalOperands.push_back(C); }
826
Karl Schimpfd6064a12014-08-27 15:34:58 -0700827private:
828 // Timer for reading function bitcode and converting to ICE.
829 Ice::Timer TConvert;
830 // The corresponding ICE function defined by the function block.
831 Ice::Cfg *Func;
832 // The index to the current basic block being built.
833 uint32_t CurrentBbIndex;
834 // The basic block being built.
835 Ice::CfgNode *CurrentNode;
836 // The ID for the function.
837 unsigned FcnId;
838 // The corresponding LLVM function.
839 Function *LLVMFunc;
840 // Holds operands local to the function block, based on indices
841 // defined in the bitcode file.
842 std::vector<Ice::Operand *> LocalOperands;
843 // Holds the dividing point between local and global absolute value indices.
844 uint32_t CachedNumGlobalValueIDs;
845 // True if the last processed instruction was a terminating
846 // instruction.
847 bool InstIsTerminating;
Karl Schimpf742d72d2014-09-09 11:40:09 -0700848 // Upper limit of alignment power allowed by LLVM
849 static const uint64_t AlignPowerLimit = 29;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700850
Karl Schimpff12355e2014-09-08 13:41:09 -0700851 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
852
Karl Schimpfd6064a12014-08-27 15:34:58 -0700853 virtual void ProcessRecord() LLVM_OVERRIDE;
854
855 virtual void ExitBlock() LLVM_OVERRIDE;
856
857 // Creates and appends a new basic block to the list of basic blocks.
858 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); }
859
860 // Returns the Index-th basic block in the list of basic blocks.
861 Ice::CfgNode *GetBasicBlock(uint32_t Index) {
862 const Ice::NodeList &Nodes = Func->getNodes();
863 if (Index >= Nodes.size()) {
864 std::string Buffer;
865 raw_string_ostream StrBuf(Buffer);
866 StrBuf << "Reference to basic block " << Index
867 << " not found. Must be less than " << Nodes.size();
868 Error(StrBuf.str());
869 // TODO(kschimpf) Remove error recovery once implementation complete.
870 Index = 0;
871 }
872 return Nodes[Index];
873 }
874
Karl Schimpfc836acb2014-09-05 08:32:47 -0700875 // Returns the Index-th basic block in the list of basic blocks.
876 // Assumes Index corresponds to a branch instruction. Hence, if
877 // the branch references the entry block, it also generates a
878 // corresponding error.
879 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) {
880 if (Index == 0) {
881 Error("Branch to entry block not allowed");
882 // TODO(kschimpf) Remove error recovery once implementation complete.
883 }
884 return GetBasicBlock(Index);
885 }
886
Karl Schimpfd6064a12014-08-27 15:34:58 -0700887 // Generates the next available local variable using the given
888 // type. Note: if Ty is void, this function returns NULL.
889 Ice::Variable *NextInstVar(Ice::Type Ty) {
890 if (Ty == Ice::IceType_void)
891 return NULL;
892 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode);
893 LocalOperands.push_back(Var);
894 return Var;
895 }
896
897 // Converts a relative index (to the next instruction to be read) to
898 // an absolute value index.
899 uint32_t convertRelativeToAbsIndex(int32_t Id) {
900 int32_t AbsNextId = CachedNumGlobalValueIDs + LocalOperands.size();
Jan Voungce581632014-08-28 10:04:03 -0700901 if (Id > 0 && AbsNextId < Id) {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700902 std::string Buffer;
903 raw_string_ostream StrBuf(Buffer);
904 StrBuf << "Invalid relative value id: " << Id
905 << " (must be <= " << AbsNextId << ")";
906 Error(StrBuf.str());
907 // TODO(kschimpf) Remove error recovery once implementation complete.
908 return 0;
909 }
910 return AbsNextId - Id;
911 }
912
913 // Returns the value referenced by the given value Index.
914 Ice::Operand *getOperand(uint32_t Index) {
915 if (Index < CachedNumGlobalValueIDs) {
916 // TODO(kschimpf): Define implementation.
917 report_fatal_error("getOperand of global addresses not implemented");
918 }
919 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
920 if (LocalIndex >= LocalOperands.size()) {
921 std::string Buffer;
922 raw_string_ostream StrBuf(Buffer);
923 StrBuf << "Value index " << Index << " out of range. Must be less than "
924 << (LocalOperands.size() + CachedNumGlobalValueIDs);
925 Error(StrBuf.str());
926 report_fatal_error("Unable to continue");
927 }
928 return LocalOperands[LocalIndex];
929 }
930
Karl Schimpf71ba8222014-09-03 09:46:24 -0700931 // Returns the relative operand (wrt to next instruction) referenced by
932 // the given value index.
933 Ice::Operand *getRelativeOperand(uint32_t Index) {
934 return getOperand(convertRelativeToAbsIndex(Index));
935 }
936
Karl Schimpfd6064a12014-08-27 15:34:58 -0700937 // Generates type error message for binary operator Op
938 // operating on Type OpTy.
939 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
940
941 // Validates if integer logical Op, for type OpTy, is valid.
942 // Returns true if valid. Otherwise generates error message and
943 // returns false.
944 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
945 if (Ice::isIntegerType(OpTy))
946 return true;
947 ReportInvalidBinaryOp(Op, OpTy);
948 return false;
949 }
950
951 // Validates if integer (or vector of integers) arithmetic Op, for type
952 // OpTy, is valid. Returns true if valid. Otherwise generates
953 // error message and returns false.
954 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
955 if (Ice::isIntegerArithmeticType(OpTy))
956 return true;
957 ReportInvalidBinaryOp(Op, OpTy);
958 return false;
959 }
960
961 // Checks if floating arithmetic Op, for type OpTy, is valid.
962 // Returns false if valid. Otherwise generates an error message and
963 // returns true.
964 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
965 if (Ice::isFloatingType(OpTy))
966 return true;
967 ReportInvalidBinaryOp(Op, OpTy);
968 return false;
969 }
970
971 // Reports that the given binary Opcode, for the given type Ty,
972 // is not understood.
973 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty);
974
975 // Takes the PNaCl bitcode binary operator Opcode, and the opcode
976 // type Ty, and sets Op to the corresponding ICE binary
977 // opcode. Returns true if able to convert, false otherwise.
978 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
979 Ice::InstArithmetic::OpKind &Op) {
980 Instruction::BinaryOps LLVMOpcode;
981 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty),
982 LLVMOpcode)) {
983 ReportInvalidBinopOpcode(Opcode, Ty);
984 // TODO(kschimpf) Remove error recovery once implementation complete.
985 Op = Ice::InstArithmetic::Add;
986 return false;
987 }
988 switch (LLVMOpcode) {
989 default: {
990 ReportInvalidBinopOpcode(Opcode, Ty);
991 // TODO(kschimpf) Remove error recovery once implementation complete.
992 Op = Ice::InstArithmetic::Add;
993 return false;
994 }
995 case Instruction::Add:
996 Op = Ice::InstArithmetic::Add;
997 return isValidIntegerArithOp(Op, Ty);
998 case Instruction::FAdd:
999 Op = Ice::InstArithmetic::Fadd;
1000 return isValidFloatingArithOp(Op, Ty);
1001 case Instruction::Sub:
1002 Op = Ice::InstArithmetic::Sub;
1003 return isValidIntegerArithOp(Op, Ty);
1004 case Instruction::FSub:
1005 Op = Ice::InstArithmetic::Fsub;
1006 return isValidFloatingArithOp(Op, Ty);
1007 case Instruction::Mul:
1008 Op = Ice::InstArithmetic::Mul;
1009 return isValidIntegerArithOp(Op, Ty);
1010 case Instruction::FMul:
1011 Op = Ice::InstArithmetic::Fmul;
1012 return isValidFloatingArithOp(Op, Ty);
1013 case Instruction::UDiv:
1014 Op = Ice::InstArithmetic::Udiv;
1015 return isValidIntegerArithOp(Op, Ty);
1016 case Instruction::SDiv:
1017 Op = Ice::InstArithmetic::Sdiv;
1018 return isValidIntegerArithOp(Op, Ty);
1019 case Instruction::FDiv:
1020 Op = Ice::InstArithmetic::Fdiv;
1021 return isValidFloatingArithOp(Op, Ty);
1022 case Instruction::URem:
1023 Op = Ice::InstArithmetic::Urem;
1024 return isValidIntegerArithOp(Op, Ty);
1025 case Instruction::SRem:
1026 Op = Ice::InstArithmetic::Srem;
1027 return isValidIntegerArithOp(Op, Ty);
1028 case Instruction::FRem:
1029 Op = Ice::InstArithmetic::Frem;
1030 return isValidFloatingArithOp(Op, Ty);
1031 case Instruction::Shl:
1032 Op = Ice::InstArithmetic::Shl;
1033 return isValidIntegerArithOp(Op, Ty);
1034 case Instruction::LShr:
1035 Op = Ice::InstArithmetic::Lshr;
1036 return isValidIntegerArithOp(Op, Ty);
1037 case Instruction::AShr:
1038 Op = Ice::InstArithmetic::Ashr;
1039 return isValidIntegerArithOp(Op, Ty);
1040 case Instruction::And:
1041 Op = Ice::InstArithmetic::And;
1042 return isValidIntegerLogicalOp(Op, Ty);
1043 case Instruction::Or:
1044 Op = Ice::InstArithmetic::Or;
1045 return isValidIntegerLogicalOp(Op, Ty);
1046 case Instruction::Xor:
1047 Op = Ice::InstArithmetic::Xor;
1048 return isValidIntegerLogicalOp(Op, Ty);
1049 }
1050 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001051
1052 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice
1053 /// cast opcode and assigns to CastKind. Returns true if successful,
1054 /// false otherwise.
1055 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp,
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001056 Ice::InstCast::OpKind &CastKind) const {
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001057 switch (LLVMCastOp) {
1058 case Instruction::ZExt:
1059 CastKind = Ice::InstCast::Zext;
1060 break;
1061 case Instruction::SExt:
1062 CastKind = Ice::InstCast::Sext;
1063 break;
1064 case Instruction::Trunc:
1065 CastKind = Ice::InstCast::Trunc;
1066 break;
1067 case Instruction::FPTrunc:
1068 CastKind = Ice::InstCast::Fptrunc;
1069 break;
1070 case Instruction::FPExt:
1071 CastKind = Ice::InstCast::Fpext;
1072 break;
1073 case Instruction::FPToSI:
1074 CastKind = Ice::InstCast::Fptosi;
1075 break;
1076 case Instruction::FPToUI:
1077 CastKind = Ice::InstCast::Fptoui;
1078 break;
1079 case Instruction::SIToFP:
1080 CastKind = Ice::InstCast::Sitofp;
1081 break;
1082 case Instruction::UIToFP:
1083 CastKind = Ice::InstCast::Uitofp;
1084 break;
1085 case Instruction::BitCast:
1086 CastKind = Ice::InstCast::Bitcast;
1087 break;
1088 default:
1089 return false;
1090 }
1091 return true;
1092 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001093
1094 // Converts PNaCl bitcode Icmp operator to corresponding ICE op.
1095 // Returns true if able to convert, false otherwise.
1096 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1097 Ice::InstIcmp::ICond &Cond) const {
1098 switch (Op) {
1099 case naclbitc::ICMP_EQ:
1100 Cond = Ice::InstIcmp::Eq;
1101 return true;
1102 case naclbitc::ICMP_NE:
1103 Cond = Ice::InstIcmp::Ne;
1104 return true;
1105 case naclbitc::ICMP_UGT:
1106 Cond = Ice::InstIcmp::Ugt;
1107 return true;
1108 case naclbitc::ICMP_UGE:
1109 Cond = Ice::InstIcmp::Uge;
1110 return true;
1111 case naclbitc::ICMP_ULT:
1112 Cond = Ice::InstIcmp::Ult;
1113 return true;
1114 case naclbitc::ICMP_ULE:
1115 Cond = Ice::InstIcmp::Ule;
1116 return true;
1117 case naclbitc::ICMP_SGT:
1118 Cond = Ice::InstIcmp::Sgt;
1119 return true;
1120 case naclbitc::ICMP_SGE:
1121 Cond = Ice::InstIcmp::Sge;
1122 return true;
1123 case naclbitc::ICMP_SLT:
1124 Cond = Ice::InstIcmp::Slt;
1125 return true;
1126 case naclbitc::ICMP_SLE:
1127 Cond = Ice::InstIcmp::Sle;
1128 return true;
1129 default:
1130 return false;
1131 }
1132 }
1133
1134 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op.
1135 // Returns true if able to convert, false otherwise.
1136 bool convertNaClBitcFCompOpToIce(uint64_t Op,
1137 Ice::InstFcmp::FCond &Cond) const {
1138 switch (Op) {
1139 case naclbitc::FCMP_FALSE:
1140 Cond = Ice::InstFcmp::False;
1141 return true;
1142 case naclbitc::FCMP_OEQ:
1143 Cond = Ice::InstFcmp::Oeq;
1144 return true;
1145 case naclbitc::FCMP_OGT:
1146 Cond = Ice::InstFcmp::Ogt;
1147 return true;
1148 case naclbitc::FCMP_OGE:
1149 Cond = Ice::InstFcmp::Oge;
1150 return true;
1151 case naclbitc::FCMP_OLT:
1152 Cond = Ice::InstFcmp::Olt;
1153 return true;
1154 case naclbitc::FCMP_OLE:
1155 Cond = Ice::InstFcmp::Ole;
1156 return true;
1157 case naclbitc::FCMP_ONE:
1158 Cond = Ice::InstFcmp::One;
1159 return true;
1160 case naclbitc::FCMP_ORD:
1161 Cond = Ice::InstFcmp::Ord;
1162 return true;
1163 case naclbitc::FCMP_UNO:
1164 Cond = Ice::InstFcmp::Uno;
1165 return true;
1166 case naclbitc::FCMP_UEQ:
1167 Cond = Ice::InstFcmp::Ueq;
1168 return true;
1169 case naclbitc::FCMP_UGT:
1170 Cond = Ice::InstFcmp::Ugt;
1171 return true;
1172 case naclbitc::FCMP_UGE:
1173 Cond = Ice::InstFcmp::Uge;
1174 return true;
1175 case naclbitc::FCMP_ULT:
1176 Cond = Ice::InstFcmp::Ult;
1177 return true;
1178 case naclbitc::FCMP_ULE:
1179 Cond = Ice::InstFcmp::Ule;
1180 return true;
1181 case naclbitc::FCMP_UNE:
1182 Cond = Ice::InstFcmp::Une;
1183 return true;
1184 case naclbitc::FCMP_TRUE:
1185 Cond = Ice::InstFcmp::True;
1186 return true;
1187 default:
1188 return false;
1189 }
1190 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001191};
1192
1193FunctionParser::~FunctionParser() {
1194 if (getTranslator().getFlags().SubzeroTimingEnabled) {
1195 errs() << "[Subzero timing] Convert function " << Func->getFunctionName()
1196 << ": " << TConvert.getElapsedSec() << " sec\n";
1197 }
1198}
1199
1200void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) {
1201 std::string Buffer;
1202 raw_string_ostream StrBuf(Buffer);
1203 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1204 Error(StrBuf.str());
1205}
1206
1207void FunctionParser::ExitBlock() {
1208 // Before translating, check for blocks without instructions, and
1209 // insert unreachable. This shouldn't happen, but be safe.
1210 unsigned Index = 0;
1211 const Ice::NodeList &Nodes = Func->getNodes();
1212 for (std::vector<Ice::CfgNode *>::const_iterator Iter = Nodes.begin(),
1213 IterEnd = Nodes.end();
1214 Iter != IterEnd; ++Iter, ++Index) {
1215 Ice::CfgNode *Node = *Iter;
1216 if (Node->getInsts().size() == 0) {
1217 std::string Buffer;
1218 raw_string_ostream StrBuf(Buffer);
1219 StrBuf << "Basic block " << Index << " contains no instructions";
1220 Error(StrBuf.str());
1221 // TODO(kschimpf) Remove error recovery once implementation complete.
1222 Node->appendInst(Ice::InstUnreachable::create(Func));
1223 }
1224 }
Karl Schimpfc836acb2014-09-05 08:32:47 -07001225 // Note: Once any errors have been found, we turn off all
1226 // translation of all remaining functions. This allows use to see
1227 // multiple errors, without adding extra checks to the translator
1228 // for such parsing errors.
1229 if (Context->getNumErrors() == 0)
1230 getTranslator().translateFcn(Func);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001231}
1232
1233void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
1234 Ice::Type OpTy) {
1235 std::string Buffer;
1236 raw_string_ostream StrBuf(Buffer);
1237 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
1238 << ". Found " << OpTy;
1239 Error(StrBuf.str());
1240}
1241
1242void FunctionParser::ProcessRecord() {
1243 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1244 if (InstIsTerminating) {
1245 InstIsTerminating = false;
1246 CurrentNode = GetBasicBlock(++CurrentBbIndex);
1247 }
1248 Ice::Inst *Inst = NULL;
1249 switch (Record.GetCode()) {
1250 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
1251 // DECLAREBLOCKS: [n]
1252 if (!isValidRecordSize(1, "function block count"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001253 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001254 if (Func->getNodes().size() != 1) {
1255 Error("Duplicate function block count record");
1256 return;
1257 }
1258 uint32_t NumBbs = Values[0];
1259 if (NumBbs == 0) {
1260 Error("Functions must contain at least one basic block.");
1261 // TODO(kschimpf) Remove error recovery once implementation complete.
1262 NumBbs = 1;
1263 }
1264 // Install the basic blocks, skipping bb0 which was created in the
1265 // constructor.
1266 for (size_t i = 1; i < NumBbs; ++i)
1267 InstallNextBasicBlock();
1268 break;
1269 }
1270 case naclbitc::FUNC_CODE_INST_BINOP: {
1271 // BINOP: [opval, opval, opcode]
1272 if (!isValidRecordSize(3, "function block binop"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001273 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07001274 Ice::Operand *Op1 = getRelativeOperand(Values[0]);
1275 Ice::Operand *Op2 = getRelativeOperand(Values[1]);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001276 Ice::Type Type1 = Op1->getType();
1277 Ice::Type Type2 = Op2->getType();
1278 if (Type1 != Type2) {
1279 std::string Buffer;
1280 raw_string_ostream StrBuf(Buffer);
1281 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
1282 Error(StrBuf.str());
1283 // TODO(kschimpf) Remove error recovery once implementation complete.
1284 Op2 = Op1;
1285 }
1286
1287 Ice::InstArithmetic::OpKind Opcode;
1288 if (!convertBinopOpcode(Values[2], Type1, Opcode))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001289 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001290 Ice::Variable *Dest = NextInstVar(Type1);
1291 Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2);
1292 break;
1293 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001294 case naclbitc::FUNC_CODE_INST_CAST: {
1295 // CAST: [opval, destty, castopc]
1296 if (!isValidRecordSize(3, "function block cast"))
1297 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07001298 Ice::Operand *Src = getRelativeOperand(Values[0]);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001299 Type *CastType = Context->getTypeByID(Values[1]);
1300 Instruction::CastOps LLVMCastOp;
1301 Ice::InstCast::OpKind CastKind;
1302 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) ||
1303 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) {
1304 std::string Buffer;
1305 raw_string_ostream StrBuf(Buffer);
1306 StrBuf << "Cast opcode not understood: " << Values[2];
1307 Error(StrBuf.str());
1308 return;
1309 }
1310 Type *SrcType = Context->convertToLLVMType(Src->getType());
1311 if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) {
1312 std::string Buffer;
1313 raw_string_ostream StrBuf(Buffer);
1314 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
1315 << " " << *SrcType << " to " << *CastType;
1316 Error(StrBuf.str());
1317 return;
1318 }
1319 Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType));
1320 Inst = Ice::InstCast::create(Func, CastKind, Dest, Src);
1321 break;
1322 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001323 case naclbitc::FUNC_CODE_INST_VSELECT: {
1324 // VSELECT: [opval, opval, pred]
1325 Ice::Operand *ThenVal = getOperand(convertRelativeToAbsIndex(Values[0]));
1326 Ice::Type ThenType = ThenVal->getType();
1327 Ice::Operand *ElseVal = getOperand(convertRelativeToAbsIndex(Values[1]));
1328 Ice::Type ElseType = ElseVal->getType();
1329 if (ThenType != ElseType) {
1330 std::string Buffer;
1331 raw_string_ostream StrBuf(Buffer);
1332 StrBuf << "Select operands not same type. Found " << ThenType << " and "
1333 << ElseType;
1334 Error(StrBuf.str());
1335 return;
1336 }
1337 Ice::Operand *CondVal = getOperand(convertRelativeToAbsIndex(Values[2]));
1338 Ice::Type CondType = CondVal->getType();
1339 if (isVectorType(CondType)) {
1340 if (!isVectorType(ThenType) ||
1341 typeElementType(CondType) != Ice::IceType_i1 ||
1342 typeNumElements(ThenType) != typeNumElements(CondType)) {
1343 std::string Buffer;
1344 raw_string_ostream StrBuf(Buffer);
1345 StrBuf << "Select condition " << CondType
1346 << " not allowed for values of type " << ThenType;
1347 Error(StrBuf.str());
1348 return;
1349 }
1350 } else if (CondVal->getType() != Ice::IceType_i1) {
1351 std::string Buffer;
1352 raw_string_ostream StrBuf(Buffer);
1353 StrBuf << "Select condition not type i1. Found: " << CondVal->getType();
1354 Error(StrBuf.str());
1355 return;
1356 }
1357 Ice::Variable *DestVal = NextInstVar(ThenType);
1358 Inst = Ice::InstSelect::create(Func, DestVal, CondVal, ThenVal, ElseVal);
1359 break;
1360 }
Karl Schimpf71ba8222014-09-03 09:46:24 -07001361 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
1362 // EXTRACTELT: [opval, opval]
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001363 if (!isValidRecordSize(2, "function block extract element"))
1364 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07001365 Ice::Operand *Vec = getRelativeOperand(Values[0]);
1366 Ice::Type VecType = Vec->getType();
1367 if (!Ice::isVectorType(VecType)) {
1368 std::string Buffer;
1369 raw_string_ostream StrBuf(Buffer);
1370 StrBuf << "Extractelement not on vector. Found: " << Vec;
1371 Error(StrBuf.str());
1372 }
1373 Ice::Operand *Index = getRelativeOperand(Values[1]);
1374 if (Index->getType() != Ice::IceType_i32) {
1375 std::string Buffer;
1376 raw_string_ostream StrBuf(Buffer);
1377 StrBuf << "Extractelement index not i32. Found: " << Index;
1378 Error(StrBuf.str());
1379 }
1380 // TODO(kschimpf): Restrict index to a legal constant index (once
1381 // constants can be defined).
1382 Ice::Variable *Dest = NextInstVar(typeElementType(VecType));
1383 Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index);
1384 break;
1385 }
1386 case naclbitc::FUNC_CODE_INST_INSERTELT: {
1387 // INSERTELT: [opval, opval, opval]
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001388 if (!isValidRecordSize(3, "function block insert element"))
1389 return;
Karl Schimpf71ba8222014-09-03 09:46:24 -07001390 Ice::Operand *Vec = getRelativeOperand(Values[0]);
1391 Ice::Type VecType = Vec->getType();
1392 if (!Ice::isVectorType(VecType)) {
1393 std::string Buffer;
1394 raw_string_ostream StrBuf(Buffer);
1395 StrBuf << "Insertelement not on vector. Found: " << Vec;
1396 Error(StrBuf.str());
1397 }
1398 Ice::Operand *Elt = getRelativeOperand(Values[1]);
1399 Ice::Type EltType = Elt->getType();
1400 if (EltType != typeElementType(VecType)) {
1401 std::string Buffer;
1402 raw_string_ostream StrBuf(Buffer);
1403 StrBuf << "Insertelement element not " << typeElementType(VecType)
1404 << ". Found: " << Elt;
1405 Error(StrBuf.str());
1406 }
1407 Ice::Operand *Index = getRelativeOperand(Values[2]);
1408 if (Index->getType() != Ice::IceType_i32) {
1409 std::string Buffer;
1410 raw_string_ostream StrBuf(Buffer);
1411 StrBuf << "Insertelement index not i32. Found: " << Index;
1412 Error(StrBuf.str());
1413 }
1414 // TODO(kschimpf): Restrict index to a legal constant index (once
1415 // constants can be defined).
1416 Ice::Variable *Dest = NextInstVar(EltType);
1417 Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index);
1418 break;
1419 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001420 case naclbitc::FUNC_CODE_INST_CMP2: {
1421 // CMP2: [opval, opval, pred]
1422 if (!isValidRecordSize(3, "function block compare"))
1423 return;
1424 Ice::Operand *Op1 = getRelativeOperand(Values[0]);
1425 Ice::Operand *Op2 = getRelativeOperand(Values[1]);
1426 Ice::Type Op1Type = Op1->getType();
1427 Ice::Type Op2Type = Op2->getType();
1428 if (Op1Type != Op2Type) {
1429 std::string Buffer;
1430 raw_string_ostream StrBuf(Buffer);
1431 StrBuf << "Compare argument types differ: " << Op1Type
1432 << " and " << Op2Type;
1433 Error(StrBuf.str());
1434 // TODO(kschimpf) Remove error recovery once implementation complete.
1435 Op2 = Op1;
1436 }
1437 Ice::Type DestType = getCompareResultType(Op1Type);
1438 if (DestType == Ice::IceType_void) {
1439 std::string Buffer;
1440 raw_string_ostream StrBuf(Buffer);
1441 StrBuf << "Compare not defined for type " << Op1Type;
1442 Error(StrBuf.str());
1443 return;
1444 }
1445 Ice::Variable *Dest = NextInstVar(DestType);
1446 if (isIntegerType(Op1Type)) {
1447 Ice::InstIcmp::ICond Cond;
1448 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
1449 std::string Buffer;
1450 raw_string_ostream StrBuf(Buffer);
1451 StrBuf << "Compare record contains unknown integer predicate index: "
1452 << Values[2];
1453 Error(StrBuf.str());
1454 // TODO(kschimpf) Remove error recovery once implementation complete.
1455 Cond = Ice::InstIcmp::Eq;
1456 }
1457 Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2);
1458 } else if (isFloatingType(Op1Type)){
1459 Ice::InstFcmp::FCond Cond;
1460 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
1461 std::string Buffer;
1462 raw_string_ostream StrBuf(Buffer);
1463 StrBuf << "Compare record contains unknown float predicate index: "
1464 << Values[2];
1465 Error(StrBuf.str());
1466 // TODO(kschimpf) Remove error recovery once implementation complete.
1467 Cond = Ice::InstFcmp::False;
1468 }
1469 Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2);
1470 } else {
1471 // Not sure this can happen, but be safe.
1472 std::string Buffer;
1473 raw_string_ostream StrBuf(Buffer);
1474 StrBuf << "Compare on type not understood: " << Op1Type;
1475 Error(StrBuf.str());
1476 return;
1477 }
1478 break;
1479 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001480 case naclbitc::FUNC_CODE_INST_RET: {
1481 // RET: [opval?]
Karl Schimpfd6064a12014-08-27 15:34:58 -07001482 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001483 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001484 if (Values.size() == 0) {
1485 Inst = Ice::InstRet::create(Func);
1486 } else {
Karl Schimpf71ba8222014-09-03 09:46:24 -07001487 Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0]));
Karl Schimpfd6064a12014-08-27 15:34:58 -07001488 }
Karl Schimpfc836acb2014-09-05 08:32:47 -07001489 InstIsTerminating = true;
1490 break;
1491 }
1492 case naclbitc::FUNC_CODE_INST_BR: {
1493 if (Values.size() == 1) {
1494 // BR: [bb#]
1495 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
1496 if (Block == NULL)
1497 return;
1498 Inst = Ice::InstBr::create(Func, Block);
1499 } else {
1500 // BR: [bb#, bb#, opval]
1501 if (!isValidRecordSize(3, "function block branch"))
1502 return;
1503 Ice::Operand *Cond = getRelativeOperand(Values[2]);
1504 if (Cond->getType() != Ice::IceType_i1) {
1505 std::string Buffer;
1506 raw_string_ostream StrBuf(Buffer);
1507 StrBuf << "Branch condition not i1";
1508 Error(StrBuf.str());
1509 return;
1510 }
1511 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
1512 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
1513 if (ThenBlock == NULL || ElseBlock == NULL)
1514 return;
1515 Inst = Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock);
1516 }
1517 InstIsTerminating = true;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001518 break;
1519 }
Karl Schimpf742d72d2014-09-09 11:40:09 -07001520 case naclbitc::FUNC_CODE_INST_ALLOCA: {
1521 // ALLOCA: [Size, align]
1522 if (!isValidRecordSize(2, "function block alloca"))
1523 return;
1524 Ice::Operand *ByteCount = getRelativeOperand(Values[0]);
1525 if (ByteCount->getType() != Ice::IceType_i32) {
1526 std::string Buffer;
1527 raw_string_ostream StrBuf(Buffer);
1528 StrBuf << "Alloca on non-i32 value. Found: " << ByteCount;
1529 Error(StrBuf.str());
1530 return;
1531 }
1532 uint64_t AlignPower = Values[1];
1533 unsigned Alignment = 1;
1534 if (AlignPower <= AlignPowerLimit) {
1535 Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1;
1536 } else {
1537 std::string Buffer;
1538 raw_string_ostream StrBuf(Buffer);
1539 StrBuf << "Alloca on alignment greater than 2**" << AlignPowerLimit
1540 << ". Found: 2**" << AlignPower;
1541 Error(StrBuf.str());
1542 // TODO(kschimpf) Remove error recovery once implementation complete.
1543 }
1544 Ice::Variable *Dest = NextInstVar(Context->getIcePointerType());
1545 Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest);
1546 break;
1547 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001548 default:
1549 // Generate error message!
1550 BlockParserBaseClass::ProcessRecord();
1551 break;
1552 }
1553 if (Inst)
1554 CurrentNode->appendInst(Inst);
1555}
1556
Karl Schimpff12355e2014-09-08 13:41:09 -07001557/// Parses constants within a function block.
1558class ConstantsParser : public BlockParserBaseClass {
1559 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION;
1560 ConstantsParser &operator=(const ConstantsParser &) LLVM_DELETED_FUNCTION;
1561
1562public:
1563 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
1564 : BlockParserBaseClass(BlockID, FuncParser), FuncParser(FuncParser),
1565 NextConstantType(Ice::IceType_void) {}
1566
1567 ~ConstantsParser() LLVM_OVERRIDE {}
1568
1569private:
1570 // The parser of the function block this constants block appears in.
1571 FunctionParser *FuncParser;
1572 // The type to use for succeeding constants.
1573 Ice::Type NextConstantType;
1574
1575 virtual void ProcessRecord() LLVM_OVERRIDE;
1576
1577 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
1578
1579 // Returns true if the type to use for succeeding constants is defined.
1580 // If false, also generates an error message.
1581 bool isValidNextConstantType() {
1582 if (NextConstantType != Ice::IceType_void)
1583 return true;
1584 Error("Constant record not preceded by set type record");
1585 return false;
1586 }
1587};
1588
1589void ConstantsParser::ProcessRecord() {
1590 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1591 switch (Record.GetCode()) {
1592 case naclbitc::CST_CODE_SETTYPE: {
1593 // SETTYPE: [typeid]
1594 if (!isValidRecordSize(1, "constants block set type"))
1595 return;
1596 NextConstantType =
1597 Context->convertToIceType(Context->getTypeByID(Values[0]));
1598 if (NextConstantType == Ice::IceType_void)
1599 Error("constants block set type not allowed for void type");
1600 return;
1601 }
1602 case naclbitc::CST_CODE_UNDEF: {
1603 // UNDEF
1604 if (!isValidRecordSize(0, "constants block undef"))
1605 return;
1606 if (!isValidNextConstantType())
1607 return;
1608 FuncParser->setNextConstantID(
1609 getContext()->getConstantUndef(NextConstantType));
1610 return;
1611 }
1612 case naclbitc::CST_CODE_INTEGER: {
1613 // INTEGER: [intval]
1614 if (!isValidRecordSize(1, "constants block integer"))
1615 return;
1616 if (!isValidNextConstantType())
1617 return;
1618 if (IntegerType *IType = dyn_cast<IntegerType>(
1619 Context->convertToLLVMType(NextConstantType))) {
1620 APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0]));
1621 Ice::Constant *C =
1622 getContext()->getConstantInt(NextConstantType, Value.getSExtValue());
1623 FuncParser->setNextConstantID(C);
1624 return;
1625 }
1626 std::string Buffer;
1627 raw_string_ostream StrBuf(Buffer);
1628 StrBuf << "constant block integer record for non-integer type "
1629 << NextConstantType;
1630 Error(StrBuf.str());
1631 return;
1632 }
1633 case naclbitc::CST_CODE_FLOAT: {
1634 // FLOAT: [fpval]
1635 if (!isValidRecordSize(1, "constants block float"))
1636 return;
1637 if (!isValidNextConstantType())
1638 return;
1639 switch (NextConstantType) {
1640 case Ice::IceType_f32: {
1641 APFloat Value(APFloat::IEEEsingle,
1642 APInt(32, static_cast<uint32_t>(Values[0])));
1643 FuncParser->setNextConstantID(
1644 getContext()->getConstantFloat(Value.convertToFloat()));
1645 return;
1646 }
1647 case Ice::IceType_f64: {
1648 APFloat Value(APFloat::IEEEdouble, APInt(64, Values[0]));
1649 FuncParser->setNextConstantID(
1650 getContext()->getConstantDouble(Value.convertToDouble()));
1651 return;
1652 }
1653 default: {
1654 std::string Buffer;
1655 raw_string_ostream StrBuf(Buffer);
1656 StrBuf << "constant block float record for non-floating type "
1657 << NextConstantType;
1658 Error(StrBuf.str());
1659 return;
1660 }
1661 }
1662 }
1663 default:
1664 // Generate error message!
1665 BlockParserBaseClass::ProcessRecord();
1666 return;
1667 }
1668}
1669
1670bool FunctionParser::ParseBlock(unsigned BlockID) {
1671 switch (BlockID) {
1672 case naclbitc::CONSTANTS_BLOCK_ID: {
1673 ConstantsParser Parser(BlockID, this);
1674 return Parser.ParseThisBlock();
1675 }
1676 default:
1677 return BlockParserBaseClass::ParseBlock(BlockID);
1678 }
1679}
1680
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001681/// Parses the module block in the bitcode file.
1682class ModuleParser : public BlockParserBaseClass {
1683public:
1684 ModuleParser(unsigned BlockID, TopLevelParser *Context)
1685 : BlockParserBaseClass(BlockID, Context) {}
1686
1687 virtual ~ModuleParser() LLVM_OVERRIDE {}
1688
1689protected:
1690 virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
1691
1692 virtual void ProcessRecord() LLVM_OVERRIDE;
1693};
1694
1695bool ModuleParser::ParseBlock(unsigned BlockID) LLVM_OVERRIDE {
1696 switch (BlockID) {
1697 case naclbitc::BLOCKINFO_BLOCK_ID:
1698 return NaClBitcodeParser::ParseBlock(BlockID);
1699 case naclbitc::TYPE_BLOCK_ID_NEW: {
1700 TypesParser Parser(BlockID, this);
1701 return Parser.ParseThisBlock();
1702 }
1703 case naclbitc::GLOBALVAR_BLOCK_ID: {
1704 GlobalsParser Parser(BlockID, this);
1705 return Parser.ParseThisBlock();
1706 }
1707 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
1708 ValuesymtabParser Parser(BlockID, this, false);
1709 return Parser.ParseThisBlock();
1710 }
1711 case naclbitc::FUNCTION_BLOCK_ID: {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001712 FunctionParser Parser(BlockID, this);
1713 return Parser.ParseThisBlock();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001714 }
1715 default:
1716 return BlockParserBaseClass::ParseBlock(BlockID);
1717 }
1718}
1719
1720void ModuleParser::ProcessRecord() {
1721 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1722 switch (Record.GetCode()) {
1723 case naclbitc::MODULE_CODE_VERSION: {
1724 // VERSION: [version#]
Karl Schimpfd6064a12014-08-27 15:34:58 -07001725 if (!isValidRecordSize(1, "Module version"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001726 return;
1727 unsigned Version = Values[0];
1728 if (Version != 1) {
1729 std::string Buffer;
1730 raw_string_ostream StrBuf(Buffer);
1731 StrBuf << "Unknown bitstream version: " << Version;
1732 Error(StrBuf.str());
1733 }
1734 return;
1735 }
1736 case naclbitc::MODULE_CODE_FUNCTION: {
1737 // FUNCTION: [type, callingconv, isproto, linkage]
Karl Schimpfd6064a12014-08-27 15:34:58 -07001738 if (!isValidRecordSize(4, "Function heading"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001739 return;
1740 Type *Ty = Context->getTypeByID(Values[0]);
1741 FunctionType *FTy = dyn_cast<FunctionType>(Ty);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001742 if (FTy == NULL) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001743 std::string Buffer;
1744 raw_string_ostream StrBuf(Buffer);
1745 StrBuf << "Function heading expects function type. Found: " << Ty;
1746 Error(StrBuf.str());
1747 return;
1748 }
1749 CallingConv::ID CallingConv;
1750 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
1751 std::string Buffer;
1752 raw_string_ostream StrBuf(Buffer);
1753 StrBuf << "Function heading has unknown calling convention: "
1754 << Values[1];
1755 Error(StrBuf.str());
1756 return;
1757 }
1758 GlobalValue::LinkageTypes Linkage;
1759 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
1760 std::string Buffer;
1761 raw_string_ostream StrBuf(Buffer);
1762 StrBuf << "Function heading has unknown linkage. Found " << Values[3];
1763 Error(StrBuf.str());
1764 return;
1765 }
1766 Function *Func = Function::Create(FTy, Linkage, "", Context->getModule());
1767 Func->setCallingConv(CallingConv);
1768 if (Values[2] == 0)
1769 Context->setNextValueIDAsImplementedFunction();
1770 Context->setNextFunctionID(Func);
1771 // TODO(kschimpf) verify if Func matches PNaCl ABI.
1772 return;
1773 }
1774 default:
1775 BlockParserBaseClass::ProcessRecord();
1776 return;
1777 }
1778}
1779
1780bool TopLevelParser::ParseBlock(unsigned BlockID) {
1781 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
1782 ModuleParser Parser(BlockID, this);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001783 return Parser.ParseThisBlock();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001784 }
1785 // Generate error message by using default block implementation.
1786 BlockParserBaseClass Parser(BlockID, this);
1787 return Parser.ParseThisBlock();
1788}
1789
Jim Stichnoth989a7032014-08-08 10:13:44 -07001790} // end of anonymous namespace
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001791
1792namespace Ice {
1793
1794void PNaClTranslator::translate(const std::string &IRFilename) {
1795 OwningPtr<MemoryBuffer> MemBuf;
1796 if (error_code ec =
1797 MemoryBuffer::getFileOrSTDIN(IRFilename.c_str(), MemBuf)) {
1798 errs() << "Error reading '" << IRFilename << "': " << ec.message() << "\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001799 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001800 return;
1801 }
1802
1803 if (MemBuf->getBufferSize() % 4 != 0) {
1804 errs() << IRFilename
1805 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001806 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001807 return;
1808 }
1809
1810 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
1811 const unsigned char *EndBufPtr = BufPtr + MemBuf->getBufferSize();
1812
1813 // Read header and verify it is good.
1814 NaClBitcodeHeader Header;
1815 if (Header.Read(BufPtr, EndBufPtr) || !Header.IsSupported()) {
1816 errs() << "Invalid PNaCl bitcode header.\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001817 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001818 return;
1819 }
1820
1821 // Create a bitstream reader to read the bitcode file.
1822 NaClBitstreamReader InputStreamFile(BufPtr, EndBufPtr);
1823 NaClBitstreamCursor InputStream(InputStreamFile);
1824
Karl Schimpfd6064a12014-08-27 15:34:58 -07001825 TopLevelParser Parser(*this, MemBuf->getBufferIdentifier(), Header,
1826 InputStream, ErrorStatus);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001827 int TopLevelBlocks = 0;
1828 while (!InputStream.AtEndOfStream()) {
1829 if (Parser.Parse()) {
Karl Schimpfb164d202014-07-11 10:26:34 -07001830 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001831 return;
1832 }
1833 ++TopLevelBlocks;
1834 }
1835
1836 if (TopLevelBlocks != 1) {
1837 errs() << IRFilename
1838 << ": Contains more than one module. Found: " << TopLevelBlocks
1839 << "\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07001840 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07001841 }
1842 return;
1843}
1844
Jim Stichnoth989a7032014-08-08 10:13:44 -07001845} // end of namespace Ice