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"
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Wunused-parameter"
31 #include "llvm/ADT/Hashing.h"
32 #include "llvm/ADT/SmallString.h"
33 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
34 #include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h"
35 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
36 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
37 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
38 #include "llvm/Support/Format.h"
39 #include "llvm/Support/MemoryBuffer.h"
40 #include "llvm/Support/raw_ostream.h"
43 #pragma clang diagnostic pop
46 #include <unordered_set>
48 // Define a hash function for SmallString's, so that it can be used in hash
51 template <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> {
52 size_t operator()(const llvm::SmallString<InternalLen> &Key) const {
53 return llvm::hash_combine_range(Key.begin(), Key.end());
56 } // end of namespace std
61 // Models elements in the list of types defined in the types block. These
62 // elements can be undefined, a (simple) type, or a function type signature.
63 // Note that an extended type is undefined on construction. Use methods
64 // setAsSimpleType and setAsFuncSigType to define the extended type.
66 ExtendedType &operator=(const ExtendedType &Ty) = delete;
69 /// Discriminator for LLVM-style RTTI.
70 enum TypeKind { Undefined, Simple, FuncSig };
72 ExtendedType() = default;
73 ExtendedType(const ExtendedType &Ty) = default;
75 virtual ~ExtendedType() = default;
77 ExtendedType::TypeKind getKind() const { return Kind; }
78 void dump(Ice::Ostream &Stream) const;
80 /// Changes the extended type to a simple type with the given / value.
81 void setAsSimpleType(Ice::Type Ty) {
82 assert(Kind == Undefined);
84 Signature.setReturnType(Ty);
87 /// Changes the extended type to an (empty) function signature type.
88 void setAsFunctionType() {
89 assert(Kind == Undefined);
94 // Note: For simple types, the return type of the signature will be used to
95 // hold the simple type.
96 Ice::FuncSigType Signature;
99 ExtendedType::TypeKind Kind = Undefined;
102 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
103 if (!Ice::BuildDefs::dump())
109 Ice::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) {
110 if (!Ice::BuildDefs::dump())
112 Stream << "ExtendedType::";
114 case ExtendedType::Undefined:
115 Stream << "Undefined";
117 case ExtendedType::Simple:
120 case ExtendedType::FuncSig:
127 // Models an ICE type as an extended type.
128 class SimpleExtendedType : public ExtendedType {
129 SimpleExtendedType() = delete;
130 SimpleExtendedType(const SimpleExtendedType &) = delete;
131 SimpleExtendedType &operator=(const SimpleExtendedType &) = delete;
134 Ice::Type getType() const { return Signature.getReturnType(); }
136 static bool classof(const ExtendedType *Ty) {
137 return Ty->getKind() == Simple;
141 // Models a function signature as an extended type.
142 class FuncSigExtendedType : public ExtendedType {
143 FuncSigExtendedType() = delete;
144 FuncSigExtendedType(const FuncSigExtendedType &) = delete;
145 FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete;
148 const Ice::FuncSigType &getSignature() const { return Signature; }
149 void setReturnType(Ice::Type ReturnType) {
150 Signature.setReturnType(ReturnType);
152 void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); }
153 static bool classof(const ExtendedType *Ty) {
154 return Ty->getKind() == FuncSig;
158 void ExtendedType::dump(Ice::Ostream &Stream) const {
159 if (!Ice::BuildDefs::dump())
164 Stream << " " << Signature.getReturnType();
168 Stream << " " << Signature;
175 // Models integer literals as a sequence of bits. Used to read integer values
176 // from bitcode files. Based on llvm::APInt.
178 BitcodeInt() = delete;
179 BitcodeInt(const BitcodeInt &) = delete;
180 BitcodeInt &operator=(const BitcodeInt &) = delete;
183 BitcodeInt(Ice::SizeT Bits, uint64_t Val) : BitWidth(Bits), Val(Val) {
184 assert(Bits && "bitwidth too small");
185 assert(Bits <= BITS_PER_WORD && "bitwidth too big");
189 int64_t getSExtValue() const {
190 return static_cast<int64_t>(Val << (BITS_PER_WORD - BitWidth)) >>
191 (BITS_PER_WORD - BitWidth);
194 template <typename IntType, typename FpType>
195 inline FpType convertToFp() const {
196 static_assert(sizeof(IntType) == sizeof(FpType),
197 "IntType and FpType should be the same width");
198 assert(BitWidth == sizeof(IntType) * CHAR_BIT);
199 auto V = static_cast<IntType>(Val);
200 return Ice::Utils::bitCopy<FpType>(V);
204 /// Bits in the (internal) value.
205 static const Ice::SizeT BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT;
207 uint32_t BitWidth; /// The number of bits in the floating point number.
208 uint64_t Val; /// The (64-bit) equivalent integer value.
210 /// Clear unused high order bits.
211 void clearUnusedBits() {
212 // If all bits are used, we want to leave the value alone.
213 if (BitWidth == BITS_PER_WORD)
216 // Mask out the high bits.
217 Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth);
221 class BlockParserBaseClass;
223 // Top-level class to read PNaCl bitcode files, and translate to ICE.
224 class TopLevelParser : public NaClBitcodeParser {
225 TopLevelParser() = delete;
226 TopLevelParser(const TopLevelParser &) = delete;
227 TopLevelParser &operator=(const TopLevelParser &) = delete;
230 TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor,
231 Ice::ErrorCode &ErrorStatus)
232 : NaClBitcodeParser(Cursor), Translator(Translator),
233 ErrorStatus(ErrorStatus),
234 VariableDeclarations(new Ice::VariableDeclarationList()) {}
236 ~TopLevelParser() override = default;
238 Ice::Translator &getTranslator() const { return Translator; }
240 void setBlockParser(BlockParserBaseClass *NewBlockParser) {
241 BlockParser = NewBlockParser;
244 /// Generates error with given Message, occurring at BitPosition within the
245 /// bitcode file. Always returns true.
246 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition,
247 const std::string &Message) final;
249 /// Generates error message with respect to the current block parser.
250 bool blockError(const std::string &Message);
252 /// Returns the number of errors found while parsing the bitcode file.
253 unsigned getNumErrors() const { return NumErrors; }
255 /// Changes the size of the type list to the given size.
256 void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); }
258 size_t getNumTypeIDValues() const { return TypeIDValues.size(); }
260 /// Returns the undefined type associated with type ID. Note: Returns extended
261 /// type ready to be defined.
262 ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) {
263 // Get corresponding element, verifying the value is still undefined (and
264 // hence allowed to be defined).
265 ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined);
268 if (ID >= TypeIDValues.size()) {
269 if (ID >= NaClBcIndexSize_t_Max) {
271 raw_string_ostream StrBuf(Buffer);
272 StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max
274 blockError(StrBuf.str());
275 // Recover by using existing type slot.
276 return &TypeIDValues[0];
278 TypeIDValues.resize(ID + 1);
280 return &TypeIDValues[ID];
283 /// Returns the type associated with the given index.
284 Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) {
285 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple);
287 // Return error recovery value.
288 return Ice::IceType_void;
289 return cast<SimpleExtendedType>(Ty)->getType();
292 /// Returns the type signature associated with the given index.
293 const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) {
294 const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig);
296 // Return error recovery value.
297 return UndefinedFuncSigType;
298 return cast<FuncSigExtendedType>(Ty)->getSignature();
301 /// Sets the next function ID to the given LLVM function.
302 void setNextFunctionID(Ice::FunctionDeclaration *Fcn) {
303 FunctionDeclarations.push_back(Fcn);
306 /// Returns the value id that should be associated with the the current
307 /// function block. Increments internal counters during call so that it will
308 /// be in correct position for next function block.
309 NaClBcIndexSize_t getNextFunctionBlockValueID() {
310 size_t NumDeclaredFunctions = FunctionDeclarations.size();
311 while (NextDefiningFunctionID < NumDeclaredFunctions &&
312 FunctionDeclarations[NextDefiningFunctionID]->isProto())
313 ++NextDefiningFunctionID;
314 if (NextDefiningFunctionID >= NumDeclaredFunctions)
315 Fatal("More function blocks than defined function addresses");
316 return NextDefiningFunctionID++;
319 /// Returns the function associated with ID.
320 Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) {
321 if (ID < FunctionDeclarations.size())
322 return FunctionDeclarations[ID];
323 return reportGetFunctionByIDError(ID);
326 /// Returns the constant associated with the given global value ID.
327 Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) {
328 assert(ID < ValueIDConstants.size());
329 return ValueIDConstants[ID];
332 /// Install names for all global values without names. Called after the global
333 /// value symbol table is processed, but before any function blocks are
335 void installGlobalNames() {
336 assert(VariableDeclarations);
337 installGlobalVarNames();
338 installFunctionNames();
341 void verifyFunctionTypeSignatures();
343 void createValueIDs() {
344 assert(VariableDeclarations);
345 ValueIDConstants.reserve(VariableDeclarations->size() +
346 FunctionDeclarations.size());
347 createValueIDsForFunctions();
348 createValueIDsForGlobalVars();
351 /// Returns the number of function declarations in the bitcode file.
352 size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); }
354 /// Returns the number of global declarations (i.e. IDs) defined in the
356 size_t getNumGlobalIDs() const {
357 if (VariableDeclarations) {
358 return FunctionDeclarations.size() + VariableDeclarations->size();
360 return ValueIDConstants.size();
364 /// Adds the given global declaration to the end of the list of global
366 void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
367 assert(VariableDeclarations);
368 VariableDeclarations->push_back(Decl);
371 /// Returns the global variable declaration with the given index.
372 Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) {
373 assert(VariableDeclarations);
374 if (Index < VariableDeclarations->size())
375 return VariableDeclarations->at(Index);
376 return reportGetGlobalVariableByIDError(Index);
379 /// Returns the global declaration (variable or function) with the given
381 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) {
382 size_t NumFunctionIds = FunctionDeclarations.size();
383 if (Index < NumFunctionIds)
384 return getFunctionByID(Index);
386 return getGlobalVariableByID(Index - NumFunctionIds);
389 /// Returns true if a module block has been parsed.
390 bool parsedModuleBlock() const { return ParsedModuleBlock; }
392 /// Returns the list of parsed global variable declarations. Releases
393 /// ownership of the current list of global variables. Note: only returns
394 /// non-null pointer on first call. All successive calls return a null
396 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() {
397 // Before returning, check that ValidIDConstants has already been built.
398 assert(!VariableDeclarations ||
399 VariableDeclarations->size() <= ValueIDConstants.size());
400 return std::move(VariableDeclarations);
403 // Upper limit of alignment power allowed by LLVM
404 static constexpr uint32_t AlignPowerLimit = 29;
406 // Extracts the corresponding Alignment to use, given the AlignPower (i.e.
407 // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block
408 // context the alignment check appears in, and Prefix defines the context the
409 // alignment appears in.
410 uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix,
411 uint32_t AlignPower) {
412 if (AlignPower <= AlignPowerLimit + 1)
413 return (1 << AlignPower) >> 1;
415 raw_string_ostream StrBuf(Buffer);
416 StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit
417 << ". Found: 2**" << (AlignPower - 1);
418 Parser->Error(StrBuf.str());
419 // Error recover with value that is always acceptable.
424 // The translator associated with the parser.
425 Ice::Translator &Translator;
426 // The exit status that should be set to true if an error occurs.
427 Ice::ErrorCode &ErrorStatus;
428 // The number of errors reported.
429 unsigned NumErrors = 0;
430 // The types associated with each type ID.
431 std::vector<ExtendedType> TypeIDValues;
432 // The set of functions (prototype and defined).
433 Ice::FunctionDeclarationList FunctionDeclarations;
434 // The ID of the next possible defined function ID in FunctionDeclarations.
435 // FunctionDeclarations is filled first. It's the set of functions (either
436 // defined or isproto). Then function definitions are encountered/parsed and
437 // NextDefiningFunctionID is incremented to track the next actually-defined
439 size_t NextDefiningFunctionID = 0;
440 // The set of global variables.
441 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations;
442 // Relocatable constants associated with global declarations.
443 Ice::ConstantList ValueIDConstants;
444 // Error recovery value to use when getFuncSigTypeByID fails.
445 Ice::FuncSigType UndefinedFuncSigType;
446 // The block parser currently being applied. Used for error reporting.
447 BlockParserBaseClass *BlockParser = nullptr;
448 // Defines if a module block has already been parsed.
449 bool ParsedModuleBlock = false;
451 bool ParseBlock(unsigned BlockID) override;
453 // Gets extended type associated with the given index, assuming the extended
454 // type is of the WantedKind. Generates error message if corresponding
455 // extended type of WantedKind can't be found, and returns nullptr.
456 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID,
457 ExtendedType::TypeKind WantedKind) {
458 ExtendedType *Ty = nullptr;
459 if (ID < TypeIDValues.size()) {
460 Ty = &TypeIDValues[ID];
461 if (Ty->getKind() == WantedKind)
464 // Generate an error message and set ErrorStatus.
465 this->reportBadTypeIDAs(ID, Ty, WantedKind);
469 // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are
470 // used to generate the name. NameIndex is automatically incremented if a new
471 // name is created. DeclType is literal text describing the type of name
472 // being created. Also generates warning if created names may conflict with
473 // named declarations.
474 void installDeclarationName(Ice::GlobalDeclaration *Decl,
475 const Ice::IceString &Prefix,
476 const char *DeclType,
477 NaClBcIndexSize_t &NameIndex) {
478 if (Decl->hasName()) {
479 Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix);
481 Decl->setName(Translator.createUnnamedName(Prefix, NameIndex));
486 // Installs names for global variables without names.
487 void installGlobalVarNames() {
488 assert(VariableDeclarations);
489 const Ice::IceString &GlobalPrefix =
490 getTranslator().getFlags().getDefaultGlobalPrefix();
491 if (!GlobalPrefix.empty()) {
492 NaClBcIndexSize_t NameIndex = 0;
493 for (Ice::VariableDeclaration *Var : *VariableDeclarations) {
494 installDeclarationName(Var, GlobalPrefix, "global", NameIndex);
499 // Installs names for functions without names.
500 void installFunctionNames() {
501 const Ice::IceString &FunctionPrefix =
502 getTranslator().getFlags().getDefaultFunctionPrefix();
503 if (!FunctionPrefix.empty()) {
504 NaClBcIndexSize_t NameIndex = 0;
505 for (Ice::FunctionDeclaration *Func : FunctionDeclarations) {
506 installDeclarationName(Func, FunctionPrefix, "function", NameIndex);
511 // Builds a constant symbol named Name, suppressing name mangling if
512 // SuppressMangling. IsExternal is true iff the symbol is external.
513 Ice::Constant *getConstantSym(const Ice::IceString &Name,
514 bool SuppressMangling, bool IsExternal) const {
516 return getTranslator().getContext()->getConstantExternSym(Name);
518 const Ice::RelocOffsetT Offset = 0;
519 return getTranslator().getContext()->getConstantSym(Offset, Name,
524 void reportLinkageError(const char *Kind,
525 const Ice::GlobalDeclaration &Decl) {
527 raw_string_ostream StrBuf(Buffer);
528 StrBuf << Kind << " " << Decl.getName()
529 << " has incorrect linkage: " << Decl.getLinkageName();
530 if (Decl.isExternal())
531 StrBuf << "\n Use flag -allow-externally-defined-symbols to override";
535 // Converts function declarations into constant value IDs.
536 void createValueIDsForFunctions() {
537 Ice::GlobalContext *Ctx = getTranslator().getContext();
538 for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) {
539 if (!Func->verifyLinkageCorrect(Ctx))
540 reportLinkageError("Function", *Func);
541 Ice::Constant *C = getConstantSym(
542 Func->getName(), Func->getSuppressMangling(), Func->isProto());
543 ValueIDConstants.push_back(C);
547 // Converts global variable declarations into constant value IDs.
548 void createValueIDsForGlobalVars() {
549 Ice::GlobalContext *Ctx = getTranslator().getContext();
550 for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) {
551 if (!Decl->verifyLinkageCorrect(Ctx))
552 reportLinkageError("Global", *Decl);
554 getConstantSym(Decl->getName(), Decl->getSuppressMangling(),
555 !Decl->hasInitializer());
556 ValueIDConstants.push_back(C);
560 // Reports that type ID is undefined, or not of the WantedType.
561 void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty,
562 ExtendedType::TypeKind WantedType);
564 // Reports that there is no function declaration for ID. Returns an error
565 // recovery value to use.
566 Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID);
568 // Reports that there is not global variable declaration for ID. Returns an
569 // error recovery value to use.
570 Ice::VariableDeclaration *
571 reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index);
573 // Reports that there is no corresponding ICE type for LLVMTy, and returns
574 // Ice::IceType_void.
575 Ice::Type convertToIceTypeError(Type *LLVMTy);
578 bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
579 const std::string &Message) {
580 ErrorStatus.assign(Ice::EC_Bitcode);
582 Ice::GlobalContext *Context = Translator.getContext();
583 { // Lock while printing out error message.
584 Ice::OstreamLocker L(Context);
585 raw_ostream &OldErrStream = setErrStream(Context->getStrError());
586 NaClBitcodeParser::ErrorAt(Level, Bit, Message);
587 setErrStream(OldErrStream);
589 if (Level >= naclbitc::Error &&
590 !Translator.getFlags().getAllowErrorRecovery())
595 void TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID,
596 const ExtendedType *Ty,
597 ExtendedType::TypeKind WantedType) {
599 raw_string_ostream StrBuf(Buffer);
601 StrBuf << "Can't find extended type for type id: " << ID;
603 StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty;
605 blockError(StrBuf.str());
608 Ice::FunctionDeclaration *
609 TopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) {
611 raw_string_ostream StrBuf(Buffer);
612 StrBuf << "Function index " << ID
613 << " not allowed. Out of range. Must be less than "
614 << FunctionDeclarations.size();
615 blockError(StrBuf.str());
616 if (!FunctionDeclarations.empty())
617 return FunctionDeclarations[0];
621 Ice::VariableDeclaration *
622 TopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) {
624 raw_string_ostream StrBuf(Buffer);
625 StrBuf << "Global index " << Index
626 << " not allowed. Out of range. Must be less than "
627 << VariableDeclarations->size();
628 blockError(StrBuf.str());
629 if (!VariableDeclarations->empty())
630 return VariableDeclarations->at(0);
634 Ice::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) {
636 raw_string_ostream StrBuf(Buffer);
637 StrBuf << "Invalid LLVM type: " << *LLVMTy;
639 return Ice::IceType_void;
642 void TopLevelParser::verifyFunctionTypeSignatures() {
643 const Ice::GlobalContext *Ctx = getTranslator().getContext();
644 for (Ice::FunctionDeclaration *FuncDecl : FunctionDeclarations) {
645 if (!FuncDecl->validateTypeSignature(Ctx))
646 Error(FuncDecl->getTypeSignatureError(Ctx));
650 // Base class for parsing blocks within the bitcode file. Note: Because this is
651 // the base class of block parsers, we generate error messages if ParseBlock or
652 // ParseRecord is not overridden in derived classes.
653 class BlockParserBaseClass : public NaClBitcodeParser {
654 BlockParserBaseClass() = delete;
655 BlockParserBaseClass(const BlockParserBaseClass &) = delete;
656 BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete;
659 // Constructor for the top-level module block parser.
660 BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context)
661 : NaClBitcodeParser(BlockID, Context), Context(Context) {
662 Context->setBlockParser(this);
665 ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); }
667 // Returns the printable name of the type of block being parsed.
668 virtual const char *getBlockName() const {
669 // If this class is used, it is parsing an unknown block.
673 // Generates an error Message with the Bit address prefixed to it.
674 bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
675 const std::string &Message) final;
678 // The context parser that contains the decoded state.
679 TopLevelParser *Context;
681 // Constructor for nested block parsers.
682 BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
683 : NaClBitcodeParser(BlockID, EnclosingParser),
684 Context(EnclosingParser->Context) {}
686 // Gets the translator associated with the bitcode parser.
687 Ice::Translator &getTranslator() const { return Context->getTranslator(); }
689 const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); }
691 // Default implementation. Reports that block is unknown and skips its
693 bool ParseBlock(unsigned BlockID) override;
695 // Default implementation. Reports that the record is not understood.
696 void ProcessRecord() override;
698 // Checks if the size of the record is Size. Return true if valid. Otherwise
699 // generates an error and returns false.
700 bool isValidRecordSize(size_t Size, const char *RecordName) {
701 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
702 if (Values.size() == Size)
704 reportRecordSizeError(Size, RecordName, nullptr);
708 // Checks if the size of the record is at least as large as the LowerLimit.
709 // Returns true if valid. Otherwise generates an error and returns false.
710 bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) {
711 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
712 if (Values.size() >= LowerLimit)
714 reportRecordSizeError(LowerLimit, RecordName, "at least");
718 // Checks if the size of the record is no larger than the
719 // UpperLimit. Returns true if valid. Otherwise generates an error and
721 bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) {
722 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
723 if (Values.size() <= UpperLimit)
725 reportRecordSizeError(UpperLimit, RecordName, "no more than");
729 // Checks if the size of the record is at least as large as the LowerLimit,
730 // and no larger than the UpperLimit. Returns true if valid. Otherwise
731 // generates an error and returns false.
732 bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit,
733 const char *RecordName) {
734 return isValidRecordSizeAtLeast(LowerLimit, RecordName) ||
735 isValidRecordSizeAtMost(UpperLimit, RecordName);
739 /// Generates a record size error. ExpectedSize is the number of elements
740 /// expected. RecordName is the name of the kind of record that has incorrect
741 /// size. ContextMessage (if not nullptr) is appended to "record expects" to
742 /// describe how ExpectedSize should be interpreted.
743 void reportRecordSizeError(size_t ExpectedSize, const char *RecordName,
744 const char *ContextMessage);
747 bool TopLevelParser::blockError(const std::string &Message) {
749 return BlockParser->Error(Message);
751 return Error(Message);
754 // Generates an error Message with the bit address prefixed to it.
755 bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
756 const std::string &Message) {
758 raw_string_ostream StrBuf(Buffer);
759 // Note: If dump routines have been turned off, the error messages will not
760 // be readable. Hence, replace with simple error. We also use the simple form
762 if (getFlags().getGenerateUnitTestMessages()) {
763 StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode();
764 for (const uint64_t Val : Record.GetValues()) {
765 StrBuf << " " << Val;
771 return Context->ErrorAt(Level, Bit, StrBuf.str());
774 void BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize,
775 const char *RecordName,
776 const char *ContextMessage) {
778 raw_string_ostream StrBuf(Buffer);
779 const char *BlockName = getBlockName();
780 const char FirstChar = toupper(*BlockName);
781 StrBuf << FirstChar << (BlockName + 1) << " " << RecordName
782 << " record expects";
784 StrBuf << " " << ContextMessage;
785 StrBuf << " " << ExpectedSize << " argument";
786 if (ExpectedSize > 1)
788 StrBuf << ". Found: " << Record.GetValues().size();
792 bool BlockParserBaseClass::ParseBlock(unsigned BlockID) {
793 // If called, derived class doesn't know how to handle block. Report error
796 raw_string_ostream StrBuf(Buffer);
797 StrBuf << "Don't know how to parse block id: " << BlockID;
803 void BlockParserBaseClass::ProcessRecord() {
804 // If called, derived class doesn't know how to handle.
806 raw_string_ostream StrBuf(Buffer);
807 StrBuf << "Don't know how to process " << getBlockName()
808 << " record:" << Record;
812 // Class to parse a types block.
813 class TypesParser : public BlockParserBaseClass {
814 TypesParser() = delete;
815 TypesParser(const TypesParser &) = delete;
816 TypesParser &operator=(const TypesParser &) = delete;
819 TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
820 : BlockParserBaseClass(BlockID, EnclosingParser),
821 Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {}
823 ~TypesParser() override {
824 if (ExpectedNumTypes != Context->getNumTypeIDValues()) {
826 raw_string_ostream StrBuf(Buffer);
827 StrBuf << "Types block expected " << ExpectedNumTypes
828 << " types but found: " << NextTypeId;
834 Ice::TimerMarker Timer;
835 // The type ID that will be associated with the next type defining record in
837 NaClBcIndexSize_t NextTypeId = 0;
839 // The expected number of types, based on record TYPE_CODE_NUMENTRY.
840 NaClBcIndexSize_t ExpectedNumTypes = 0;
842 void ProcessRecord() override;
844 const char *getBlockName() const override { return "type"; }
846 void setNextTypeIDAsSimpleType(Ice::Type Ty) {
847 Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty);
851 void TypesParser::ProcessRecord() {
852 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
853 switch (Record.GetCode()) {
854 case naclbitc::TYPE_CODE_NUMENTRY: {
855 // NUMENTRY: [numentries]
856 if (!isValidRecordSize(1, "count"))
858 uint64_t Size = Values[0];
859 if (Size > NaClBcIndexSize_t_Max) {
861 raw_string_ostream StrBuf(Buffer);
862 StrBuf << "Size to big for count record: " << Size;
864 ExpectedNumTypes = NaClBcIndexSize_t_Max;
866 // The code double checks that Expected size and the actual size at the end
867 // of the block. To reduce allocations we preallocate the space.
869 // However, if the number is large, we suspect that the number is
870 // (possibly) incorrect. In that case, we preallocate a smaller space.
871 constexpr uint64_t DefaultLargeResizeValue = 1000000;
872 Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue));
873 ExpectedNumTypes = Size;
876 case naclbitc::TYPE_CODE_VOID:
878 if (!isValidRecordSize(0, "void"))
880 setNextTypeIDAsSimpleType(Ice::IceType_void);
882 case naclbitc::TYPE_CODE_FLOAT:
884 if (!isValidRecordSize(0, "float"))
886 setNextTypeIDAsSimpleType(Ice::IceType_f32);
888 case naclbitc::TYPE_CODE_DOUBLE:
890 if (!isValidRecordSize(0, "double"))
892 setNextTypeIDAsSimpleType(Ice::IceType_f64);
894 case naclbitc::TYPE_CODE_INTEGER:
896 if (!isValidRecordSize(1, "integer"))
900 setNextTypeIDAsSimpleType(Ice::IceType_i1);
903 setNextTypeIDAsSimpleType(Ice::IceType_i8);
906 setNextTypeIDAsSimpleType(Ice::IceType_i16);
909 setNextTypeIDAsSimpleType(Ice::IceType_i32);
912 setNextTypeIDAsSimpleType(Ice::IceType_i64);
919 raw_string_ostream StrBuf(Buffer);
920 StrBuf << "Type integer record with invalid bitsize: " << Values[0];
924 case naclbitc::TYPE_CODE_VECTOR: {
925 // VECTOR: [numelts, eltty]
926 if (!isValidRecordSize(2, "vector"))
928 Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]);
929 Ice::SizeT Size = Values[0];
931 case Ice::IceType_i1:
934 setNextTypeIDAsSimpleType(Ice::IceType_v4i1);
937 setNextTypeIDAsSimpleType(Ice::IceType_v8i1);
940 setNextTypeIDAsSimpleType(Ice::IceType_v16i1);
946 case Ice::IceType_i8:
948 setNextTypeIDAsSimpleType(Ice::IceType_v16i8);
952 case Ice::IceType_i16:
954 setNextTypeIDAsSimpleType(Ice::IceType_v8i16);
958 case Ice::IceType_i32:
960 setNextTypeIDAsSimpleType(Ice::IceType_v4i32);
964 case Ice::IceType_f32:
966 setNextTypeIDAsSimpleType(Ice::IceType_v4f32);
975 raw_string_ostream StrBuf(Buffer);
976 StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy
982 case naclbitc::TYPE_CODE_FUNCTION: {
983 // FUNCTION: [vararg, retty, paramty x N]
984 if (!isValidRecordSizeAtLeast(2, "signature"))
987 Error("Function type can't define varargs");
988 ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++);
989 Ty->setAsFunctionType();
990 auto *FuncTy = cast<FuncSigExtendedType>(Ty);
991 FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1]));
992 for (size_t i = 2, e = Values.size(); i != e; ++i) {
993 // Check that type void not used as argument type. Note: PNaCl
994 // restrictions can't be checked until we know the name, because we have
995 // to check for intrinsic signatures.
996 Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]);
997 if (ArgTy == Ice::IceType_void) {
999 raw_string_ostream StrBuf(Buffer);
1000 StrBuf << "Type for parameter " << (i - 1)
1001 << " not valid. Found: " << ArgTy;
1002 ArgTy = Ice::IceType_i32;
1004 FuncTy->appendArgType(ArgTy);
1009 BlockParserBaseClass::ProcessRecord();
1012 llvm_unreachable("Unknown type block record not processed!");
1015 /// Parses the globals block (i.e. global variable declarations and
1016 /// corresponding initializers).
1017 class GlobalsParser : public BlockParserBaseClass {
1018 GlobalsParser() = delete;
1019 GlobalsParser(const GlobalsParser &) = delete;
1020 GlobalsParser &operator=(const GlobalsParser &) = delete;
1023 GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1024 : BlockParserBaseClass(BlockID, EnclosingParser),
1025 Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
1026 NumFunctionIDs(Context->getNumFunctionIDs()),
1028 Ice::VariableDeclaration::create(getTranslator().getContext())),
1029 CurGlobalVar(DummyGlobalVar) {}
1031 ~GlobalsParser() final = default;
1033 const char *getBlockName() const override { return "globals"; }
1036 using GlobalVarsMapType =
1037 std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>;
1039 Ice::TimerMarker Timer;
1041 // Holds global variables generated/referenced in the global variables block.
1042 GlobalVarsMapType GlobalVarsMap;
1044 // Holds the number of defined function IDs.
1045 NaClBcIndexSize_t NumFunctionIDs;
1047 // Holds the specified number of global variables by the count record in the
1048 // global variables block.
1049 NaClBcIndexSize_t SpecifiedNumberVars = 0;
1051 // Keeps track of how many initializers are expected for the global variable
1052 // declaration being built.
1053 NaClBcIndexSize_t InitializersNeeded = 0;
1055 // The index of the next global variable declaration.
1056 NaClBcIndexSize_t NextGlobalID = 0;
1058 // Dummy global variable declaration to guarantee CurGlobalVar is always
1059 // defined (allowing code to not need to check if CurGlobalVar is nullptr).
1060 Ice::VariableDeclaration *DummyGlobalVar;
1062 // Holds the current global variable declaration being built.
1063 Ice::VariableDeclaration *CurGlobalVar;
1065 // Returns the global variable associated with the given Index.
1066 Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
1067 Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
1068 if (Decl == nullptr)
1069 Decl = Ice::VariableDeclaration::create(getTranslator().getContext());
1073 // Returns the global declaration associated with the given index.
1074 Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
1075 if (Index < NumFunctionIDs)
1076 return Context->getFunctionByID(Index);
1077 return getGlobalVarByID(Index - NumFunctionIDs);
1080 // If global variables parsed correctly, install them into the top-level
1082 void installGlobalVariables() {
1083 // Verify specified number of globals matches number found.
1084 size_t NumGlobals = GlobalVarsMap.size();
1085 if (SpecifiedNumberVars != NumGlobals ||
1086 SpecifiedNumberVars != NextGlobalID) {
1088 raw_string_ostream StrBuf(Buffer);
1089 StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
1090 << " global variables. Found: " << GlobalVarsMap.size();
1091 Error(StrBuf.str());
1094 // Install global variables into top-level context.
1095 for (size_t I = 0; I < NumGlobals; ++I)
1096 Context->addGlobalDeclaration(GlobalVarsMap[I]);
1099 void ExitBlock() override {
1100 verifyNoMissingInitializers();
1101 installGlobalVariables();
1102 BlockParserBaseClass::ExitBlock();
1105 void ProcessRecord() override;
1107 // Checks if the number of initializers for the CurGlobalVar is the same as
1108 // the number found in the bitcode file. If different, and error message is
1109 // generated, and the internal state of the parser is fixed so this condition
1110 // is no longer violated.
1111 void verifyNoMissingInitializers() {
1112 size_t NumInits = CurGlobalVar->getInitializers().size();
1113 if (InitializersNeeded != NumInits) {
1115 raw_string_ostream StrBuf(Buffer);
1116 StrBuf << "Global variable @g" << NextGlobalID << " expected "
1117 << InitializersNeeded << " initializer";
1118 if (InitializersNeeded > 1)
1120 StrBuf << ". Found: " << NumInits;
1121 Error(StrBuf.str());
1122 InitializersNeeded = NumInits;
1127 void GlobalsParser::ProcessRecord() {
1128 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1129 switch (Record.GetCode()) {
1130 case naclbitc::GLOBALVAR_COUNT:
1132 if (!isValidRecordSize(1, "count"))
1134 if (SpecifiedNumberVars || NextGlobalID) {
1135 Error("Globals count record not first in block.");
1138 SpecifiedNumberVars = Values[0];
1140 case naclbitc::GLOBALVAR_VAR: {
1141 // VAR: [align, isconst]
1142 if (!isValidRecordSize(2, "variable"))
1144 verifyNoMissingInitializers();
1145 // Always build the global variable, even if IR generation is turned off.
1146 // This is needed because we need a placeholder in the top-level context
1147 // when no IR is generated.
1148 uint32_t Alignment =
1149 Context->extractAlignment(this, "Global variable", Values[0]);
1150 CurGlobalVar = getGlobalVarByID(NextGlobalID);
1151 InitializersNeeded = 1;
1152 CurGlobalVar->setAlignment(Alignment);
1153 CurGlobalVar->setIsConstant(Values[1] != 0);
1157 case naclbitc::GLOBALVAR_COMPOUND:
1159 if (!isValidRecordSize(1, "compound"))
1161 if (!CurGlobalVar->getInitializers().empty()) {
1162 Error("Globals compound record not first initializer");
1165 if (Values[0] < 2) {
1167 raw_string_ostream StrBuf(Buffer);
1168 StrBuf << getBlockName()
1169 << " compound record size invalid. Found: " << Values[0];
1170 Error(StrBuf.str());
1173 InitializersNeeded = Values[0];
1175 case naclbitc::GLOBALVAR_ZEROFILL: {
1177 if (!isValidRecordSize(1, "zerofill"))
1179 CurGlobalVar->addInitializer(
1180 Ice::VariableDeclaration::ZeroInitializer::create(Values[0]));
1183 case naclbitc::GLOBALVAR_DATA: {
1184 // DATA: [b0, b1, ...]
1185 if (!isValidRecordSizeAtLeast(1, "data"))
1187 CurGlobalVar->addInitializer(
1188 Ice::VariableDeclaration::DataInitializer::create(Values));
1191 case naclbitc::GLOBALVAR_RELOC: {
1192 // RELOC: [val, [addend]]
1193 if (!isValidRecordSizeInRange(1, 2, "reloc"))
1195 NaClBcIndexSize_t Index = Values[0];
1196 NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
1197 if (Index >= IndexLimit) {
1199 raw_string_ostream StrBuf(Buffer);
1200 StrBuf << "Relocation index " << Index << " to big. Expect index < "
1202 Error(StrBuf.str());
1204 uint64_t Offset = 0;
1205 if (Values.size() == 2) {
1207 if (Offset > std::numeric_limits<uint32_t>::max()) {
1209 raw_string_ostream StrBuf(Buffer);
1210 StrBuf << "Addend of global reloc record too big: " << Offset;
1211 Error(StrBuf.str());
1214 Ice::GlobalContext *Ctx = getTranslator().getContext();
1215 CurGlobalVar->addInitializer(
1216 Ice::VariableDeclaration::RelocInitializer::create(
1217 getGlobalDeclByID(Index), {Ice::RelocOffset::create(Ctx, Offset)}));
1221 BlockParserBaseClass::ProcessRecord();
1226 /// Base class for parsing a valuesymtab block in the bitcode file.
1227 class ValuesymtabParser : public BlockParserBaseClass {
1228 ValuesymtabParser() = delete;
1229 ValuesymtabParser(const ValuesymtabParser &) = delete;
1230 void operator=(const ValuesymtabParser &) = delete;
1233 ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1234 : BlockParserBaseClass(BlockID, EnclosingParser) {}
1236 ~ValuesymtabParser() override = default;
1238 const char *getBlockName() const override { return "valuesymtab"; }
1241 using StringType = SmallString<128>;
1243 // Returns the name to identify the kind of symbol table this is
1244 // in error messages.
1245 virtual const char *getTableKind() const = 0;
1247 // Associates Name with the value defined by the given Index.
1248 virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1250 // Associates Name with the value defined by the given Index;
1251 virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0;
1253 // Reports that the assignment of Name to the value associated with
1254 // index is not possible, for the given Context.
1255 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
1259 using NamesSetType = std::unordered_set<StringType>;
1260 NamesSetType ValueNames;
1261 NamesSetType BlockNames;
1263 void ProcessRecord() override;
1265 // Extracts out ConvertedName. Returns true if unique wrt to Names.
1266 bool convertToString(NamesSetType &Names, StringType &ConvertedName) {
1267 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1268 for (size_t i = 1, e = Values.size(); i != e; ++i) {
1269 ConvertedName += static_cast<char>(Values[i]);
1271 auto Pair = Names.insert(ConvertedName);
1275 void ReportDuplicateName(const char *NameCat, StringType &Name);
1278 void ValuesymtabParser::reportUnableToAssign(const char *Context,
1279 NaClBcIndexSize_t Index,
1282 raw_string_ostream StrBuf(Buffer);
1283 StrBuf << getTableKind() << " " << getBlockName() << ": " << Context
1284 << " name '" << Name << "' can't be associated with index " << Index;
1285 Error(StrBuf.str());
1288 void ValuesymtabParser::ReportDuplicateName(const char *NameCat,
1291 raw_string_ostream StrBuf(Buffer);
1292 StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate "
1293 << NameCat << " name: '" << Name << "'";
1294 Error(StrBuf.str());
1297 void ValuesymtabParser::ProcessRecord() {
1298 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
1299 StringType ConvertedName;
1300 switch (Record.GetCode()) {
1301 case naclbitc::VST_CODE_ENTRY: {
1302 // VST_ENTRY: [ValueId, namechar x N]
1303 if (!isValidRecordSizeAtLeast(2, "value entry"))
1305 if (convertToString(ValueNames, ConvertedName))
1306 setValueName(Values[0], ConvertedName);
1308 ReportDuplicateName("value", ConvertedName);
1311 case naclbitc::VST_CODE_BBENTRY: {
1312 // VST_BBENTRY: [BbId, namechar x N]
1313 if (!isValidRecordSizeAtLeast(2, "basic block entry"))
1315 if (convertToString(BlockNames, ConvertedName))
1316 setBbName(Values[0], ConvertedName);
1318 ReportDuplicateName("block", ConvertedName);
1324 // If reached, don't know how to handle record.
1325 BlockParserBaseClass::ProcessRecord();
1329 /// Parses function blocks in the bitcode file.
1330 class FunctionParser : public BlockParserBaseClass {
1331 FunctionParser() = delete;
1332 FunctionParser(const FunctionParser &) = delete;
1333 FunctionParser &operator=(const FunctionParser &) = delete;
1336 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
1337 : BlockParserBaseClass(BlockID, EnclosingParser),
1338 Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
1339 Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()),
1340 FuncDecl(Context->getFunctionByID(FcnId)),
1341 CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
1342 NextLocalInstIndex(Context->getNumGlobalIDs()) {}
1344 bool convertFunction() {
1345 const Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs;
1346 Ice::TimerIdT TimerID = 0;
1347 const bool TimeThisFunction = getFlags().getTimeEachFunction();
1348 if (TimeThisFunction) {
1349 TimerID = getTranslator().getContext()->getTimerID(StackID,
1350 FuncDecl->getName());
1351 getTranslator().getContext()->pushTimer(TimerID, StackID);
1354 // Note: The Cfg is created, even when IR generation is disabled. This is
1355 // done to install a CfgLocalAllocator for various internal containers.
1356 Func = Ice::Cfg::create(getTranslator().getContext(),
1357 getTranslator().getNextSequenceNumber());
1358 Ice::Cfg::setCurrentCfg(Func.get());
1360 // TODO(kschimpf) Clean up API to add a function signature to a CFG.
1361 const Ice::FuncSigType &Signature = FuncDecl->getSignature();
1363 Func->setFunctionName(FuncDecl->getName());
1364 Func->setReturnType(Signature.getReturnType());
1365 Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
1366 CurrentNode = installNextBasicBlock();
1367 Func->setEntryNode(CurrentNode);
1368 for (Ice::Type ArgType : Signature.getArgList()) {
1369 Func->addArg(getNextInstVar(ArgType));
1372 bool ParserResult = ParseThisBlock();
1374 // Temporarily end per-function timing, which will be resumed by the
1375 // translator function. This is because translation may be done
1376 // asynchronously in a separate thread.
1377 if (TimeThisFunction)
1378 getTranslator().getContext()->popTimer(TimerID, StackID);
1380 Ice::Cfg::setCurrentCfg(nullptr);
1381 // Note: Once any errors have been found, we turn off all translation of
1382 // all remaining functions. This allows successive parsing errors to be
1383 // reported, without adding extra checks to the translator for such parsing
1385 if (Context->getNumErrors() == 0 && Func) {
1386 getTranslator().translateFcn(std::move(Func));
1387 // The translator now has ownership of Func.
1392 return ParserResult;
1395 ~FunctionParser() final = default;
1397 const char *getBlockName() const override { return "function"; }
1399 Ice::Cfg *getFunc() const { return Func.get(); }
1401 size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; }
1403 void setNextLocalInstIndex(Ice::Operand *Op) {
1404 setOperand(NextLocalInstIndex++, Op);
1407 // Set the next constant ID to the given constant C.
1408 void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); }
1410 // Returns the value referenced by the given value Index.
1411 Ice::Operand *getOperand(NaClBcIndexSize_t Index) {
1412 if (Index < CachedNumGlobalValueIDs) {
1413 return Context->getGlobalConstantByID(Index);
1415 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1416 if (LocalIndex >= LocalOperands.size())
1417 reportGetOperandUndefined(Index);
1418 Ice::Operand *Op = LocalOperands[LocalIndex];
1420 reportGetOperandUndefined(Index);
1425 Ice::TimerMarker Timer;
1426 // The number of words in the bitstream defining the function block.
1427 uint64_t NumBytesDefiningFunction = 0;
1428 // Maximum number of records that can appear in the function block, based on
1429 // the number of bytes defining the function block.
1430 uint64_t MaxRecordsInBlock = 0;
1431 // The corresponding ICE function defined by the function block.
1432 std::unique_ptr<Ice::Cfg> Func;
1433 // The index to the current basic block being built.
1434 NaClBcIndexSize_t CurrentBbIndex = 0;
1435 // The number of basic blocks declared for the function block.
1436 NaClBcIndexSize_t DeclaredNumberBbs = 0;
1437 // The basic block being built.
1438 Ice::CfgNode *CurrentNode = nullptr;
1439 // The ID for the function.
1440 NaClBcIndexSize_t FcnId;
1441 // The corresponding function declaration.
1442 Ice::FunctionDeclaration *FuncDecl;
1443 // Holds the dividing point between local and global absolute value indices.
1444 size_t CachedNumGlobalValueIDs;
1445 // Holds operands local to the function block, based on indices defined in
1446 // the bitcode file.
1447 Ice::OperandList LocalOperands;
1448 // Holds the index within LocalOperands corresponding to the next instruction
1449 // that generates a value.
1450 NaClBcIndexSize_t NextLocalInstIndex;
1451 // True if the last processed instruction was a terminating instruction.
1452 bool InstIsTerminating = false;
1454 bool ParseBlock(unsigned BlockID) override;
1456 void ProcessRecord() override;
1458 void EnterBlock(unsigned NumWords) final {
1459 // Note: Bitstream defines words as 32-bit values.
1460 NumBytesDefiningFunction = NumWords * sizeof(uint32_t);
1461 // We know that all records are minimally defined by a two-bit abreviation.
1462 MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1);
1465 void ExitBlock() override;
1467 // Creates and appends a new basic block to the list of basic blocks.
1468 Ice::CfgNode *installNextBasicBlock() {
1469 Ice::CfgNode *Node = Func->makeNode();
1473 // Returns the Index-th basic block in the list of basic blocks.
1474 Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
1475 if (Index >= Func->getNumNodes()) {
1477 raw_string_ostream StrBuf(Buffer);
1478 StrBuf << "Reference to basic block " << Index
1479 << " not found. Must be less than " << Func->getNumNodes();
1480 Error(StrBuf.str());
1483 return Func->getNodes()[Index];
1486 // Returns the Index-th basic block in the list of basic blocks. Assumes
1487 // Index corresponds to a branch instruction. Hence, if the branch references
1488 // the entry block, it also generates a corresponding error.
1489 Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) {
1491 Error("Branch to entry block not allowed");
1493 return getBasicBlock(Index);
1496 // Generate an instruction variable with type Ty.
1497 Ice::Variable *createInstVar(Ice::Type Ty) {
1498 if (Ty == Ice::IceType_void) {
1499 Error("Can't define instruction value using type void");
1500 // Recover since we can't throw an exception.
1501 Ty = Ice::IceType_i32;
1503 return Func->makeVariable(Ty);
1506 // Generates the next available local variable using the given type.
1507 Ice::Variable *getNextInstVar(Ice::Type Ty) {
1508 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs);
1509 // Before creating one, see if a forwardtyperef has already defined it.
1510 NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs;
1511 if (LocalIndex < LocalOperands.size()) {
1512 Ice::Operand *Op = LocalOperands[LocalIndex];
1513 if (Op != nullptr) {
1514 if (auto *Var = dyn_cast<Ice::Variable>(Op)) {
1515 if (Var->getType() == Ty) {
1516 ++NextLocalInstIndex;
1521 raw_string_ostream StrBuf(Buffer);
1522 StrBuf << "Illegal forward referenced instruction ("
1523 << NextLocalInstIndex << "): " << *Op;
1524 Error(StrBuf.str());
1525 ++NextLocalInstIndex;
1526 return createInstVar(Ty);
1529 Ice::Variable *Var = createInstVar(Ty);
1530 setOperand(NextLocalInstIndex++, Var);
1534 // Converts a relative index (wrt to BaseIndex) to an absolute value index.
1535 NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id,
1536 NaClRelBcIndexSize_t BaseIndex) {
1537 if (BaseIndex < Id) {
1539 raw_string_ostream StrBuf(Buffer);
1540 StrBuf << "Invalid relative value id: " << Id
1541 << " (must be <= " << BaseIndex << ")";
1542 Error(StrBuf.str());
1545 return BaseIndex - Id;
1548 // Sets element Index (in the local operands list) to Op.
1549 void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) {
1551 // Check if simple push works.
1552 NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
1553 if (LocalIndex == LocalOperands.size()) {
1554 LocalOperands.push_back(Op);
1558 // Must be forward reference, expand vector to accommodate.
1559 if (LocalIndex >= LocalOperands.size()) {
1560 if (LocalIndex > MaxRecordsInBlock) {
1562 raw_string_ostream StrBuf(Buffer);
1563 StrBuf << "Forward reference @" << Index << " too big. Have "
1564 << CachedNumGlobalValueIDs << " globals and function contains "
1565 << NumBytesDefiningFunction << " bytes";
1566 Fatal(StrBuf.str());
1567 // Recover by using index one beyond the maximal allowed.
1568 LocalIndex = MaxRecordsInBlock;
1570 LocalOperands.resize(LocalIndex + 1);
1573 // If element not defined, set it.
1574 Ice::Operand *OldOp = LocalOperands[LocalIndex];
1575 if (OldOp == nullptr) {
1576 LocalOperands[LocalIndex] = Op;
1580 // See if forward reference matches.
1584 // Error has occurred.
1586 raw_string_ostream StrBuf(Buffer);
1587 StrBuf << "Multiple definitions for index " << Index << ": " << *Op
1588 << " and " << *OldOp;
1589 Error(StrBuf.str());
1590 LocalOperands[LocalIndex] = Op;
1593 // Returns the relative operand (wrt to BaseIndex) referenced by the given
1595 Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index,
1596 NaClBcIndexSize_t BaseIndex) {
1597 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
1600 // Returns the absolute index of the next value generating instruction.
1601 NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; }
1603 // Generates type error message for binary operator Op operating on Type
1605 void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
1607 // Validates if integer logical Op, for type OpTy, is valid. Returns true if
1608 // valid. Otherwise generates error message and returns false.
1609 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1610 if (Ice::isIntegerType(OpTy))
1612 reportInvalidBinaryOp(Op, OpTy);
1616 // Validates if integer (or vector of integers) arithmetic Op, for type OpTy,
1617 // is valid. Returns true if valid. Otherwise generates error message and
1619 bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1620 if (Ice::isIntegerArithmeticType(OpTy))
1622 reportInvalidBinaryOp(Op, OpTy);
1626 // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if
1627 // valid. Otherwise generates an error message and returns false;
1628 bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) {
1629 if (Ice::isFloatingType(OpTy))
1631 reportInvalidBinaryOp(Op, OpTy);
1635 // Checks if the type of operand Op is the valid pointer type, for the given
1636 // InstructionName. Returns true if valid. Otherwise generates an error
1637 // message and returns false.
1638 bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) {
1639 Ice::Type PtrType = Ice::getPointerType();
1640 if (Op->getType() == PtrType)
1643 raw_string_ostream StrBuf(Buffer);
1644 StrBuf << InstructionName << " address not " << PtrType
1645 << ". Found: " << Op->getType();
1646 Error(StrBuf.str());
1650 // Checks if loading/storing a value of type Ty is allowed. Returns true if
1651 // Valid. Otherwise generates an error message and returns false.
1652 bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) {
1653 if (isLoadStoreType(Ty))
1656 raw_string_ostream StrBuf(Buffer);
1657 StrBuf << InstructionName << " type not allowed: " << Ty << "*";
1658 Error(StrBuf.str());
1662 // Checks if loading/storing a value of type Ty is allowed for the given
1663 // Alignment. Otherwise generates an error message and returns false.
1664 bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty,
1665 const char *InstructionName) {
1666 if (!isValidLoadStoreType(Ty, InstructionName))
1668 if (isAllowedAlignment(Alignment, Ty))
1671 raw_string_ostream StrBuf(Buffer);
1672 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment "
1674 Error(StrBuf.str());
1678 // Defines if the given alignment is valid for the given type. Simplified
1679 // version of PNaClABIProps::isAllowedAlignment, based on API's offered for
1681 bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const {
1682 return Alignment == typeAlignInBytes(Ty) ||
1683 (Alignment == 1 && !isVectorType(Ty));
1686 // Types of errors that can occur for insertelement and extractelement
1688 enum VectorIndexCheckValue {
1689 VectorIndexNotVector,
1690 VectorIndexNotConstant,
1691 VectorIndexNotInRange,
1696 void dumpVectorIndexCheckValue(raw_ostream &Stream,
1697 VectorIndexCheckValue Value) const {
1698 if (!Ice::BuildDefs::dump())
1701 case VectorIndexNotVector:
1702 Stream << "Vector index on non vector";
1704 case VectorIndexNotConstant:
1705 Stream << "Vector index not integer constant";
1707 case VectorIndexNotInRange:
1708 Stream << "Vector index not in range of vector";
1710 case VectorIndexNotI32:
1711 Stream << "Vector index not of type " << Ice::IceType_i32;
1713 case VectorIndexValid:
1714 Stream << "Valid vector index";
1719 // Returns whether the given vector index (for insertelement and
1720 // extractelement instructions) is valid.
1721 VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec,
1722 const Ice::Operand *Index) const {
1723 Ice::Type VecType = Vec->getType();
1724 if (!Ice::isVectorType(VecType))
1725 return VectorIndexNotVector;
1726 const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
1728 return VectorIndexNotConstant;
1729 if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
1730 return VectorIndexNotInRange;
1731 if (Index->getType() != Ice::IceType_i32)
1732 return VectorIndexNotI32;
1733 return VectorIndexValid;
1736 // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty,
1737 // and sets Op to the corresponding ICE binary opcode. Returns true if able
1738 // to convert, false otherwise.
1739 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty,
1740 Ice::InstArithmetic::OpKind &Op) {
1744 raw_string_ostream StrBuf(Buffer);
1745 StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty;
1746 Error(StrBuf.str());
1747 Op = Ice::InstArithmetic::Add;
1750 case naclbitc::BINOP_ADD:
1751 if (Ice::isIntegerType(Ty)) {
1752 Op = Ice::InstArithmetic::Add;
1753 return isValidIntegerArithOp(Op, Ty);
1755 Op = Ice::InstArithmetic::Fadd;
1756 return isValidFloatingArithOp(Op, Ty);
1758 case naclbitc::BINOP_SUB:
1759 if (Ice::isIntegerType(Ty)) {
1760 Op = Ice::InstArithmetic::Sub;
1761 return isValidIntegerArithOp(Op, Ty);
1763 Op = Ice::InstArithmetic::Fsub;
1764 return isValidFloatingArithOp(Op, Ty);
1766 case naclbitc::BINOP_MUL:
1767 if (Ice::isIntegerType(Ty)) {
1768 Op = Ice::InstArithmetic::Mul;
1769 return isValidIntegerArithOp(Op, Ty);
1771 Op = Ice::InstArithmetic::Fmul;
1772 return isValidFloatingArithOp(Op, Ty);
1774 case naclbitc::BINOP_UDIV:
1775 Op = Ice::InstArithmetic::Udiv;
1776 return isValidIntegerArithOp(Op, Ty);
1777 case naclbitc::BINOP_SDIV:
1778 if (Ice::isIntegerType(Ty)) {
1779 Op = Ice::InstArithmetic::Sdiv;
1780 return isValidIntegerArithOp(Op, Ty);
1782 Op = Ice::InstArithmetic::Fdiv;
1783 return isValidFloatingArithOp(Op, Ty);
1785 case naclbitc::BINOP_UREM:
1786 Op = Ice::InstArithmetic::Urem;
1787 return isValidIntegerArithOp(Op, Ty);
1788 case naclbitc::BINOP_SREM:
1789 if (Ice::isIntegerType(Ty)) {
1790 Op = Ice::InstArithmetic::Srem;
1791 return isValidIntegerArithOp(Op, Ty);
1793 Op = Ice::InstArithmetic::Frem;
1794 return isValidFloatingArithOp(Op, Ty);
1796 case naclbitc::BINOP_SHL:
1797 Op = Ice::InstArithmetic::Shl;
1798 return isValidIntegerArithOp(Op, Ty);
1799 case naclbitc::BINOP_LSHR:
1800 Op = Ice::InstArithmetic::Lshr;
1801 return isValidIntegerArithOp(Op, Ty);
1802 case naclbitc::BINOP_ASHR:
1803 Op = Ice::InstArithmetic::Ashr;
1804 return isValidIntegerArithOp(Op, Ty);
1805 case naclbitc::BINOP_AND:
1806 Op = Ice::InstArithmetic::And;
1807 return isValidIntegerLogicalOp(Op, Ty);
1808 case naclbitc::BINOP_OR:
1809 Op = Ice::InstArithmetic::Or;
1810 return isValidIntegerLogicalOp(Op, Ty);
1811 case naclbitc::BINOP_XOR:
1812 Op = Ice::InstArithmetic::Xor;
1813 return isValidIntegerLogicalOp(Op, Ty);
1817 /// Simplifies out vector types from Type1 and Type2, if both are vectors of
1818 /// the same size. Returns true iff both are vectors of the same size, or are
1819 /// both scalar types.
1820 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
1821 bool IsType1Vector = isVectorType(Type1);
1822 bool IsType2Vector = isVectorType(Type2);
1823 if (IsType1Vector != IsType2Vector)
1827 if (typeNumElements(Type1) != typeNumElements(Type2))
1829 Type1 = typeElementType(Type1);
1830 Type2 = typeElementType(Type2);
1834 /// Returns true iff an integer truncation from SourceType to TargetType is
1836 static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1837 return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) &&
1838 simplifyOutCommonVectorType(SourceType, TargetType) &&
1839 getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType);
1842 /// Returns true iff a floating type truncation from SourceType to TargetType
1844 static bool isFloatTruncCastValid(Ice::Type SourceType,
1845 Ice::Type TargetType) {
1846 return simplifyOutCommonVectorType(SourceType, TargetType) &&
1847 SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32;
1850 /// Returns true iff an integer extension from SourceType to TargetType is
1852 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1853 return isIntTruncCastValid(TargetType, SourceType);
1856 /// Returns true iff a floating type extension from SourceType to TargetType
1858 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
1859 return isFloatTruncCastValid(TargetType, SourceType);
1862 /// Returns true iff a cast from floating type SourceType to integer type
1863 /// TargetType is valid.
1864 static bool isFloatToIntCastValid(Ice::Type SourceType,
1865 Ice::Type TargetType) {
1866 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType)))
1868 bool IsSourceVector = isVectorType(SourceType);
1869 bool IsTargetVector = isVectorType(TargetType);
1870 if (IsSourceVector != IsTargetVector)
1872 if (IsSourceVector) {
1873 return typeNumElements(SourceType) == typeNumElements(TargetType);
1878 /// Returns true iff a cast from integer type SourceType to floating type
1879 /// TargetType is valid.
1880 static bool isIntToFloatCastValid(Ice::Type SourceType,
1881 Ice::Type TargetType) {
1882 return isFloatToIntCastValid(TargetType, SourceType);
1885 /// Returns the number of bits used to model type Ty when defining the bitcast
1887 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) {
1888 if (Ice::isVectorType(Ty))
1889 return Ice::typeNumElements(Ty) *
1890 bitcastSizeInBits(Ice::typeElementType(Ty));
1891 if (Ty == Ice::IceType_i1)
1893 return Ice::typeWidthInBytes(Ty) * CHAR_BIT;
1896 /// Returns true iff a bitcast from SourceType to TargetType is allowed.
1897 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) {
1898 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType);
1901 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for
1902 /// converting SourceType to TargetType. Updates CastKind to the corresponding
1903 /// instruction cast opcode. Also generates an error message when this
1904 /// function returns false.
1905 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType,
1906 Ice::Type TargetType,
1907 Ice::InstCast::OpKind &CastKind) {
1912 raw_string_ostream StrBuf(Buffer);
1913 StrBuf << "Cast opcode " << Opcode << " not understood.\n";
1914 Error(StrBuf.str());
1915 CastKind = Ice::InstCast::Bitcast;
1918 case naclbitc::CAST_TRUNC:
1919 CastKind = Ice::InstCast::Trunc;
1920 Result = isIntTruncCastValid(SourceType, TargetType);
1922 case naclbitc::CAST_ZEXT:
1923 CastKind = Ice::InstCast::Zext;
1924 Result = isIntExtCastValid(SourceType, TargetType);
1926 case naclbitc::CAST_SEXT:
1927 CastKind = Ice::InstCast::Sext;
1928 Result = isIntExtCastValid(SourceType, TargetType);
1930 case naclbitc::CAST_FPTOUI:
1931 CastKind = Ice::InstCast::Fptoui;
1932 Result = isFloatToIntCastValid(SourceType, TargetType);
1934 case naclbitc::CAST_FPTOSI:
1935 CastKind = Ice::InstCast::Fptosi;
1936 Result = isFloatToIntCastValid(SourceType, TargetType);
1938 case naclbitc::CAST_UITOFP:
1939 CastKind = Ice::InstCast::Uitofp;
1940 Result = isIntToFloatCastValid(SourceType, TargetType);
1942 case naclbitc::CAST_SITOFP:
1943 CastKind = Ice::InstCast::Sitofp;
1944 Result = isIntToFloatCastValid(SourceType, TargetType);
1946 case naclbitc::CAST_FPTRUNC:
1947 CastKind = Ice::InstCast::Fptrunc;
1948 Result = isFloatTruncCastValid(SourceType, TargetType);
1950 case naclbitc::CAST_FPEXT:
1951 CastKind = Ice::InstCast::Fpext;
1952 Result = isFloatExtCastValid(SourceType, TargetType);
1954 case naclbitc::CAST_BITCAST:
1955 CastKind = Ice::InstCast::Bitcast;
1956 Result = isBitcastValid(SourceType, TargetType);
1961 raw_string_ostream StrBuf(Buffer);
1962 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " "
1963 << SourceType << " to " << TargetType;
1964 Error(StrBuf.str());
1969 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true
1970 // if able to convert, false otherwise.
1971 bool convertNaClBitcICmpOpToIce(uint64_t Op,
1972 Ice::InstIcmp::ICond &Cond) const {
1974 case naclbitc::ICMP_EQ:
1975 Cond = Ice::InstIcmp::Eq;
1977 case naclbitc::ICMP_NE:
1978 Cond = Ice::InstIcmp::Ne;
1980 case naclbitc::ICMP_UGT:
1981 Cond = Ice::InstIcmp::Ugt;
1983 case naclbitc::ICMP_UGE:
1984 Cond = Ice::InstIcmp::Uge;
1986 case naclbitc::ICMP_ULT:
1987 Cond = Ice::InstIcmp::Ult;
1989 case naclbitc::ICMP_ULE:
1990 Cond = Ice::InstIcmp::Ule;
1992 case naclbitc::ICMP_SGT:
1993 Cond = Ice::InstIcmp::Sgt;
1995 case naclbitc::ICMP_SGE:
1996 Cond = Ice::InstIcmp::Sge;
1998 case naclbitc::ICMP_SLT:
1999 Cond = Ice::InstIcmp::Slt;
2001 case naclbitc::ICMP_SLE:
2002 Cond = Ice::InstIcmp::Sle;
2005 // Make sure Cond is always initialized.
2006 Cond = static_cast<Ice::InstIcmp::ICond>(0);
2011 // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true
2012 // if able to convert, false otherwise.
2013 bool convertNaClBitcFCompOpToIce(uint64_t Op,
2014 Ice::InstFcmp::FCond &Cond) const {
2016 case naclbitc::FCMP_FALSE:
2017 Cond = Ice::InstFcmp::False;
2019 case naclbitc::FCMP_OEQ:
2020 Cond = Ice::InstFcmp::Oeq;
2022 case naclbitc::FCMP_OGT:
2023 Cond = Ice::InstFcmp::Ogt;
2025 case naclbitc::FCMP_OGE:
2026 Cond = Ice::InstFcmp::Oge;
2028 case naclbitc::FCMP_OLT:
2029 Cond = Ice::InstFcmp::Olt;
2031 case naclbitc::FCMP_OLE:
2032 Cond = Ice::InstFcmp::Ole;
2034 case naclbitc::FCMP_ONE:
2035 Cond = Ice::InstFcmp::One;
2037 case naclbitc::FCMP_ORD:
2038 Cond = Ice::InstFcmp::Ord;
2040 case naclbitc::FCMP_UNO:
2041 Cond = Ice::InstFcmp::Uno;
2043 case naclbitc::FCMP_UEQ:
2044 Cond = Ice::InstFcmp::Ueq;
2046 case naclbitc::FCMP_UGT:
2047 Cond = Ice::InstFcmp::Ugt;
2049 case naclbitc::FCMP_UGE:
2050 Cond = Ice::InstFcmp::Uge;
2052 case naclbitc::FCMP_ULT:
2053 Cond = Ice::InstFcmp::Ult;
2055 case naclbitc::FCMP_ULE:
2056 Cond = Ice::InstFcmp::Ule;
2058 case naclbitc::FCMP_UNE:
2059 Cond = Ice::InstFcmp::Une;
2061 case naclbitc::FCMP_TRUE:
2062 Cond = Ice::InstFcmp::True;
2065 // Make sure Cond is always initialized.
2066 Cond = static_cast<Ice::InstFcmp::FCond>(0);
2071 // Creates an error instruction, generating a value of type Ty, and adds a
2072 // placeholder so that instruction indices line up. Some instructions, such
2073 // as a call, will not generate a value if the return type is void. In such
2074 // cases, a placeholder value for the badly formed instruction is not needed.
2075 // Hence, if Ty is void, an error instruction is not appended.
2076 void appendErrorInstruction(Ice::Type Ty) {
2077 // Note: we don't worry about downstream translation errors because the
2078 // function will not be translated if any errors occur.
2079 if (Ty == Ice::IceType_void)
2081 Ice::Variable *Var = getNextInstVar(Ty);
2082 CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var));
2085 Ice::Operand *reportGetOperandUndefined(NaClBcIndexSize_t Index) {
2087 raw_string_ostream StrBuf(Buffer);
2088 StrBuf << "Value index " << Index << " not defined!";
2089 Error(StrBuf.str());
2090 // Recover and return some value.
2091 if (!LocalOperands.empty())
2092 return LocalOperands.front();
2093 return Context->getGlobalConstantByID(0);
2096 void verifyCallArgTypeMatches(Ice::FunctionDeclaration *Fcn, Ice::SizeT Index,
2097 Ice::Type ArgType, Ice::Type ParamType) {
2098 if (ArgType != ParamType) {
2100 raw_string_ostream StrBuf(Buffer);
2101 StrBuf << "Argument " << (Index + 1) << " of " << printName(Fcn)
2102 << " expects " << ParamType << ". Found: " << ArgType;
2103 Error(StrBuf.str());
2107 const Ice::IceString printName(Ice::FunctionDeclaration *Fcn) {
2109 return Fcn->getName();
2114 void FunctionParser::ExitBlock() {
2115 // Check if the last instruction in the function was terminating.
2116 if (!InstIsTerminating) {
2117 Error("Last instruction in function not terminator");
2118 // Recover by inserting an unreachable instruction.
2119 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2122 if (CurrentBbIndex != DeclaredNumberBbs) {
2124 raw_string_ostream StrBuf(Buffer);
2125 StrBuf << "Function declared " << DeclaredNumberBbs
2126 << " basic blocks, but defined " << CurrentBbIndex << ".";
2127 Error(StrBuf.str());
2129 // Before translating, check for blocks without instructions, and insert
2130 // unreachable. This shouldn't happen, but be safe.
2132 for (Ice::CfgNode *Node : Func->getNodes()) {
2133 if (Node->getInsts().empty()) {
2135 raw_string_ostream StrBuf(Buffer);
2136 StrBuf << "Basic block " << Index << " contains no instructions";
2137 Error(StrBuf.str());
2138 Node->appendInst(Ice::InstUnreachable::create(Func.get()));
2142 Func->computeInOutEdges();
2145 void FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op,
2148 raw_string_ostream StrBuf(Buffer);
2149 StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op)
2150 << ". Found " << OpTy;
2151 Error(StrBuf.str());
2154 void FunctionParser::ProcessRecord() {
2155 // Note: To better separate parse/IR generation times, when IR generation is
2156 // disabled we do the following:
2157 // 1) Delay exiting until after we extract operands.
2158 // 2) return before we access operands, since all operands will be a nullptr.
2159 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2160 if (InstIsTerminating) {
2161 InstIsTerminating = false;
2163 CurrentNode = getBasicBlock(CurrentBbIndex);
2165 // The base index for relative indexing.
2166 NaClBcIndexSize_t BaseIndex = getNextInstIndex();
2167 switch (Record.GetCode()) {
2168 case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
2169 // DECLAREBLOCKS: [n]
2170 if (!isValidRecordSize(1, "count"))
2172 if (DeclaredNumberBbs > 0) {
2173 Error("Duplicate function block count record");
2177 // Check for bad large sizes, since they can make ridiculous memory
2178 // requests and hang the user for large amounts of time.
2179 uint64_t NumBbs = Values[0];
2180 if (NumBbs > MaxRecordsInBlock) {
2182 raw_string_ostream StrBuf(Buffer);
2183 StrBuf << "Function defines " << NumBbs
2184 << " basic blocks, which is too big for a function containing "
2185 << NumBytesDefiningFunction << " bytes";
2186 Error(StrBuf.str());
2187 NumBbs = MaxRecordsInBlock;
2191 Error("Functions must contain at least one basic block.");
2195 DeclaredNumberBbs = NumBbs;
2196 // Install the basic blocks, skipping bb0 which was created in the
2198 for (size_t i = 1; i < NumBbs; ++i)
2199 installNextBasicBlock();
2202 case naclbitc::FUNC_CODE_INST_BINOP: {
2203 // BINOP: [opval, opval, opcode]
2204 if (!isValidRecordSize(3, "binop"))
2206 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2207 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
2208 Ice::Type Type1 = Op1->getType();
2209 Ice::Type Type2 = Op2->getType();
2210 if (Type1 != Type2) {
2212 raw_string_ostream StrBuf(Buffer);
2213 StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
2214 Error(StrBuf.str());
2215 appendErrorInstruction(Type1);
2219 Ice::InstArithmetic::OpKind Opcode;
2220 if (!convertBinopOpcode(Values[2], Type1, Opcode)) {
2221 appendErrorInstruction(Type1);
2224 CurrentNode->appendInst(Ice::InstArithmetic::create(
2225 Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2));
2228 case naclbitc::FUNC_CODE_INST_CAST: {
2229 // CAST: [opval, destty, castopc]
2230 if (!isValidRecordSize(3, "cast"))
2232 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
2233 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
2234 Ice::InstCast::OpKind CastKind;
2235 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
2236 appendErrorInstruction(CastType);
2239 CurrentNode->appendInst(Ice::InstCast::create(
2240 Func.get(), CastKind, getNextInstVar(CastType), Src));
2243 case naclbitc::FUNC_CODE_INST_VSELECT: {
2244 // VSELECT: [opval, opval, pred]
2245 if (!isValidRecordSize(3, "select"))
2247 Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
2248 Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
2249 Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
2250 Ice::Type ThenType = ThenVal->getType();
2251 Ice::Type ElseType = ElseVal->getType();
2252 if (ThenType != ElseType) {
2254 raw_string_ostream StrBuf(Buffer);
2255 StrBuf << "Select operands not same type. Found " << ThenType << " and "
2257 Error(StrBuf.str());
2258 appendErrorInstruction(ThenType);
2261 Ice::Type CondType = CondVal->getType();
2262 if (isVectorType(CondType)) {
2263 if (!isVectorType(ThenType) ||
2264 typeElementType(CondType) != Ice::IceType_i1 ||
2265 typeNumElements(ThenType) != typeNumElements(CondType)) {
2267 raw_string_ostream StrBuf(Buffer);
2268 StrBuf << "Select condition type " << CondType
2269 << " not allowed for values of type " << ThenType;
2270 Error(StrBuf.str());
2271 appendErrorInstruction(ThenType);
2274 } else if (CondVal->getType() != Ice::IceType_i1) {
2276 raw_string_ostream StrBuf(Buffer);
2277 StrBuf << "Select condition " << CondVal
2278 << " not type i1. Found: " << CondVal->getType();
2279 Error(StrBuf.str());
2280 appendErrorInstruction(ThenType);
2283 CurrentNode->appendInst(Ice::InstSelect::create(
2284 Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
2287 case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
2288 // EXTRACTELT: [opval, opval]
2289 if (!isValidRecordSize(2, "extract element"))
2291 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
2292 Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
2293 Ice::Type VecType = Vec->getType();
2294 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2295 if (IndexCheckValue != VectorIndexValid) {
2297 raw_string_ostream StrBuf(Buffer);
2298 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2299 StrBuf << ": extractelement " << VecType << " " << *Vec << ", "
2300 << Index->getType() << " " << *Index;
2301 Error(StrBuf.str());
2302 appendErrorInstruction(VecType);
2305 CurrentNode->appendInst(Ice::InstExtractElement::create(
2306 Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index));
2309 case naclbitc::FUNC_CODE_INST_INSERTELT: {
2310 // INSERTELT: [opval, opval, opval]
2311 if (!isValidRecordSize(3, "insert element"))
2313 Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
2314 Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
2315 Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
2316 Ice::Type VecType = Vec->getType();
2317 VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
2318 if (IndexCheckValue != VectorIndexValid) {
2320 raw_string_ostream StrBuf(Buffer);
2321 dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
2322 StrBuf << ": insertelement " << VecType << " " << *Vec << ", "
2323 << Elt->getType() << " " << *Elt << ", " << Index->getType() << " "
2325 Error(StrBuf.str());
2326 appendErrorInstruction(Elt->getType());
2329 if (Ice::typeElementType(VecType) != Elt->getType()) {
2331 raw_string_ostream StrBuf(Buffer);
2332 StrBuf << "Insertelement: Element type "
2333 << Ice::typeString(Elt->getType()) << " doesn't match vector type "
2334 << Ice::typeString(VecType);
2335 Error(StrBuf.str());
2336 appendErrorInstruction(Elt->getType());
2339 CurrentNode->appendInst(Ice::InstInsertElement::create(
2340 Func.get(), getNextInstVar(VecType), Vec, Elt, Index));
2343 case naclbitc::FUNC_CODE_INST_CMP2: {
2344 // CMP2: [opval, opval, pred]
2345 if (!isValidRecordSize(3, "compare"))
2347 Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
2348 Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
2349 Ice::Type Op1Type = Op1->getType();
2350 Ice::Type Op2Type = Op2->getType();
2351 Ice::Type DestType = getCompareResultType(Op1Type);
2352 if (Op1Type != Op2Type) {
2354 raw_string_ostream StrBuf(Buffer);
2355 StrBuf << "Compare argument types differ: " << Op1Type << " and "
2357 Error(StrBuf.str());
2358 appendErrorInstruction(DestType);
2361 if (DestType == Ice::IceType_void) {
2363 raw_string_ostream StrBuf(Buffer);
2364 StrBuf << "Compare not defined for type " << Op1Type;
2365 Error(StrBuf.str());
2368 Ice::Variable *Dest = getNextInstVar(DestType);
2369 if (isIntegerType(Op1Type)) {
2370 Ice::InstIcmp::ICond Cond;
2371 if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
2373 raw_string_ostream StrBuf(Buffer);
2374 StrBuf << "Compare record contains unknown integer predicate index: "
2376 Error(StrBuf.str());
2377 appendErrorInstruction(DestType);
2379 CurrentNode->appendInst(
2380 Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2));
2381 } else if (isFloatingType(Op1Type)) {
2382 Ice::InstFcmp::FCond Cond;
2383 if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
2385 raw_string_ostream StrBuf(Buffer);
2386 StrBuf << "Compare record contains unknown float predicate index: "
2388 Error(StrBuf.str());
2389 appendErrorInstruction(DestType);
2391 CurrentNode->appendInst(
2392 Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2));
2394 // Not sure this can happen, but be safe.
2396 raw_string_ostream StrBuf(Buffer);
2397 StrBuf << "Compare on type not understood: " << Op1Type;
2398 Error(StrBuf.str());
2399 appendErrorInstruction(DestType);
2404 case naclbitc::FUNC_CODE_INST_RET: {
2406 InstIsTerminating = true;
2407 if (!isValidRecordSizeInRange(0, 1, "return"))
2409 if (Values.empty()) {
2410 CurrentNode->appendInst(Ice::InstRet::create(Func.get()));
2412 Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex);
2413 CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal));
2417 case naclbitc::FUNC_CODE_INST_BR: {
2418 InstIsTerminating = true;
2419 if (Values.size() == 1) {
2421 Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
2422 if (Block == nullptr)
2424 CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block));
2426 // BR: [bb#, bb#, opval]
2427 if (!isValidRecordSize(3, "branch"))
2429 Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
2430 if (Cond->getType() != Ice::IceType_i1) {
2432 raw_string_ostream StrBuf(Buffer);
2433 StrBuf << "Branch condition " << *Cond
2434 << " not i1. Found: " << Cond->getType();
2435 Error(StrBuf.str());
2438 Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]);
2439 Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
2440 if (ThenBlock == nullptr || ElseBlock == nullptr)
2442 CurrentNode->appendInst(
2443 Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock));
2447 case naclbitc::FUNC_CODE_INST_SWITCH: {
2448 // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
2449 // where Case = [1, 1, Value, BbIndex].
2451 // Note: Unlike most instructions, we don't infer the type of Cond, but
2452 // provide it as a separate field. There are also unnecessary data fields
2453 // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because
2454 // the bitcode format was already frozen when the problem was noticed.
2455 InstIsTerminating = true;
2456 if (!isValidRecordSizeAtLeast(4, "switch"))
2459 Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]);
2460 if (!Ice::isScalarIntegerType(CondTy)) {
2462 raw_string_ostream StrBuf(Buffer);
2463 StrBuf << "Case condition must be non-wide integer. Found: " << CondTy;
2464 Error(StrBuf.str());
2467 Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy);
2468 Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex);
2470 if (CondTy != Cond->getType()) {
2472 raw_string_ostream StrBuf(Buffer);
2473 StrBuf << "Case condition expects type " << CondTy
2474 << ". Found: " << Cond->getType();
2475 Error(StrBuf.str());
2478 Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]);
2479 if (DefaultLabel == nullptr)
2481 uint64_t NumCasesRaw = Values[3];
2482 if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) {
2484 raw_string_ostream StrBuf(Buffer);
2485 StrBuf << "Too many cases specified in switch: " << NumCasesRaw;
2486 Error(StrBuf.str());
2487 NumCasesRaw = std::numeric_limits<uint32_t>::max();
2489 uint32_t NumCases = NumCasesRaw;
2491 // Now recognize each of the cases.
2492 if (!isValidRecordSize(4 + NumCases * 4, "switch"))
2494 std::unique_ptr<Ice::InstSwitch> Switch(
2495 Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel));
2496 unsigned ValCaseIndex = 4; // index to beginning of case entry.
2497 for (uint32_t CaseIndex = 0; CaseIndex < NumCases;
2498 ++CaseIndex, ValCaseIndex += 4) {
2499 if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) {
2501 raw_string_ostream StrBuf(Buffer);
2502 StrBuf << "Sequence [1, 1, value, label] expected for case entry "
2503 << "in switch record. (at index" << ValCaseIndex << ")";
2504 Error(StrBuf.str());
2507 BitcodeInt Value(BitWidth,
2508 NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]));
2509 Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]);
2510 if (Label == nullptr)
2512 Switch->addBranch(CaseIndex, Value.getSExtValue(), Label);
2514 CurrentNode->appendInst(Switch.release());
2517 case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
2519 InstIsTerminating = true;
2520 if (!isValidRecordSize(0, "unreachable"))
2522 CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
2525 case naclbitc::FUNC_CODE_INST_PHI: {
2526 // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
2527 if (!isValidRecordSizeAtLeast(3, "phi"))
2529 Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
2530 if ((Values.size() & 0x1) == 0) {
2531 // Not an odd number of values.
2533 raw_string_ostream StrBuf(Buffer);
2534 StrBuf << "function block phi record size not valid: " << Values.size();
2535 Error(StrBuf.str());
2536 appendErrorInstruction(Ty);
2539 if (Ty == Ice::IceType_void) {
2540 Error("Phi record using type void not allowed");
2543 Ice::Variable *Dest = getNextInstVar(Ty);
2545 Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest);
2546 for (size_t i = 1; i < Values.size(); i += 2) {
2548 getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
2549 if (Op->getType() != Ty) {
2551 raw_string_ostream StrBuf(Buffer);
2552 StrBuf << "Value " << *Op << " not type " << Ty
2553 << " in phi instruction. Found: " << Op->getType();
2554 Error(StrBuf.str());
2555 appendErrorInstruction(Ty);
2558 Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
2560 CurrentNode->appendInst(Phi);
2563 case naclbitc::FUNC_CODE_INST_ALLOCA: {
2564 // ALLOCA: [Size, align]
2565 if (!isValidRecordSize(2, "alloca"))
2567 Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
2568 uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]);
2569 Ice::Type PtrTy = Ice::getPointerType();
2570 if (ByteCount->getType() != Ice::IceType_i32) {
2572 raw_string_ostream StrBuf(Buffer);
2573 StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
2574 Error(StrBuf.str());
2575 appendErrorInstruction(PtrTy);
2578 CurrentNode->appendInst(Ice::InstAlloca::create(
2579 Func.get(), getNextInstVar(PtrTy), ByteCount, Alignment));
2582 case naclbitc::FUNC_CODE_INST_LOAD: {
2583 // LOAD: [address, align, ty]
2584 if (!isValidRecordSize(3, "load"))
2586 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
2587 Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
2588 uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]);
2589 if (!isValidPointerType(Address, "Load")) {
2590 appendErrorInstruction(Ty);
2593 if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) {
2594 appendErrorInstruction(Ty);
2597 CurrentNode->appendInst(Ice::InstLoad::create(
2598 Func.get(), getNextInstVar(Ty), Address, Alignment));
2601 case naclbitc::FUNC_CODE_INST_STORE: {
2602 // STORE: [address, value, align]
2603 if (!isValidRecordSize(3, "store"))
2605 Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
2606 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
2607 uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]);
2608 if (!isValidPointerType(Address, "Store"))
2610 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
2612 CurrentNode->appendInst(
2613 Ice::InstStore::create(Func.get(), Value, Address, Alignment));
2616 case naclbitc::FUNC_CODE_INST_CALL:
2617 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
2618 // CALL: [cc, fnid, arg0, arg1...]
2619 // CALL_INDIRECT: [cc, fn, returnty, args...]
2621 // Note: The difference between CALL and CALL_INDIRECT is that CALL has a
2622 // reference to an explicit function declaration, while the CALL_INDIRECT
2623 // is just an address. For CALL, we can infer the return type by looking up
2624 // the type signature associated with the function declaration. For
2625 // CALL_INDIRECT we can only infer the type signature via argument types,
2626 // and the corresponding return type stored in CALL_INDIRECT record.
2627 Ice::SizeT ParamsStartIndex = 2;
2628 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
2629 if (!isValidRecordSizeAtLeast(2, "call"))
2632 if (!isValidRecordSizeAtLeast(3, "call indirect"))
2634 ParamsStartIndex = 3;
2637 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
2638 Ice::Operand *Callee = getOperand(CalleeIndex);
2640 // Pull out signature/return type of call (if possible).
2641 Ice::FunctionDeclaration *Fcn = nullptr;
2642 const Ice::FuncSigType *Signature = nullptr;
2643 Ice::Type ReturnType = Ice::IceType_void;
2644 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr;
2645 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) {
2646 Fcn = Context->getFunctionByID(CalleeIndex);
2647 Signature = &Fcn->getSignature();
2648 ReturnType = Signature->getReturnType();
2649 Ice::SizeT NumParams = Values.size() - ParamsStartIndex;
2650 if (NumParams != Signature->getNumArgs()) {
2652 raw_string_ostream StrBuf(Buffer);
2653 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2654 << " parameters. Signature expects: " << Signature->getNumArgs();
2655 Error(StrBuf.str());
2656 if (ReturnType != Ice::IceType_void)
2657 setNextLocalInstIndex(nullptr);
2661 // Check if this direct call is to an Intrinsic (starts with "llvm.")
2662 IntrinsicInfo = Fcn->getIntrinsicInfo(getTranslator().getContext());
2663 if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) {
2665 raw_string_ostream StrBuf(Buffer);
2666 StrBuf << "Call to " << printName(Fcn) << " has " << NumParams
2667 << " parameters. Intrinsic expects: " << Signature->getNumArgs();
2668 Error(StrBuf.str());
2669 if (ReturnType != Ice::IceType_void)
2670 setNextLocalInstIndex(nullptr);
2673 } else { // Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT
2674 // There is no signature. Assume defined by parameter types.
2675 ReturnType = Context->getSimpleTypeByID(Values[2]);
2676 if (Callee != nullptr)
2677 isValidPointerType(Callee, "Call indirect");
2680 if (Callee == nullptr)
2683 // Extract out the the call parameters.
2684 SmallVector<Ice::Operand *, 8> Params;
2685 for (Ice::SizeT Index = ParamsStartIndex; Index < Values.size(); ++Index) {
2686 Ice::Operand *Op = getRelativeOperand(Values[Index], BaseIndex);
2687 if (Op == nullptr) {
2689 raw_string_ostream StrBuf(Buffer);
2690 StrBuf << "Parameter " << (Index - ParamsStartIndex + 1) << " of "
2691 << printName(Fcn) << " is not defined";
2692 Error(StrBuf.str());
2693 if (ReturnType != Ice::IceType_void)
2694 setNextLocalInstIndex(nullptr);
2697 Params.push_back(Op);
2700 // Check return type.
2701 if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) {
2703 raw_string_ostream StrBuf(Buffer);
2704 StrBuf << "Return type of " << printName(Fcn)
2705 << " is invalid: " << ReturnType;
2706 Error(StrBuf.str());
2707 ReturnType = Ice::IceType_i32;
2710 // Type check call parameters.
2711 for (Ice::SizeT Index = 0; Index < Params.size(); ++Index) {
2712 Ice::Operand *Op = Params[Index];
2713 Ice::Type OpType = Op->getType();
2715 verifyCallArgTypeMatches(Fcn, Index, OpType,
2716 Signature->getArgType(Index));
2717 else if (!isCallParameterType(OpType)) {
2719 raw_string_ostream StrBuf(Buffer);
2720 StrBuf << "Argument " << *Op << " of " << printName(Fcn)
2721 << " has invalid type: " << Op->getType();
2722 Error(StrBuf.str());
2723 appendErrorInstruction(ReturnType);
2728 // Extract call information.
2729 uint64_t CCInfo = Values[0];
2730 CallingConv::ID CallingConv;
2731 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
2733 raw_string_ostream StrBuf(Buffer);
2734 StrBuf << "Function call calling convention value " << (CCInfo >> 1)
2735 << " not understood.";
2736 Error(StrBuf.str());
2737 appendErrorInstruction(ReturnType);
2740 bool IsTailCall = static_cast<bool>(CCInfo & 1);
2742 // Create the call instruction.
2743 Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
2745 : getNextInstVar(ReturnType);
2746 std::unique_ptr<Ice::InstCall> Inst;
2747 if (IntrinsicInfo) {
2748 Inst.reset(Ice::InstIntrinsicCall::create(Func.get(), Params.size(), Dest,
2749 Callee, IntrinsicInfo->Info));
2751 Inst.reset(Ice::InstCall::create(Func.get(), Params.size(), Dest, Callee,
2754 for (Ice::Operand *Param : Params)
2755 Inst->addArg(Param);
2756 CurrentNode->appendInst(Inst.release());
2759 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: {
2760 // FORWARDTYPEREF: [opval, ty]
2761 if (!isValidRecordSize(2, "forward type ref"))
2763 Ice::Type OpType = Context->getSimpleTypeByID(Values[1]);
2764 setOperand(Values[0], createInstVar(OpType));
2768 // Generate error message!
2769 BlockParserBaseClass::ProcessRecord();
2774 /// Parses constants within a function block.
2775 class ConstantsParser : public BlockParserBaseClass {
2776 ConstantsParser() = delete;
2777 ConstantsParser(const ConstantsParser &) = delete;
2778 ConstantsParser &operator=(const ConstantsParser &) = delete;
2781 ConstantsParser(unsigned BlockID, FunctionParser *FuncParser)
2782 : BlockParserBaseClass(BlockID, FuncParser),
2783 Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()),
2784 FuncParser(FuncParser) {}
2786 ~ConstantsParser() override = default;
2788 const char *getBlockName() const override { return "constants"; }
2791 Ice::TimerMarker Timer;
2792 // The parser of the function block this constants block appears in.
2793 FunctionParser *FuncParser;
2794 // The type to use for succeeding constants.
2795 Ice::Type NextConstantType = Ice::IceType_void;
2797 void ProcessRecord() override;
2799 Ice::GlobalContext *getContext() { return getTranslator().getContext(); }
2801 // Returns true if the type to use for succeeding constants is defined. If
2802 // false, also generates an error message.
2803 bool isValidNextConstantType() {
2804 if (NextConstantType != Ice::IceType_void)
2806 Error("Constant record not preceded by set type record");
2811 void ConstantsParser::ProcessRecord() {
2812 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
2813 switch (Record.GetCode()) {
2814 case naclbitc::CST_CODE_SETTYPE: {
2815 // SETTYPE: [typeid]
2816 if (!isValidRecordSize(1, "set type"))
2818 NextConstantType = Context->getSimpleTypeByID(Values[0]);
2819 if (NextConstantType == Ice::IceType_void)
2820 Error("constants block set type not allowed for void type");
2823 case naclbitc::CST_CODE_UNDEF: {
2825 if (!isValidRecordSize(0, "undef"))
2827 if (!isValidNextConstantType())
2829 FuncParser->setNextConstantID(
2830 getContext()->getConstantUndef(NextConstantType));
2833 case naclbitc::CST_CODE_INTEGER: {
2834 // INTEGER: [intval]
2835 if (!isValidRecordSize(1, "integer"))
2837 if (!isValidNextConstantType())
2839 if (Ice::isScalarIntegerType(NextConstantType)) {
2840 BitcodeInt Value(Ice::getScalarIntBitWidth(NextConstantType),
2841 NaClDecodeSignRotatedValue(Values[0]));
2842 if (Ice::Constant *C = getContext()->getConstantInt(
2843 NextConstantType, Value.getSExtValue())) {
2844 FuncParser->setNextConstantID(C);
2849 raw_string_ostream StrBuf(Buffer);
2850 StrBuf << "constant block integer record for non-integer type "
2851 << NextConstantType;
2852 Error(StrBuf.str());
2855 case naclbitc::CST_CODE_FLOAT: {
2857 if (!isValidRecordSize(1, "float"))
2859 if (!isValidNextConstantType())
2861 switch (NextConstantType) {
2862 case Ice::IceType_f32: {
2863 const BitcodeInt Value(32, static_cast<uint32_t>(Values[0]));
2864 float FpValue = Value.convertToFp<int32_t, float>();
2865 FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue));
2868 case Ice::IceType_f64: {
2869 const BitcodeInt Value(64, Values[0]);
2870 double FpValue = Value.convertToFp<uint64_t, double>();
2871 FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue));
2876 raw_string_ostream StrBuf(Buffer);
2877 StrBuf << "constant block float record for non-floating type "
2878 << NextConstantType;
2879 Error(StrBuf.str());
2885 // Generate error message!
2886 BlockParserBaseClass::ProcessRecord();
2891 // Parses valuesymtab blocks appearing in a function block.
2892 class FunctionValuesymtabParser : public ValuesymtabParser {
2893 FunctionValuesymtabParser() = delete;
2894 FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete;
2895 void operator=(const FunctionValuesymtabParser &) = delete;
2898 FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser)
2899 : ValuesymtabParser(BlockID, EnclosingParser),
2900 Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs,
2901 getTranslator().getContext()) {}
2904 Ice::TimerMarker Timer;
2905 // Returns the enclosing function parser.
2906 FunctionParser *getFunctionParser() const {
2907 return reinterpret_cast<FunctionParser *>(GetEnclosingParser());
2910 const char *getTableKind() const final { return "Function"; }
2912 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
2913 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
2915 // Reports that the assignment of Name to the value associated with index is
2916 // not possible, for the given Context.
2917 void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index,
2920 raw_string_ostream StrBuf(Buffer);
2921 StrBuf << "Function-local " << Context << " name '" << Name
2922 << "' can't be associated with index " << Index;
2923 Error(StrBuf.str());
2927 void FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
2929 // Note: We check when Index is too small, so that we can error recover
2930 // (FP->getOperand will create fatal error).
2931 if (Index < getFunctionParser()->getNumGlobalIDs()) {
2932 reportUnableToAssign("Global value", Index, Name);
2935 Ice::Operand *Op = getFunctionParser()->getOperand(Index);
2936 if (auto *V = dyn_cast<Ice::Variable>(Op)) {
2937 if (Ice::BuildDefs::dump()) {
2938 std::string Nm(Name.data(), Name.size());
2939 V->setName(getFunctionParser()->getFunc(), Nm);
2942 reportUnableToAssign("Local value", Index, Name);
2946 void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
2948 if (!Ice::BuildDefs::dump())
2950 if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
2951 reportUnableToAssign("Basic block", Index, Name);
2954 std::string Nm(Name.data(), Name.size());
2955 if (Ice::BuildDefs::dump())
2956 getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
2959 bool FunctionParser::ParseBlock(unsigned BlockID) {
2961 case naclbitc::CONSTANTS_BLOCK_ID: {
2962 ConstantsParser Parser(BlockID, this);
2963 return Parser.ParseThisBlock();
2965 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
2966 if (PNaClAllowLocalSymbolTables) {
2967 FunctionValuesymtabParser Parser(BlockID, this);
2968 return Parser.ParseThisBlock();
2975 return BlockParserBaseClass::ParseBlock(BlockID);
2978 /// Parses the module block in the bitcode file.
2979 class ModuleParser : public BlockParserBaseClass {
2980 ModuleParser() = delete;
2981 ModuleParser(const ModuleParser &) = delete;
2982 ModuleParser &operator=(const ModuleParser &) = delete;
2985 ModuleParser(unsigned BlockID, TopLevelParser *Context)
2986 : BlockParserBaseClass(BlockID, Context),
2987 Timer(Ice::TimerStack::TT_parseModule,
2988 Context->getTranslator().getContext()) {}
2990 ~ModuleParser() override = default;
2992 const char *getBlockName() const override { return "module"; }
2995 Ice::TimerMarker Timer;
2996 // True if we have already installed names for unnamed global declarations,
2997 // and have generated global constant initializers.
2998 bool GlobalDeclarationNamesAndInitializersInstalled = false;
2999 // True if we have already processed the symbol table for the module.
3000 bool FoundValuesymtab = false;
3002 // Generates names for unnamed global addresses (i.e. functions and global
3003 // variables). Then lowers global variable declaration initializers to the
3004 // target. May be called multiple times. Only the first call will do the
3006 void installGlobalNamesAndGlobalVarInitializers() {
3007 if (!GlobalDeclarationNamesAndInitializersInstalled) {
3008 Context->installGlobalNames();
3009 Context->createValueIDs();
3010 Context->verifyFunctionTypeSignatures();
3011 std::unique_ptr<Ice::VariableDeclarationList> Globals =
3012 Context->getGlobalVariables();
3014 getTranslator().lowerGlobals(std::move(Globals));
3015 GlobalDeclarationNamesAndInitializersInstalled = true;
3018 bool ParseBlock(unsigned BlockID) override;
3020 void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); }
3022 void ProcessRecord() override;
3025 class ModuleValuesymtabParser : public ValuesymtabParser {
3026 ModuleValuesymtabParser() = delete;
3027 ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete;
3028 void operator=(const ModuleValuesymtabParser &) = delete;
3031 ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP)
3032 : ValuesymtabParser(BlockID, MP),
3033 Timer(Ice::TimerStack::TT_parseModuleValuesymtabs,
3034 getTranslator().getContext()) {}
3036 ~ModuleValuesymtabParser() override = default;
3039 Ice::TimerMarker Timer;
3040 const char *getTableKind() const final { return "Module"; }
3041 void setValueName(NaClBcIndexSize_t Index, StringType &Name) final;
3042 void setBbName(NaClBcIndexSize_t Index, StringType &Name) final;
3045 void ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index,
3047 Context->getGlobalDeclarationByID(Index)
3048 ->setName(StringRef(Name.data(), Name.size()));
3051 void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
3053 reportUnableToAssign("Basic block", Index, Name);
3056 bool ModuleParser::ParseBlock(unsigned BlockID) {
3058 case naclbitc::BLOCKINFO_BLOCK_ID:
3059 return NaClBitcodeParser::ParseBlock(BlockID);
3060 case naclbitc::TYPE_BLOCK_ID_NEW: {
3061 TypesParser Parser(BlockID, this);
3062 return Parser.ParseThisBlock();
3064 case naclbitc::GLOBALVAR_BLOCK_ID: {
3065 GlobalsParser Parser(BlockID, this);
3066 return Parser.ParseThisBlock();
3068 case naclbitc::VALUE_SYMTAB_BLOCK_ID: {
3069 if (FoundValuesymtab)
3070 Fatal("Duplicate valuesymtab in module");
3072 // If we have already processed a function block (i.e. we have already
3073 // installed global names and variable initializers) we can no longer accept
3074 // the value symbol table. Names have already been generated.
3075 if (GlobalDeclarationNamesAndInitializersInstalled)
3076 Fatal("Module valuesymtab not allowed after function blocks");
3078 FoundValuesymtab = true;
3079 ModuleValuesymtabParser Parser(BlockID, this);
3080 return Parser.ParseThisBlock();
3082 case naclbitc::FUNCTION_BLOCK_ID: {
3083 installGlobalNamesAndGlobalVarInitializers();
3084 FunctionParser Parser(BlockID, this);
3085 return Parser.convertFunction();
3088 return BlockParserBaseClass::ParseBlock(BlockID);
3092 void ModuleParser::ProcessRecord() {
3093 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
3094 switch (Record.GetCode()) {
3095 case naclbitc::MODULE_CODE_VERSION: {
3096 // VERSION: [version#]
3097 if (!isValidRecordSize(1, "version"))
3099 uint64_t Version = Values[0];
3102 raw_string_ostream StrBuf(Buffer);
3103 StrBuf << "Unknown bitstream version: " << Version;
3104 Error(StrBuf.str());
3108 case naclbitc::MODULE_CODE_FUNCTION: {
3109 // FUNCTION: [type, callingconv, isproto, linkage]
3110 if (!isValidRecordSize(4, "address"))
3112 const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]);
3113 CallingConv::ID CallingConv;
3114 if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) {
3116 raw_string_ostream StrBuf(Buffer);
3117 StrBuf << "Function address has unknown calling convention: "
3119 Error(StrBuf.str());
3122 GlobalValue::LinkageTypes Linkage;
3123 if (!naclbitc::DecodeLinkage(Values[3], Linkage)) {
3125 raw_string_ostream StrBuf(Buffer);
3126 StrBuf << "Function address has unknown linkage. Found " << Values[3];
3127 Error(StrBuf.str());
3130 bool IsProto = Values[2] == 1;
3131 auto *Func = Ice::FunctionDeclaration::create(
3132 Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
3134 Context->setNextFunctionID(Func);
3138 BlockParserBaseClass::ProcessRecord();
3143 bool TopLevelParser::ParseBlock(unsigned BlockID) {
3144 if (BlockID == naclbitc::MODULE_BLOCK_ID) {
3145 if (ParsedModuleBlock)
3146 Fatal("Input can't contain more than one module");
3147 ModuleParser Parser(BlockID, this);
3148 bool ParseFailed = Parser.ParseThisBlock();
3149 ParsedModuleBlock = true;
3152 // Generate error message by using default block implementation.
3153 BlockParserBaseClass Parser(BlockID, this);
3154 return Parser.ParseThisBlock();
3157 } // end of anonymous namespace
3161 void PNaClTranslator::translateBuffer(const std::string &IRFilename,
3162 MemoryBuffer *MemBuf) {
3163 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject(
3164 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()),
3165 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd())));
3166 translate(IRFilename, std::move(MemObj));
3169 void PNaClTranslator::translate(const std::string &IRFilename,
3170 std::unique_ptr<MemoryObject> &&MemObj) {
3171 // On error, we report_fatal_error to avoid destroying the MemObj. That may
3172 // still be in use by IceBrowserCompileServer. Otherwise, we need to change
3173 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also
3174 // need a hook to tell the IceBrowserCompileServer to unblock its
3176 // https://code.google.com/p/nativeclient/issues/detail?id=4163
3177 // Read header and verify it is good.
3178 NaClBitcodeHeader Header;
3179 if (Header.Read(MemObj.get())) {
3180 llvm::report_fatal_error("Invalid PNaCl bitcode header");
3182 if (!Header.IsSupported()) {
3183 getContext()->getStrError() << Header.Unsupported();
3184 if (!Header.IsReadable()) {
3185 llvm::report_fatal_error("Invalid PNaCl bitcode header");
3189 // Create a bitstream reader to read the bitcode file.
3190 NaClBitstreamReader InputStreamFile(MemObj.release(), Header);
3191 NaClBitstreamCursor InputStream(InputStreamFile);
3193 TopLevelParser Parser(*this, InputStream, ErrorStatus);
3194 while (!InputStream.AtEndOfStream()) {
3195 if (Parser.Parse()) {
3196 ErrorStatus.assign(EC_Bitcode);
3201 if (!Parser.parsedModuleBlock()) {
3203 raw_string_ostream StrBuf(Buffer);
3204 StrBuf << IRFilename << ": Does not contain a module!";
3205 llvm::report_fatal_error(StrBuf.str());
3207 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
3208 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes");
3212 } // end of namespace Ice