1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===//
3 // The Subzero Code Generator
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Implements the interface for translation from PNaCl bitcode files to
12 /// ICE to machine code.
14 //===----------------------------------------------------------------------===//
16 #include "PNaClTranslator.h"
19 #include "IceCfgNode.h"
20 #include "IceClFlags.h"
22 #include "IceGlobalInits.h"
24 #include "IceOperand.h"
25 #include "IceRangeSpec.h"
28 #pragma clang diagnostic push
29 #pragma clang diagnostic ignored "-Wunused-parameter"
32 #include "llvm/ADT/Hashing.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
35 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
36 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
37 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
38 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
39 #include "llvm/Support/Format.h"
40 #include "llvm/Support/MemoryBuffer.h"
41 #include "llvm/Support/raw_ostream.h"
44 #pragma clang diagnostic pop
47 #include <unordered_set>
49 // Define a hash function for SmallString's, so that it can be used in hash
52 template <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> {
53 size_t operator()(const llvm::SmallString<InternalLen> &Key) const {
54 return llvm::hash_combine_range(Key.begin(), Key.end());
57 } // end of namespace std
62 // Models elements in the list of types defined in the types block. These
63 // elements can be undefined, a (simple) type, or a function type signature.
64 // Note that an extended type is undefined on construction. Use methods
65 // setAsSimpleType and setAsFuncSigType to define the extended type.
67 ExtendedType &operator=(const ExtendedType &Ty) = delete;
70 /// Discriminator for LLVM-style RTTI.
71 enum TypeKind { Undefined, Simple, FuncSig };
73 ExtendedType() = default;
74 ExtendedType(const ExtendedType &Ty) = default;
76 virtual ~ExtendedType() = default;
78 ExtendedType::TypeKind getKind() const { return Kind; }
79 void dump(Ice::Ostream &Stream) const;
81 /// Changes the extended type to a simple type with the given / value.
82 void setAsSimpleType(Ice::Type Ty) {
83 assert(Kind == Undefined);
85 Signature.setReturnType(Ty);
88 /// Changes the extended type to an (empty) function signature type.
89 void setAsFunctionType() {
90 assert(Kind == Undefined);
95 // Note: For simple types, the return type of the signature will be used to
96 // hold the simple type.
97 Ice::FuncSigType Signature;
100 ExtendedType::TypeKind Kind = Undefined;
103 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
104 if (!Ice::BuildDefs::dump())
110 Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
111 if (!Ice::BuildDefs::dump())
113 Stream << "ExtendedType::";
115 case ExtendedType::Undefined:
116 Stream << "Undefined";
118 case ExtendedType::Simple:
121 case ExtendedType::FuncSig:
128 // Models an ICE type as an extended type.
129 class SimpleExtendedType : public ExtendedType {
130 SimpleExtendedType() = delete;
131 SimpleExtendedType(const SimpleExtendedType &) = delete;
132 SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
135 Ice::Type getType() const { return Signature.getReturnType(); }
137 static bool classof(const ExtendedType *Ty) {
138 return Ty->getKind() == Simple;
142 // Models a function signature as an extended type.
143 class FuncSigExtendedType : public ExtendedType {
144 FuncSigExtendedType() = delete;
145 FuncSigExtendedType(const FuncSigExtendedType &) = delete;
146 FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
149 const Ice::FuncSigType &getSignature() const { return Signature; }
150 void setReturnType(Ice::Type ReturnType) {
151 Signature.setReturnType(ReturnType);
153 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
154 static bool classof(const ExtendedType *Ty) {
155 return Ty->getKind() == FuncSig;
159 void ExtendedType::dump(Ice::Ostream &Stream) const {
160 if (!Ice::BuildDefs::dump())
165 Stream << " " << Signature.getReturnType();
169 Stream << " " << Signature;
176 // Models integer literals as a sequence of bits. Used to read integer values
177 // from bitcode files. Based on llvm::APInt.
179 BitcodeInt() = delete;
180 BitcodeInt(const BitcodeInt &) = delete;
181 BitcodeInt &operator=(const BitcodeInt &) = delete;
184 BitcodeInt(Ice::SizeT Bits, uint64_t Val) : BitWidth(Bits), Val(Val) {
185 assert(Bits && "bitwidth too small");
186 assert(Bits <= BITS_PER_WORD && "bitwidth too big");
190 int64_t getSExtValue() const {
191 return static_cast<int64_t>(Val << (BITS_PER_WORD - BitWidth)) >>
192 (BITS_PER_WORD - BitWidth);
195 template <typename IntType, typename FpType>
196 inline FpType convertToFp() const {
197 static_assert(sizeof(IntType) == sizeof(FpType),
198 "IntType and FpType should be the same width");
199 assert(BitWidth == sizeof(IntType) * CHAR_BIT);
200 auto V = static_cast<IntType>(Val);
201 return Ice::Utils::bitCopy<FpType>(V);
205 /// Bits in the (internal) value.
206 static const Ice::SizeT BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT;
208 uint32_t BitWidth; /// The number of bits in the floating point number.
209 uint64_t Val; /// The (64-bit) equivalent integer value.
211 /// Clear unused high order bits.
212 void clearUnusedBits() {
213 // If all bits are used, we want to leave the value alone.
214 if (BitWidth == BITS_PER_WORD)
217 // Mask out the high bits.
218 Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth);
222 class BlockParserBaseClass;
224 // Top-level class to read PNaCl bitcode files, and translate to ICE.
225 class TopLevelParser final : public NaClBitcodeParser {
226 TopLevelParser() = delete;
227 TopLevelParser(const TopLevelParser &) = delete;
228 TopLevelParser &operator=(const TopLevelParser &) = delete;
231 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor,
232 Ice::ErrorCode &ErrorStatus)
233 : NaClBitcodeParser(Cursor), Translator(Translator),
234 ErrorStatus(ErrorStatus),
235 VariableDeclarations(new Ice::VariableDeclarationList()) {}
237 ~TopLevelParser() override = default;
239 Ice::Translator &getTranslator() const { return Translator; }
241 /// Generates error with given Message, occurring at BitPosition within the
242 /// bitcode file. Always returns true.
243 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition,
244 const std::string &Message) override;
246 /// Generates error message with respect to the current block parser.
247 bool blockError(const std::string &Message);
249 /// Changes the size of the type list to the given size.
250 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); }
252 size_t getNumTypeIDValues() const { return TypeIDValues.size(); }
254 /// Returns a pointer to the pool where globals are allocated.
255 Ice::VariableDeclarationList *getGlobalVariablesPool() {
256 return VariableDeclarations.get();
259 /// Returns the undefined type associated with type ID. Note: Returns extended
260 /// type ready to be defined.
261 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) {
262 // Get corresponding element, verifying the value is still undefined (and
263 // hence allowed to be defined).
264 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
267 if (ID >= TypeIDValues.size()) {
268 if (ID >= NaClBcIndexSize_t_Max) {
270 raw_string_ostream StrBuf(Buffer);
271 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max
273 blockError(StrBuf.str());
274 // Recover by using existing type slot.
275 return &TypeIDValues[0];
277 Ice::Utils::reserveAndResize(TypeIDValues, ID + 1);
279 return &TypeIDValues[ID];
282 /// Returns the type associated with the given index.
283 Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) {
284 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
286 // Return error recovery value.
287 return Ice::IceType_void;
288 return cast<SimpleExtendedType>(Ty)->getType();
291 /// Returns the type signature associated with the given index.
292 const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) {
293 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
295 // Return error recovery value.
296 return UndefinedFuncSigType;
297 return cast<FuncSigExtendedType>(Ty)->getSignature();
300 /// Sets the next function ID to the given LLVM function.
301 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) {
302 FunctionDeclarations.push_back(Fcn);
305 /// Returns the value id that should be associated with the the current
306 /// function block. Increments internal counters during call so that it will
307 /// be in correct position for next function block.
308 NaClBcIndexSize_t getNextFunctionBlockValueID() {
309 size_t NumDeclaredFunctions = FunctionDeclarations.size();
310 while (NextDefiningFunctionID < NumDeclaredFunctions &&
311 FunctionDeclarations[NextDefiningFunctionID]->isProto())
312 ++NextDefiningFunctionID;
313 if (NextDefiningFunctionID >= NumDeclaredFunctions)
314 Fatal("More function blocks than defined function addresses");
315 return NextDefiningFunctionID++;
318 /// Returns the function associated with ID.
319 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) {
320 if (ID < FunctionDeclarations.size())
321 return FunctionDeclarations[ID];
322 return reportGetFunctionByIDError(ID);
325 /// Returns the constant associated with the given global value ID.
326 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) {
327 assert(ID < ValueIDConstants.size());
328 return ValueIDConstants[ID];
331 /// Install names for all global values without names. Called after the global
332 /// value symbol table is processed, but before any function blocks are
334 void installGlobalNames() {
335 assert(VariableDeclarations);
336 installGlobalVarNames();
337 installFunctionNames();
340 void verifyFunctionTypeSignatures();
342 void createValueIDs() {
343 assert(VariableDeclarations);
344 ValueIDConstants.reserve(VariableDeclarations->size() +
345 FunctionDeclarations.size());
346 createValueIDsForFunctions();
347 createValueIDsForGlobalVars();
350 /// Returns the number of function declarations in the bitcode file.
351 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); }
353 /// Returns the number of global declarations (i.e. IDs) defined in the
355 size_t getNumGlobalIDs() const {
356 if (VariableDeclarations) {
357 return FunctionDeclarations.size() + VariableDeclarations->size();
359 return ValueIDConstants.size();
363 /// Adds the given global declaration to the end of the list of global
365 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
366 assert(VariableDeclarations);
367 VariableDeclarations->push_back(Decl);
370 /// Returns the global variable declaration with the given index.
371 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) {
372 assert(VariableDeclarations);
373 if (Index < VariableDeclarations->size())
374 return VariableDeclarations->at(Index);
375 return reportGetGlobalVariableByIDError(Index);
378 /// Returns the global declaration (variable or function) with the given
380 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) {
381 size_t NumFunctionIds = FunctionDeclarations.size();
382 if (Index < NumFunctionIds)
383 return getFunctionByID(Index);
385 return getGlobalVariableByID(Index - NumFunctionIds);
388 /// Returns true if a module block has been parsed.
389 bool parsedModuleBlock() const { return ParsedModuleBlock; }
391 /// Returns the list of parsed global variable declarations. Releases
392 /// ownership of the current list of global variables. Note: only returns
393 /// non-null pointer on first call. All successive calls return a null
395 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() {
396 // Before returning, check that ValidIDConstants has already been built.
397 assert(!VariableDeclarations ||
398 VariableDeclarations->size() <= ValueIDConstants.size());
399 return std::move(VariableDeclarations);
402 // Upper limit of alignment power allowed by LLVM
403 static constexpr uint32_t AlignPowerLimit = 29;
405 // Extracts the corresponding Alignment to use, given the AlignPower (i.e.
406 // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block
407 // context the alignment check appears in, and Prefix defines the context the
408 // alignment appears in.
409 uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix,
410 uint32_t AlignPower) {
411 if (AlignPower <= AlignPowerLimit + 1)
412 return (1 << AlignPower) >> 1;
414 raw_string_ostream StrBuf(Buffer);
415 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit
416 << ". Found: 2**" << (AlignPower - 1);
417 Parser->Error(StrBuf.str());
418 // Error recover with value that is always acceptable.
423 // The translator associated with the parser.
424 Ice::Translator &Translator;
426 // ErrorStatus should only be updated while this lock is locked.
427 Ice::GlobalLockType ErrorReportingLock;
428 // The exit status that should be set to true if an error occurs.
429 Ice::ErrorCode &ErrorStatus;
431 // The types associated with each type ID.
432 std::vector<ExtendedType> TypeIDValues;
433 // The set of functions (prototype and defined).
434 Ice::FunctionDeclarationList FunctionDeclarations;
435 // The ID of the next possible defined function ID in FunctionDeclarations.
436 // FunctionDeclarations is filled first. It's the set of functions (either
437 // defined or isproto). Then function definitions are encountered/parsed and
438 // NextDefiningFunctionID is incremented to track the next actually-defined
440 size_t NextDefiningFunctionID = 0;
441 // The set of global variables.
442 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations;
443 // Relocatable constants associated with global declarations.
444 Ice::ConstantList ValueIDConstants;
445 // Error recovery value to use when getFuncSigTypeByID fails.
446 Ice::FuncSigType UndefinedFuncSigType;
447 // Defines if a module block has already been parsed.
448 bool ParsedModuleBlock = false;
450 bool ParseBlock(unsigned BlockID) override;
452 // Gets extended type associated with the given index, assuming the extended
453 // type is of the WantedKind. Generates error message if corresponding
454 // extended type of WantedKind can't be found, and returns nullptr.
455 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID,
456 ExtendedType::TypeKind WantedKind) {
457 ExtendedType *Ty = nullptr;
458 if (ID < TypeIDValues.size()) {
459 Ty = &TypeIDValues[ID];
460 if (Ty->getKind() == WantedKind)
463 // Generate an error message and set ErrorStatus.
464 this->reportBadTypeIDAs(ID, Ty, WantedKind);
468 // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are
469 // used to generate the name. NameIndex is automatically incremented if a new
470 // name is created. DeclType is literal text describing the type of name being
471 // created. Also generates a warning if created names may conflict with named
473 void installDeclarationName(Ice::GlobalDeclaration *Decl,
474 const std::string &Prefix, const char *DeclType,
475 NaClBcIndexSize_t &NameIndex) {
476 if (Decl->hasName()) {
477 Translator.checkIfUnnamedNameSafe(Decl->getName().toString(), DeclType,
480 Ice::GlobalContext *Ctx = Translator.getContext();
481 // Synthesize a dummy name if any of the following is true:
483 // - The symbol is external
484 // - The -timing-funcs flag is enabled
485 // - Some RangeSpec is initialized with actual names
486 if (Ice::BuildDefs::dump() || !Decl->isInternal() ||
487 Ice::RangeSpec::hasNames() || Ice::getFlags().getTimeEachFunction()) {
488 Decl->setName(Ctx, Translator.createUnnamedName(Prefix, NameIndex));
496 // Installs names for global variables without names.
497 void installGlobalVarNames() {
498 assert(VariableDeclarations);
499 const std::string &GlobalPrefix = Ice::getFlags().getDefaultGlobalPrefix();
500 if (!GlobalPrefix.empty()) {
501 NaClBcIndexSize_t NameIndex = 0;
502 for (Ice::VariableDeclaration *Var : *VariableDeclarations) {
503 installDeclarationName(Var, GlobalPrefix, "global", NameIndex);
508 // Installs names for functions without names.
509 void installFunctionNames() {
510 const std::string &FunctionPrefix =
511 Ice::getFlags().getDefaultFunctionPrefix();
512 if (!FunctionPrefix.empty()) {
513 NaClBcIndexSize_t NameIndex = 0;
514 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) {
515 installDeclarationName(Func, FunctionPrefix, "function", NameIndex);
520 // Builds a constant symbol named Name. IsExternal is true iff the symbol is
522 Ice::Constant *getConstantSym(Ice::GlobalString Name, bool IsExternal) const {
523 Ice::GlobalContext *Ctx = getTranslator().getContext();
525 return Ctx->getConstantExternSym(Name);
527 const Ice::RelocOffsetT Offset = 0;
528 return Ctx->getConstantSym(Offset, Name);
532 void reportLinkageError(const char *Kind,
533 const Ice::GlobalDeclaration &Decl) {
535 raw_string_ostream StrBuf(Buffer);
536 StrBuf << Kind << " " << Decl.getName()
537 << " has incorrect linkage: " << Decl.getLinkageName();
538 if (Decl.isExternal())
539 StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
543 // Converts function declarations into constant value IDs.
544 void createValueIDsForFunctions() {
545 Ice::GlobalContext *Ctx = getTranslator().getContext();
546 for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) {
547 if (!Func->verifyLinkageCorrect(Ctx))
548 reportLinkageError("Function", *Func);
549 Ice::Constant *C = getConstantSym(Func->getName(), Func->isProto());
550 ValueIDConstants.push_back(C);
554 // Converts global variable declarations into constant value IDs.
555 void createValueIDsForGlobalVars() {
556 for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) {
557 if (!Decl->verifyLinkageCorrect())
558 reportLinkageError("Global", *Decl);
560 getConstantSym(Decl->getName(), !Decl->hasInitializer());
561 ValueIDConstants.push_back(C);
565 // Reports that type ID is undefined, or not of the WantedType.
566 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty,
567 ExtendedType::TypeKind WantedType);
569 // Reports that there is no function declaration for ID. Returns an error
570 // recovery value to use.
571 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID);
573 // Reports that there is not global variable declaration for ID. Returns an
574 // error recovery value to use.
575 Ice::VariableDeclaration *
576 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index);
578 // Reports that there is no corresponding ICE type for LLVMTy, and returns
579 // Ice::IceType_void.
580 Ice::Type convertToIceTypeError(Type *LLVMTy);
583 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
584 const std::string &Message) {
585 Ice::GlobalContext *Context = Translator.getContext();
587 std::unique_lock<Ice::GlobalLockType> _(ErrorReportingLock);
588 ErrorStatus.assign(Ice::EC_Bitcode);
590 { // Lock while printing out error message.
591 Ice::OstreamLocker L(Context);
592 raw_ostream &OldErrStream = setErrStream(Context->getStrError());
593 NaClBitcodeParser::ErrorAt(Level, Bit, Message);
594 setErrStream(OldErrStream);
596 if (Level >= naclbitc::Error && !Ice::getFlags().getAllowErrorRecovery())
601 void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID,
602 const ExtendedType *Ty,
603 ExtendedType::TypeKind WantedType) {
605 raw_string_ostream StrBuf(Buffer);
607 StrBuf << "Can't find extended type for type id: " << ID;
609 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
611 blockError(StrBuf.str());
614 Ice::FunctionDeclaration *
615 TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) {
617 raw_string_ostream StrBuf(Buffer);
618 StrBuf << "Function index " << ID
619 << " not allowed. Out of range. Must be less than "
620 << FunctionDeclarations.size();
621 blockError(StrBuf.str());
622 if (!FunctionDeclarations.empty())
623 return FunctionDeclarations[0];
627 Ice::VariableDeclaration *
628 TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) {
630 raw_string_ostream StrBuf(Buffer);
631 StrBuf << "Global index " << Index
632 << " not allowed. Out of range. Must be less than "
633 << VariableDeclarations->size();
634 blockError(StrBuf.str());
635 if (!VariableDeclarations->empty())
636 return VariableDeclarations->at(0);
640 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
642 raw_string_ostream StrBuf(Buffer);
643 StrBuf << "Invalid LLVM type: " << *LLVMTy;
645 return Ice::IceType_void;
648 void TopLevelParser::verifyFunctionTypeSignatures() {
649 const Ice::GlobalContext *Ctx = getTranslator().getContext();
650 for (Ice::FunctionDeclaration *FuncDecl : FunctionDeclarations) {
651 if (!FuncDecl->validateTypeSignature(Ctx))
652 Error(FuncDecl->getTypeSignatureError(Ctx));
656 // Base class for parsing blocks within the bitcode file. Note: Because this is
657 // the base class of block parsers, we generate error messages if ParseBlock or
658 // ParseRecord is not overridden in derived classes.
659 class BlockParserBaseClass : public NaClBitcodeParser {
660 BlockParserBaseClass() = delete;
661 BlockParserBaseClass(const BlockParserBaseClass &) = delete;
662 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
665 // Constructor for the top-level module block parser.
666 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
667 : NaClBitcodeParser(BlockID, Context), Context(Context) {}
669 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
670 NaClBitstreamCursor &Cursor)
671 : NaClBitcodeParser(BlockID, EnclosingParser, Cursor),
672 Context(EnclosingParser->Context) {}
674 ~BlockParserBaseClass() override {}
676 // Returns the printable name of the type of block being parsed.
677 virtual const char *getBlockName() const {
678 // If this class is used, it is parsing an unknown block.
682 // Generates an error Message with the Bit address prefixed to it.
683 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
684 const std::string &Message) override;
687 // The context parser that contains the decoded state.
688 TopLevelParser *Context;
689 // True if ErrorAt has been called in this block.
690 bool BlockHasError = false;
692 // Constructor for nested block parsers.
693 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
694 : NaClBitcodeParser(BlockID, EnclosingParser),
695 Context(EnclosingParser->Context) {}
697 // Gets the translator associated with the bitcode parser.
698 Ice::Translator &getTranslator() const { return Context->getTranslator(); }
700 // Default implementation. Reports that block is unknown and skips its
702 bool ParseBlock(unsigned BlockID) override;
704 // Default implementation. Reports that the record is not understood.
705 void ProcessRecord() override;
707 // Checks if the size of the record is Size. Return true if valid. Otherwise
708 // generates an error and returns false.
709 bool isValidRecordSize(size_t Size, const char *RecordName) {
710 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
711 if (Values.size() == Size)
713 reportRecordSizeError(Size, RecordName, nullptr);
717 // Checks if the size of the record is at least as large as the LowerLimit.
718 // Returns true if valid. Otherwise generates an error and returns false.
719 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) {
720 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
721 if (Values.size() >= LowerLimit)
723 reportRecordSizeError(LowerLimit, RecordName, "at least");
727 // Checks if the size of the record is no larger than the
728 // UpperLimit. Returns true if valid. Otherwise generates an error and
730 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) {
731 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
732 if (Values.size() <= UpperLimit)
734 reportRecordSizeError(UpperLimit, RecordName, "no more than");
738 // Checks if the size of the record is at least as large as the LowerLimit,
739 // and no larger than the UpperLimit. Returns true if valid. Otherwise
740 // generates an error and returns false.
741 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit,
742 const char *RecordName) {
743 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
744 isValidRecordSizeAtMost(UpperLimit, RecordName);
748 /// Generates a record size error. ExpectedSize is the number of elements
749 /// expected. RecordName is the name of the kind of record that has incorrect
750 /// size. ContextMessage (if not nullptr) is appended to "record expects" to
751 /// describe how ExpectedSize should be interpreted.
752 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName,
753 const char *ContextMessage);
756 bool TopLevelParser::blockError(const std::string &Message) {
757 // TODO(kschimpf): Remove this method. This method used to redirect
758 // block-level errors to the block we are in, rather than the top-level
759 // block. This gave better bit location for error messages. However, with
760 // parallel parsing, we can't keep a field to redirect (there could be many
761 // and we don't know which block parser applies). Hence, This redirect can't
762 // be applied anymore.
763 return Error(Message);
766 // Generates an error Message with the bit address prefixed to it.
767 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
768 const std::string &Message) {
769 BlockHasError = true;
771 raw_string_ostream StrBuf(Buffer);
772 // Note: If dump routines have been turned off, the error messages will not
773 // be readable. Hence, replace with simple error. We also use the simple form
775 if (Ice::getFlags().getGenerateUnitTestMessages()) {
776 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode();
777 for (const uint64_t Val : Record.GetValues()) {
778 StrBuf << " " << Val;
784 return Context->ErrorAt(Level, Record.GetCursor().getErrorBitNo(Bit),
788 void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize,
789 const char *RecordName,
790 const char *ContextMessage) {
792 raw_string_ostream StrBuf(Buffer);
793 const char *BlockName = getBlockName();
794 const char FirstChar = toupper(*BlockName);
795 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName
796 << " record expects";
798 StrBuf << " " << ContextMessage;
799 StrBuf << " " << ExpectedSize << " argument";
800 if (ExpectedSize > 1)
802 StrBuf << ". Found: " << Record.GetValues().size();
806 bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
807 // If called, derived class doesn't know how to handle block. Report error
810 raw_string_ostream StrBuf(Buffer);
811 StrBuf << "Don't know how to parse block id: " << BlockID;
817 void BlockParserBaseClass::ProcessRecord() {
818 // If called, derived class doesn't know how to handle.
820 raw_string_ostream StrBuf(Buffer);
821 StrBuf << "Don't know how to process " << getBlockName()
822 << " record:" << Record;
826 // Class to parse a types block.
827 class TypesParser final : public BlockParserBaseClass {
828 TypesParser() = delete;
829 TypesParser(const TypesParser &) = delete;
830 TypesParser &operator=(const TypesParser &) = delete;
833 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
834 : BlockParserBaseClass(BlockID, EnclosingParser),
835 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {}
837 ~TypesParser() override {
838 if (ExpectedNumTypes != Context->getNumTypeIDValues()) {
840 raw_string_ostream StrBuf(Buffer);
841 StrBuf << "Types block expected " << ExpectedNumTypes
842 << " types but found: " << NextTypeId;
848 Ice::TimerMarker Timer;
849 // The type ID that will be associated with the next type defining record in
851 NaClBcIndexSize_t NextTypeId = 0;
853 // The expected number of types, based on record TYPE_CODE_NUMENTRY.
854 NaClBcIndexSize_t ExpectedNumTypes = 0;
856 void ProcessRecord() override;
858 const char *getBlockName() const override { return "type"; }
860 void setNextTypeIDAsSimpleType(Ice::Type Ty) {
861 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
865 void TypesParser::ProcessRecord() {
866 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
867 switch (Record.GetCode()) {
868 case naclbitc::TYPE_CODE_NUMENTRY: {
869 // NUMENTRY: [numentries]
870 if (!isValidRecordSize(1, "count"))
872 uint64_t Size = Values[0];
873 if (Size > NaClBcIndexSize_t_Max) {
875 raw_string_ostream StrBuf(Buffer);
876 StrBuf << "Size to big for count record: " << Size;
878 ExpectedNumTypes = NaClBcIndexSize_t_Max;
880 // The code double checks that Expected size and the actual size at the end
881 // of the block. To reduce allocations we preallocate the space.
883 // However, if the number is large, we suspect that the number is
884 // (possibly) incorrect. In that case, we preallocate a smaller space.
885 constexpr uint64_t DefaultLargeResizeValue = 1000000;
886 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue));
887 ExpectedNumTypes = Size;
890 case naclbitc::TYPE_CODE_VOID:
892 if (!isValidRecordSize(0, "void"))
894 setNextTypeIDAsSimpleType(Ice::IceType_void);
896 case naclbitc::TYPE_CODE_FLOAT:
898 if (!isValidRecordSize(0, "float"))
900 setNextTypeIDAsSimpleType(Ice::IceType_f32);
902 case naclbitc::TYPE_CODE_DOUBLE:
904 if (!isValidRecordSize(0, "double"))
906 setNextTypeIDAsSimpleType(Ice::IceType_f64);
908 case naclbitc::TYPE_CODE_INTEGER:
910 if (!isValidRecordSize(1, "integer"))
914 setNextTypeIDAsSimpleType(Ice::IceType_i1);
917 setNextTypeIDAsSimpleType(Ice::IceType_i8);
920 setNextTypeIDAsSimpleType(Ice::IceType_i16);
923 setNextTypeIDAsSimpleType(Ice::IceType_i32);
926 setNextTypeIDAsSimpleType(Ice::IceType_i64);
933 raw_string_ostream StrBuf(Buffer);
934 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
938 case naclbitc::TYPE_CODE_VECTOR: {
939 // VECTOR: [numelts, eltty]
940 if (!isValidRecordSize(2, "vector"))
942 Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
943 Ice::SizeT Size = Values[0];
945 case Ice::IceType_i1:
948 setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
951 setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
954 setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
960 case Ice::IceType_i8:
962 setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
966 case Ice::IceType_i16:
968 setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
972 case Ice::IceType_i32:
974 setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
978 case Ice::IceType_f32:
980 setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
989 raw_string_ostream StrBuf(Buffer);
990 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
996 case naclbitc::TYPE_CODE_FUNCTION: {
997 // FUNCTION: [vararg, retty, paramty x N]
998 if (!isValidRecordSizeAtLeast(2, "signature"))
1001 Error("Function type can't define varargs");
1002 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
1003 Ty->setAsFunctionType();
1004 auto *FuncTy = cast<FuncSigExtendedType>(Ty);
1005 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
1006 for (size_t i = 2, e = Values.size(); i != e; ++i) {
1007 // Check that type void not used as argument type. Note: PNaCl
1008 // restrictions can't be checked until we know the name, because we have
1009 // to check for intrinsic signatures.
1010 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
1011 if (ArgTy == Ice::IceType_void) {
1013 raw_string_ostream StrBuf(Buffer);
1014 StrBuf << "Type for parameter " << (i - 1)
1015 << " not valid. Found: " << ArgTy;
1016 ArgTy = Ice::IceType_i32;
1018 FuncTy->appendArgType(ArgTy);
1023 BlockParserBaseClass::ProcessRecord();
1026 llvm_unreachable("Unknown type block record not processed!");
1029 /// Parses the globals block (i.e. global variable declarations and
1030 /// corresponding initializers).
1031 class GlobalsParser final : public BlockParserBaseClass {
1032 GlobalsParser() = delete;
1033 GlobalsParser(const GlobalsParser &) = delete;
1034 GlobalsParser &operator=(const GlobalsParser &) = delete;
1037 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1038 : BlockParserBaseClass(BlockID, EnclosingParser),
1039 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
1040 NumFunctionIDs(Context->getNumFunctionIDs()),
1041 DummyGlobalVar(Ice::VariableDeclaration::create(
1042 Context->getGlobalVariablesPool())),
1043 CurGlobalVar(DummyGlobalVar) {
1044 Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar);
1047 ~GlobalsParser() override = default;
1049 const char *getBlockName() const override { return "globals"; }
1052 using GlobalVarsMapType =
1053 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>;
1055 Ice::TimerMarker Timer;
1057 // Holds global variables generated/referenced in the global variables block.
1058 GlobalVarsMapType GlobalVarsMap;
1060 // Holds the number of defined function IDs.
1061 NaClBcIndexSize_t NumFunctionIDs;
1063 // Holds the specified number of global variables by the count record in the
1064 // global variables block.
1065 NaClBcIndexSize_t SpecifiedNumberVars = 0;
1067 // Keeps track of how many initializers are expected for the global variable
1068 // declaration being built.
1069 NaClBcIndexSize_t InitializersNeeded = 0;
1071 // The index of the next global variable declaration.
1072 NaClBcIndexSize_t NextGlobalID = 0;
1074 // Dummy global variable declaration to guarantee CurGlobalVar is always
1075 // defined (allowing code to not need to check if CurGlobalVar is nullptr).
1076 Ice::VariableDeclaration *DummyGlobalVar;
1078 // Holds the current global variable declaration being built.
1079 Ice::VariableDeclaration *CurGlobalVar;
1081 // Returns the global variable associated with the given Index.
1082 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
1083 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
1084 if (Decl == nullptr)
1086 Ice::VariableDeclaration::create(Context->getGlobalVariablesPool());
1090 // Returns the global declaration associated with the given index.
1091 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
1092 if (Index < NumFunctionIDs)
1093 return Context->getFunctionByID(Index);
1094 return getGlobalVarByID(Index - NumFunctionIDs);
1097 // If global variables parsed correctly, install them into the top-level
1099 void installGlobalVariables() {
1100 // Verify specified number of globals matches number found.
1101 size_t NumGlobals = GlobalVarsMap.size();
1102 if (SpecifiedNumberVars != NumGlobals ||
1103 SpecifiedNumberVars != NextGlobalID) {
1105 raw_string_ostream StrBuf(Buffer);
1106 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1107 << " global variables. Found: " << GlobalVarsMap.size();
1108 Error(StrBuf.str());
1111 // Install global variables into top-level context.
1112 for (size_t I = 0; I < NumGlobals; ++I)
1113 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1116 void ExitBlock() override {
1117 verifyNoMissingInitializers();
1118 installGlobalVariables();
1119 BlockParserBaseClass::ExitBlock();
1122 void ProcessRecord() override;
1124 // Checks if the number of initializers for the CurGlobalVar is the same as
1125 // the number found in the bitcode file. If different, and error message is
1126 // generated, and the internal state of the parser is fixed so this condition
1127 // is no longer violated.
1128 void verifyNoMissingInitializers() {
1129 size_t NumInits = CurGlobalVar->getInitializers().size();
1130 if (InitializersNeeded != NumInits) {
1132 raw_string_ostream StrBuf(Buffer);
1133 StrBuf << "Global variable @g" << NextGlobalID << " expected "
1134 << InitializersNeeded << " initializer";
1135 if (InitializersNeeded > 1)
1137 StrBuf << ". Found: " << NumInits;
1138 Error(StrBuf.str());
1139 InitializersNeeded = NumInits;
1144 void GlobalsParser::ProcessRecord() {
1145 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1146 switch (Record.GetCode()) {
1147 case naclbitc::GLOBALVAR_COUNT:
1149 if (!isValidRecordSize(1, "count"))
1151 if (SpecifiedNumberVars || NextGlobalID) {
1152 Error("Globals count record not first in block.");
1155 SpecifiedNumberVars = Values[0];
1157 case naclbitc::GLOBALVAR_VAR: {
1158 // VAR: [align, isconst]
1159 if (!isValidRecordSize(2, "variable"))
1161 verifyNoMissingInitializers();
1162 // Always build the global variable, even if IR generation is turned off.
1163 // This is needed because we need a placeholder in the top-level context
1164 // when no IR is generated.
1165 uint32_t Alignment =
1166 Context->extractAlignment(this, "Global variable", Values[0]);
1167 CurGlobalVar = getGlobalVarByID(NextGlobalID);
1168 InitializersNeeded = 1;
1169 CurGlobalVar->setAlignment(Alignment);
1170 CurGlobalVar->setIsConstant(Values[1] != 0);
1174 case naclbitc::GLOBALVAR_COMPOUND:
1176 if (!isValidRecordSize(1, "compound"))
1178 if (!CurGlobalVar->getInitializers().empty()) {
1179 Error("Globals compound record not first initializer");
1182 if (Values[0] < 2) {
1184 raw_string_ostream StrBuf(Buffer);
1185 StrBuf << getBlockName()
1186 << " compound record size invalid. Found: " << Values[0];
1187 Error(StrBuf.str());
1190 InitializersNeeded = Values[0];
1192 case naclbitc::GLOBALVAR_ZEROFILL: {
1194 if (!isValidRecordSize(1, "zerofill"))
1196 auto *Pool = Context->getGlobalVariablesPool();
1197 CurGlobalVar->addInitializer(
1198 Ice::VariableDeclaration::ZeroInitializer::create(Pool, Values[0]));
1201 case naclbitc::GLOBALVAR_DATA: {
1202 // DATA: [b0, b1, ...]
1203 if (!isValidRecordSizeAtLeast(1, "data"))
1205 auto *Pool = Context->getGlobalVariablesPool();
1206 CurGlobalVar->addInitializer(
1207 Ice::VariableDeclaration::DataInitializer::create(Pool, Values));
1210 case naclbitc::GLOBALVAR_RELOC: {
1211 // RELOC: [val, [addend]]
1212 if (!isValidRecordSizeInRange(1, 2, "reloc"))
1214 NaClBcIndexSize_t Index = Values[0];
1215 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1216 if (Index >= IndexLimit) {
1218 raw_string_ostream StrBuf(Buffer);
1219 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1221 Error(StrBuf.str());
1223 uint64_t Offset = 0;
1224 if (Values.size() == 2) {
1226 if (Offset > std::numeric_limits<uint32_t>::max()) {
1228 raw_string_ostream StrBuf(Buffer);
1229 StrBuf << "Addend of global reloc record too big: " << Offset;
1230 Error(StrBuf.str());
1233 auto *Pool = Context->getGlobalVariablesPool();
1234 Ice::GlobalContext *Ctx = getTranslator().getContext();
1235 CurGlobalVar->addInitializer(
1236 Ice::VariableDeclaration::RelocInitializer::create(
1237 Pool, getGlobalDeclByID(Index),
1238 {Ice::RelocOffset::create(Ctx, Offset)}));
1242 BlockParserBaseClass::ProcessRecord();
1247 /// Base class for parsing a valuesymtab block in the bitcode file.
1248 class ValuesymtabParser : public BlockParserBaseClass {
1249 ValuesymtabParser() = delete;
1250 ValuesymtabParser(const ValuesymtabParser &) = delete;
1251 void operator=(const ValuesymtabParser &) = delete;
1254 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1255 : BlockParserBaseClass(BlockID, EnclosingParser) {}
1257 ~ValuesymtabParser() override = default;
1259 const char *getBlockName() const override { return "valuesymtab"; }
1262 using StringType = SmallString<128>;
1264 // Returns the name to identify the kind of symbol table this is
1265 // in error messages.
1266 virtual const char *getTableKind() const = 0;
1268 // Associates Name with the value defined by the given Index.
1269 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1271 // Associates Name with the value defined by the given Index;
1272 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1274 // Reports that the assignment of Name to the value associated with
1275 // index is not possible, for the given Context.
1276 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
1280 using NamesSetType = std::unordered_set<StringType>;
1281 NamesSetType ValueNames;
1282 NamesSetType BlockNames;
1284 void ProcessRecord() override;
1286 // Extracts out ConvertedName. Returns true if unique wrt to Names.
1287 bool convertToString(NamesSetType &Names, StringType &ConvertedName) {
1288 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1289 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1290 ConvertedName += static_cast<char>(Values[i]);
1292 auto Pair = Names.insert(ConvertedName);
1296 void ReportDuplicateName(const char *NameCat, StringType &Name);
1299 void ValuesymtabParser::reportUnableToAssign(const char *Context,
1300 NaClBcIndexSize_t Index,
1303 raw_string_ostream StrBuf(Buffer);
1304 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context
1305 << " name '" << Name << "' can't be associated with index " << Index;
1306 Error(StrBuf.str());
1309 void ValuesymtabParser::ReportDuplicateName(const char *NameCat,
1312 raw_string_ostream StrBuf(Buffer);
1313 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate "
1314 << NameCat << " name: '" << Name << "'";
1315 Error(StrBuf.str());
1318 void ValuesymtabParser::ProcessRecord() {
1319 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1320 StringType ConvertedName;
1321 switch (Record.GetCode()) {
1322 case naclbitc::VST_CODE_ENTRY: {
1323 // VST_ENTRY: [ValueId, namechar x N]
1324 if (!isValidRecordSizeAtLeast(2, "value entry"))
1326 if (convertToString(ValueNames, ConvertedName))
1327 setValueName(Values[0], ConvertedName);
1329 ReportDuplicateName("value", ConvertedName);
1332 case naclbitc::VST_CODE_BBENTRY: {
1333 // VST_BBENTRY: [BbId, namechar x N]
1334 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
1336 if (convertToString(BlockNames, ConvertedName))
1337 setBbName(Values[0], ConvertedName);
1339 ReportDuplicateName("block", ConvertedName);
1345 // If reached, don't know how to handle record.
1346 BlockParserBaseClass::ProcessRecord();
1350 /// Parses function blocks in the bitcode file.
1351 class FunctionParser final : public BlockParserBaseClass {
1352 FunctionParser() = delete;
1353 FunctionParser(const FunctionParser &) = delete;
1354 FunctionParser &operator=(const FunctionParser &) = delete;
1357 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
1358 NaClBcIndexSize_t FcnId)
1359 : BlockParserBaseClass(BlockID, EnclosingParser),
1360 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
1361 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
1362 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
1363 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
1365 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
1366 NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor)
1367 : BlockParserBaseClass(BlockID, EnclosingParser, Cursor),
1368 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
1369 Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
1370 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
1371 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
1373 std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) {
1375 Ice::GlobalContext *Ctx = getTranslator().getContext();
1377 Ice::TimerMarker T(Ctx, FuncDecl->getName().toStringOrEmpty());
1378 // Note: The Cfg is created, even when IR generation is disabled. This is
1379 // done to install a CfgLocalAllocator for various internal containers.
1380 Ice::GlobalContext *Ctx = getTranslator().getContext();
1381 Func = Ice::Cfg::create(Ctx, SeqNumber);
1383 Ice::CfgLocalAllocatorScope _(Func.get());
1385 // TODO(kschimpf) Clean up API to add a function signature to a CFG.
1386 const Ice::FuncSigType &Signature = FuncDecl->getSignature();
1388 Func->setFunctionName(FuncDecl->getName());
1389 Func->setReturnType(Signature.getReturnType());
1390 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
1391 CurrentNode = installNextBasicBlock();
1392 Func->setEntryNode(CurrentNode);
1393 for (Ice::Type ArgType : Signature.getArgList()) {
1394 Func->addArg(getNextInstVar(ArgType));
1397 ParserResult = ParseThisBlock();
1400 if (ParserResult || BlockHasError)
1401 Func->setError("Unable to parse function");
1403 return std::move(Func);
1406 ~FunctionParser() override = default;
1408 const char *getBlockName() const override { return "function"; }
1410 Ice::Cfg *getFunc() const { return Func.get(); }
1412 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; }
1414 void setNextLocalInstIndex(Ice::Operand *Op) {
1415 setOperand(NextLocalInstIndex++, Op);
1418 // Set the next constant ID to the given constant C.
1419 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
1421 // Returns the value referenced by the given value Index.
1422 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
1423 if (Index < CachedNumGlobalValueIDs) {
1424 return Context->getGlobalConstantByID(Index);
1426 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1427 if (LocalIndex >= LocalOperands.size())
1428 reportGetOperandUndefined(Index);
1429 Ice::Operand *Op = LocalOperands[LocalIndex];
1431 reportGetOperandUndefined(Index);
1436 Ice::TimerMarker Timer;
1437 // The number of words in the bitstream defining the function block.
1438 uint64_t NumBytesDefiningFunction = 0;
1439 // Maximum number of records that can appear in the function block, based on
1440 // the number of bytes defining the function block.
1441 uint64_t MaxRecordsInBlock = 0;
1442 // The corresponding ICE function defined by the function block.
1443 std::unique_ptr<Ice::Cfg> Func;
1444 // The index to the current basic block being built.
1445 NaClBcIndexSize_t CurrentBbIndex = 0;
1446 // The number of basic blocks declared for the function block.
1447 NaClBcIndexSize_t DeclaredNumberBbs = 0;
1448 // The basic block being built.
1449 Ice::CfgNode *CurrentNode = nullptr;
1450 // The corresponding function declaration.
1451 Ice::FunctionDeclaration *FuncDecl;
1452 // Holds the dividing point between local and global absolute value indices.
1453 size_t CachedNumGlobalValueIDs;
1454 // Holds operands local to the function block, based on indices defined in
1455 // the bitcode file.
1456 Ice::OperandList LocalOperands;
1457 // Holds the index within LocalOperands corresponding to the next instruction
1458 // that generates a value.
1459 NaClBcIndexSize_t NextLocalInstIndex;
1460 // True if the last processed instruction was a terminating instruction.
1461 bool InstIsTerminating = false;
1463 bool ParseBlock(unsigned BlockID) override;
1465 void ProcessRecord() override;
1467 void EnterBlock(unsigned NumWords) override {
1468 // Note: Bitstream defines words as 32-bit values.
1469 NumBytesDefiningFunction = NumWords * sizeof(uint32_t);
1470 // We know that all records are minimally defined by a two-bit abreviation.
1471 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1);
1474 void ExitBlock() override;
1476 // Creates and appends a new basic block to the list of basic blocks.
1477 Ice::CfgNode *installNextBasicBlock() {
1478 Ice::CfgNode *Node = Func->makeNode();
1482 // Returns the Index-th basic block in the list of basic blocks.
1483 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
1484 if (Index >= Func->getNumNodes()) {
1486 raw_string_ostream StrBuf(Buffer);
1487 StrBuf << "Reference to basic block " << Index
1488 << " not found. Must be less than " << Func->getNumNodes();
1489 Error(StrBuf.str());
1492 return Func->getNodes()[Index];
1495 // Returns the Index-th basic block in the list of basic blocks. Assumes
1496 // Index corresponds to a branch instruction. Hence, if the branch references
1497 // the entry block, it also generates a corresponding error.
1498 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
1500 Error("Branch to entry block not allowed");
1502 return getBasicBlock(Index);
1505 // Generate an instruction variable with type Ty.
1506 Ice::Variable *createInstVar(Ice::Type Ty) {
1507 if (Ty == Ice::IceType_void) {
1508 Error("Can't define instruction value using type void");
1509 // Recover since we can't throw an exception.
1510 Ty = Ice::IceType_i32;
1512 return Func->makeVariable(Ty);
1515 // Generates the next available local variable using the given type.
1516 Ice::Variable *getNextInstVar(Ice::Type Ty) {
1517 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
1518 // Before creating one, see if a forwardtyperef has already defined it.
1519 NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
1520 if (LocalIndex < LocalOperands.size()) {
1521 Ice::Operand *Op = LocalOperands[LocalIndex];
1522 if (Op != nullptr) {
1523 if (auto *Var = dyn_cast<Ice::Variable>(Op)) {
1524 if (Var->getType() == Ty) {
1525 ++NextLocalInstIndex;
1530 raw_string_ostream StrBuf(Buffer);
1531 StrBuf << "Illegal forward referenced instruction ("
1532 << NextLocalInstIndex << "): " << *Op;
1533 Error(StrBuf.str());
1534 ++NextLocalInstIndex;
1535 return createInstVar(Ty);
1538 Ice::Variable *Var = createInstVar(Ty);
1539 setOperand(NextLocalInstIndex++, Var);
1543 // Converts a relative index (wrt to BaseIndex) to an absolute value index.
1544 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id,
1545 NaClRelBcIndexSize_t BaseIndex) {
1546 if (BaseIndex < Id) {
1548 raw_string_ostream StrBuf(Buffer);
1549 StrBuf << "Invalid relative value id: " << Id
1550 << " (must be <= " << BaseIndex << ")";
1551 Error(StrBuf.str());
1554 return BaseIndex - Id;
1557 // Sets element Index (in the local operands list) to Op.
1558 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
1560 // Check if simple push works.
1561 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1562 if (LocalIndex == LocalOperands.size()) {
1563 LocalOperands.push_back(Op);
1567 // Must be forward reference, expand vector to accommodate.
1568 if (LocalIndex >= LocalOperands.size()) {
1569 if (LocalIndex > MaxRecordsInBlock) {
1571 raw_string_ostream StrBuf(Buffer);
1572 StrBuf << "Forward reference @" << Index << " too big. Have "
1573 << CachedNumGlobalValueIDs << " globals and function contains "
1574 << NumBytesDefiningFunction << " bytes";
1575 Fatal(StrBuf.str());
1576 // Recover by using index one beyond the maximal allowed.
1577 LocalIndex = MaxRecordsInBlock;
1579 Ice::Utils::reserveAndResize(LocalOperands, LocalIndex + 1);
1582 // If element not defined, set it.
1583 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1584 if (OldOp == nullptr) {
1585 LocalOperands[LocalIndex] = Op;
1589 // See if forward reference matches.
1593 // Error has occurred.
1595 raw_string_ostream StrBuf(Buffer);
1596 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
1597 << " and " << *OldOp;
1598 Error(StrBuf.str());
1599 LocalOperands[LocalIndex] = Op;
1602 // Returns the relative operand (wrt to BaseIndex) referenced by the given
1604 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1605 NaClBcIndexSize_t BaseIndex) {
1606 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1609 // Returns the absolute index of the next value generating instruction.
1610 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; }
1612 // Generates type error message for binary operator Op operating on Type
1614 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
1616 // Validates if integer logical Op, for type OpTy, is valid. Returns true if
1617 // valid. Otherwise generates error message and returns false.
1618 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1619 if (Ice::isIntegerType(OpTy))
1621 reportInvalidBinaryOp(Op, OpTy);
1625 // Validates if integer (or vector of integers) arithmetic Op, for type OpTy,
1626 // is valid. Returns true if valid. Otherwise generates error message and
1628 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1629 if (Ice::isIntegerArithmeticType(OpTy))
1631 reportInvalidBinaryOp(Op, OpTy);
1635 // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if
1636 // valid. Otherwise generates an error message and returns false;
1637 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1638 if (Ice::isFloatingType(OpTy))
1640 reportInvalidBinaryOp(Op, OpTy);
1644 // Checks if the type of operand Op is the valid pointer type, for the given
1645 // InstructionName. Returns true if valid. Otherwise generates an error
1646 // message and returns false.
1647 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
1648 Ice::Type PtrType = Ice::getPointerType();
1649 if (Op->getType() == PtrType)
1652 raw_string_ostream StrBuf(Buffer);
1653 StrBuf << InstructionName << " address not " << PtrType
1654 << ". Found: " << Op->getType();
1655 Error(StrBuf.str());
1659 // Checks if loading/storing a value of type Ty is allowed. Returns true if
1660 // Valid. Otherwise generates an error message and returns false.
1661 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1662 if (isLoadStoreType(Ty))
1665 raw_string_ostream StrBuf(Buffer);
1666 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1667 Error(StrBuf.str());
1671 // Checks if loading/storing a value of type Ty is allowed for the given
1672 // Alignment. Otherwise generates an error message and returns false.
1673 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty,
1674 const char *InstructionName) {
1675 if (!isValidLoadStoreType(Ty, InstructionName))
1677 if (isAllowedAlignment(Alignment, Ty))
1680 raw_string_ostream StrBuf(Buffer);
1681 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1683 Error(StrBuf.str());
1687 // Defines if the given alignment is valid for the given type. Simplified
1688 // version of PNaClABIProps::isAllowedAlignment, based on API's offered for
1690 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const {
1691 return Alignment == typeAlignInBytes(Ty) ||
1692 (Alignment == 1 && !isVectorType(Ty));
1695 // Types of errors that can occur for insertelement and extractelement
1697 enum VectorIndexCheckValue {
1698 VectorIndexNotVector,
1699 VectorIndexNotConstant,
1700 VectorIndexNotInRange,
1705 void dumpVectorIndexCheckValue(raw_ostream &Stream,
1706 VectorIndexCheckValue Value) const {
1707 if (!Ice::BuildDefs::dump())
1710 case VectorIndexNotVector:
1711 Stream << "Vector index on non vector";
1713 case VectorIndexNotConstant:
1714 Stream << "Vector index not integer constant";
1716 case VectorIndexNotInRange:
1717 Stream << "Vector index not in range of vector";
1719 case VectorIndexNotI32:
1720 Stream << "Vector index not of type " << Ice::IceType_i32;
1722 case VectorIndexValid:
1723 Stream << "Valid vector index";
1728 // Returns whether the given vector index (for insertelement and
1729 // extractelement instructions) is valid.
1730 VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec,
1731 const Ice::Operand *Index) const {
1732 Ice::Type VecType = Vec->getType();
1733 if (!Ice::isVectorType(VecType))
1734 return VectorIndexNotVector;
1735 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
1737 return VectorIndexNotConstant;
1738 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
1739 return VectorIndexNotInRange;
1740 if (Index->getType() != Ice::IceType_i32)
1741 return VectorIndexNotI32;
1742 return VectorIndexValid;
1745 // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty,
1746 // and sets Op to the corresponding ICE binary opcode. Returns true if able
1747 // to convert, false otherwise.
1748 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1749 Ice::InstArithmetic::OpKind &Op) {
1753 raw_string_ostream StrBuf(Buffer);
1754 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1755 Error(StrBuf.str());
1756 Op = Ice::InstArithmetic::Add;
1759 case naclbitc::BINOP_ADD:
1760 if (Ice::isIntegerType(Ty)) {
1761 Op = Ice::InstArithmetic::Add;
1762 return isValidIntegerArithOp(Op, Ty);
1764 Op = Ice::InstArithmetic::Fadd;
1765 return isValidFloatingArithOp(Op, Ty);
1767 case naclbitc::BINOP_SUB:
1768 if (Ice::isIntegerType(Ty)) {
1769 Op = Ice::InstArithmetic::Sub;
1770 return isValidIntegerArithOp(Op, Ty);
1772 Op = Ice::InstArithmetic::Fsub;
1773 return isValidFloatingArithOp(Op, Ty);
1775 case naclbitc::BINOP_MUL:
1776 if (Ice::isIntegerType(Ty)) {
1777 Op = Ice::InstArithmetic::Mul;
1778 return isValidIntegerArithOp(Op, Ty);
1780 Op = Ice::InstArithmetic::Fmul;
1781 return isValidFloatingArithOp(Op, Ty);
1783 case naclbitc::BINOP_UDIV:
1784 Op = Ice::InstArithmetic::Udiv;
1785 return isValidIntegerArithOp(Op, Ty);
1786 case naclbitc::BINOP_SDIV:
1787 if (Ice::isIntegerType(Ty)) {
1788 Op = Ice::InstArithmetic::Sdiv;
1789 return isValidIntegerArithOp(Op, Ty);
1791 Op = Ice::InstArithmetic::Fdiv;
1792 return isValidFloatingArithOp(Op, Ty);
1794 case naclbitc::BINOP_UREM:
1795 Op = Ice::InstArithmetic::Urem;
1796 return isValidIntegerArithOp(Op, Ty);
1797 case naclbitc::BINOP_SREM:
1798 if (Ice::isIntegerType(Ty)) {
1799 Op = Ice::InstArithmetic::Srem;
1800 return isValidIntegerArithOp(Op, Ty);
1802 Op = Ice::InstArithmetic::Frem;
1803 return isValidFloatingArithOp(Op, Ty);
1805 case naclbitc::BINOP_SHL:
1806 Op = Ice::InstArithmetic::Shl;
1807 return isValidIntegerArithOp(Op, Ty);
1808 case naclbitc::BINOP_LSHR:
1809 Op = Ice::InstArithmetic::Lshr;
1810 return isValidIntegerArithOp(Op, Ty);
1811 case naclbitc::BINOP_ASHR:
1812 Op = Ice::InstArithmetic::Ashr;
1813 return isValidIntegerArithOp(Op, Ty);
1814 case naclbitc::BINOP_AND:
1815 Op = Ice::InstArithmetic::And;
1816 return isValidIntegerLogicalOp(Op, Ty);
1817 case naclbitc::BINOP_OR:
1818 Op = Ice::InstArithmetic::Or;
1819 return isValidIntegerLogicalOp(Op, Ty);
1820 case naclbitc::BINOP_XOR:
1821 Op = Ice::InstArithmetic::Xor;
1822 return isValidIntegerLogicalOp(Op, Ty);
1826 /// Simplifies out vector types from Type1 and Type2, if both are vectors of
1827 /// the same size. Returns true iff both are vectors of the same size, or are
1828 /// both scalar types.
1829 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
1830 bool IsType1Vector = isVectorType(Type1);
1831 bool IsType2Vector = isVectorType(Type2);
1832 if (IsType1Vector != IsType2Vector)
1836 if (typeNumElements(Type1) != typeNumElements(Type2))
1838 Type1 = typeElementType(Type1);
1839 Type2 = typeElementType(Type2);
1843 /// Returns true iff an integer truncation from SourceType to TargetType is
1845 static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1846 return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) &&
1847 simplifyOutCommonVectorType(SourceType, TargetType) &&
1848 getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType);
1851 /// Returns true iff a floating type truncation from SourceType to TargetType
1853 static bool isFloatTruncCastValid(Ice::Type SourceType,
1854 Ice::Type TargetType) {
1855 return simplifyOutCommonVectorType(SourceType, TargetType) &&
1856 SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32;
1859 /// Returns true iff an integer extension from SourceType to TargetType is
1861 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1862 return isIntTruncCastValid(TargetType, SourceType);
1865 /// Returns true iff a floating type extension from SourceType to TargetType
1867 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1868 return isFloatTruncCastValid(TargetType, SourceType);
1871 /// Returns true iff a cast from floating type SourceType to integer type
1872 /// TargetType is valid.
1873 static bool isFloatToIntCastValid(Ice::Type SourceType,
1874 Ice::Type TargetType) {
1875 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType)))
1877 bool IsSourceVector = isVectorType(SourceType);
1878 bool IsTargetVector = isVectorType(TargetType);
1879 if (IsSourceVector != IsTargetVector)
1881 if (IsSourceVector) {
1882 return typeNumElements(SourceType) == typeNumElements(TargetType);
1887 /// Returns true iff a cast from integer type SourceType to floating type
1888 /// TargetType is valid.
1889 static bool isIntToFloatCastValid(Ice::Type SourceType,
1890 Ice::Type TargetType) {
1891 return isFloatToIntCastValid(TargetType, SourceType);
1894 /// Returns the number of bits used to model type Ty when defining the bitcast
1896 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) {
1897 if (Ice::isVectorType(Ty))
1898 return Ice::typeNumElements(Ty) *
1899 bitcastSizeInBits(Ice::typeElementType(Ty));
1900 if (Ty == Ice::IceType_i1)
1902 return Ice::typeWidthInBytes(Ty) * CHAR_BIT;
1905 /// Returns true iff a bitcast from SourceType to TargetType is allowed.
1906 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) {
1907 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType);
1910 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for
1911 /// converting SourceType to TargetType. Updates CastKind to the corresponding
1912 /// instruction cast opcode. Also generates an error message when this
1913 /// function returns false.
1914 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType,
1915 Ice::Type TargetType,
1916 Ice::InstCast::OpKind &CastKind) {
1921 raw_string_ostream StrBuf(Buffer);
1922 StrBuf << "Cast opcode " << Opcode << " not understood.\n";
1923 Error(StrBuf.str());
1924 CastKind = Ice::InstCast::Bitcast;
1927 case naclbitc::CAST_TRUNC:
1928 CastKind = Ice::InstCast::Trunc;
1929 Result = isIntTruncCastValid(SourceType, TargetType);
1931 case naclbitc::CAST_ZEXT:
1932 CastKind = Ice::InstCast::Zext;
1933 Result = isIntExtCastValid(SourceType, TargetType);
1935 case naclbitc::CAST_SEXT:
1936 CastKind = Ice::InstCast::Sext;
1937 Result = isIntExtCastValid(SourceType, TargetType);
1939 case naclbitc::CAST_FPTOUI:
1940 CastKind = Ice::InstCast::Fptoui;
1941 Result = isFloatToIntCastValid(SourceType, TargetType);
1943 case naclbitc::CAST_FPTOSI:
1944 CastKind = Ice::InstCast::Fptosi;
1945 Result = isFloatToIntCastValid(SourceType, TargetType);
1947 case naclbitc::CAST_UITOFP:
1948 CastKind = Ice::InstCast::Uitofp;
1949 Result = isIntToFloatCastValid(SourceType, TargetType);
1951 case naclbitc::CAST_SITOFP:
1952 CastKind = Ice::InstCast::Sitofp;
1953 Result = isIntToFloatCastValid(SourceType, TargetType);
1955 case naclbitc::CAST_FPTRUNC:
1956 CastKind = Ice::InstCast::Fptrunc;
1957 Result = isFloatTruncCastValid(SourceType, TargetType);
1959 case naclbitc::CAST_FPEXT:
1960 CastKind = Ice::InstCast::Fpext;
1961 Result = isFloatExtCastValid(SourceType, TargetType);
1963 case naclbitc::CAST_BITCAST:
1964 CastKind = Ice::InstCast::Bitcast;
1965 Result = isBitcastValid(SourceType, TargetType);
1970 raw_string_ostream StrBuf(Buffer);
1971 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " "
1972 << SourceType << " to " << TargetType;
1973 Error(StrBuf.str());
1978 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true
1979 // if able to convert, false otherwise.
1980 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1981 Ice::InstIcmp::ICond &Cond) const {
1983 case naclbitc::ICMP_EQ:
1984 Cond = Ice::InstIcmp::Eq;
1986 case naclbitc::ICMP_NE:
1987 Cond = Ice::InstIcmp::Ne;
1989 case naclbitc::ICMP_UGT:
1990 Cond = Ice::InstIcmp::Ugt;
1992 case naclbitc::ICMP_UGE:
1993 Cond = Ice::InstIcmp::Uge;
1995 case naclbitc::ICMP_ULT:
1996 Cond = Ice::InstIcmp::Ult;
1998 case naclbitc::ICMP_ULE:
1999 Cond = Ice::InstIcmp::Ule;
2001 case naclbitc::ICMP_SGT:
2002 Cond = Ice::InstIcmp::Sgt;
2004 case naclbitc::ICMP_SGE:
2005 Cond = Ice::InstIcmp::Sge;
2007 case naclbitc::ICMP_SLT:
2008 Cond = Ice::InstIcmp::Slt;
2010 case naclbitc::ICMP_SLE:
2011 Cond = Ice::InstIcmp::Sle;
2014 // Make sure Cond is always initialized.
2015 Cond = static_cast<Ice::InstIcmp::ICond>(0);
2020 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true
2021 // if able to convert, false otherwise.
2022 bool convertNaClBitcFCompOpToIce(uint64_t Op,
2023 Ice::InstFcmp::FCond &Cond) const {
2025 case naclbitc::FCMP_FALSE:
2026 Cond = Ice::InstFcmp::False;
2028 case naclbitc::FCMP_OEQ:
2029 Cond = Ice::InstFcmp::Oeq;
2031 case naclbitc::FCMP_OGT:
2032 Cond = Ice::InstFcmp::Ogt;
2034 case naclbitc::FCMP_OGE:
2035 Cond = Ice::InstFcmp::Oge;
2037 case naclbitc::FCMP_OLT:
2038 Cond = Ice::InstFcmp::Olt;
2040 case naclbitc::FCMP_OLE:
2041 Cond = Ice::InstFcmp::Ole;
2043 case naclbitc::FCMP_ONE:
2044 Cond = Ice::InstFcmp::One;
2046 case naclbitc::FCMP_ORD:
2047 Cond = Ice::InstFcmp::Ord;
2049 case naclbitc::FCMP_UNO:
2050 Cond = Ice::InstFcmp::Uno;
2052 case naclbitc::FCMP_UEQ:
2053 Cond = Ice::InstFcmp::Ueq;
2055 case naclbitc::FCMP_UGT:
2056 Cond = Ice::InstFcmp::Ugt;
2058 case naclbitc::FCMP_UGE:
2059 Cond = Ice::InstFcmp::Uge;
2061 case naclbitc::FCMP_ULT:
2062 Cond = Ice::InstFcmp::Ult;
2064 case naclbitc::FCMP_ULE:
2065 Cond = Ice::InstFcmp::Ule;
2067 case naclbitc::FCMP_UNE:
2068 Cond = Ice::InstFcmp::Une;
2070 case naclbitc::FCMP_TRUE:
2071 Cond = Ice::InstFcmp::True;
2074 // Make sure Cond is always initialized.
2075 Cond = static_cast<Ice::InstFcmp::FCond>(0);
2080 // Creates an error instruction, generating a value of type Ty, and adds a
2081 // placeholder so that instruction indices line up. Some instructions, such
2082 // as a call, will not generate a value if the return type is void. In such
2083 // cases, a placeholder value for the badly formed instruction is not needed.
2084 // Hence, if Ty is void, an error instruction is not appended.
2085 void appendErrorInstruction(Ice::Type Ty) {
2086 // Note: we don't worry about downstream translation errors because the
2087 // function will not be translated if any errors occur.
2088 if (Ty == Ice::IceType_void)
2090 Ice::Variable *Var = getNextInstVar(Ty);
2091 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
2094 Ice::Operand *reportGetOperandUndefined(NaClBcIndexSize_t Index) {
2096 raw_string_ostream StrBuf(Buffer);
2097 StrBuf << "Value index " << Index << " not defined!";
2098 Error(StrBuf.str());
2099 // Recover and return some value.
2100 if (!LocalOperands.empty())
2101 return LocalOperands.front();
2102 return Context->getGlobalConstantByID(0);
2105 void verifyCallArgTypeMatches(Ice::FunctionDeclaration *Fcn, Ice::SizeT Index,
2106 Ice::Type ArgType, Ice::Type ParamType) {
2107 if (ArgType != ParamType) {
2109 raw_string_ostream StrBuf(Buffer);
2110 StrBuf << "Argument " << (Index + 1) << " of " << printName(Fcn)
2111 << " expects " << ParamType << ". Found: " << ArgType;
2112 Error(StrBuf.str());
2116 const std::string printName(Ice::FunctionDeclaration *Fcn) {
2118 return Fcn->getName().toString();
2123 void FunctionParser::ExitBlock() {
2124 // Check if the last instruction in the function was terminating.
2125 if (!InstIsTerminating) {
2126 Error("Last instruction in function not terminator");
2127 // Recover by inserting an unreachable instruction.
2128 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2131 if (CurrentBbIndex != DeclaredNumberBbs) {
2133 raw_string_ostream StrBuf(Buffer);
2134 StrBuf << "Function declared " << DeclaredNumberBbs
2135 << " basic blocks, but defined " << CurrentBbIndex << ".";
2136 Error(StrBuf.str());
2138 // Before translating, check for blocks without instructions, and insert
2139 // unreachable. This shouldn't happen, but be safe.
2141 for (Ice::CfgNode *Node : Func->getNodes()) {
2142 if (Node->getInsts().empty()) {
2144 raw_string_ostream StrBuf(Buffer);
2145 StrBuf << "Basic block " << Index << " contains no instructions";
2146 Error(StrBuf.str());
2147 Node->appendInst(Ice::InstUnreachable::create(Func.get()));
2151 Func->computeInOutEdges();
2154 void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
2157 raw_string_ostream StrBuf(Buffer);
2158 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
2159 << ". Found " << OpTy;
2160 Error(StrBuf.str());
2163 void FunctionParser::ProcessRecord() {
2164 // Note: To better separate parse/IR generation times, when IR generation is
2165 // disabled we do the following:
2166 // 1) Delay exiting until after we extract operands.
2167 // 2) return before we access operands, since all operands will be a nullptr.
2168 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2169 if (InstIsTerminating) {
2170 InstIsTerminating = false;
2172 CurrentNode = getBasicBlock(CurrentBbIndex);
2174 // The base index for relative indexing.
2175 NaClBcIndexSize_t BaseIndex = getNextInstIndex();
2176 switch (Record.GetCode()) {
2177 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
2178 // DECLAREBLOCKS: [n]
2179 if (!isValidRecordSize(1, "count"))
2181 if (DeclaredNumberBbs > 0) {
2182 Error("Duplicate function block count record");
2186 // Check for bad large sizes, since they can make ridiculous memory
2187 // requests and hang the user for large amounts of time.
2188 uint64_t NumBbs = Values[0];
2189 if (NumBbs > MaxRecordsInBlock) {
2191 raw_string_ostream StrBuf(Buffer);
2192 StrBuf << "Function defines " << NumBbs
2193 << " basic blocks, which is too big for a function containing "
2194 << NumBytesDefiningFunction << " bytes";
2195 Error(StrBuf.str());
2196 NumBbs = MaxRecordsInBlock;
2200 Error("Functions must contain at least one basic block.");
2204 DeclaredNumberBbs = NumBbs;
2205 // Install the basic blocks, skipping bb0 which was created in the
2207 for (size_t i = 1; i < NumBbs; ++i)
2208 installNextBasicBlock();
2211 case naclbitc::FUNC_CODE_INST_BINOP: {
2212 // Note: Old bitcode files may have an additional 'flags' operand, which is
2215 // BINOP: [opval, opval, opcode, [flags]]
2217 if (!isValidRecordSizeInRange(3, 4, "binop"))
2219 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2220 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
2221 Ice::Type Type1 = Op1->getType();
2222 Ice::Type Type2 = Op2->getType();
2223 if (Type1 != Type2) {
2225 raw_string_ostream StrBuf(Buffer);
2226 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
2227 Error(StrBuf.str());
2228 appendErrorInstruction(Type1);
2232 Ice::InstArithmetic::OpKind Opcode;
2233 if (!convertBinopOpcode(Values[2], Type1, Opcode)) {
2234 appendErrorInstruction(Type1);
2237 CurrentNode->appendInst(Ice::InstArithmetic::create(
2238 Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2));
2241 case naclbitc::FUNC_CODE_INST_CAST: {
2242 // CAST: [opval, destty, castopc]
2243 if (!isValidRecordSize(3, "cast"))
2245 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
2246 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
2247 Ice::InstCast::OpKind CastKind;
2248 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
2249 appendErrorInstruction(CastType);
2252 CurrentNode->appendInst(Ice::InstCast::create(
2253 Func.get(), CastKind, getNextInstVar(CastType), Src));
2256 case naclbitc::FUNC_CODE_INST_VSELECT: {
2257 // VSELECT: [opval, opval, pred]
2258 if (!isValidRecordSize(3, "select"))
2260 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
2261 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
2262 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
2263 Ice::Type ThenType = ThenVal->getType();
2264 Ice::Type ElseType = ElseVal->getType();
2265 if (ThenType != ElseType) {
2267 raw_string_ostream StrBuf(Buffer);
2268 StrBuf << "Select operands not same type. Found " << ThenType << " and "
2270 Error(StrBuf.str());
2271 appendErrorInstruction(ThenType);
2274 Ice::Type CondType = CondVal->getType();
2275 if (isVectorType(CondType)) {
2276 if (!isVectorType(ThenType) ||
2277 typeElementType(CondType) != Ice::IceType_i1 ||
2278 typeNumElements(ThenType) != typeNumElements(CondType)) {
2280 raw_string_ostream StrBuf(Buffer);
2281 StrBuf << "Select condition type " << CondType
2282 << " not allowed for values of type " << ThenType;
2283 Error(StrBuf.str());
2284 appendErrorInstruction(ThenType);
2287 } else if (CondVal->getType() != Ice::IceType_i1) {
2289 raw_string_ostream StrBuf(Buffer);
2290 StrBuf << "Select condition " << CondVal
2291 << " not type i1. Found: " << CondVal->getType();
2292 Error(StrBuf.str());
2293 appendErrorInstruction(ThenType);
2296 CurrentNode->appendInst(Ice::InstSelect::create(
2297 Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
2300 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
2301 // EXTRACTELT: [opval, opval]
2302 if (!isValidRecordSize(2, "extract element"))
2304 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
2305 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
2306 Ice::Type VecType = Vec->getType();
2307 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2308 if (IndexCheckValue != VectorIndexValid) {
2310 raw_string_ostream StrBuf(Buffer);
2311 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2312 StrBuf << ": extractelement " << VecType << " " << *Vec << ", "
2313 << Index->getType() << " " << *Index;
2314 Error(StrBuf.str());
2315 appendErrorInstruction(VecType);
2318 CurrentNode->appendInst(Ice::InstExtractElement::create(
2319 Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index));
2322 case naclbitc::FUNC_CODE_INST_INSERTELT: {
2323 // INSERTELT: [opval, opval, opval]
2324 if (!isValidRecordSize(3, "insert element"))
2326 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
2327 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
2328 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
2329 Ice::Type VecType = Vec->getType();
2330 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2331 if (IndexCheckValue != VectorIndexValid) {
2333 raw_string_ostream StrBuf(Buffer);
2334 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2335 StrBuf << ": insertelement " << VecType << " " << *Vec << ", "
2336 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " "
2338 Error(StrBuf.str());
2339 appendErrorInstruction(Elt->getType());
2342 if (Ice::typeElementType(VecType) != Elt->getType()) {
2344 raw_string_ostream StrBuf(Buffer);
2345 StrBuf << "Insertelement: Element type "
2346 << Ice::typeString(Elt->getType()) << " doesn't match vector type "
2347 << Ice::typeString(VecType);
2348 Error(StrBuf.str());
2349 appendErrorInstruction(Elt->getType());
2352 CurrentNode->appendInst(Ice::InstInsertElement::create(
2353 Func.get(), getNextInstVar(VecType), Vec, Elt, Index));
2356 case naclbitc::FUNC_CODE_INST_CMP2: {
2357 // CMP2: [opval, opval, pred]
2358 if (!isValidRecordSize(3, "compare"))
2360 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2361 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
2362 Ice::Type Op1Type = Op1->getType();
2363 Ice::Type Op2Type = Op2->getType();
2364 Ice::Type DestType = getCompareResultType(Op1Type);
2365 if (Op1Type != Op2Type) {
2367 raw_string_ostream StrBuf(Buffer);
2368 StrBuf << "Compare argument types differ: " << Op1Type << " and "
2370 Error(StrBuf.str());
2371 appendErrorInstruction(DestType);
2374 if (DestType == Ice::IceType_void) {
2376 raw_string_ostream StrBuf(Buffer);
2377 StrBuf << "Compare not defined for type " << Op1Type;
2378 Error(StrBuf.str());
2381 Ice::Variable *Dest = getNextInstVar(DestType);
2382 if (isIntegerType(Op1Type)) {
2383 Ice::InstIcmp::ICond Cond;
2384 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
2386 raw_string_ostream StrBuf(Buffer);
2387 StrBuf << "Compare record contains unknown integer predicate index: "
2389 Error(StrBuf.str());
2390 appendErrorInstruction(DestType);
2392 CurrentNode->appendInst(
2393 Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2));
2394 } else if (isFloatingType(Op1Type)) {
2395 Ice::InstFcmp::FCond Cond;
2396 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
2398 raw_string_ostream StrBuf(Buffer);
2399 StrBuf << "Compare record contains unknown float predicate index: "
2401 Error(StrBuf.str());
2402 appendErrorInstruction(DestType);
2404 CurrentNode->appendInst(
2405 Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2));
2407 // Not sure this can happen, but be safe.
2409 raw_string_ostream StrBuf(Buffer);
2410 StrBuf << "Compare on type not understood: " << Op1Type;
2411 Error(StrBuf.str());
2412 appendErrorInstruction(DestType);
2417 case naclbitc::FUNC_CODE_INST_RET: {
2419 InstIsTerminating = true;
2420 if (!isValidRecordSizeInRange(0, 1, "return"))
2422 if (Values.empty()) {
2423 CurrentNode->appendInst(Ice::InstRet::create(Func.get()));
2425 Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex);
2426 CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal));
2430 case naclbitc::FUNC_CODE_INST_BR: {
2431 InstIsTerminating = true;
2432 if (Values.size() == 1) {
2434 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
2435 if (Block == nullptr)
2437 CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block));
2439 // BR: [bb#, bb#, opval]
2440 if (!isValidRecordSize(3, "branch"))
2442 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
2443 if (Cond->getType() != Ice::IceType_i1) {
2445 raw_string_ostream StrBuf(Buffer);
2446 StrBuf << "Branch condition " << *Cond
2447 << " not i1. Found: " << Cond->getType();
2448 Error(StrBuf.str());
2451 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
2452 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
2453 if (ThenBlock == nullptr || ElseBlock == nullptr)
2455 CurrentNode->appendInst(
2456 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock));
2460 case naclbitc::FUNC_CODE_INST_SWITCH: {
2461 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
2462 // where Case = [1, 1, Value, BbIndex].
2464 // Note: Unlike most instructions, we don't infer the type of Cond, but
2465 // provide it as a separate field. There are also unnecessary data fields
2466 // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because
2467 // the bitcode format was already frozen when the problem was noticed.
2468 InstIsTerminating = true;
2469 if (!isValidRecordSizeAtLeast(4, "switch"))
2472 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
2473 if (!Ice::isScalarIntegerType(CondTy)) {
2475 raw_string_ostream StrBuf(Buffer);
2476 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy;
2477 Error(StrBuf.str());
2480 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy);
2481 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex);
2483 if (CondTy != Cond->getType()) {
2485 raw_string_ostream StrBuf(Buffer);
2486 StrBuf << "Case condition expects type " << CondTy
2487 << ". Found: " << Cond->getType();
2488 Error(StrBuf.str());
2491 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]);
2492 if (DefaultLabel == nullptr)
2494 uint64_t NumCasesRaw = Values[3];
2495 if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) {
2497 raw_string_ostream StrBuf(Buffer);
2498 StrBuf << "Too many cases specified in switch: " << NumCasesRaw;
2499 Error(StrBuf.str());
2500 NumCasesRaw = std::numeric_limits<uint32_t>::max();
2502 uint32_t NumCases = NumCasesRaw;
2504 // Now recognize each of the cases.
2505 if (!isValidRecordSize(4 + NumCases * 4, "switch"))
2507 std::unique_ptr<Ice::InstSwitch> Switch(
2508 Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel));
2509 unsigned ValCaseIndex = 4; // index to beginning of case entry.
2510 for (uint32_t CaseIndex = 0; CaseIndex < NumCases;
2511 ++CaseIndex, ValCaseIndex += 4) {
2512 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) {
2514 raw_string_ostream StrBuf(Buffer);
2515 StrBuf << "Sequence [1, 1, value, label] expected for case entry "
2516 << "in switch record. (at index" << ValCaseIndex << ")";
2517 Error(StrBuf.str());
2520 BitcodeInt Value(BitWidth,
2521 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]));
2522 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]);
2523 if (Label == nullptr)
2525 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label);
2527 CurrentNode->appendInst(Switch.release());
2530 case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
2532 InstIsTerminating = true;
2533 if (!isValidRecordSize(0, "unreachable"))
2535 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2538 case naclbitc::FUNC_CODE_INST_PHI: {
2539 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
2540 if (!isValidRecordSizeAtLeast(3, "phi"))
2542 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
2543 if ((Values.size() & 0x1) == 0) {
2544 // Not an odd number of values.
2546 raw_string_ostream StrBuf(Buffer);
2547 StrBuf << "function block phi record size not valid: " << Values.size();
2548 Error(StrBuf.str());
2549 appendErrorInstruction(Ty);
2552 if (Ty == Ice::IceType_void) {
2553 Error("Phi record using type void not allowed");
2556 Ice::Variable *Dest = getNextInstVar(Ty);
2558 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest);
2559 for (size_t i = 1; i < Values.size(); i += 2) {
2561 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
2562 if (Op->getType() != Ty) {
2564 raw_string_ostream StrBuf(Buffer);
2565 StrBuf << "Value " << *Op << " not type " << Ty
2566 << " in phi instruction. Found: " << Op->getType();
2567 Error(StrBuf.str());
2568 appendErrorInstruction(Ty);
2571 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
2573 CurrentNode->appendInst(Phi);
2576 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2577 // ALLOCA: [Size, align]
2578 if (!isValidRecordSize(2, "alloca"))
2580 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
2581 uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]);
2582 Ice::Type PtrTy = Ice::getPointerType();
2583 if (ByteCount->getType() != Ice::IceType_i32) {
2585 raw_string_ostream StrBuf(Buffer);
2586 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
2587 Error(StrBuf.str());
2588 appendErrorInstruction(PtrTy);
2591 CurrentNode->appendInst(Ice::InstAlloca::create(
2592 Func.get(), getNextInstVar(PtrTy), ByteCount, Alignment));
2595 case naclbitc::FUNC_CODE_INST_LOAD: {
2596 // LOAD: [address, align, ty]
2597 if (!isValidRecordSize(3, "load"))
2599 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
2600 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
2601 uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]);
2602 if (!isValidPointerType(Address, "Load")) {
2603 appendErrorInstruction(Ty);
2606 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) {
2607 appendErrorInstruction(Ty);
2610 CurrentNode->appendInst(Ice::InstLoad::create(
2611 Func.get(), getNextInstVar(Ty), Address, Alignment));
2614 case naclbitc::FUNC_CODE_INST_STORE: {
2615 // STORE: [address, value, align]
2616 if (!isValidRecordSize(3, "store"))
2618 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
2619 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
2620 uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]);
2621 if (!isValidPointerType(Address, "Store"))
2623 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
2625 CurrentNode->appendInst(
2626 Ice::InstStore::create(Func.get(), Value, Address, Alignment));
2629 case naclbitc::FUNC_CODE_INST_CALL:
2630 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
2631 // CALL: [cc, fnid, arg0, arg1...]
2632 // CALL_INDIRECT: [cc, fn, returnty, args...]
2634 // Note: The difference between CALL and CALL_INDIRECT is that CALL has a
2635 // reference to an explicit function declaration, while the CALL_INDIRECT
2636 // is just an address. For CALL, we can infer the return type by looking up
2637 // the type signature associated with the function declaration. For
2638 // CALL_INDIRECT we can only infer the type signature via argument types,
2639 // and the corresponding return type stored in CALL_INDIRECT record.
2640 Ice::SizeT ParamsStartIndex = 2;
2641 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
2642 if (!isValidRecordSizeAtLeast(2, "call"))
2645 if (!isValidRecordSizeAtLeast(3, "call indirect"))
2647 ParamsStartIndex = 3;
2650 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
2651 Ice::Operand *Callee = getOperand(CalleeIndex);
2653 // Pull out signature/return type of call (if possible).
2654 Ice::FunctionDeclaration *Fcn = nullptr;
2655 const Ice::FuncSigType *Signature = nullptr;
2656 Ice::Type ReturnType = Ice::IceType_void;
2657 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
2658 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
2659 Fcn = Context->getFunctionByID(CalleeIndex);
2660 Signature = &Fcn->getSignature();
2661 ReturnType = Signature->getReturnType();
2662 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
2663 if (NumParams != Signature->getNumArgs()) {
2665 raw_string_ostream StrBuf(Buffer);
2666 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2667 << " parameters. Signature expects: " << Signature->getNumArgs();
2668 Error(StrBuf.str());
2669 if (ReturnType != Ice::IceType_void)
2670 setNextLocalInstIndex(nullptr);
2674 // Check if this direct call is to an Intrinsic (starts with "llvm.")
2675 IntrinsicInfo = Fcn->getIntrinsicInfo(getTranslator().getContext());
2676 if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) {
2678 raw_string_ostream StrBuf(Buffer);
2679 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2680 << " parameters. Intrinsic expects: " << Signature->getNumArgs();
2681 Error(StrBuf.str());
2682 if (ReturnType != Ice::IceType_void)
2683 setNextLocalInstIndex(nullptr);
2686 } else { // Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT
2687 // There is no signature. Assume defined by parameter types.
2688 ReturnType = Context->getSimpleTypeByID(Values[2]);
2689 if (Callee != nullptr)
2690 isValidPointerType(Callee, "Call indirect");
2693 if (Callee == nullptr)
2696 // Extract out the the call parameters.
2697 SmallVector<Ice::Operand *, 8> Params;
2698 for (Ice::SizeT Index = ParamsStartIndex; Index < Values.size(); ++Index) {
2699 Ice::Operand *Op = getRelativeOperand(Values[Index], BaseIndex);
2700 if (Op == nullptr) {
2702 raw_string_ostream StrBuf(Buffer);
2703 StrBuf << "Parameter " << (Index - ParamsStartIndex + 1) << " of "
2704 << printName(Fcn) << " is not defined";
2705 Error(StrBuf.str());
2706 if (ReturnType != Ice::IceType_void)
2707 setNextLocalInstIndex(nullptr);
2710 Params.push_back(Op);
2713 // Check return type.
2714 if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) {
2716 raw_string_ostream StrBuf(Buffer);
2717 StrBuf << "Return type of " << printName(Fcn)
2718 << " is invalid: " << ReturnType;
2719 Error(StrBuf.str());
2720 ReturnType = Ice::IceType_i32;
2723 // Type check call parameters.
2724 for (Ice::SizeT Index = 0; Index < Params.size(); ++Index) {
2725 Ice::Operand *Op = Params[Index];
2726 Ice::Type OpType = Op->getType();
2728 verifyCallArgTypeMatches(Fcn, Index, OpType,
2729 Signature->getArgType(Index));
2730 else if (!isCallParameterType(OpType)) {
2732 raw_string_ostream StrBuf(Buffer);
2733 StrBuf << "Argument " << *Op << " of " << printName(Fcn)
2734 << " has invalid type: " << Op->getType();
2735 Error(StrBuf.str());
2736 appendErrorInstruction(ReturnType);
2741 // Extract call information.
2742 uint64_t CCInfo = Values[0];
2743 CallingConv::ID CallingConv;
2744 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
2746 raw_string_ostream StrBuf(Buffer);
2747 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
2748 << " not understood.";
2749 Error(StrBuf.str());
2750 appendErrorInstruction(ReturnType);
2753 const bool IsTailCall = (CCInfo & 1);
2755 // Create the call instruction.
2756 Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
2758 : getNextInstVar(ReturnType);
2759 std::unique_ptr<Ice::InstCall> Instr;
2760 if (IntrinsicInfo) {
2761 Instr.reset(Ice::InstIntrinsicCall::create(
2762 Func.get(), Params.size(), Dest, Callee, IntrinsicInfo->Info));
2764 Instr.reset(Ice::InstCall::create(Func.get(), Params.size(), Dest, Callee,
2767 for (Ice::Operand *Param : Params)
2768 Instr->addArg(Param);
2769 CurrentNode->appendInst(Instr.release());
2772 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
2773 // FORWARDTYPEREF: [opval, ty]
2774 if (!isValidRecordSize(2, "forward type ref"))
2776 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
2777 setOperand(Values[0], createInstVar(OpType));
2781 // Generate error message!
2782 BlockParserBaseClass::ProcessRecord();
2787 /// Parses constants within a function block.
2788 class ConstantsParser final : public BlockParserBaseClass {
2789 ConstantsParser() = delete;
2790 ConstantsParser(const ConstantsParser &) = delete;
2791 ConstantsParser &operator=(const ConstantsParser &) = delete;
2794 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
2795 : BlockParserBaseClass(BlockID, FuncParser),
2796 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()),
2797 FuncParser(FuncParser) {}
2799 ~ConstantsParser() override = default;
2801 const char *getBlockName() const override { return "constants"; }
2804 Ice::TimerMarker Timer;
2805 // The parser of the function block this constants block appears in.
2806 FunctionParser *FuncParser;
2807 // The type to use for succeeding constants.
2808 Ice::Type NextConstantType = Ice::IceType_void;
2810 void ProcessRecord() override;
2812 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
2814 // Returns true if the type to use for succeeding constants is defined. If
2815 // false, also generates an error message.
2816 bool isValidNextConstantType() {
2817 if (NextConstantType != Ice::IceType_void)
2819 Error("Constant record not preceded by set type record");
2824 void ConstantsParser::ProcessRecord() {
2825 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2826 switch (Record.GetCode()) {
2827 case naclbitc::CST_CODE_SETTYPE: {
2828 // SETTYPE: [typeid]
2829 if (!isValidRecordSize(1, "set type"))
2831 NextConstantType = Context->getSimpleTypeByID(Values[0]);
2832 if (NextConstantType == Ice::IceType_void)
2833 Error("constants block set type not allowed for void type");
2836 case naclbitc::CST_CODE_UNDEF: {
2838 if (!isValidRecordSize(0, "undef"))
2840 if (!isValidNextConstantType())
2842 FuncParser->setNextConstantID(
2843 getContext()->getConstantUndef(NextConstantType));
2846 case naclbitc::CST_CODE_INTEGER: {
2847 // INTEGER: [intval]
2848 if (!isValidRecordSize(1, "integer"))
2850 if (!isValidNextConstantType())
2852 if (Ice::isScalarIntegerType(NextConstantType)) {
2853 BitcodeInt Value(Ice::getScalarIntBitWidth(NextConstantType),
2854 NaClDecodeSignRotatedValue(Values[0]));
2855 if (Ice::Constant *C = getContext()->getConstantInt(
2856 NextConstantType, Value.getSExtValue())) {
2857 FuncParser->setNextConstantID(C);
2862 raw_string_ostream StrBuf(Buffer);
2863 StrBuf << "constant block integer record for non-integer type "
2864 << NextConstantType;
2865 Error(StrBuf.str());
2868 case naclbitc::CST_CODE_FLOAT: {
2870 if (!isValidRecordSize(1, "float"))
2872 if (!isValidNextConstantType())
2874 switch (NextConstantType) {
2875 case Ice::IceType_f32: {
2876 const BitcodeInt Value(32, static_cast<uint32_t>(Values[0]));
2877 float FpValue = Value.convertToFp<int32_t, float>();
2878 FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue));
2881 case Ice::IceType_f64: {
2882 const BitcodeInt Value(64, Values[0]);
2883 double FpValue = Value.convertToFp<uint64_t, double>();
2884 FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue));
2889 raw_string_ostream StrBuf(Buffer);
2890 StrBuf << "constant block float record for non-floating type "
2891 << NextConstantType;
2892 Error(StrBuf.str());
2898 // Generate error message!
2899 BlockParserBaseClass::ProcessRecord();
2904 // Parses valuesymtab blocks appearing in a function block.
2905 class FunctionValuesymtabParser final : public ValuesymtabParser {
2906 FunctionValuesymtabParser() = delete;
2907 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
2908 void operator=(const FunctionValuesymtabParser &) = delete;
2911 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser)
2912 : ValuesymtabParser(BlockID, EnclosingParser),
2913 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2914 getTranslator().getContext()) {}
2917 Ice::TimerMarker Timer;
2918 // Returns the enclosing function parser.
2919 FunctionParser *getFunctionParser() const {
2920 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2923 const char *getTableKind() const override { return "Function"; }
2925 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
2926 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
2928 // Reports that the assignment of Name to the value associated with index is
2929 // not possible, for the given Context.
2930 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
2933 raw_string_ostream StrBuf(Buffer);
2934 StrBuf << "Function-local " << Context << " name '" << Name
2935 << "' can't be associated with index " << Index;
2936 Error(StrBuf.str());
2940 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2942 // Note: We check when Index is too small, so that we can error recover
2943 // (FP->getOperand will create fatal error).
2944 if (Index < getFunctionParser()->getNumGlobalIDs()) {
2945 reportUnableToAssign("Global value", Index, Name);
2948 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
2949 if (auto *V = dyn_cast<Ice::Variable>(Op)) {
2950 if (Ice::BuildDefs::dump()) {
2951 std::string Nm(Name.data(), Name.size());
2952 V->setName(getFunctionParser()->getFunc(), Nm);
2955 reportUnableToAssign("Local value", Index, Name);
2959 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2961 if (!Ice::BuildDefs::dump())
2963 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
2964 reportUnableToAssign("Basic block", Index, Name);
2967 std::string Nm(Name.data(), Name.size());
2968 if (Ice::BuildDefs::dump())
2969 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
2972 bool FunctionParser::ParseBlock(unsigned BlockID) {
2974 constexpr bool PNaClAllowLocalSymbolTables = true;
2975 #endif // !PNACL_LLVM
2977 case naclbitc::CONSTANTS_BLOCK_ID: {
2978 ConstantsParser Parser(BlockID, this);
2979 return Parser.ParseThisBlock();
2981 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2982 if (PNaClAllowLocalSymbolTables) {
2983 FunctionValuesymtabParser Parser(BlockID, this);
2984 return Parser.ParseThisBlock();
2991 return BlockParserBaseClass::ParseBlock(BlockID);
2994 /// Parses the module block in the bitcode file.
2995 class ModuleParser final : public BlockParserBaseClass {
2996 ModuleParser() = delete;
2997 ModuleParser(const ModuleParser &) = delete;
2998 ModuleParser &operator=(const ModuleParser &) = delete;
3001 ModuleParser(unsigned BlockID, TopLevelParser *Context)
3002 : BlockParserBaseClass(BlockID, Context),
3003 Timer(Ice::TimerStack::TT_parseModule,
3004 Context->getTranslator().getContext()),
3005 IsParseParallel(Ice::getFlags().isParseParallel()) {}
3006 ~ModuleParser() override = default;
3007 const char *getBlockName() const override { return "module"; }
3008 NaClBitstreamCursor &getCursor() const { return Record.GetCursor(); }
3011 Ice::TimerMarker Timer;
3012 // True if we have already installed names for unnamed global declarations,
3013 // and have generated global constant initializers.
3014 bool GlobalDeclarationNamesAndInitializersInstalled = false;
3015 // True if we have already processed the symbol table for the module.
3016 bool FoundValuesymtab = false;
3017 const bool IsParseParallel;
3019 // Generates names for unnamed global addresses (i.e. functions and global
3020 // variables). Then lowers global variable declaration initializers to the
3021 // target. May be called multiple times. Only the first call will do the
3023 void installGlobalNamesAndGlobalVarInitializers() {
3024 if (!GlobalDeclarationNamesAndInitializersInstalled) {
3025 Context->installGlobalNames();
3026 Context->createValueIDs();
3027 Context->verifyFunctionTypeSignatures();
3028 std::unique_ptr<Ice::VariableDeclarationList> Globals =
3029 Context->getGlobalVariables();
3031 getTranslator().lowerGlobals(std::move(Globals));
3032 GlobalDeclarationNamesAndInitializersInstalled = true;
3035 bool ParseBlock(unsigned BlockID) override;
3037 void ExitBlock() override {
3038 installGlobalNamesAndGlobalVarInitializers();
3039 Context->getTranslator().getContext()->waitForWorkerThreads();
3042 void ProcessRecord() override;
3045 class ModuleValuesymtabParser : public ValuesymtabParser {
3046 ModuleValuesymtabParser() = delete;
3047 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
3048 void operator=(const ModuleValuesymtabParser &) = delete;
3051 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
3052 : ValuesymtabParser(BlockID, MP),
3053 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
3054 getTranslator().getContext()) {}
3056 ~ModuleValuesymtabParser() override = default;
3059 Ice::TimerMarker Timer;
3060 const char *getTableKind() const override { return "Module"; }
3061 void setValueName(NaClBcIndexSize_t Index, StringType &Name) override;
3062 void setBbName(NaClBcIndexSize_t Index, StringType &Name) override;
3065 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
3067 Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index);
3068 if (llvm::isa<Ice::VariableDeclaration>(Decl) &&
3069 Decl->isPNaClABIExternalName(Name.str())) {
3070 // Force linkage of (specific) Global Variables be external for the PNaCl
3071 // ABI. PNaCl bitcode has a linkage field for Functions, but not for
3072 // GlobalVariables (because the latter is not needed for pexes, so it has
3074 Decl->setLinkage(llvm::GlobalValue::ExternalLinkage);
3077 // Unconditionally capture the name if it is provided in the input file,
3078 // regardless of whether dump is enabled or whether the symbol is internal vs
3079 // external. This fits in well with the lit tests, and most symbols in a
3080 // conforming pexe are nameless and don't take this path.
3081 Decl->setName(getTranslator().getContext(),
3082 StringRef(Name.data(), Name.size()));
3085 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3087 reportUnableToAssign("Basic block", Index, Name);
3090 class CfgParserWorkItem final : public Ice::OptWorkItem {
3091 CfgParserWorkItem() = delete;
3092 CfgParserWorkItem(const CfgParserWorkItem &) = delete;
3093 CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete;
3096 CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId,
3097 ModuleParser *ModParser, std::unique_ptr<uint8_t[]> Buffer,
3098 uintptr_t BufferSize, uint64_t StartBit, uint32_t SeqNumber)
3099 : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser),
3100 Buffer(std::move(Buffer)), BufferSize(BufferSize), StartBit(StartBit),
3101 SeqNumber(SeqNumber) {}
3102 std::unique_ptr<Ice::Cfg> getParsedCfg() override;
3103 ~CfgParserWorkItem() override = default;
3106 const unsigned BlockID;
3107 const NaClBcIndexSize_t FcnId;
3108 // Note: ModParser can't be const because the function parser needs to
3109 // access non-const member functions (of ModuleParser and TopLevelParser).
3110 // TODO(kschimpf): Fix this issue.
3111 ModuleParser *ModParser;
3112 const std::unique_ptr<uint8_t[]> Buffer;
3113 const uintptr_t BufferSize;
3114 const uint64_t StartBit;
3115 const uint32_t SeqNumber;
3118 std::unique_ptr<Ice::Cfg> CfgParserWorkItem::getParsedCfg() {
3119 NaClBitstreamCursor &OldCursor(ModParser->getCursor());
3120 llvm::NaClBitstreamReader Reader(OldCursor.getStartWordByteForBit(StartBit),
3121 Buffer.get(), Buffer.get() + BufferSize,
3122 OldCursor.getBitStreamReader());
3123 NaClBitstreamCursor NewCursor(Reader);
3124 NewCursor.JumpToBit(NewCursor.getWordBitNo(StartBit));
3125 FunctionParser Parser(BlockID, ModParser, FcnId, NewCursor);
3126 return Parser.parseFunction(SeqNumber);
3129 bool ModuleParser::ParseBlock(unsigned BlockID) {
3131 case naclbitc::BLOCKINFO_BLOCK_ID:
3132 return NaClBitcodeParser::ParseBlock(BlockID);
3133 case naclbitc::TYPE_BLOCK_ID_NEW: {
3134 TypesParser Parser(BlockID, this);
3135 return Parser.ParseThisBlock();
3137 case naclbitc::GLOBALVAR_BLOCK_ID: {
3138 GlobalsParser Parser(BlockID, this);
3139 return Parser.ParseThisBlock();
3141 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
3142 if (FoundValuesymtab)
3143 Fatal("Duplicate valuesymtab in module");
3145 // If we have already processed a function block (i.e. we have already
3146 // installed global names and variable initializers) we can no longer accept
3147 // the value symbol table. Names have already been generated.
3148 if (GlobalDeclarationNamesAndInitializersInstalled)
3149 Fatal("Module valuesymtab not allowed after function blocks");
3151 FoundValuesymtab = true;
3152 ModuleValuesymtabParser Parser(BlockID, this);
3153 return Parser.ParseThisBlock();
3155 case naclbitc::FUNCTION_BLOCK_ID: {
3156 installGlobalNamesAndGlobalVarInitializers();
3157 Ice::GlobalContext *Ctx = Context->getTranslator().getContext();
3158 uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber();
3159 NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID();
3160 if (IsParseParallel) {
3161 // Skip the block and copy into a buffer. Note: We copy into a buffer
3162 // using the top-level parser to make sure that the underlying
3163 // buffer reading from the data streamer is not thread safe.
3164 NaClBitstreamCursor &Cursor = Record.GetCursor();
3165 uint64_t StartBit = Cursor.GetCurrentBitNo();
3168 const uint64_t EndBit = Cursor.GetCurrentBitNo();
3169 const uintptr_t StartByte = Cursor.getStartWordByteForBit(StartBit);
3170 const uintptr_t EndByte = Cursor.getEndWordByteForBit(EndBit);
3171 const uintptr_t BufferSize = EndByte - StartByte;
3172 std::unique_ptr<uint8_t[]> Buffer((uint8_t *)(new uint8_t[BufferSize]));
3173 for (size_t i = Cursor.fillBuffer(Buffer.get(), BufferSize, StartByte);
3174 i < BufferSize; ++i) {
3177 Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>(
3178 BlockID, FcnId, this, std::move(Buffer), BufferSize, StartBit,
3182 FunctionParser Parser(BlockID, this, FcnId);
3183 std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber);
3184 bool Failed = Func->hasError();
3185 getTranslator().translateFcn(std::move(Func));
3186 return Failed && !Ice::getFlags().getAllowErrorRecovery();
3190 return BlockParserBaseClass::ParseBlock(BlockID);
3194 void ModuleParser::ProcessRecord() {
3195 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
3196 switch (Record.GetCode()) {
3197 case naclbitc::MODULE_CODE_VERSION: {
3198 // VERSION: [version#]
3199 if (!isValidRecordSize(1, "version"))
3201 uint64_t Version = Values[0];
3204 raw_string_ostream StrBuf(Buffer);
3205 StrBuf << "Unknown bitstream version: " << Version;
3206 Error(StrBuf.str());
3210 case naclbitc::MODULE_CODE_FUNCTION: {
3211 // FUNCTION: [type, callingconv, isproto, linkage]
3212 if (!isValidRecordSize(4, "address"))
3214 const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
3215 CallingConv::ID CallingConv;
3216 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3218 raw_string_ostream StrBuf(Buffer);
3219 StrBuf << "Function address has unknown calling convention: "
3221 Error(StrBuf.str());
3224 GlobalValue::LinkageTypes Linkage;
3225 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3227 raw_string_ostream StrBuf(Buffer);
3228 StrBuf << "Function address has unknown linkage. Found " << Values[3];
3229 Error(StrBuf.str());
3232 bool IsProto = Values[2] == 1;
3233 auto *Func = Ice::FunctionDeclaration::create(
3234 Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
3236 Context->setNextFunctionID(Func);
3240 BlockParserBaseClass::ProcessRecord();
3245 bool TopLevelParser::ParseBlock(unsigned BlockID) {
3246 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
3247 if (ParsedModuleBlock)
3248 Fatal("Input can't contain more than one module");
3249 ModuleParser Parser(BlockID, this);
3250 bool ParseFailed = Parser.ParseThisBlock();
3251 ParsedModuleBlock = true;
3254 // Generate error message by using default block implementation.
3255 BlockParserBaseClass Parser(BlockID, this);
3256 return Parser.ParseThisBlock();
3259 } // end of anonymous namespace
3263 void PNaClTranslator::translateBuffer(const std::string &IRFilename,
3264 MemoryBuffer *MemBuf) {
3265 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject(
3266 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()),
3267 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd())));
3268 translate(IRFilename, std::move(MemObj));
3271 void PNaClTranslator::translate(const std::string &IRFilename,
3272 std::unique_ptr<MemoryObject> &&MemObj) {
3273 // On error, we report_fatal_error to avoid destroying the MemObj. That may
3274 // still be in use by IceBrowserCompileServer. Otherwise, we need to change
3275 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also
3276 // need a hook to tell the IceBrowserCompileServer to unblock its
3278 // https://code.google.com/p/nativeclient/issues/detail?id=4163
3279 // Read header and verify it is good.
3280 NaClBitcodeHeader Header;
3281 if (Header.Read(MemObj.get())) {
3282 llvm::report_fatal_error("Invalid PNaCl bitcode header");
3284 if (!Header.IsSupported()) {
3285 getContext()->getStrError() << Header.Unsupported();
3286 if (!Header.IsReadable()) {
3287 llvm::report_fatal_error("Invalid PNaCl bitcode header");
3291 // Create a bitstream reader to read the bitcode file.
3292 NaClBitstreamReader InputStreamFile(MemObj.release(), Header);
3293 NaClBitstreamCursor InputStream(InputStreamFile);
3295 TopLevelParser Parser(*this, InputStream, ErrorStatus);
3296 while (!InputStream.AtEndOfStream()) {
3297 if (Parser.Parse()) {
3298 ErrorStatus.assign(EC_Bitcode);
3303 if (!Parser.parsedModuleBlock()) {
3305 raw_string_ostream StrBuf(Buffer);
3306 StrBuf << IRFilename << ": Does not contain a module!";
3307 llvm::report_fatal_error(StrBuf.str());
3309 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3310 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3314 } // end of namespace Ice