blob: 6642ba977bbc57b588503bfb6416e5bd02f14db8 [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
Karl Schimpf41689df2014-09-10 14:36:07 -070015#include "llvm/Analysis/NaCl/PNaClABIProps.h"
Karl Schimpf8d7abae2014-07-07 14:50:30 -070016#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
17#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
18#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
19#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
20#include "llvm/IR/Constants.h"
Karl Schimpf41689df2014-09-10 14:36:07 -070021#include "llvm/IR/DataLayout.h"
Karl Schimpf8d7abae2014-07-07 14:50:30 -070022#include "llvm/IR/LLVMContext.h"
23#include "llvm/IR/Module.h"
24#include "llvm/Support/Format.h"
25#include "llvm/Support/MemoryBuffer.h"
26#include "llvm/Support/raw_ostream.h"
27#include "llvm/Support/ValueHandle.h"
28
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070029#include "IceCfg.h"
30#include "IceCfgNode.h"
31#include "IceClFlags.h"
32#include "IceDefs.h"
Karl Schimpfe3f64d02014-10-07 10:38:22 -070033#include "IceGlobalInits.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070034#include "IceInst.h"
35#include "IceOperand.h"
36#include "IceTypeConverter.h"
37#include "PNaClTranslator.h"
Karl Schimpf8d7abae2014-07-07 14:50:30 -070038
39using namespace llvm;
40
41namespace {
42
Karl Schimpfd6064a12014-08-27 15:34:58 -070043// TODO(kschimpf) Remove error recovery once implementation complete.
44static cl::opt<bool> AllowErrorRecovery(
45 "allow-pnacl-reader-error-recovery",
46 cl::desc("Allow error recovery when reading PNaCl bitcode."),
47 cl::init(false));
48
Karl Schimpf645aa1a2014-10-08 09:05:53 -070049// Models elements in the list of types defined in the types block.
50// These elements can be undefined, a (simple) type, or a function type
51// signature. Note that an extended type is undefined on construction.
52// Use methods setAsSimpleType and setAsFuncSigType to define
53// the extended type.
54class ExtendedType {
55 // ExtendedType(const ExtendedType &Ty) = delete;
56 ExtendedType &operator=(const ExtendedType &Ty) = delete;
57public:
58 /// Discriminator for LLVM-style RTTI.
59 enum TypeKind { Undefined, Simple, FuncSig };
60
61 ExtendedType() : Kind(Undefined) {}
62
63 virtual ~ExtendedType() {}
64
65 ExtendedType::TypeKind getKind() const { return Kind; }
66 void Dump(Ice::Ostream &Stream) const;
67
68 /// Changes the extended type to a simple type with the given
69 /// value.
70 void setAsSimpleType(Ice::Type Ty) {
71 assert(Kind == Undefined);
72 Kind = Simple;
73 Signature.setReturnType(Ty);
74 }
75
76 /// Changes the extended type to an (empty) function signature type.
77 void setAsFunctionType() {
78 assert(Kind == Undefined);
79 Kind = FuncSig;
80 }
81
82protected:
83 // Note: For simple types, the return type of the signature will
84 // be used to hold the simple type.
85 Ice::FuncSigType Signature;
86
87private:
88 ExtendedType::TypeKind Kind;
89};
90
91Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
92 Ty.Dump(Stream);
93 return Stream;
94}
95
96Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
97 Stream << "ExtendedType::";
98 switch (Kind) {
99 case ExtendedType::Undefined:
100 Stream << "Undefined";
101 break;
102 case ExtendedType::Simple:
103 Stream << "Simple";
104 break;
105 case ExtendedType::FuncSig:
106 Stream << "FuncSig";
107 break;
108 default:
109 Stream << "??";
110 break;
111 }
112 return Stream;
113}
114
115// Models an ICE type as an extended type.
116class SimpleExtendedType : public ExtendedType {
117 SimpleExtendedType(const SimpleExtendedType &) = delete;
118 SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
119public:
120 Ice::Type getType() const { return Signature.getReturnType(); }
121
122 static bool classof(const ExtendedType *Ty) {
123 return Ty->getKind() == Simple;
124 }
125};
126
127// Models a function signature as an extended type.
128class FuncSigExtendedType : public ExtendedType {
129 FuncSigExtendedType(const FuncSigExtendedType &) = delete;
130 FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
131public:
132 const Ice::FuncSigType &getSignature() const { return Signature; }
133 void setReturnType(Ice::Type ReturnType) {
134 Signature.setReturnType(ReturnType);
135 }
136 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
137 static bool classof(const ExtendedType *Ty) {
138 return Ty->getKind() == FuncSig;
139 }
140};
141
142void ExtendedType::Dump(Ice::Ostream &Stream) const {
143 Stream << Kind;
144 switch (Kind) {
145 case Simple: {
146 Stream << " " << Signature.getReturnType();
147 break;
148 }
149 case FuncSig: {
150 Stream << " " << Signature;
151 }
152 default:
153 break;
154 }
155}
156
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700157// Top-level class to read PNaCl bitcode files, and translate to ICE.
158class TopLevelParser : public NaClBitcodeParser {
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700159 TopLevelParser(const TopLevelParser &) = delete;
160 TopLevelParser &operator=(const TopLevelParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700161
162public:
Karl Schimpfd6064a12014-08-27 15:34:58 -0700163 TopLevelParser(Ice::Translator &Translator, const std::string &InputName,
164 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor,
165 bool &ErrorStatus)
166 : NaClBitcodeParser(Cursor), Translator(Translator),
Karl Schimpf41689df2014-09-10 14:36:07 -0700167 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout),
168 Header(Header), TypeConverter(getLLVMContext()),
169 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0),
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700170 NumFunctionBlocks(0) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700171 Mod->setDataLayout(PNaClDataLayout);
Karl Schimpf8df26f32014-09-19 09:33:26 -0700172 setErrStream(Translator.getContext()->getStrDump());
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700173 }
174
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700175 ~TopLevelParser() override { DeleteContainerPointers(GlobalIDAddresses); }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700176
Karl Schimpfd6064a12014-08-27 15:34:58 -0700177 Ice::Translator &getTranslator() { return Translator; }
178
179 // Generates error with given Message. Always returns true.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700180 bool Error(const std::string &Message) override {
Karl Schimpfb164d202014-07-11 10:26:34 -0700181 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700182 ++NumErrors;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700183 NaClBitcodeParser::Error(Message);
184 if (!AllowErrorRecovery)
185 report_fatal_error("Unable to continue");
186 return true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700187 }
188
189 /// Returns the number of errors found while parsing the bitcode
190 /// file.
191 unsigned getNumErrors() const { return NumErrors; }
192
193 /// Returns the LLVM module associated with the translation.
194 Module *getModule() const { return Mod.get(); }
195
Karl Schimpf41689df2014-09-10 14:36:07 -0700196 const DataLayout &getDataLayout() const { return DL; }
197
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700198 /// Returns the number of bytes in the bitcode header.
199 size_t getHeaderSize() const { return Header.getHeaderSize(); }
200
201 /// Returns the llvm context to use.
202 LLVMContext &getLLVMContext() const { return Mod->getContext(); }
203
204 /// Changes the size of the type list to the given size.
205 void resizeTypeIDValues(unsigned NewSize) { TypeIDValues.resize(NewSize); }
206
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700207 /// Returns the undefined type associated with type ID.
208 /// Note: Returns extended type ready to be defined.
209 ExtendedType *getTypeByIDForDefining(unsigned ID) {
210 // Get corresponding element, verifying the value is still undefined
211 // (and hence allowed to be defined).
212 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700213 if (Ty)
214 return Ty;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700215 if (ID >= TypeIDValues.size())
216 TypeIDValues.resize(ID+1);
217 return &TypeIDValues[ID];
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700218 }
219
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700220 /// Returns the type associated with the given index.
221 Ice::Type getSimpleTypeByID(unsigned ID) {
222 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
223 if (Ty == nullptr)
224 // Return error recovery value.
225 return Ice::IceType_void;
226 return cast<SimpleExtendedType>(Ty)->getType();
227 }
228
229 /// Returns the type signature associated with the given index.
230 const Ice::FuncSigType &getFuncSigTypeByID(unsigned ID) {
231 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
232 if (Ty == nullptr)
233 // Return error recovery value.
234 return UndefinedFuncSigType;
235 return cast<FuncSigExtendedType>(Ty)->getSignature();
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700236 }
237
238 /// Sets the next function ID to the given LLVM function.
239 void setNextFunctionID(Function *Fcn) {
240 ++NumFunctionIds;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700241 FunctionIDValues.push_back(Fcn);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700242 }
243
244 /// Defines the next function ID as one that has an implementation
245 /// (i.e a corresponding function block in the bitcode).
246 void setNextValueIDAsImplementedFunction() {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700247 DefiningFunctionsList.push_back(FunctionIDValues.size());
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700248 }
249
Karl Schimpfd6064a12014-08-27 15:34:58 -0700250 /// Returns the value id that should be associated with the the
251 /// current function block. Increments internal counters during call
252 /// so that it will be in correct position for next function block.
253 unsigned getNextFunctionBlockValueID() {
254 if (NumFunctionBlocks >= DefiningFunctionsList.size())
255 report_fatal_error(
256 "More function blocks than defined function addresses");
257 return DefiningFunctionsList[NumFunctionBlocks++];
258 }
259
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700260 /// Returns the LLVM Function address associated with ID.
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700261 Function *getFunctionByID(unsigned ID) const {
262 if (ID >= FunctionIDValues.size())
263 return nullptr;
264 Value *V = FunctionIDValues[ID];
265 return cast<Function>(V);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700266 }
267
Karl Schimpf8df26f32014-09-19 09:33:26 -0700268 /// Returns the corresponding constant associated with a global value
269 /// (i.e. relocatable).
270 Ice::Constant *getOrCreateGlobalConstantByID(unsigned ID) {
271 // TODO(kschimpf): Can this be built when creating global initializers?
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700272 Ice::Constant *C;
Karl Schimpf8df26f32014-09-19 09:33:26 -0700273 if (ID >= ValueIDConstants.size()) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700274 C = nullptr;
275 unsigned ExpectedSize =
276 FunctionIDValues.size() + GlobalIDAddresses.size();
277 if (ID >= ExpectedSize)
278 ExpectedSize = ID;
279 ValueIDConstants.resize(ExpectedSize);
280 } else {
281 C = ValueIDConstants[ID];
Karl Schimpf8df26f32014-09-19 09:33:26 -0700282 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700283 if (C != nullptr)
Karl Schimpf8df26f32014-09-19 09:33:26 -0700284 return C;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700285
286 // If reached, no such constant exists, create one.
287 std::string Name;
288 unsigned FcnIDSize = FunctionIDValues.size();
289 if (ID < FcnIDSize) {
290 Name = FunctionIDValues[ID]->getName();
291 } else if ((ID - FcnIDSize) < GlobalIDAddresses.size()) {
292 Name = GlobalIDAddresses[ID - FcnIDSize]->getName();
293 } else {
294 std::string Buffer;
295 raw_string_ostream StrBuf(Buffer);
296 StrBuf << "Reference to global not defined: " << ID;
297 Error(StrBuf.str());
298 Name = "??";
299 }
300 const uint64_t Offset = 0;
301 C = getTranslator().getContext()->getConstantSym(
302 getIcePointerType(), Offset, Name);
Karl Schimpf8df26f32014-09-19 09:33:26 -0700303 ValueIDConstants[ID] = C;
304 return C;
305 }
306
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700307 /// Returns the number of function addresses (i.e. ID's) defined in
308 /// the bitcode file.
309 unsigned getNumFunctionIDs() const { return NumFunctionIds; }
310
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700311 /// Returns the number of global IDs (function and global addresses)
312 /// defined in the bitcode file.
313 unsigned getNumGlobalIDs() const {
314 return FunctionIDValues.size() + GlobalIDAddresses.size();
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700315 }
316
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700317 /// Creates Count global addresses.
318 void CreateGlobalAddresses(size_t Count) {
319 assert(GlobalIDAddresses.empty());
320 for (size_t i = 0; i < Count; ++i) {
321 GlobalIDAddresses.push_back(new Ice::GlobalAddress());
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700322 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700323 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700324
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700325 /// Returns the number of global addresses (i.e. ID's) defined in
326 /// the bitcode file.
327 Ice::SizeT getNumGlobalAddresses() const { return GlobalIDAddresses.size(); }
328
329 /// Returns the global address with the given index.
330 Ice::GlobalAddress *getGlobalAddress(size_t Index) {
331 if (Index < GlobalIDAddresses.size())
332 return GlobalIDAddresses[Index];
333 std::string Buffer;
334 raw_string_ostream StrBuf(Buffer);
335 StrBuf << "Global index " << Index
336 << " not allowed. Out of range. Must be less than "
337 << GlobalIDAddresses.size();
338 Error(StrBuf.str());
339 // TODO(kschimpf) Remove error recovery once implementation complete.
340 if (!GlobalIDAddresses.empty())
341 return GlobalIDAddresses[0];
342 report_fatal_error("Unable to continue");
343 }
344
345 /// Returns the list of read global addresses.
346 const Ice::Translator::GlobalAddressList &getGlobalIDAddresses() {
347 return GlobalIDAddresses;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700348 }
349
Karl Schimpfd6064a12014-08-27 15:34:58 -0700350 /// Returns the corresponding ICE type for LLVMTy.
351 Ice::Type convertToIceType(Type *LLVMTy) {
352 Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy);
353 if (IceTy >= Ice::IceType_NUM) {
354 return convertToIceTypeError(LLVMTy);
355 }
356 return IceTy;
357 }
358
359 /// Returns the corresponding LLVM type for IceTy.
360 Type *convertToLLVMType(Ice::Type IceTy) const {
361 return TypeConverter.convertToLLVMType(IceTy);
362 }
363
Karl Schimpfd6064a12014-08-27 15:34:58 -0700364 /// Returns the model for pointer types in ICE.
365 Ice::Type getIcePointerType() const {
366 return TypeConverter.getIcePointerType();
367 }
368
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700369private:
Karl Schimpfd6064a12014-08-27 15:34:58 -0700370 // The translator associated with the parser.
371 Ice::Translator &Translator;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700372 // The parsed module.
Jim Stichnotha18cc9c2014-09-30 19:10:22 -0700373 std::unique_ptr<Module> Mod;
Karl Schimpf41689df2014-09-10 14:36:07 -0700374 // The data layout to use.
375 DataLayout DL;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700376 // The bitcode header.
377 NaClBitcodeHeader &Header;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700378 // Converter between LLVM and ICE types.
379 Ice::TypeConverter TypeConverter;
Karl Schimpfb164d202014-07-11 10:26:34 -0700380 // The exit status that should be set to true if an error occurs.
381 bool &ErrorStatus;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700382 // The number of errors reported.
383 unsigned NumErrors;
384 // The types associated with each type ID.
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700385 std::vector<ExtendedType> TypeIDValues;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700386 // The set of function value IDs.
387 std::vector<WeakVH> FunctionIDValues;
388 // The set of global addresses IDs.
389 Ice::Translator::GlobalAddressList GlobalIDAddresses;
390 // Relocatable constants associated with FunctionIDValues and
391 // GlobalIDAddresses.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700392 std::vector<Ice::Constant *> ValueIDConstants;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700393 // The number of function IDs.
394 unsigned NumFunctionIds;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700395 // The number of function blocks (processed so far).
396 unsigned NumFunctionBlocks;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700397 // The list of value IDs (in the order found) of defining function
398 // addresses.
399 std::vector<unsigned> DefiningFunctionsList;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700400 // Error recovery value to use when getFuncSigTypeByID fails.
401 Ice::FuncSigType UndefinedFuncSigType;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700402
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700403 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700404
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700405 // Gets extended type associated with the given index, assuming the
406 // extended type is of the WantedKind. Generates error message if
407 // corresponding extended type of WantedKind can't be found, and
408 // returns nullptr.
409 ExtendedType *getTypeByIDAsKind(unsigned ID,
410 ExtendedType::TypeKind WantedKind) {
411 ExtendedType *Ty = nullptr;
412 if (ID < TypeIDValues.size()) {
413 Ty = &TypeIDValues[ID];
414 if (Ty->getKind() == WantedKind)
415 return Ty;
416 }
417 // Generate an error message and set ErrorStatus.
418 this->reportBadTypeIDAs(ID, Ty, WantedKind);
419 return nullptr;
420 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700421
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700422 // Reports that type ID is undefined, or not of the WantedType.
423 void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
424 ExtendedType::TypeKind WantedType);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700425
426 // Reports that there is no corresponding ICE type for LLVMTy, and
427 // returns ICE::IceType_void.
428 Ice::Type convertToIceTypeError(Type *LLVMTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700429};
430
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700431void TopLevelParser::reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty,
432 ExtendedType::TypeKind WantedType) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700433 std::string Buffer;
434 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700435 if (Ty == nullptr) {
436 StrBuf << "Can't find extended type for type id: " << ID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700437 } else {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700438 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700439 }
440 Error(StrBuf.str());
441}
442
Karl Schimpfd6064a12014-08-27 15:34:58 -0700443Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
444 std::string Buffer;
445 raw_string_ostream StrBuf(Buffer);
446 StrBuf << "Invalid LLVM type: " << *LLVMTy;
447 Error(StrBuf.str());
448 return Ice::IceType_void;
449}
450
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700451// Base class for parsing blocks within the bitcode file. Note:
452// Because this is the base class of block parsers, we generate error
453// messages if ParseBlock or ParseRecord is not overridden in derived
454// classes.
455class BlockParserBaseClass : public NaClBitcodeParser {
456public:
457 // Constructor for the top-level module block parser.
458 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
459 : NaClBitcodeParser(BlockID, Context), Context(Context) {}
460
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700461 ~BlockParserBaseClass() override {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700462
463protected:
464 // The context parser that contains the decoded state.
465 TopLevelParser *Context;
466
467 // Constructor for nested block parsers.
468 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
469 : NaClBitcodeParser(BlockID, EnclosingParser),
470 Context(EnclosingParser->Context) {}
471
Karl Schimpfd6064a12014-08-27 15:34:58 -0700472 // Gets the translator associated with the bitcode parser.
Karl Schimpf6ff33d22014-09-22 10:28:42 -0700473 Ice::Translator &getTranslator() const { return Context->getTranslator(); }
474
475 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); }
Karl Schimpfd6064a12014-08-27 15:34:58 -0700476
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700477 // Generates an error Message with the bit address prefixed to it.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700478 bool Error(const std::string &Message) override {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700479 uint64_t Bit = Record.GetStartBit() + Context->getHeaderSize() * 8;
480 std::string Buffer;
481 raw_string_ostream StrBuf(Buffer);
482 StrBuf << "(" << format("%" PRIu64 ":%u", (Bit / 8),
483 static_cast<unsigned>(Bit % 8)) << ") " << Message;
484 return Context->Error(StrBuf.str());
485 }
486
487 // Default implementation. Reports that block is unknown and skips
488 // its contents.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700489 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700490
491 // Default implementation. Reports that the record is not
492 // understood.
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700493 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700494
Karl Schimpfd6064a12014-08-27 15:34:58 -0700495 // Checks if the size of the record is Size. Return true if valid.
496 // Otherwise generates an error and returns false.
497 bool isValidRecordSize(unsigned Size, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700498 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700499 if (Values.size() == Size)
500 return true;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700501 ReportRecordSizeError(Size, RecordName, nullptr);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700502 return false;
503 }
504
Karl Schimpfd6064a12014-08-27 15:34:58 -0700505 // Checks if the size of the record is at least as large as the
506 // LowerLimit. Returns true if valid. Otherwise generates an error
507 // and returns false.
508 bool isValidRecordSizeAtLeast(unsigned LowerLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700509 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700510 if (Values.size() >= LowerLimit)
511 return true;
512 ReportRecordSizeError(LowerLimit, RecordName, "at least");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700513 return false;
514 }
515
Karl Schimpfd6064a12014-08-27 15:34:58 -0700516 // Checks if the size of the record is no larger than the
517 // UpperLimit. Returns true if valid. Otherwise generates an error
518 // and returns false.
519 bool isValidRecordSizeAtMost(unsigned UpperLimit, const char *RecordName) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700520 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700521 if (Values.size() <= UpperLimit)
522 return true;
523 ReportRecordSizeError(UpperLimit, RecordName, "no more than");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700524 return false;
525 }
526
Karl Schimpfd6064a12014-08-27 15:34:58 -0700527 // Checks if the size of the record is at least as large as the
528 // LowerLimit, and no larger than the UpperLimit. Returns true if
529 // valid. Otherwise generates an error and returns false.
530 bool isValidRecordSizeInRange(unsigned LowerLimit, unsigned UpperLimit,
531 const char *RecordName) {
532 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
533 isValidRecordSizeAtMost(UpperLimit, RecordName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700534 }
535
536private:
537 /// Generates a record size error. ExpectedSize is the number
538 /// of elements expected. RecordName is the name of the kind of
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700539 /// record that has incorrect size. ContextMessage (if not nullptr)
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700540 /// is appended to "record expects" to describe how ExpectedSize
541 /// should be interpreted.
Karl Schimpfd6064a12014-08-27 15:34:58 -0700542 void ReportRecordSizeError(unsigned ExpectedSize, const char *RecordName,
543 const char *ContextMessage);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700544};
545
Karl Schimpfd6064a12014-08-27 15:34:58 -0700546void BlockParserBaseClass::ReportRecordSizeError(unsigned ExpectedSize,
547 const char *RecordName,
548 const char *ContextMessage) {
549 std::string Buffer;
550 raw_string_ostream StrBuf(Buffer);
551 StrBuf << RecordName << " record expects";
552 if (ContextMessage)
553 StrBuf << " " << ContextMessage;
554 StrBuf << " " << ExpectedSize << " argument";
555 if (ExpectedSize > 1)
556 StrBuf << "s";
557 StrBuf << ". Found: " << Record.GetValues().size();
558 Error(StrBuf.str());
559}
560
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700561bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
562 // If called, derived class doesn't know how to handle block.
563 // Report error and skip.
564 std::string Buffer;
565 raw_string_ostream StrBuf(Buffer);
566 StrBuf << "Don't know how to parse block id: " << BlockID;
567 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700568 // TODO(kschimpf) Remove error recovery once implementation complete.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700569 SkipBlock();
570 return false;
571}
572
573void BlockParserBaseClass::ProcessRecord() {
574 // If called, derived class doesn't know how to handle.
575 std::string Buffer;
576 raw_string_ostream StrBuf(Buffer);
577 StrBuf << "Don't know how to process record: " << Record;
578 Error(StrBuf.str());
579}
580
581// Class to parse a types block.
582class TypesParser : public BlockParserBaseClass {
583public:
584 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
585 : BlockParserBaseClass(BlockID, EnclosingParser), NextTypeId(0) {}
586
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700587 ~TypesParser() override {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700588
589private:
590 // The type ID that will be associated with the next type defining
591 // record in the types block.
592 unsigned NextTypeId;
593
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700594 void ProcessRecord() override;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700595
596 void setNextTypeIDAsSimpleType(Ice::Type Ty) {
597 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
598 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700599};
600
601void TypesParser::ProcessRecord() {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700602 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
603 switch (Record.GetCode()) {
604 case naclbitc::TYPE_CODE_NUMENTRY:
605 // NUMENTRY: [numentries]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700606 if (!isValidRecordSize(1, "Type count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700607 return;
608 Context->resizeTypeIDValues(Values[0]);
609 return;
610 case naclbitc::TYPE_CODE_VOID:
611 // VOID
Karl Schimpfd6064a12014-08-27 15:34:58 -0700612 if (!isValidRecordSize(0, "Type void"))
613 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700614 setNextTypeIDAsSimpleType(Ice::IceType_void);
615 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700616 case naclbitc::TYPE_CODE_FLOAT:
617 // FLOAT
Karl Schimpfd6064a12014-08-27 15:34:58 -0700618 if (!isValidRecordSize(0, "Type float"))
619 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700620 setNextTypeIDAsSimpleType(Ice::IceType_f32);
621 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700622 case naclbitc::TYPE_CODE_DOUBLE:
623 // DOUBLE
Karl Schimpfd6064a12014-08-27 15:34:58 -0700624 if (!isValidRecordSize(0, "Type double"))
625 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700626 setNextTypeIDAsSimpleType(Ice::IceType_f64);
627 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700628 case naclbitc::TYPE_CODE_INTEGER:
629 // INTEGER: [width]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700630 if (!isValidRecordSize(1, "Type integer"))
631 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700632 switch (Values[0]) {
633 case 1:
634 setNextTypeIDAsSimpleType(Ice::IceType_i1);
635 return;
636 case 8:
637 setNextTypeIDAsSimpleType(Ice::IceType_i8);
638 return;
639 case 16:
640 setNextTypeIDAsSimpleType(Ice::IceType_i16);
641 return;
642 case 32:
643 setNextTypeIDAsSimpleType(Ice::IceType_i32);
644 return;
645 case 64:
646 setNextTypeIDAsSimpleType(Ice::IceType_i64);
647 return;
648 default:
649 break;
650 }
651 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700652 std::string Buffer;
653 raw_string_ostream StrBuf(Buffer);
654 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
655 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700656 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700657 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700658 case naclbitc::TYPE_CODE_VECTOR: {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700659 // VECTOR: [numelts, eltty]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700660 if (!isValidRecordSize(2, "Type vector"))
661 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700662 Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
663 Ice::SizeT Size = Values[0];
664 switch (BaseTy) {
665 case Ice::IceType_i1:
666 switch (Size) {
667 case 4:
668 setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
669 return;
670 case 8:
671 setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
672 return;
673 case 16:
674 setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
675 return;
676 default:
677 break;
678 }
679 break;
680 case Ice::IceType_i8:
681 if (Size == 16) {
682 setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
683 return;
684 }
685 break;
686 case Ice::IceType_i16:
687 if (Size == 8) {
688 setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
689 return;
690 }
691 break;
692 case Ice::IceType_i32:
693 if (Size == 4) {
694 setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
695 return;
696 }
697 break;
698 case Ice::IceType_f32:
699 if (Size == 4) {
700 setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
701 return;
702 }
703 break;
704 default:
705 break;
706 }
707 {
Karl Schimpfd6064a12014-08-27 15:34:58 -0700708 std::string Buffer;
709 raw_string_ostream StrBuf(Buffer);
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700710 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
Karl Schimpfd6064a12014-08-27 15:34:58 -0700711 << ">";
712 Error(StrBuf.str());
Karl Schimpfd6064a12014-08-27 15:34:58 -0700713 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700714 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700715 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700716 case naclbitc::TYPE_CODE_FUNCTION: {
717 // FUNCTION: [vararg, retty, paramty x N]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700718 if (!isValidRecordSizeAtLeast(2, "Type signature"))
719 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700720 if (Values[0])
721 Error("Function type can't define varargs");
722 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
723 Ty->setAsFunctionType();
724 FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty);
725 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700726 for (unsigned i = 2, e = Values.size(); i != e; ++i) {
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700727 // Check that type void not used as argument type.
728 // Note: PNaCl restrictions can't be checked until we
729 // know the name, because we have to check for intrinsic signatures.
730 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
731 if (ArgTy == Ice::IceType_void) {
732 std::string Buffer;
733 raw_string_ostream StrBuf(Buffer);
734 StrBuf << "Type for parameter " << (i - 1)
735 << " not valid. Found: " << ArgTy;
736 // TODO(kschimpf) Remove error recovery once implementation complete.
737 ArgTy = Ice::IceType_i32;
738 }
739 FuncTy->appendArgType(ArgTy);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700740 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700741 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700742 }
743 default:
744 BlockParserBaseClass::ProcessRecord();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700745 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700746 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -0700747 llvm_unreachable("Unknown type block record not processed!");
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700748}
749
750/// Parses the globals block (i.e. global variables).
751class GlobalsParser : public BlockParserBaseClass {
752public:
753 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
754 : BlockParserBaseClass(BlockID, EnclosingParser), InitializersNeeded(0),
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700755 NextGlobalID(0), CurrentAddress(&DummyAddress) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700756
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700757 ~GlobalsParser() override {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700758
759private:
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700760 // Keeps track of how many initializers are expected for the global variable
761 // being built.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700762 unsigned InitializersNeeded;
763
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700764 // The index of the next global variable.
765 unsigned NextGlobalID;
766
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700767 // Holds the current global address whose initializer is being defined.
768 Ice::GlobalAddress *CurrentAddress;
769
770 // Dummy global address to guarantee CurrentAddress is always defined
771 // (allowing code to not need to check if CurrentAddress is nullptr).
772 Ice::GlobalAddress DummyAddress;
773
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700774 void ExitBlock() override {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700775 verifyNoMissingInitializers();
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700776 unsigned NumIDs = Context->getNumGlobalAddresses();
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700777 if (NextGlobalID < NumIDs) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700778 std::string Buffer;
779 raw_string_ostream StrBuf(Buffer);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700780 StrBuf << "Globals block expects " << NumIDs
781 << " global definitions. Found: " << NextGlobalID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700782 Error(StrBuf.str());
783 }
784 BlockParserBaseClass::ExitBlock();
785 }
786
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700787 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700788
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700789 // Checks if the number of initializers for the CurrentAddress is the same as
790 // the number found in the bitcode file. If different, and error message is
791 // generated, and the internal state of the parser is fixed so this condition
792 // is no longer violated.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700793 void verifyNoMissingInitializers() {
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700794 size_t NumInits = CurrentAddress->getInitializers().size();
795 if (InitializersNeeded != NumInits) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700796 std::string Buffer;
797 raw_string_ostream StrBuf(Buffer);
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700798 StrBuf << "Global variable @g" << NextGlobalID << " expected "
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700799 << InitializersNeeded << " initializer";
800 if (InitializersNeeded > 1)
801 StrBuf << "s";
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700802 StrBuf << ". Found: " << NumInits;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700803 Error(StrBuf.str());
804 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700805 }
806};
807
808void GlobalsParser::ProcessRecord() {
809 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
810 switch (Record.GetCode()) {
811 case naclbitc::GLOBALVAR_COUNT:
812 // COUNT: [n]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700813 if (!isValidRecordSize(1, "Globals count"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700814 return;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700815 if (NextGlobalID != Context->getNumGlobalAddresses()) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700816 Error("Globals count record not first in block.");
817 return;
818 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700819 Context->CreateGlobalAddresses(Values[0]);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700820 return;
821 case naclbitc::GLOBALVAR_VAR: {
822 // VAR: [align, isconst]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700823 if (!isValidRecordSize(2, "Globals variable"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700824 return;
825 verifyNoMissingInitializers();
826 InitializersNeeded = 1;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700827 CurrentAddress = Context->getGlobalAddress(NextGlobalID);
828 CurrentAddress->setAlignment((1 << Values[0]) >> 1);
829 CurrentAddress->setIsConstant(Values[1] != 0);
830 ++NextGlobalID;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700831 return;
832 }
833 case naclbitc::GLOBALVAR_COMPOUND:
834 // COMPOUND: [size]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700835 if (!isValidRecordSize(1, "globals compound"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700836 return;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700837 if (!CurrentAddress->getInitializers().empty()) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700838 Error("Globals compound record not first initializer");
839 return;
840 }
841 if (Values[0] < 2) {
842 std::string Buffer;
843 raw_string_ostream StrBuf(Buffer);
844 StrBuf << "Globals compound record size invalid. Found: " << Values[0];
845 Error(StrBuf.str());
846 return;
847 }
848 InitializersNeeded = Values[0];
849 return;
850 case naclbitc::GLOBALVAR_ZEROFILL: {
851 // ZEROFILL: [size]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700852 if (!isValidRecordSize(1, "Globals zerofill"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700853 return;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700854 CurrentAddress->addInitializer(
855 new Ice::GlobalAddress::ZeroInitializer(Values[0]));
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700856 break;
857 }
858 case naclbitc::GLOBALVAR_DATA: {
859 // DATA: [b0, b1, ...]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700860 if (!isValidRecordSizeAtLeast(1, "Globals data"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700861 return;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700862 CurrentAddress->addInitializer(
863 new Ice::GlobalAddress::DataInitializer(Values));
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700864 break;
865 }
866 case naclbitc::GLOBALVAR_RELOC: {
867 // RELOC: [val, [addend]]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700868 if (!isValidRecordSizeInRange(1, 2, "Globals reloc"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700869 return;
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700870 unsigned Index = Values[0];
871 Ice::SizeT Offset = 0;
872 if (Values.size() == 2)
873 Offset = Values[1];
874 unsigned NumFunctions = Context->getNumFunctionIDs();
875 if (Index < NumFunctions) {
876 llvm::Function *Fcn = Context->getFunctionByID(Index);
877 Ice::GlobalAddress::RelocationAddress Addr(Fcn);
878 CurrentAddress->addInitializer(
879 new Ice::GlobalAddress::RelocInitializer(Addr, Offset));
880 } else {
881 Ice::GlobalAddress::RelocationAddress Addr(
882 Context->getGlobalAddress(Index - NumFunctions));
883 CurrentAddress->addInitializer(
884 new Ice::GlobalAddress::RelocInitializer(Addr, Offset));
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700885 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700886 break;
887 }
888 default:
889 BlockParserBaseClass::ProcessRecord();
890 return;
891 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700892}
893
Karl Schimpfc132b762014-09-11 09:43:47 -0700894/// Base class for parsing a valuesymtab block in the bitcode file.
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700895class ValuesymtabParser : public BlockParserBaseClass {
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700896 ValuesymtabParser(const ValuesymtabParser &) = delete;
897 void operator=(const ValuesymtabParser &) = delete;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700898
899public:
Karl Schimpfc132b762014-09-11 09:43:47 -0700900 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
901 : BlockParserBaseClass(BlockID, EnclosingParser) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700902
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700903 ~ValuesymtabParser() override {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700904
Karl Schimpfc132b762014-09-11 09:43:47 -0700905protected:
906 typedef SmallString<128> StringType;
907
908 // Associates Name with the value defined by the given Index.
909 virtual void setValueName(uint64_t Index, StringType &Name) = 0;
910
911 // Associates Name with the value defined by the given Index;
912 virtual void setBbName(uint64_t Index, StringType &Name) = 0;
913
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700914private:
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700915
Jim Stichnoth8e8042c2014-09-25 17:51:47 -0700916 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700917
918 void ConvertToString(StringType &ConvertedName) {
919 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
920 for (size_t i = 1, e = Values.size(); i != e; ++i) {
921 ConvertedName += static_cast<char>(Values[i]);
922 }
923 }
924};
925
926void ValuesymtabParser::ProcessRecord() {
927 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
928 StringType ConvertedName;
929 switch (Record.GetCode()) {
930 case naclbitc::VST_CODE_ENTRY: {
931 // VST_ENTRY: [ValueId, namechar x N]
Karl Schimpfd6064a12014-08-27 15:34:58 -0700932 if (!isValidRecordSizeAtLeast(2, "Valuesymtab value entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700933 return;
934 ConvertToString(ConvertedName);
Karl Schimpfc132b762014-09-11 09:43:47 -0700935 setValueName(Values[0], ConvertedName);
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700936 return;
937 }
938 case naclbitc::VST_CODE_BBENTRY: {
939 // VST_BBENTRY: [BbId, namechar x N]
Karl Schimpfc132b762014-09-11 09:43:47 -0700940 if (!isValidRecordSizeAtLeast(2, "Valuesymtab basic block entry"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700941 return;
Karl Schimpfc132b762014-09-11 09:43:47 -0700942 ConvertToString(ConvertedName);
943 setBbName(Values[0], ConvertedName);
944 return;
Karl Schimpf8d7abae2014-07-07 14:50:30 -0700945 }
946 default:
947 break;
948 }
949 // If reached, don't know how to handle record.
950 BlockParserBaseClass::ProcessRecord();
951 return;
952}
953
Karl Schimpfc132b762014-09-11 09:43:47 -0700954class FunctionValuesymtabParser;
955
Karl Schimpfd6064a12014-08-27 15:34:58 -0700956/// Parses function blocks in the bitcode file.
957class FunctionParser : public BlockParserBaseClass {
Jim Stichnoth0795ba02014-10-01 14:23:01 -0700958 FunctionParser(const FunctionParser &) = delete;
959 FunctionParser &operator=(const FunctionParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -0700960 friend class FunctionValuesymtabParser;
Karl Schimpfd6064a12014-08-27 15:34:58 -0700961
962public:
963 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
964 : BlockParserBaseClass(BlockID, EnclosingParser),
965 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0),
966 FcnId(Context->getNextFunctionBlockValueID()),
Karl Schimpfe3f64d02014-10-07 10:38:22 -0700967 LLVMFunc(Context->getFunctionByID(FcnId)),
968 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
969 NextLocalInstIndex(Context->getNumGlobalIDs()),
Karl Schimpfd6064a12014-08-27 15:34:58 -0700970 InstIsTerminating(false) {
971 Func->setFunctionName(LLVMFunc->getName());
Jim Stichnoth8363a062014-10-07 10:02:38 -0700972 if (getFlags().TimeEachFunction)
973 getTranslator().getContext()->pushTimer(
974 getTranslator().getContext()->getTimerID(
975 Ice::GlobalContext::TSK_Funcs, Func->getFunctionName()),
976 Ice::GlobalContext::TSK_Funcs);
Karl Schimpfd6064a12014-08-27 15:34:58 -0700977 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType()));
978 Func->setInternal(LLVMFunc->hasInternalLinkage());
979 CurrentNode = InstallNextBasicBlock();
Karl Schimpfc132b762014-09-11 09:43:47 -0700980 Func->setEntryNode(CurrentNode);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700981 for (auto ArgI = LLVMFunc->arg_begin(), ArgE = LLVMFunc->arg_end();
Karl Schimpfd6064a12014-08-27 15:34:58 -0700982 ArgI != ArgE; ++ArgI) {
Karl Schimpf47661562014-09-11 14:42:49 -0700983 Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType())));
Karl Schimpfd6064a12014-08-27 15:34:58 -0700984 }
985 }
986
Jim Stichnothc4554d72014-09-30 16:49:38 -0700987 ~FunctionParser() override {};
Karl Schimpfd6064a12014-08-27 15:34:58 -0700988
Karl Schimpff12355e2014-09-08 13:41:09 -0700989 // Set the next constant ID to the given constant C.
Karl Schimpf8f07aa82014-09-17 09:07:20 -0700990 void setNextConstantID(Ice::Constant *C) {
991 setOperand(NextLocalInstIndex++, C);
992 }
Karl Schimpff12355e2014-09-08 13:41:09 -0700993
Karl Schimpfd6064a12014-08-27 15:34:58 -0700994private:
Karl Schimpfd6064a12014-08-27 15:34:58 -0700995 // The corresponding ICE function defined by the function block.
996 Ice::Cfg *Func;
997 // The index to the current basic block being built.
998 uint32_t CurrentBbIndex;
999 // The basic block being built.
1000 Ice::CfgNode *CurrentNode;
1001 // The ID for the function.
1002 unsigned FcnId;
1003 // The corresponding LLVM function.
1004 Function *LLVMFunc;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001005 // Holds the dividing point between local and global absolute value indices.
1006 uint32_t CachedNumGlobalValueIDs;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001007 // Holds operands local to the function block, based on indices
1008 // defined in the bitcode file.
1009 std::vector<Ice::Operand *> LocalOperands;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001010 // Holds the index within LocalOperands corresponding to the next
1011 // instruction that generates a value.
1012 uint32_t NextLocalInstIndex;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001013 // True if the last processed instruction was a terminating
1014 // instruction.
1015 bool InstIsTerminating;
Karl Schimpf742d72d2014-09-09 11:40:09 -07001016 // Upper limit of alignment power allowed by LLVM
1017 static const uint64_t AlignPowerLimit = 29;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001018
Karl Schimpf41689df2014-09-10 14:36:07 -07001019 // Extracts the corresponding Alignment to use, given the AlignPower
1020 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the
1021 // name of the instruction the alignment appears in.
1022 void extractAlignment(const char *InstName, uint64_t AlignPower,
1023 unsigned &Alignment) {
1024 if (AlignPower <= AlignPowerLimit) {
1025 Alignment = (1 << static_cast<unsigned>(AlignPower)) >> 1;
1026 return;
1027 }
1028 std::string Buffer;
1029 raw_string_ostream StrBuf(Buffer);
1030 StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit
1031 << ". Found: 2**" << AlignPower;
1032 Error(StrBuf.str());
1033 // Error recover with value that is always acceptable.
1034 Alignment = 1;
1035 }
1036
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001037 bool ParseBlock(unsigned BlockID) override;
Karl Schimpff12355e2014-09-08 13:41:09 -07001038
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001039 void ProcessRecord() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001040
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07001041 void ExitBlock() override;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001042
1043 // Creates and appends a new basic block to the list of basic blocks.
1044 Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); }
1045
1046 // Returns the Index-th basic block in the list of basic blocks.
Karl Schimpf47661562014-09-11 14:42:49 -07001047 Ice::CfgNode *getBasicBlock(uint32_t Index) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001048 const Ice::NodeList &Nodes = Func->getNodes();
1049 if (Index >= Nodes.size()) {
1050 std::string Buffer;
1051 raw_string_ostream StrBuf(Buffer);
1052 StrBuf << "Reference to basic block " << Index
1053 << " not found. Must be less than " << Nodes.size();
1054 Error(StrBuf.str());
1055 // TODO(kschimpf) Remove error recovery once implementation complete.
1056 Index = 0;
1057 }
1058 return Nodes[Index];
1059 }
1060
Karl Schimpfc836acb2014-09-05 08:32:47 -07001061 // Returns the Index-th basic block in the list of basic blocks.
1062 // Assumes Index corresponds to a branch instruction. Hence, if
1063 // the branch references the entry block, it also generates a
1064 // corresponding error.
1065 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) {
1066 if (Index == 0) {
1067 Error("Branch to entry block not allowed");
1068 // TODO(kschimpf) Remove error recovery once implementation complete.
1069 }
Karl Schimpf47661562014-09-11 14:42:49 -07001070 return getBasicBlock(Index);
Karl Schimpfc836acb2014-09-05 08:32:47 -07001071 }
1072
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001073 // Generate an instruction variable with type Ty.
1074 Ice::Variable *createInstVar(Ice::Type Ty) {
Karl Schimpf47661562014-09-11 14:42:49 -07001075 if (Ty == Ice::IceType_void) {
1076 Error("Can't define instruction value using type void");
1077 // Recover since we can't throw an exception.
1078 Ty = Ice::IceType_i32;
1079 }
Jim Stichnoth144cdce2014-09-22 16:02:59 -07001080 return Func->makeVariable(Ty);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001081 }
1082
1083 // Generates the next available local variable using the given type.
1084 Ice::Variable *getNextInstVar(Ice::Type Ty) {
1085 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
1086 // Before creating one, see if a forwardtyperef has already defined it.
1087 uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
1088 if (LocalIndex < LocalOperands.size()) {
1089 Ice::Operand *Op = LocalOperands[LocalIndex];
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001090 if (Op != nullptr) {
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001091 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) {
1092 if (Var->getType() == Ty) {
1093 ++NextLocalInstIndex;
1094 return Var;
1095 }
1096 }
1097 std::string Buffer;
1098 raw_string_ostream StrBuf(Buffer);
1099 StrBuf << "Illegal forward referenced instruction ("
1100 << NextLocalInstIndex << "): " << *Op;
1101 Error(StrBuf.str());
1102 // TODO(kschimpf) Remove error recovery once implementation complete.
1103 ++NextLocalInstIndex;
1104 return createInstVar(Ty);
1105 }
1106 }
1107 Ice::Variable *Var = createInstVar(Ty);
1108 setOperand(NextLocalInstIndex++, Var);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001109 return Var;
1110 }
1111
Karl Schimpf47661562014-09-11 14:42:49 -07001112 // Converts a relative index (wrt to BaseIndex) to an absolute value
1113 // index.
1114 uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) {
1115 if (BaseIndex < Id) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001116 std::string Buffer;
1117 raw_string_ostream StrBuf(Buffer);
1118 StrBuf << "Invalid relative value id: " << Id
Karl Schimpf47661562014-09-11 14:42:49 -07001119 << " (must be <= " << BaseIndex << ")";
Karl Schimpfd6064a12014-08-27 15:34:58 -07001120 Error(StrBuf.str());
1121 // TODO(kschimpf) Remove error recovery once implementation complete.
1122 return 0;
1123 }
Karl Schimpf47661562014-09-11 14:42:49 -07001124 return BaseIndex - Id;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001125 }
1126
1127 // Returns the value referenced by the given value Index.
1128 Ice::Operand *getOperand(uint32_t Index) {
1129 if (Index < CachedNumGlobalValueIDs) {
Karl Schimpf8df26f32014-09-19 09:33:26 -07001130 return Context->getOrCreateGlobalConstantByID(Index);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001131 }
1132 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
1133 if (LocalIndex >= LocalOperands.size()) {
1134 std::string Buffer;
1135 raw_string_ostream StrBuf(Buffer);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001136 StrBuf << "Value index " << Index << " not defined!";
Karl Schimpfd6064a12014-08-27 15:34:58 -07001137 Error(StrBuf.str());
1138 report_fatal_error("Unable to continue");
1139 }
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001140 Ice::Operand *Op = LocalOperands[LocalIndex];
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001141 if (Op == nullptr) {
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001142 std::string Buffer;
1143 raw_string_ostream StrBuf(Buffer);
1144 StrBuf << "Value index " << Index << " not defined!";
1145 Error(StrBuf.str());
1146 report_fatal_error("Unable to continue");
1147 }
1148 return Op;
1149 }
1150
1151 // Sets element Index (in the local operands list) to Op.
1152 void setOperand(uint32_t Index, Ice::Operand *Op) {
1153 assert(Op);
1154 // Check if simple push works.
1155 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs;
1156 if (LocalIndex == LocalOperands.size()) {
1157 LocalOperands.push_back(Op);
1158 return;
1159 }
1160
1161 // Must be forward reference, expand vector to accommodate.
1162 if (LocalIndex >= LocalOperands.size())
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001163 LocalOperands.resize(LocalIndex + 1);
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001164
1165 // If element not defined, set it.
1166 Ice::Operand *OldOp = LocalOperands[LocalIndex];
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001167 if (OldOp == nullptr) {
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001168 LocalOperands[LocalIndex] = Op;
1169 return;
1170 }
1171
1172 // See if forward reference matches.
1173 if (OldOp == Op)
1174 return;
1175
1176 // Error has occurred.
1177 std::string Buffer;
1178 raw_string_ostream StrBuf(Buffer);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001179 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
1180 << " and " << *OldOp;
Karl Schimpf8f07aa82014-09-17 09:07:20 -07001181 Error(StrBuf.str());
1182 // TODO(kschimpf) Remove error recovery once implementation complete.
1183 LocalOperands[LocalIndex] = Op;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001184 }
1185
Karl Schimpf47661562014-09-11 14:42:49 -07001186 // Returns the relative operand (wrt to BaseIndex) referenced by
1187 // the given value Index.
1188 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) {
1189 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1190 }
1191
1192 // Returns the absolute index of the next value generating instruction.
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001193 uint32_t getNextInstIndex() const { return NextLocalInstIndex; }
Karl Schimpf71ba8222014-09-03 09:46:24 -07001194
Karl Schimpfd6064a12014-08-27 15:34:58 -07001195 // Generates type error message for binary operator Op
1196 // operating on Type OpTy.
1197 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
1198
1199 // Validates if integer logical Op, for type OpTy, is valid.
1200 // Returns true if valid. Otherwise generates error message and
1201 // returns false.
1202 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1203 if (Ice::isIntegerType(OpTy))
1204 return true;
1205 ReportInvalidBinaryOp(Op, OpTy);
1206 return false;
1207 }
1208
1209 // Validates if integer (or vector of integers) arithmetic Op, for type
1210 // OpTy, is valid. Returns true if valid. Otherwise generates
1211 // error message and returns false.
1212 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1213 if (Ice::isIntegerArithmeticType(OpTy))
1214 return true;
1215 ReportInvalidBinaryOp(Op, OpTy);
1216 return false;
1217 }
1218
1219 // Checks if floating arithmetic Op, for type OpTy, is valid.
Karl Schimpf41689df2014-09-10 14:36:07 -07001220 // Returns true if valid. Otherwise generates an error message and
1221 // returns false;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001222 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1223 if (Ice::isFloatingType(OpTy))
1224 return true;
1225 ReportInvalidBinaryOp(Op, OpTy);
1226 return false;
1227 }
1228
Karl Schimpf41689df2014-09-10 14:36:07 -07001229 // Checks if the type of operand Op is the valid pointer type, for
1230 // the given InstructionName. Returns true if valid. Otherwise
1231 // generates an error message and returns false.
1232 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
1233 Ice::Type PtrType = Context->getIcePointerType();
1234 if (Op->getType() == PtrType)
1235 return true;
1236 std::string Buffer;
1237 raw_string_ostream StrBuf(Buffer);
1238 StrBuf << InstructionName << " address not " << PtrType
Karl Schimpf97501832014-09-16 13:35:32 -07001239 << ". Found: " << *Op;
Karl Schimpf41689df2014-09-10 14:36:07 -07001240 Error(StrBuf.str());
1241 return false;
1242 }
1243
1244 // Checks if loading/storing a value of type Ty is allowed.
1245 // Returns true if Valid. Otherwise generates an error message and
1246 // returns false.
1247 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1248 if (isLoadStoreType(Ty))
1249 return true;
1250 std::string Buffer;
1251 raw_string_ostream StrBuf(Buffer);
1252 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1253 Error(StrBuf.str());
1254 return false;
1255 }
1256
1257 // Checks if loading/storing a value of type Ty is allowed for
1258 // the given Alignment. Otherwise generates an error message and
1259 // returns false.
1260 bool isValidLoadStoreAlignment(unsigned Alignment, Ice::Type Ty,
1261 const char *InstructionName) {
1262 if (!isValidLoadStoreType(Ty, InstructionName))
1263 return false;
1264 if (PNaClABIProps::isAllowedAlignment(&Context->getDataLayout(), Alignment,
1265 Context->convertToLLVMType(Ty)))
1266 return true;
1267 std::string Buffer;
1268 raw_string_ostream StrBuf(Buffer);
1269 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1270 << Alignment;
1271 Error(StrBuf.str());
1272 return false;
1273 }
1274
Karl Schimpfd6064a12014-08-27 15:34:58 -07001275 // Reports that the given binary Opcode, for the given type Ty,
1276 // is not understood.
1277 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty);
1278
Karl Schimpf8df26f32014-09-19 09:33:26 -07001279 // Returns true if the Str begins with Prefix.
1280 bool isStringPrefix(Ice::IceString &Str, Ice::IceString &Prefix) {
1281 const size_t PrefixSize = Prefix.size();
1282 if (Str.size() < PrefixSize)
1283 return false;
1284 for (size_t i = 0; i < PrefixSize; ++i) {
1285 if (Str[i] != Prefix[i])
1286 return false;
1287 }
1288 return true;
1289 }
1290
Karl Schimpfd6064a12014-08-27 15:34:58 -07001291 // Takes the PNaCl bitcode binary operator Opcode, and the opcode
1292 // type Ty, and sets Op to the corresponding ICE binary
1293 // opcode. Returns true if able to convert, false otherwise.
1294 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1295 Ice::InstArithmetic::OpKind &Op) {
1296 Instruction::BinaryOps LLVMOpcode;
1297 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty),
1298 LLVMOpcode)) {
1299 ReportInvalidBinopOpcode(Opcode, Ty);
1300 // TODO(kschimpf) Remove error recovery once implementation complete.
1301 Op = Ice::InstArithmetic::Add;
1302 return false;
1303 }
1304 switch (LLVMOpcode) {
1305 default: {
1306 ReportInvalidBinopOpcode(Opcode, Ty);
1307 // TODO(kschimpf) Remove error recovery once implementation complete.
1308 Op = Ice::InstArithmetic::Add;
1309 return false;
1310 }
1311 case Instruction::Add:
1312 Op = Ice::InstArithmetic::Add;
1313 return isValidIntegerArithOp(Op, Ty);
1314 case Instruction::FAdd:
1315 Op = Ice::InstArithmetic::Fadd;
1316 return isValidFloatingArithOp(Op, Ty);
1317 case Instruction::Sub:
1318 Op = Ice::InstArithmetic::Sub;
1319 return isValidIntegerArithOp(Op, Ty);
1320 case Instruction::FSub:
1321 Op = Ice::InstArithmetic::Fsub;
1322 return isValidFloatingArithOp(Op, Ty);
1323 case Instruction::Mul:
1324 Op = Ice::InstArithmetic::Mul;
1325 return isValidIntegerArithOp(Op, Ty);
1326 case Instruction::FMul:
1327 Op = Ice::InstArithmetic::Fmul;
1328 return isValidFloatingArithOp(Op, Ty);
1329 case Instruction::UDiv:
1330 Op = Ice::InstArithmetic::Udiv;
1331 return isValidIntegerArithOp(Op, Ty);
1332 case Instruction::SDiv:
1333 Op = Ice::InstArithmetic::Sdiv;
1334 return isValidIntegerArithOp(Op, Ty);
1335 case Instruction::FDiv:
1336 Op = Ice::InstArithmetic::Fdiv;
1337 return isValidFloatingArithOp(Op, Ty);
1338 case Instruction::URem:
1339 Op = Ice::InstArithmetic::Urem;
1340 return isValidIntegerArithOp(Op, Ty);
1341 case Instruction::SRem:
1342 Op = Ice::InstArithmetic::Srem;
1343 return isValidIntegerArithOp(Op, Ty);
1344 case Instruction::FRem:
1345 Op = Ice::InstArithmetic::Frem;
1346 return isValidFloatingArithOp(Op, Ty);
1347 case Instruction::Shl:
1348 Op = Ice::InstArithmetic::Shl;
1349 return isValidIntegerArithOp(Op, Ty);
1350 case Instruction::LShr:
1351 Op = Ice::InstArithmetic::Lshr;
1352 return isValidIntegerArithOp(Op, Ty);
1353 case Instruction::AShr:
1354 Op = Ice::InstArithmetic::Ashr;
1355 return isValidIntegerArithOp(Op, Ty);
1356 case Instruction::And:
1357 Op = Ice::InstArithmetic::And;
1358 return isValidIntegerLogicalOp(Op, Ty);
1359 case Instruction::Or:
1360 Op = Ice::InstArithmetic::Or;
1361 return isValidIntegerLogicalOp(Op, Ty);
1362 case Instruction::Xor:
1363 Op = Ice::InstArithmetic::Xor;
1364 return isValidIntegerLogicalOp(Op, Ty);
1365 }
1366 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001367
1368 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice
1369 /// cast opcode and assigns to CastKind. Returns true if successful,
1370 /// false otherwise.
1371 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp,
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001372 Ice::InstCast::OpKind &CastKind) const {
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001373 switch (LLVMCastOp) {
1374 case Instruction::ZExt:
1375 CastKind = Ice::InstCast::Zext;
1376 break;
1377 case Instruction::SExt:
1378 CastKind = Ice::InstCast::Sext;
1379 break;
1380 case Instruction::Trunc:
1381 CastKind = Ice::InstCast::Trunc;
1382 break;
1383 case Instruction::FPTrunc:
1384 CastKind = Ice::InstCast::Fptrunc;
1385 break;
1386 case Instruction::FPExt:
1387 CastKind = Ice::InstCast::Fpext;
1388 break;
1389 case Instruction::FPToSI:
1390 CastKind = Ice::InstCast::Fptosi;
1391 break;
1392 case Instruction::FPToUI:
1393 CastKind = Ice::InstCast::Fptoui;
1394 break;
1395 case Instruction::SIToFP:
1396 CastKind = Ice::InstCast::Sitofp;
1397 break;
1398 case Instruction::UIToFP:
1399 CastKind = Ice::InstCast::Uitofp;
1400 break;
1401 case Instruction::BitCast:
1402 CastKind = Ice::InstCast::Bitcast;
1403 break;
1404 default:
1405 return false;
1406 }
1407 return true;
1408 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001409
1410 // Converts PNaCl bitcode Icmp operator to corresponding ICE op.
1411 // Returns true if able to convert, false otherwise.
1412 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1413 Ice::InstIcmp::ICond &Cond) const {
1414 switch (Op) {
1415 case naclbitc::ICMP_EQ:
1416 Cond = Ice::InstIcmp::Eq;
1417 return true;
1418 case naclbitc::ICMP_NE:
1419 Cond = Ice::InstIcmp::Ne;
1420 return true;
1421 case naclbitc::ICMP_UGT:
1422 Cond = Ice::InstIcmp::Ugt;
1423 return true;
1424 case naclbitc::ICMP_UGE:
1425 Cond = Ice::InstIcmp::Uge;
1426 return true;
1427 case naclbitc::ICMP_ULT:
1428 Cond = Ice::InstIcmp::Ult;
1429 return true;
1430 case naclbitc::ICMP_ULE:
1431 Cond = Ice::InstIcmp::Ule;
1432 return true;
1433 case naclbitc::ICMP_SGT:
1434 Cond = Ice::InstIcmp::Sgt;
1435 return true;
1436 case naclbitc::ICMP_SGE:
1437 Cond = Ice::InstIcmp::Sge;
1438 return true;
1439 case naclbitc::ICMP_SLT:
1440 Cond = Ice::InstIcmp::Slt;
1441 return true;
1442 case naclbitc::ICMP_SLE:
1443 Cond = Ice::InstIcmp::Sle;
1444 return true;
1445 default:
1446 return false;
1447 }
1448 }
1449
1450 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op.
1451 // Returns true if able to convert, false otherwise.
1452 bool convertNaClBitcFCompOpToIce(uint64_t Op,
1453 Ice::InstFcmp::FCond &Cond) const {
1454 switch (Op) {
1455 case naclbitc::FCMP_FALSE:
1456 Cond = Ice::InstFcmp::False;
1457 return true;
1458 case naclbitc::FCMP_OEQ:
1459 Cond = Ice::InstFcmp::Oeq;
1460 return true;
1461 case naclbitc::FCMP_OGT:
1462 Cond = Ice::InstFcmp::Ogt;
1463 return true;
1464 case naclbitc::FCMP_OGE:
1465 Cond = Ice::InstFcmp::Oge;
1466 return true;
1467 case naclbitc::FCMP_OLT:
1468 Cond = Ice::InstFcmp::Olt;
1469 return true;
1470 case naclbitc::FCMP_OLE:
1471 Cond = Ice::InstFcmp::Ole;
1472 return true;
1473 case naclbitc::FCMP_ONE:
1474 Cond = Ice::InstFcmp::One;
1475 return true;
1476 case naclbitc::FCMP_ORD:
1477 Cond = Ice::InstFcmp::Ord;
1478 return true;
1479 case naclbitc::FCMP_UNO:
1480 Cond = Ice::InstFcmp::Uno;
1481 return true;
1482 case naclbitc::FCMP_UEQ:
1483 Cond = Ice::InstFcmp::Ueq;
1484 return true;
1485 case naclbitc::FCMP_UGT:
1486 Cond = Ice::InstFcmp::Ugt;
1487 return true;
1488 case naclbitc::FCMP_UGE:
1489 Cond = Ice::InstFcmp::Uge;
1490 return true;
1491 case naclbitc::FCMP_ULT:
1492 Cond = Ice::InstFcmp::Ult;
1493 return true;
1494 case naclbitc::FCMP_ULE:
1495 Cond = Ice::InstFcmp::Ule;
1496 return true;
1497 case naclbitc::FCMP_UNE:
1498 Cond = Ice::InstFcmp::Une;
1499 return true;
1500 case naclbitc::FCMP_TRUE:
1501 Cond = Ice::InstFcmp::True;
1502 return true;
1503 default:
1504 return false;
1505 }
1506 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001507};
1508
Karl Schimpfd6064a12014-08-27 15:34:58 -07001509void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) {
1510 std::string Buffer;
1511 raw_string_ostream StrBuf(Buffer);
1512 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1513 Error(StrBuf.str());
1514}
1515
1516void FunctionParser::ExitBlock() {
1517 // Before translating, check for blocks without instructions, and
1518 // insert unreachable. This shouldn't happen, but be safe.
1519 unsigned Index = 0;
Jim Stichnothf44f3712014-10-01 14:05:51 -07001520 for (Ice::CfgNode *Node : Func->getNodes()) {
Karl Schimpfd6064a12014-08-27 15:34:58 -07001521 if (Node->getInsts().size() == 0) {
1522 std::string Buffer;
1523 raw_string_ostream StrBuf(Buffer);
1524 StrBuf << "Basic block " << Index << " contains no instructions";
1525 Error(StrBuf.str());
1526 // TODO(kschimpf) Remove error recovery once implementation complete.
1527 Node->appendInst(Ice::InstUnreachable::create(Func));
1528 }
Jim Stichnothf44f3712014-10-01 14:05:51 -07001529 ++Index;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001530 }
Karl Schimpfc132b762014-09-11 09:43:47 -07001531 Func->computePredecessors();
Karl Schimpfc836acb2014-09-05 08:32:47 -07001532 // Note: Once any errors have been found, we turn off all
1533 // translation of all remaining functions. This allows use to see
1534 // multiple errors, without adding extra checks to the translator
1535 // for such parsing errors.
1536 if (Context->getNumErrors() == 0)
1537 getTranslator().translateFcn(Func);
Jim Stichnoth8363a062014-10-07 10:02:38 -07001538 if (getFlags().TimeEachFunction)
1539 getTranslator().getContext()->popTimer(
1540 getTranslator().getContext()->getTimerID(Ice::GlobalContext::TSK_Funcs,
1541 Func->getFunctionName()),
1542 Ice::GlobalContext::TSK_Funcs);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001543}
1544
1545void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
1546 Ice::Type OpTy) {
1547 std::string Buffer;
1548 raw_string_ostream StrBuf(Buffer);
1549 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
1550 << ". Found " << OpTy;
1551 Error(StrBuf.str());
1552}
1553
1554void FunctionParser::ProcessRecord() {
1555 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1556 if (InstIsTerminating) {
1557 InstIsTerminating = false;
Karl Schimpf47661562014-09-11 14:42:49 -07001558 CurrentNode = getBasicBlock(++CurrentBbIndex);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001559 }
Karl Schimpf47661562014-09-11 14:42:49 -07001560 // The base index for relative indexing.
1561 int32_t BaseIndex = getNextInstIndex();
Karl Schimpfd6064a12014-08-27 15:34:58 -07001562 switch (Record.GetCode()) {
1563 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
1564 // DECLAREBLOCKS: [n]
1565 if (!isValidRecordSize(1, "function block count"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001566 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001567 if (Func->getNodes().size() != 1) {
1568 Error("Duplicate function block count record");
1569 return;
1570 }
1571 uint32_t NumBbs = Values[0];
1572 if (NumBbs == 0) {
1573 Error("Functions must contain at least one basic block.");
1574 // TODO(kschimpf) Remove error recovery once implementation complete.
1575 NumBbs = 1;
1576 }
1577 // Install the basic blocks, skipping bb0 which was created in the
1578 // constructor.
1579 for (size_t i = 1; i < NumBbs; ++i)
1580 InstallNextBasicBlock();
1581 break;
1582 }
1583 case naclbitc::FUNC_CODE_INST_BINOP: {
1584 // BINOP: [opval, opval, opcode]
1585 if (!isValidRecordSize(3, "function block binop"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001586 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001587 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
1588 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpfd6064a12014-08-27 15:34:58 -07001589 Ice::Type Type1 = Op1->getType();
1590 Ice::Type Type2 = Op2->getType();
1591 if (Type1 != Type2) {
1592 std::string Buffer;
1593 raw_string_ostream StrBuf(Buffer);
1594 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
1595 Error(StrBuf.str());
1596 // TODO(kschimpf) Remove error recovery once implementation complete.
1597 Op2 = Op1;
1598 }
1599
1600 Ice::InstArithmetic::OpKind Opcode;
1601 if (!convertBinopOpcode(Values[2], Type1, Opcode))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001602 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001603 CurrentNode->appendInst(Ice::InstArithmetic::create(
1604 Func, Opcode, getNextInstVar(Type1), Op1, Op2));
Karl Schimpfd6064a12014-08-27 15:34:58 -07001605 break;
1606 }
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001607 case naclbitc::FUNC_CODE_INST_CAST: {
1608 // CAST: [opval, destty, castopc]
1609 if (!isValidRecordSize(3, "function block cast"))
1610 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001611 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001612 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001613 Instruction::CastOps LLVMCastOp;
1614 Ice::InstCast::OpKind CastKind;
1615 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) ||
1616 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) {
1617 std::string Buffer;
1618 raw_string_ostream StrBuf(Buffer);
1619 StrBuf << "Cast opcode not understood: " << Values[2];
1620 Error(StrBuf.str());
1621 return;
1622 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001623 Ice::Type SrcType = Src->getType();
1624 if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType),
1625 Context->convertToLLVMType(CastType))) {
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001626 std::string Buffer;
1627 raw_string_ostream StrBuf(Buffer);
1628 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001629 << " " << SrcType << " to " << CastType;
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001630 Error(StrBuf.str());
1631 return;
1632 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001633 CurrentNode->appendInst(
1634 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src));
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001635 break;
1636 }
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001637 case naclbitc::FUNC_CODE_INST_VSELECT: {
1638 // VSELECT: [opval, opval, pred]
Karl Schimpf47661562014-09-11 14:42:49 -07001639 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001640 Ice::Type ThenType = ThenVal->getType();
Karl Schimpf47661562014-09-11 14:42:49 -07001641 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001642 Ice::Type ElseType = ElseVal->getType();
1643 if (ThenType != ElseType) {
1644 std::string Buffer;
1645 raw_string_ostream StrBuf(Buffer);
1646 StrBuf << "Select operands not same type. Found " << ThenType << " and "
1647 << ElseType;
1648 Error(StrBuf.str());
1649 return;
1650 }
Karl Schimpf47661562014-09-11 14:42:49 -07001651 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001652 Ice::Type CondType = CondVal->getType();
1653 if (isVectorType(CondType)) {
1654 if (!isVectorType(ThenType) ||
1655 typeElementType(CondType) != Ice::IceType_i1 ||
1656 typeNumElements(ThenType) != typeNumElements(CondType)) {
1657 std::string Buffer;
1658 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001659 StrBuf << "Select condition type " << CondType
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001660 << " not allowed for values of type " << ThenType;
1661 Error(StrBuf.str());
1662 return;
1663 }
1664 } else if (CondVal->getType() != Ice::IceType_i1) {
1665 std::string Buffer;
1666 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001667 StrBuf << "Select condition " << CondVal << " not type i1. Found: "
1668 << CondVal->getType();
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001669 Error(StrBuf.str());
1670 return;
1671 }
Karl Schimpf47661562014-09-11 14:42:49 -07001672 CurrentNode->appendInst(Ice::InstSelect::create(
1673 Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
Karl Schimpf1d6f0e42014-09-04 12:22:14 -07001674 break;
1675 }
Karl Schimpf71ba8222014-09-03 09:46:24 -07001676 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
1677 // EXTRACTELT: [opval, opval]
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001678 if (!isValidRecordSize(2, "function block extract element"))
1679 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001680 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf71ba8222014-09-03 09:46:24 -07001681 Ice::Type VecType = Vec->getType();
1682 if (!Ice::isVectorType(VecType)) {
1683 std::string Buffer;
1684 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001685 StrBuf << "Extractelement not on vector. Found: " << *Vec;
Karl Schimpf71ba8222014-09-03 09:46:24 -07001686 Error(StrBuf.str());
1687 }
Karl Schimpf47661562014-09-11 14:42:49 -07001688 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf71ba8222014-09-03 09:46:24 -07001689 if (Index->getType() != Ice::IceType_i32) {
1690 std::string Buffer;
1691 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001692 StrBuf << "Extractelement index " << *Index << " not i32. Found: "
1693 << Index->getType();
Karl Schimpf71ba8222014-09-03 09:46:24 -07001694 Error(StrBuf.str());
1695 }
1696 // TODO(kschimpf): Restrict index to a legal constant index (once
1697 // constants can be defined).
Karl Schimpf47661562014-09-11 14:42:49 -07001698 CurrentNode->appendInst(Ice::InstExtractElement::create(
1699 Func, getNextInstVar(typeElementType(VecType)), Vec, Index));
Karl Schimpf71ba8222014-09-03 09:46:24 -07001700 break;
1701 }
1702 case naclbitc::FUNC_CODE_INST_INSERTELT: {
1703 // INSERTELT: [opval, opval, opval]
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001704 if (!isValidRecordSize(3, "function block insert element"))
1705 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001706 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf71ba8222014-09-03 09:46:24 -07001707 Ice::Type VecType = Vec->getType();
1708 if (!Ice::isVectorType(VecType)) {
1709 std::string Buffer;
1710 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001711 StrBuf << "Insertelement not on vector. Found: " << *Vec;
Karl Schimpf71ba8222014-09-03 09:46:24 -07001712 Error(StrBuf.str());
1713 }
Karl Schimpf47661562014-09-11 14:42:49 -07001714 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf71ba8222014-09-03 09:46:24 -07001715 Ice::Type EltType = Elt->getType();
1716 if (EltType != typeElementType(VecType)) {
1717 std::string Buffer;
1718 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001719 StrBuf << "Insertelement element " << *Elt << " not type "
1720 << typeElementType(VecType)
1721 << ". Found: " << EltType;
Karl Schimpf71ba8222014-09-03 09:46:24 -07001722 Error(StrBuf.str());
1723 }
Karl Schimpf47661562014-09-11 14:42:49 -07001724 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpf71ba8222014-09-03 09:46:24 -07001725 if (Index->getType() != Ice::IceType_i32) {
1726 std::string Buffer;
1727 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001728 StrBuf << "Insertelement index " << *Index << " not i32. Found: "
1729 << Index->getType();
Karl Schimpf71ba8222014-09-03 09:46:24 -07001730 Error(StrBuf.str());
1731 }
1732 // TODO(kschimpf): Restrict index to a legal constant index (once
1733 // constants can be defined).
Karl Schimpf47661562014-09-11 14:42:49 -07001734 CurrentNode->appendInst(Ice::InstInsertElement::create(
Karl Schimpff0657dd2014-09-25 14:04:12 -07001735 Func, getNextInstVar(VecType), Vec, Elt, Index));
Karl Schimpf71ba8222014-09-03 09:46:24 -07001736 break;
1737 }
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001738 case naclbitc::FUNC_CODE_INST_CMP2: {
1739 // CMP2: [opval, opval, pred]
1740 if (!isValidRecordSize(3, "function block compare"))
1741 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001742 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
1743 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001744 Ice::Type Op1Type = Op1->getType();
1745 Ice::Type Op2Type = Op2->getType();
1746 if (Op1Type != Op2Type) {
1747 std::string Buffer;
1748 raw_string_ostream StrBuf(Buffer);
1749 StrBuf << "Compare argument types differ: " << Op1Type
1750 << " and " << Op2Type;
1751 Error(StrBuf.str());
1752 // TODO(kschimpf) Remove error recovery once implementation complete.
1753 Op2 = Op1;
1754 }
1755 Ice::Type DestType = getCompareResultType(Op1Type);
1756 if (DestType == Ice::IceType_void) {
1757 std::string Buffer;
1758 raw_string_ostream StrBuf(Buffer);
1759 StrBuf << "Compare not defined for type " << Op1Type;
1760 Error(StrBuf.str());
1761 return;
1762 }
Karl Schimpf47661562014-09-11 14:42:49 -07001763 Ice::Variable *Dest = getNextInstVar(DestType);
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001764 if (isIntegerType(Op1Type)) {
1765 Ice::InstIcmp::ICond Cond;
1766 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
1767 std::string Buffer;
1768 raw_string_ostream StrBuf(Buffer);
1769 StrBuf << "Compare record contains unknown integer predicate index: "
1770 << Values[2];
1771 Error(StrBuf.str());
1772 // TODO(kschimpf) Remove error recovery once implementation complete.
1773 Cond = Ice::InstIcmp::Eq;
1774 }
Karl Schimpf47661562014-09-11 14:42:49 -07001775 CurrentNode->appendInst(
1776 Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2));
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001777 } else if (isFloatingType(Op1Type)){
1778 Ice::InstFcmp::FCond Cond;
1779 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
1780 std::string Buffer;
1781 raw_string_ostream StrBuf(Buffer);
1782 StrBuf << "Compare record contains unknown float predicate index: "
1783 << Values[2];
1784 Error(StrBuf.str());
1785 // TODO(kschimpf) Remove error recovery once implementation complete.
1786 Cond = Ice::InstFcmp::False;
1787 }
Karl Schimpf47661562014-09-11 14:42:49 -07001788 CurrentNode->appendInst(
1789 Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2));
Karl Schimpf83f9f0c2014-09-05 08:30:55 -07001790 } else {
1791 // Not sure this can happen, but be safe.
1792 std::string Buffer;
1793 raw_string_ostream StrBuf(Buffer);
1794 StrBuf << "Compare on type not understood: " << Op1Type;
1795 Error(StrBuf.str());
1796 return;
1797 }
1798 break;
1799 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07001800 case naclbitc::FUNC_CODE_INST_RET: {
1801 // RET: [opval?]
Karl Schimpfd6064a12014-08-27 15:34:58 -07001802 if (!isValidRecordSizeInRange(0, 1, "function block ret"))
Karl Schimpfc0fdc272014-09-02 10:47:28 -07001803 return;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001804 if (Values.size() == 0) {
Karl Schimpf47661562014-09-11 14:42:49 -07001805 CurrentNode->appendInst(Ice::InstRet::create(Func));
Karl Schimpfd6064a12014-08-27 15:34:58 -07001806 } else {
Karl Schimpf47661562014-09-11 14:42:49 -07001807 CurrentNode->appendInst(
1808 Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex)));
Karl Schimpfd6064a12014-08-27 15:34:58 -07001809 }
Karl Schimpfc836acb2014-09-05 08:32:47 -07001810 InstIsTerminating = true;
1811 break;
1812 }
1813 case naclbitc::FUNC_CODE_INST_BR: {
1814 if (Values.size() == 1) {
1815 // BR: [bb#]
1816 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001817 if (Block == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07001818 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001819 CurrentNode->appendInst(Ice::InstBr::create(Func, Block));
Karl Schimpfc836acb2014-09-05 08:32:47 -07001820 } else {
1821 // BR: [bb#, bb#, opval]
1822 if (!isValidRecordSize(3, "function block branch"))
1823 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001824 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
Karl Schimpfc836acb2014-09-05 08:32:47 -07001825 if (Cond->getType() != Ice::IceType_i1) {
1826 std::string Buffer;
1827 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001828 StrBuf << "Branch condition " << *Cond << " not i1. Found: "
1829 << Cond->getType();
Karl Schimpfc836acb2014-09-05 08:32:47 -07001830 Error(StrBuf.str());
1831 return;
1832 }
1833 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
1834 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
Karl Schimpfe3f64d02014-10-07 10:38:22 -07001835 if (ThenBlock == nullptr || ElseBlock == nullptr)
Karl Schimpfc836acb2014-09-05 08:32:47 -07001836 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001837 CurrentNode->appendInst(
1838 Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock));
Karl Schimpfc836acb2014-09-05 08:32:47 -07001839 }
1840 InstIsTerminating = true;
Karl Schimpfd6064a12014-08-27 15:34:58 -07001841 break;
1842 }
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001843 case naclbitc::FUNC_CODE_INST_SWITCH: {
1844 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
1845 // where Case = [1, 1, Value, BbIndex].
1846 //
1847 // Note: Unlike most instructions, we don't infer the type of
1848 // Cond, but provide it as a separate field. There are also
1849 // unnecesary data fields (i.e. constants 1). These were not
1850 // cleaned up in PNaCl bitcode because the bitcode format was
1851 // already frozen when the problem was noticed.
1852 if (!isValidRecordSizeAtLeast(4, "function block switch"))
1853 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001854 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
Karl Schimpfd1a971a2014-09-17 15:38:17 -07001855 if (!Ice::isScalarIntegerType(CondTy)) {
1856 std::string Buffer;
1857 raw_string_ostream StrBuf(Buffer);
1858 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy;
1859 Error(StrBuf.str());
1860 return;
1861 }
1862 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy);
1863 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex);
1864 if (CondTy != Cond->getType()) {
1865 std::string Buffer;
1866 raw_string_ostream StrBuf(Buffer);
1867 StrBuf << "Case condition expects type " << CondTy
1868 << ". Found: " << Cond->getType();
1869 Error(StrBuf.str());
1870 return;
1871 }
1872 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]);
1873 unsigned NumCases = Values[3];
1874
1875 // Now recognize each of the cases.
1876 if (!isValidRecordSize(4 + NumCases * 4, "Function block switch"))
1877 return;
1878 Ice::InstSwitch *Switch =
1879 Ice::InstSwitch::create(Func, NumCases, Cond, DefaultLabel);
1880 unsigned ValCaseIndex = 4; // index to beginning of case entry.
1881 for (unsigned CaseIndex = 0; CaseIndex < NumCases;
1882 ++CaseIndex, ValCaseIndex += 4) {
1883 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex+1] != 1) {
1884 std::string Buffer;
1885 raw_string_ostream StrBuf(Buffer);
1886 StrBuf << "Sequence [1, 1, value, label] expected for case entry "
1887 << "in switch record. (at index" << ValCaseIndex << ")";
1888 Error(StrBuf.str());
1889 return;
1890 }
1891 APInt Value(BitWidth,
1892 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]),
1893 true);
1894 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]);
1895 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label);
1896 }
1897 CurrentNode->appendInst(Switch);
1898 InstIsTerminating = true;
1899 break;
1900 }
Karl Schimpf97501832014-09-16 13:35:32 -07001901 case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
1902 // UNREACHABLE: []
1903 if (!isValidRecordSize(0, "function block unreachable"))
1904 return;
1905 CurrentNode->appendInst(
1906 Ice::InstUnreachable::create(Func));
1907 InstIsTerminating = true;
1908 break;
1909 }
Karl Schimpf47661562014-09-11 14:42:49 -07001910 case naclbitc::FUNC_CODE_INST_PHI: {
1911 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
1912 if (!isValidRecordSizeAtLeast(3, "function block phi"))
1913 return;
1914 if ((Values.size() & 0x1) == 0) {
1915 // Not an odd number of values.
1916 std::string Buffer;
1917 raw_string_ostream StrBuf(Buffer);
1918 StrBuf << "function block phi record size not valid: " << Values.size();
1919 Error(StrBuf.str());
1920 return;
1921 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001922 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
Karl Schimpf47661562014-09-11 14:42:49 -07001923 if (Ty == Ice::IceType_void) {
1924 Error("Phi record using type void not allowed");
1925 return;
1926 }
1927 Ice::Variable *Dest = getNextInstVar(Ty);
1928 Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest);
1929 for (unsigned i = 1; i < Values.size(); i += 2) {
1930 Ice::Operand *Op =
1931 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
1932 if (Op->getType() != Ty) {
1933 std::string Buffer;
1934 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001935 StrBuf << "Value " << *Op << " not type " << Ty
1936 << " in phi instruction. Found: " << Op->getType();
Karl Schimpf47661562014-09-11 14:42:49 -07001937 Error(StrBuf.str());
1938 return;
1939 }
1940 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
1941 }
1942 CurrentNode->appendInst(Phi);
1943 break;
1944 }
Karl Schimpf742d72d2014-09-09 11:40:09 -07001945 case naclbitc::FUNC_CODE_INST_ALLOCA: {
1946 // ALLOCA: [Size, align]
1947 if (!isValidRecordSize(2, "function block alloca"))
1948 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001949 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf742d72d2014-09-09 11:40:09 -07001950 if (ByteCount->getType() != Ice::IceType_i32) {
1951 std::string Buffer;
1952 raw_string_ostream StrBuf(Buffer);
Karl Schimpf97501832014-09-16 13:35:32 -07001953 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
Karl Schimpf742d72d2014-09-09 11:40:09 -07001954 Error(StrBuf.str());
1955 return;
1956 }
Karl Schimpf41689df2014-09-10 14:36:07 -07001957 unsigned Alignment;
1958 extractAlignment("Alloca", Values[1], Alignment);
Karl Schimpf47661562014-09-11 14:42:49 -07001959 CurrentNode->appendInst(
1960 Ice::InstAlloca::create(Func, ByteCount, Alignment,
1961 getNextInstVar(Context->getIcePointerType())));
Karl Schimpf742d72d2014-09-09 11:40:09 -07001962 break;
1963 }
Karl Schimpf41689df2014-09-10 14:36:07 -07001964 case naclbitc::FUNC_CODE_INST_LOAD: {
1965 // LOAD: [address, align, ty]
1966 if (!isValidRecordSize(3, "function block load"))
1967 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001968 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf41689df2014-09-10 14:36:07 -07001969 if (!isValidPointerType(Address, "Load"))
1970 return;
1971 unsigned Alignment;
1972 extractAlignment("Load", Values[1], Alignment);
Karl Schimpf645aa1a2014-10-08 09:05:53 -07001973 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
Karl Schimpf41689df2014-09-10 14:36:07 -07001974 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
1975 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001976 CurrentNode->appendInst(
1977 Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment));
Karl Schimpf41689df2014-09-10 14:36:07 -07001978 break;
1979 }
1980 case naclbitc::FUNC_CODE_INST_STORE: {
1981 // STORE: [address, value, align]
1982 if (!isValidRecordSize(3, "function block store"))
1983 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001984 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
Karl Schimpf41689df2014-09-10 14:36:07 -07001985 if (!isValidPointerType(Address, "Store"))
1986 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001987 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
Karl Schimpf41689df2014-09-10 14:36:07 -07001988 unsigned Alignment;
Karl Schimpf64dcde72014-09-10 15:02:08 -07001989 extractAlignment("Store", Values[2], Alignment);
Karl Schimpf41689df2014-09-10 14:36:07 -07001990 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
1991 return;
Karl Schimpf47661562014-09-11 14:42:49 -07001992 CurrentNode->appendInst(
1993 Ice::InstStore::create(Func, Value, Address, Alignment));
Karl Schimpf41689df2014-09-10 14:36:07 -07001994 break;
1995 }
Karl Schimpf8df26f32014-09-19 09:33:26 -07001996 case naclbitc::FUNC_CODE_INST_CALL:
1997 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
1998 // CALL: [cc, fnid, arg0, arg1...]
1999 // CALL_INDIRECT: [cc, fn, returnty, args...]
2000 //
2001 // Note: The difference between CALL and CALL_INDIRECT is that
2002 // CALL has an explicit function address, while the CALL_INDIRECT
2003 // is just an address. For CALL, we can infer the return type by
2004 // looking up the type signature associated with the function
2005 // address. For CALL_INDIRECT we can only infer the type signature
2006 // via argument types, and the corresponding return type stored in
2007 // CALL_INDIRECT record.
2008 Ice::SizeT ParamsStartIndex = 2;
2009 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
2010 if (!isValidRecordSizeAtLeast(2, "function block call"))
2011 return;
2012 } else {
2013 if (!isValidRecordSizeAtLeast(3, "function block call indirect"))
2014 return;
2015 ParamsStartIndex = 3;
2016 }
2017
2018 // Extract call information.
2019 uint64_t CCInfo = Values[0];
2020 CallingConv::ID CallingConv;
2021 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
2022 std::string Buffer;
2023 raw_string_ostream StrBuf(Buffer);
2024 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
2025 << " not understood.";
2026 Error(StrBuf.str());
2027 return;
2028 }
2029 bool IsTailCall = static_cast<bool>(CCInfo & 1);
2030
2031 // Extract out the called function and its return type.
2032 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
2033 Ice::Operand *Callee = getOperand(CalleeIndex);
2034 Ice::Type ReturnType = Ice::IceType_void;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002035 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002036 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002037 Function *Fcn = Context->getFunctionByID(CalleeIndex);
2038 if (Fcn == nullptr) {
Karl Schimpf8df26f32014-09-19 09:33:26 -07002039 std::string Buffer;
2040 raw_string_ostream StrBuf(Buffer);
2041 StrBuf << "Function call to non-function: " << *Callee;
2042 Error(StrBuf.str());
2043 return;
2044 }
2045
2046 FunctionType *FcnTy = Fcn->getFunctionType();
2047 ReturnType = Context->convertToIceType(FcnTy->getReturnType());
2048
2049 // Check if this direct call is to an Intrinsic (starts with "llvm.")
2050 static Ice::IceString LLVMPrefix("llvm.");
2051 Ice::IceString Name = Fcn->getName();
2052 if (isStringPrefix(Name, LLVMPrefix)) {
2053 Ice::IceString Suffix = Name.substr(LLVMPrefix.size());
2054 IntrinsicInfo =
2055 getTranslator().getContext()->getIntrinsicsInfo().find(Suffix);
2056 if (!IntrinsicInfo) {
2057 std::string Buffer;
2058 raw_string_ostream StrBuf(Buffer);
2059 StrBuf << "Invalid PNaCl intrinsic call to " << Name;
2060 Error(StrBuf.str());
2061 return;
2062 }
2063 }
2064 } else {
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002065 ReturnType = Context->getSimpleTypeByID(Values[2]);
Karl Schimpf8df26f32014-09-19 09:33:26 -07002066 }
2067
2068 // Create the call instruction.
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002069 Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
2070 ? nullptr
2071 : getNextInstVar(ReturnType);
Karl Schimpf8df26f32014-09-19 09:33:26 -07002072 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002073 Ice::InstCall *Inst = nullptr;
Karl Schimpf8df26f32014-09-19 09:33:26 -07002074 if (IntrinsicInfo) {
2075 Inst =
2076 Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee,
2077 IntrinsicInfo->Info);
2078 } else {
2079 Inst = Ice::InstCall::create(Func, NumParams, Dest, Callee, IsTailCall);
2080 }
2081
2082 // Add parameters.
2083 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) {
2084 Inst->addArg(
2085 getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex));
2086 }
2087
2088 // If intrinsic call, validate call signature.
2089 if (IntrinsicInfo) {
2090 Ice::SizeT ArgIndex = 0;
2091 switch (IntrinsicInfo->validateCall(Inst, ArgIndex)) {
2092 default:
2093 Error("Unknown validation error for intrinsic call");
2094 // TODO(kschimpf) Remove error recovery once implementation complete.
2095 break;
2096 case Ice::Intrinsics::IsValidCall:
2097 break;
2098 case Ice::Intrinsics::BadReturnType: {
2099 std::string Buffer;
2100 raw_string_ostream StrBuf(Buffer);
2101 StrBuf << "Intrinsic call expects return type "
2102 << IntrinsicInfo->getReturnType()
2103 << ". Found: " << Inst->getReturnType();
2104 Error(StrBuf.str());
2105 // TODO(kschimpf) Remove error recovery once implementation complete.
2106 break;
2107 }
2108 case Ice::Intrinsics::WrongNumOfArgs: {
2109 std::string Buffer;
2110 raw_string_ostream StrBuf(Buffer);
2111 StrBuf << "Intrinsic call expects " << IntrinsicInfo->getNumArgs()
2112 << ". Found: " << Inst->getNumArgs();
2113 Error(StrBuf.str());
2114 // TODO(kschimpf) Remove error recovery once implementation complete.
2115 break;
2116 }
2117 case Ice::Intrinsics::WrongCallArgType: {
2118 std::string Buffer;
2119 raw_string_ostream StrBuf(Buffer);
2120 StrBuf << "Intrinsic call argument " << ArgIndex << " expects type "
2121 << IntrinsicInfo->getArgType(ArgIndex)
2122 << ". Found: " << Inst->getArg(ArgIndex)->getType();
2123 Error(StrBuf.str());
2124 // TODO(kschimpf) Remove error recovery once implementation complete.
2125 break;
2126 }
2127 }
2128 }
2129
2130 CurrentNode->appendInst(Inst);
2131 return;
2132 }
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002133 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
2134 // FORWARDTYPEREF: [opval, ty]
2135 if (!isValidRecordSize(2, "function block forward type ref"))
2136 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002137 setOperand(Values[0], createInstVar(Context->getSimpleTypeByID(Values[1])));
Karl Schimpf8f07aa82014-09-17 09:07:20 -07002138 break;
2139 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002140 default:
2141 // Generate error message!
2142 BlockParserBaseClass::ProcessRecord();
2143 break;
2144 }
Karl Schimpfd6064a12014-08-27 15:34:58 -07002145}
2146
Karl Schimpff12355e2014-09-08 13:41:09 -07002147/// Parses constants within a function block.
2148class ConstantsParser : public BlockParserBaseClass {
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002149 ConstantsParser(const ConstantsParser &) = delete;
2150 ConstantsParser &operator=(const ConstantsParser &) = delete;
Karl Schimpff12355e2014-09-08 13:41:09 -07002151
2152public:
2153 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
2154 : BlockParserBaseClass(BlockID, FuncParser), FuncParser(FuncParser),
2155 NextConstantType(Ice::IceType_void) {}
2156
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002157 ~ConstantsParser() override {}
Karl Schimpff12355e2014-09-08 13:41:09 -07002158
2159private:
2160 // The parser of the function block this constants block appears in.
2161 FunctionParser *FuncParser;
2162 // The type to use for succeeding constants.
2163 Ice::Type NextConstantType;
2164
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002165 void ProcessRecord() override;
Karl Schimpff12355e2014-09-08 13:41:09 -07002166
2167 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
2168
2169 // Returns true if the type to use for succeeding constants is defined.
2170 // If false, also generates an error message.
2171 bool isValidNextConstantType() {
2172 if (NextConstantType != Ice::IceType_void)
2173 return true;
2174 Error("Constant record not preceded by set type record");
2175 return false;
2176 }
2177};
2178
2179void ConstantsParser::ProcessRecord() {
2180 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2181 switch (Record.GetCode()) {
2182 case naclbitc::CST_CODE_SETTYPE: {
2183 // SETTYPE: [typeid]
2184 if (!isValidRecordSize(1, "constants block set type"))
2185 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002186 NextConstantType = Context->getSimpleTypeByID(Values[0]);
Karl Schimpff12355e2014-09-08 13:41:09 -07002187 if (NextConstantType == Ice::IceType_void)
2188 Error("constants block set type not allowed for void type");
2189 return;
2190 }
2191 case naclbitc::CST_CODE_UNDEF: {
2192 // UNDEF
2193 if (!isValidRecordSize(0, "constants block undef"))
2194 return;
2195 if (!isValidNextConstantType())
2196 return;
2197 FuncParser->setNextConstantID(
2198 getContext()->getConstantUndef(NextConstantType));
2199 return;
2200 }
2201 case naclbitc::CST_CODE_INTEGER: {
2202 // INTEGER: [intval]
2203 if (!isValidRecordSize(1, "constants block integer"))
2204 return;
2205 if (!isValidNextConstantType())
2206 return;
2207 if (IntegerType *IType = dyn_cast<IntegerType>(
2208 Context->convertToLLVMType(NextConstantType))) {
2209 APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0]));
Jan Voungbc004632014-09-16 15:09:10 -07002210 Ice::Constant *C = (NextConstantType == Ice::IceType_i64)
2211 ? getContext()->getConstantInt64(
2212 NextConstantType, Value.getSExtValue())
2213 : getContext()->getConstantInt32(
2214 NextConstantType, Value.getSExtValue());
Karl Schimpff12355e2014-09-08 13:41:09 -07002215 FuncParser->setNextConstantID(C);
2216 return;
2217 }
2218 std::string Buffer;
2219 raw_string_ostream StrBuf(Buffer);
2220 StrBuf << "constant block integer record for non-integer type "
2221 << NextConstantType;
2222 Error(StrBuf.str());
2223 return;
2224 }
2225 case naclbitc::CST_CODE_FLOAT: {
2226 // FLOAT: [fpval]
2227 if (!isValidRecordSize(1, "constants block float"))
2228 return;
2229 if (!isValidNextConstantType())
2230 return;
2231 switch (NextConstantType) {
2232 case Ice::IceType_f32: {
2233 APFloat Value(APFloat::IEEEsingle,
2234 APInt(32, static_cast<uint32_t>(Values[0])));
2235 FuncParser->setNextConstantID(
2236 getContext()->getConstantFloat(Value.convertToFloat()));
2237 return;
2238 }
2239 case Ice::IceType_f64: {
2240 APFloat Value(APFloat::IEEEdouble, APInt(64, Values[0]));
2241 FuncParser->setNextConstantID(
2242 getContext()->getConstantDouble(Value.convertToDouble()));
2243 return;
2244 }
2245 default: {
2246 std::string Buffer;
2247 raw_string_ostream StrBuf(Buffer);
2248 StrBuf << "constant block float record for non-floating type "
2249 << NextConstantType;
2250 Error(StrBuf.str());
2251 return;
2252 }
2253 }
2254 }
2255 default:
2256 // Generate error message!
2257 BlockParserBaseClass::ProcessRecord();
2258 return;
2259 }
2260}
2261
Karl Schimpfc132b762014-09-11 09:43:47 -07002262// Parses valuesymtab blocks appearing in a function block.
2263class FunctionValuesymtabParser : public ValuesymtabParser {
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002264 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
2265 void operator=(const FunctionValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07002266
2267public:
2268 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser)
2269 : ValuesymtabParser(BlockID, EnclosingParser) {}
2270
2271private:
2272 // Returns the enclosing function parser.
2273 FunctionParser *getFunctionParser() const {
2274 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2275 }
2276
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002277 void setValueName(uint64_t Index, StringType &Name) override;
2278 void setBbName(uint64_t Index, StringType &Name) override;
Karl Schimpfc132b762014-09-11 09:43:47 -07002279
2280 // Reports that the assignment of Name to the value associated with
2281 // index is not possible, for the given Context.
2282 void reportUnableToAssign(const char *Context, uint64_t Index,
2283 StringType &Name) {
2284 std::string Buffer;
2285 raw_string_ostream StrBuf(Buffer);
2286 StrBuf << "Function-local " << Context << " name '" << Name
2287 << "' can't be associated with index " << Index;
2288 Error(StrBuf.str());
2289 }
2290};
2291
2292void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) {
2293 // Note: We check when Index is too small, so that we can error recover
2294 // (FP->getOperand will create fatal error).
2295 if (Index < getFunctionParser()->CachedNumGlobalValueIDs) {
2296 reportUnableToAssign("instruction", Index, Name);
2297 // TODO(kschimpf) Remove error recovery once implementation complete.
2298 return;
2299 }
2300 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
2301 if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) {
2302 std::string Nm(Name.data(), Name.size());
2303 V->setName(Nm);
2304 } else {
2305 reportUnableToAssign("variable", Index, Name);
2306 }
2307}
2308
2309void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) {
2310 if (Index >= getFunctionParser()->Func->getNumNodes()) {
2311 reportUnableToAssign("block", Index, Name);
2312 return;
2313 }
2314 std::string Nm(Name.data(), Name.size());
2315 getFunctionParser()->Func->getNodes()[Index]->setName(Nm);
2316}
2317
Karl Schimpff12355e2014-09-08 13:41:09 -07002318bool FunctionParser::ParseBlock(unsigned BlockID) {
2319 switch (BlockID) {
2320 case naclbitc::CONSTANTS_BLOCK_ID: {
2321 ConstantsParser Parser(BlockID, this);
2322 return Parser.ParseThisBlock();
2323 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002324 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2325 if (PNaClAllowLocalSymbolTables) {
2326 FunctionValuesymtabParser Parser(BlockID, this);
2327 return Parser.ParseThisBlock();
2328 }
2329 break;
Karl Schimpff12355e2014-09-08 13:41:09 -07002330 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002331 default:
2332 break;
2333 }
2334 return BlockParserBaseClass::ParseBlock(BlockID);
Karl Schimpff12355e2014-09-08 13:41:09 -07002335}
2336
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002337/// Parses the module block in the bitcode file.
2338class ModuleParser : public BlockParserBaseClass {
2339public:
2340 ModuleParser(unsigned BlockID, TopLevelParser *Context)
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002341 : BlockParserBaseClass(BlockID, Context),
2342 GlobalAddressNamesAndInitializersInstalled(false) {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002343
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002344 ~ModuleParser() override {}
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002345
Karl Schimpf5ee234a2014-09-12 10:41:40 -07002346private:
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002347 // True if we have already instaledl names for unnamed global addresses,
2348 // and generated global constant initializers.
2349 bool GlobalAddressNamesAndInitializersInstalled;
2350
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002351 // Generates names for unnamed global addresses, and lowers global
2352 // constant initializers to the target. May be called multiple
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002353 // times. Only the first call will do the installation.
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002354 void InstallGlobalAddressNamesAndInitializers() {
2355 if (!GlobalAddressNamesAndInitializersInstalled) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002356 Ice::Translator &Trans = getTranslator();
2357 const Ice::IceString &GlobalPrefix = getFlags().DefaultGlobalPrefix;
2358 if (!GlobalPrefix.empty()) {
2359 uint32_t NameIndex = 0;
2360 for (Ice::GlobalAddress *Address : Context->getGlobalIDAddresses()) {
2361 if (!Address->hasName()) {
2362 Address->setName(Trans.createUnnamedName(GlobalPrefix, NameIndex));
2363 ++NameIndex;
2364 } else {
2365 Trans.checkIfUnnamedNameSafe(Address->getName(), "global",
2366 GlobalPrefix,
2367 Trans.getContext()->getStrDump());
2368 }
2369 }
2370 }
2371 Trans.nameUnnamedFunctions(Context->getModule());
Jim Stichnoth2a063e22014-10-08 11:24:51 -07002372 getTranslator().lowerGlobals(Context->getGlobalIDAddresses());
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002373 GlobalAddressNamesAndInitializersInstalled = true;
2374 }
2375 }
2376
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002377 bool ParseBlock(unsigned BlockID) override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002378
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002379 void ExitBlock() override {
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002380 InstallGlobalAddressNamesAndInitializers();
2381 getTranslator().emitConstants();
2382 }
2383
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002384 void ProcessRecord() override;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002385};
2386
Karl Schimpfc132b762014-09-11 09:43:47 -07002387class ModuleValuesymtabParser : public ValuesymtabParser {
Jim Stichnoth0795ba02014-10-01 14:23:01 -07002388 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
2389 void operator=(const ModuleValuesymtabParser &) = delete;
Karl Schimpfc132b762014-09-11 09:43:47 -07002390
2391public:
2392 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
2393 : ValuesymtabParser(BlockID, MP) {}
2394
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002395 ~ModuleValuesymtabParser() override {}
Karl Schimpfc132b762014-09-11 09:43:47 -07002396
2397private:
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002398 void setValueName(uint64_t Index, StringType &Name) override;
2399 void setBbName(uint64_t Index, StringType &Name) override;
Karl Schimpfc132b762014-09-11 09:43:47 -07002400};
2401
2402void ModuleValuesymtabParser::setValueName(uint64_t Index, StringType &Name) {
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002403 if (Index < Context->getNumFunctionIDs()) {
2404 Function *Fcn = Context->getFunctionByID(Index);
2405 if (Fcn != nullptr) {
2406 Fcn->setName(StringRef(Name.data(), Name.size()));
2407 return;
2408 }
2409 } else {
2410 unsigned NumFunctions = Context->getNumFunctionIDs();
2411 if (Index >= NumFunctions) {
2412 Context->getGlobalAddress(Index - NumFunctions)
2413 ->setName(StringRef(Name.data(), Name.size()));
2414 }
Karl Schimpfc132b762014-09-11 09:43:47 -07002415 return;
2416 }
Karl Schimpfe3f64d02014-10-07 10:38:22 -07002417
2418 std::string Buffer;
2419 raw_string_ostream StrBuf(Buffer);
2420 StrBuf << "Invalid global address ID in valuesymtab: " << Index;
2421 Error(StrBuf.str());
2422 return;
Karl Schimpfc132b762014-09-11 09:43:47 -07002423}
2424
2425void ModuleValuesymtabParser::setBbName(uint64_t Index, StringType &Name) {
2426 std::string Buffer;
2427 raw_string_ostream StrBuf(Buffer);
2428 StrBuf << "Can't define basic block name at global level: '" << Name
2429 << "' -> " << Index;
2430 Error(StrBuf.str());
2431}
2432
Jim Stichnoth8e8042c2014-09-25 17:51:47 -07002433bool ModuleParser::ParseBlock(unsigned BlockID) {
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002434 switch (BlockID) {
2435 case naclbitc::BLOCKINFO_BLOCK_ID:
2436 return NaClBitcodeParser::ParseBlock(BlockID);
2437 case naclbitc::TYPE_BLOCK_ID_NEW: {
2438 TypesParser Parser(BlockID, this);
2439 return Parser.ParseThisBlock();
2440 }
2441 case naclbitc::GLOBALVAR_BLOCK_ID: {
2442 GlobalsParser Parser(BlockID, this);
2443 return Parser.ParseThisBlock();
2444 }
2445 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
Karl Schimpfc132b762014-09-11 09:43:47 -07002446 ModuleValuesymtabParser Parser(BlockID, this);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002447 return Parser.ParseThisBlock();
2448 }
2449 case naclbitc::FUNCTION_BLOCK_ID: {
Karl Schimpf6ff33d22014-09-22 10:28:42 -07002450 InstallGlobalAddressNamesAndInitializers();
Karl Schimpfd6064a12014-08-27 15:34:58 -07002451 FunctionParser Parser(BlockID, this);
2452 return Parser.ParseThisBlock();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002453 }
2454 default:
2455 return BlockParserBaseClass::ParseBlock(BlockID);
2456 }
2457}
2458
2459void ModuleParser::ProcessRecord() {
2460 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2461 switch (Record.GetCode()) {
2462 case naclbitc::MODULE_CODE_VERSION: {
2463 // VERSION: [version#]
Karl Schimpfd6064a12014-08-27 15:34:58 -07002464 if (!isValidRecordSize(1, "Module version"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002465 return;
2466 unsigned Version = Values[0];
2467 if (Version != 1) {
2468 std::string Buffer;
2469 raw_string_ostream StrBuf(Buffer);
2470 StrBuf << "Unknown bitstream version: " << Version;
2471 Error(StrBuf.str());
2472 }
2473 return;
2474 }
2475 case naclbitc::MODULE_CODE_FUNCTION: {
2476 // FUNCTION: [type, callingconv, isproto, linkage]
Karl Schimpfd6064a12014-08-27 15:34:58 -07002477 if (!isValidRecordSize(4, "Function heading"))
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002478 return;
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002479 const Ice::FuncSigType &Ty = Context->getFuncSigTypeByID(Values[0]);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002480 CallingConv::ID CallingConv;
2481 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
2482 std::string Buffer;
2483 raw_string_ostream StrBuf(Buffer);
2484 StrBuf << "Function heading has unknown calling convention: "
2485 << Values[1];
2486 Error(StrBuf.str());
2487 return;
2488 }
2489 GlobalValue::LinkageTypes Linkage;
2490 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
2491 std::string Buffer;
2492 raw_string_ostream StrBuf(Buffer);
2493 StrBuf << "Function heading has unknown linkage. Found " << Values[3];
2494 Error(StrBuf.str());
2495 return;
2496 }
Karl Schimpf645aa1a2014-10-08 09:05:53 -07002497 SmallVector<Type *, 8> ArgTys;
2498 for (Ice::Type ArgType : Ty.getArgList()) {
2499 ArgTys.push_back(Context->convertToLLVMType(ArgType));
2500 }
2501 Function *Func = Function::Create(
2502 FunctionType::get(Context->convertToLLVMType(Ty.getReturnType()),
2503 ArgTys, false),
2504 Linkage, "", Context->getModule());
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002505 Func->setCallingConv(CallingConv);
2506 if (Values[2] == 0)
2507 Context->setNextValueIDAsImplementedFunction();
2508 Context->setNextFunctionID(Func);
2509 // TODO(kschimpf) verify if Func matches PNaCl ABI.
2510 return;
2511 }
2512 default:
2513 BlockParserBaseClass::ProcessRecord();
2514 return;
2515 }
2516}
2517
2518bool TopLevelParser::ParseBlock(unsigned BlockID) {
2519 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
2520 ModuleParser Parser(BlockID, this);
Karl Schimpfd6064a12014-08-27 15:34:58 -07002521 return Parser.ParseThisBlock();
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002522 }
2523 // Generate error message by using default block implementation.
2524 BlockParserBaseClass Parser(BlockID, this);
2525 return Parser.ParseThisBlock();
2526}
2527
Jim Stichnoth989a7032014-08-08 10:13:44 -07002528} // end of anonymous namespace
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002529
2530namespace Ice {
2531
2532void PNaClTranslator::translate(const std::string &IRFilename) {
2533 OwningPtr<MemoryBuffer> MemBuf;
2534 if (error_code ec =
2535 MemoryBuffer::getFileOrSTDIN(IRFilename.c_str(), MemBuf)) {
2536 errs() << "Error reading '" << IRFilename << "': " << ec.message() << "\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07002537 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002538 return;
2539 }
2540
2541 if (MemBuf->getBufferSize() % 4 != 0) {
2542 errs() << IRFilename
2543 << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07002544 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002545 return;
2546 }
2547
2548 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
2549 const unsigned char *EndBufPtr = BufPtr + MemBuf->getBufferSize();
2550
2551 // Read header and verify it is good.
2552 NaClBitcodeHeader Header;
2553 if (Header.Read(BufPtr, EndBufPtr) || !Header.IsSupported()) {
2554 errs() << "Invalid PNaCl bitcode header.\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07002555 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002556 return;
2557 }
2558
2559 // Create a bitstream reader to read the bitcode file.
2560 NaClBitstreamReader InputStreamFile(BufPtr, EndBufPtr);
2561 NaClBitstreamCursor InputStream(InputStreamFile);
2562
Karl Schimpfd6064a12014-08-27 15:34:58 -07002563 TopLevelParser Parser(*this, MemBuf->getBufferIdentifier(), Header,
2564 InputStream, ErrorStatus);
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002565 int TopLevelBlocks = 0;
2566 while (!InputStream.AtEndOfStream()) {
2567 if (Parser.Parse()) {
Karl Schimpfb164d202014-07-11 10:26:34 -07002568 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002569 return;
2570 }
2571 ++TopLevelBlocks;
2572 }
2573
2574 if (TopLevelBlocks != 1) {
2575 errs() << IRFilename
2576 << ": Contains more than one module. Found: " << TopLevelBlocks
2577 << "\n";
Karl Schimpfb164d202014-07-11 10:26:34 -07002578 ErrorStatus = true;
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002579 }
Karl Schimpf8d7abae2014-07-07 14:50:30 -07002580}
2581
Jim Stichnoth989a7032014-08-08 10:13:44 -07002582} // end of namespace Ice